1. 版本更新概览:Mods 到底是个什么机制
Claude Code 的版本号走到 2.1.287 之后,圈子里讨论最多的话题从"这周又更新了什么命令"变成了"Mods 真的能改行为"。这次更新确实有点不一样——它不是简单地在原有的 Agent 循环里加几个开关,而是正式引入了一套插件体系。你可以把 Mods 理解成 Claude Code 的"外挂模块":装上去之后,工具本身的交互流程、输出格式、命令执行策略都能被改写,而不是像以前那样只能被动地在官方留好的配置文件里填参数。
先说清楚这个功能解决的是什么问题。Claude Code 本质是一个跑在终端里的 AI 编程代理,你给它一个任务,它会自己读代码、改文件、执行终端命令、分析报错,然后不断迭代直到完成。在 2.1.287 之前,想调整它的行为,主流做法无非三条路:改 CLAUDE.md 项目记忆文件、改 settings.json 里的配置项、或者用 hooks 挂外部脚本。这三条路分别管的是"长期记忆""运行参数""事件回调",但都有一个共同的天花板——它们本质上是"配置",不是"扩展"。你只能在官方预留的格子里填内容,改不了工具自身的交互框架。
Mods 的思路是把这个天花板捅破。它允许你以模块化的方式注入自定义逻辑,让插件可以影响 Claude Code 在"看到什么、决定做什么、怎么执行、怎么汇报"这四个环节上的表现。换句话说,以前你问"怎么让 Claude Code 更听话",答案往往是"去 CLAUDE.md 里写清楚规则";现在你可以直接问"怎么给 Claude Code 装一个专门负责某类任务的 Mod",然后真的装一个进去。
这个版本值得谁关注?如果你只是偶尔用 Claude Code 写点小脚本,Mods 对你来说属于"知道有这回事就行";但如果你长期用 Agent 模式跑项目重构、批量改代码、自动化测试修复这类重复性高的活儿,或者你维护着多个项目、希望不同项目有完全不同的 Agent 工作风格,那 Mods 就是这轮更新里最值得花时间研究的东西。下面的内容我会从机制原理、安装配置、手写 Mod、踩坑实录几个角度完整拆一遍,尽量让看完的人能直接上手。
2. 行为改造机制解析:Mods 为什么能做到"改行为"
2.1 从配置到扩展:旧方案的三种手段与天花板
在进入 Mods 的细节之前,值得先把"为什么以前改行为那么费劲"这件事讲透。Claude Code 早期版本的行为控制,主要依赖下面三样东西:
- CLAUDE.md:这是项目级的记忆文件。Claude Code 每次启动会话时都会读取它,把它当作最重要的上下文。你可以在里面写项目结构说明、代码规范、禁止事项,甚至直接规定"改完代码必须跑测试"。它管的是"Agent 的价值观和长期记忆"。
- settings.json:用户级或项目级的配置文件,控制模型参数、权限开关、默认行为。比如是否允许自动执行终端命令、超时时间、输出是否带详细日志。它管的是"运行参数"。
- Hooks:事件回调机制。Claude Code 在执行某些关键动作(比如读取文件、执行命令、生成回复)前后,可以调用外部脚本,根据脚本返回值决定是否放行。它管的是"流程拦截"。
这三者的共同问题是:它们都是"声明式的格子"。CLAUDE.md 是给模型读的自然语言文本,能不能执行到位取决于模型理解;settings.json 是固定字段的 JSON,没有的功能就是没有;hooks 虽然灵活,但它是"夹在官方流程里的小程序",只负责在特定节点返回"允许/禁止/改文本",你很难让一个 hook 完整接管某一段对话逻辑。
这就导致了一个很实际的痛点:你想让 Claude Code 在一些复杂场景下做出"结构性改变"——比如在生成代码时自动套用某个团队的模板、在回答前先检索项目里的某些文档、或者把多轮任务的结果按特定格式汇总——旧方案要么靠反复写提示词碰运气,要么写一堆文件系统和流程相关的胶水代码。Mods 的出现,本质上是把"填格子"升级成"装零件"。
2.2 Mods 的挂载点设计:四层注入模型
Mods 的核心设计是"挂载点"(Mount Point)。你可以把 Claude Code 的 Agent 循环拆成四个阶段:上下文收集、意图规划、动作执行、结果呈现。每个阶段都有对应的挂载点,Mod 可以指定自己挂在哪一层,从而精确地干预行为。
以官方文档和社区实践里常见的设计来归纳,挂载点大致分四类:
| 挂载点 | 干预阶段 | 典型用途 |
|---|---|---|
| context | 上下文收集 | 自动注入项目信息、读取额外文档、过滤无关文件 |
| plan | 意图规划 | 改写任务拆解策略、调整工具选择优先级 |
| action | 动作执行 | 拦截或改写终端命令、文件编辑、审批流程 |
| respond | 结果呈现 | 定制输出格式、追加摘要、格式化 diff |
这个设计的妙处在于,它跟 hooks 是互补而不是替代。Hooks 是"事件触发的外部钩子",偏底层、偏拦截;Mods 是"业务逻辑包",可以把多个小行为打包成一个可开关、可卸载的单元。你甚至可以在一个 Mod 内部同时挂到 plan 和 respond 两层,让"思考"和"汇报"保持一致风格。
2.3 Mods 与子代理、hooks 的关系
很多人第一次接触 Mods 会把它和 Subagents(子代理)搞混。这里有个简单的区分方式:子代理是"另一个独立的 Agent 实体",Claude Code 会把一部分任务委派给子代理执行;Mods 是"寄生在主 Agent 上的行为插件",它不作为一个独立实体存在,而是直接修改主 Agent 的运行逻辑。两者的关系有点像操作系统的"进程"和"内核模块"——子代理像是一个新进程,Mods 则像加载进内核的驱动,直接影响系统调用行为。
至于和 hooks 的关系,我在实际使用中的理解是:hooks 适合做"结构化回调",比如命令执行后的验证、文件变更前的安全检查,这类逻辑用脚本写更可靠;Mods 适合做"经验化定制",比如让 Agent 在遇到测试失败时先看最近三个 commit 再决定怎么修,这种规则用 Mod 写会更贴近自然语言的表达方式。
从 2.1.287 开始,Claude Code 的插件能力从"被动响应"变成了"主动参与"。这也是社区把这次更新称为"Claude Code 的插件元年"的原因——虽然版本号只是小版本递增,但架构层面的意义不小。
3. 实操:升级到 2.1.287 并装好第一个 Mod
3.1 升级与安装:两种主路径
不管你是新装还是旧版本升级,先确认一件事:Mods 功能在 2.1.287 版本里才完整可用,版本太低连目录都不会生成。如果你之前装过 Claude Code,直接在终端里跑一下升级命令就行。官方推荐的安装方式是 npm 包@anthropic-ai/claude-code,所以在大多数环境里:
# 升级到最新版本 npm update -g @anthropic-ai/claude-code # 确认版本号 claude --version如果你是在 VS Code 里用的 Claude Code 扩展,记得把扩展也更新到配套版本。插件市场里的扩展版本和 CLI 版本是绑定的,只升级一边可能出现"扩展连不上 CLI"的问题。我自己在 VS Code 里遇到过几次这种版本错位的问题,排查到最后都是两边版本不一致导致的,所以升级时尽量同步操作。
Ubuntu 这类 Linux 环境下的配置也不复杂,需要注意的点主要是 npm 的全局安装路径权限。如果你之前是用 root 装的,升级时碰到 EACCES 权限错误,大概率是 npm 全局目录的归属问题,用npm config get prefix确认目录后,把权限处理好再升级。这个坑在 macOS 和 Ubuntu 上我都踩过,后面排查实录里会详细说。
3.2 初始化 Mods 目录结构
装好 2.1.287 之后,第一次启动 Claude Code 时会在用户配置目录下生成 Mods 的默认结构。以常见路径来说,项目级的 Mods 目录是项目根目录下的.claude/mods/,用户级的是~/.claude/mods/。如果你启动后没看到这两个目录,可以手动建,Claude Code 会自动识别。
# 项目级 Mods 目录 mkdir -p .claude/mods # 用户级 Mods 目录(所有项目共享) mkdir -p ~/.claude/mods每个 Mod 就是一个独立的子目录,目录名建议用 kebab-case 命名,比如code-reviewer、commit-message-formatter。Mod 内部需要有一个入口文件,通常是mod.md(用 Markdown 写行为描述和规则)加一个可选的mod.json(声明挂载点、版本、依赖)。第一次上手,我建议先从一个纯 Markdown 描述的 Mod 开始,不写任何脚本,先感受一下"规则注入"和以前写 CLAUDE.md 有什么不同。
3.3 启停与状态查看
Mods 设计了一个很实用的特性:按项目开关。CLAUDE.md 是一份全局生效的记忆文件,你没法只对某一个项目禁用某段内容;Mods 则可以精确到"这个项目只启用这几个 Mod"。常用操作命令大概是这样的:
# 查看当前启用的 Mods 列表 claude mods list # 为当前项目启用某个 Mod claude mods enable code-reviewer # 禁用某个 Mod claude mods disable code-reviewer如果是在交互式会话里,也可以直接敲斜杠命令,比如/mods查看列表,/mods enable <名称>启用。新版 Claude Code 的命令基本都支持斜杠补全,输入一半按 Tab 就能看到候选。
这里有一个关键概念要提前说明:Mods 的"启用"和"安装"是分开的。你把一个 Mod 目录放进.claude/mods/只是"安装",它默认可能是停用的;必须执行 enable 之后才会被加载进 Agent 的上下文。这个设计避免了"装了一堆插件结果互相冲突"的尴尬,也给排查问题留了干净的开关。
4. 写一个真正能改行为的 Mod
4.1 最小可用 Mod:从"改输出风格"开始
我建议任何人第一次写 Mod,都从一个"改输出风格"的小目标入手,不要一上来就做复杂拦截。原因很简单:输出风格是肉眼可见的变化,成功了会有直观正反馈,失败了也容易排查。拿我自己写的第一个 Mod 举例,目标很简单——让 Claude Code 在每次完成代码修改后,用固定的三段式结构汇报:改了什么、为什么改、怎么验证。
这个 Mod 的入口文件mod.md内容大致如下:
# 行为规则:代码修改汇报 当一次任务涉及修改代码文件时,在最终回复中强制使用以下结构: ## 变更摘要 用三到五条要点列出本次改动的文件与改动内容 ## 决策原因 解释每个关键改动的理由,引用相关文件作为依据 ## 验证建议 给出具体的测试命令或人工检查步骤 如果任务没有涉及代码修改,则忽略本规则。就这么十几行文字,放进.claude/mods/report-formatter/mod.md,然后执行claude mods enable report-formatter,下一次会话里 Claude Code 的输出结构就会改变。你可能会问:这和直接在 CLAUDE.md 里写规则有什么区别?区别在于作用域和替换方式。CLAUDE.md 里的规则是"叠加"在系统提示词里的,写多了会膨胀,而且全项目处处生效;Mods 的规则是"模块化"的,可以独立开关,也可以被更高优先级的 Mod 替换。
4.2 用挂载点声明做"执行拦截"
纯规则类 Mod 适合改"输出风格",但如果你想改的是"执行行为",就需要用到挂载点声明了。比如我曾经写过一个 Mod,目标是禁止 Claude Code 在未确认的情况下直接执行git push这类有副作用的风险命令。这个 Mod 不能只靠文字规则,因为模型可能在长任务推进过程中忽略末尾的约束,必须让它在执行动作前被机械地检查一次。
这就是挂载点action的用武之地。声明文件mod.json大致长这样:
{ "name": "safe-git", "version": "1.0.0", "mounts": { "action": { "filter": "command", "policy": "blocklist" } } }然后在行为规则文件里,把"需要确认的命令清单"写清楚,比如包含git push、git push --force、rm -rf、DROP TABLE之类的模式。当 Claude Code 准备执行终端命令时,挂载在 action 层的 Mod 会先检查命令内容,命中黑名单就阻止执行,并返回一条提示让 Agent 先向用户确认。
这个流程本质上和 hooks 的PreToolUse很像,差别在于 Mods 把"规则描述"和"执行逻辑"分开了——规则用自然语言写,挂在哪个环节用配置声明。对不擅长写脚本的人来说,这比直接写 hook 脚本友好得多;对熟悉 hooks 的人来说,Mods 提供了更语义化的封装。
4.3 多 Mod 之间的优先级与冲突处理
当你的 Mods 数量超过三五个之后,一定会遇到冲突问题。我在实际使用中遇到过最典型的场景是:一个 Mod 要求"所有回复必须简洁",另一个 Mod 要求"代码修改必须有详细的三段式汇报",两条规则打架,Claude Code 的输出变得忽长忽短。
Mods 机制里对这个问题提供了两种处理手段。
第一种是优先级声明,通过mod.json里的priority字段设置:
{ "name": "report-formatter", "priority": 20 }优先级数值越高,规则越靠后注入,理论上越接近"最终决定"的位置。默认情况下所有 Mod 的优先级相同,按字母序加载。
第二种是命名空间隔离。在 mod.md 里用<!-- namespace: xxx -->注释声明命名空间后,Agent 会把不同命名空间的规则当作独立体系来理解,减少互相污染。比如"代码风格类"Mod 和"提交流程类"Mod 放在不同命名空间,就不会在上下文里纠缠不清。
说句实在话,优先级和命名空间并不能 100% 解决冲突,模型面对互斥规则时还是会摇摆。我的经验是:宁可少装几个 Mod,让每个 Mod 的职责单一明确,也不要堆一堆小而全的 Mod。Mods 数量越多,上下文越拥挤,Agent 的"注意力"反而会被稀释。
4.4 把 Mod 变成真正的"插件":加脚本逻辑
前面讲的 Mod 都偏"规则注入"。但既然叫插件,免不了有人想在里面跑真实逻辑。2.1.287 的 Mods 设计里,mod.md 和 mod.json 只是入口,Mod 目录里还可以放可执行脚本,在挂载点被触发时调用。比如我想写一个"提交信息生成器"Mod,它会在git commit之前运行一个脚本,读取暂存区的 diff,生成符合 conventional commits 规范的提交信息。
这时候我们就要手写一个脚本文件,放在 Mod 目录下:
mods/ └── commit-helper/ ├── mod.md ├── mod.json └── scripts/ └── generate-commit-msg.py脚本本身接收 Claude Code 传过来的 JSON 参数(包括原始命令、当前目录、变更文件列表),处理完把结果写到输出文件里,Claude Code 会读取输出决定是否替换默认行为。这个模式使 Mods 具备了完整的工具链能力——它不再是纯提示词插件,而是真正能参与执行流程的插件。
5. 常见问题与排查实录
5.1 问题速查表
这一轮更新带来的新问题主要集中在版本兼容、目录识别和规则生效几个方面。我把实际遇到过的、以及社区里高频出现的问题整理成了一张速查表,方便按图索骥。
| 现象 | 可能原因 | 解决方式 |
|---|---|---|
| 升级后没有生成 mods 目录 | 版本没升成功,或启动时未触发初始化 | 先确认claude --version为 2.1.287+,再手动mkdir -p .claude/mods |
| enable 提示 Mod 不存在 | 目录层级不对,Mod 套娃了 | 检查是否在.claude/mods/下直接放了嘡,而不是又包了一层同名目录 |
| Mod 规则时灵时不灵 | 多 Mod 优先级冲突或上下文太长被截断 | 查看/mods列表,临时禁用其他 Mod 做对照测试 |
| 自定义脚本没有被调用 | mod.json 挂载点写错或脚本没有可执行权限 | 核对挂载点名称,chmod +x后重试 |
| 升级后 VS Code 扩展报错 | CLI 和扩展版本不匹配 | 扩展和 npm 包一起升级到最新 |
| 命令被误拦截 | action 挂载点黑名单太宽 | 检查匹配规则,把模式改精确,避免用宽泛后缀匹配 |
5.2 一个典型的排查实录
我在 Ubuntu 上配置 Claude Code 并启用第一个 Mod 时,遇到过一个很迷惑的问题:Mod 文件放在项目.claude/mods/下,claude mods list能看到它,但怎么 enable 都失败,提示"Mod not found"。目录明明存在,内容也完整,为什么找不到?
后来一步步排查,发现问题是文件权限。那个项目是从同事的仓库里 clone 下来的,.claude目录被 Git 追踪了,部分文件的 owner 不是一个用户,npm 全局安装的 Claude Code 以另一个用户身份运行时,读取目录被拒,导致它把整个 Mod 判定为无效。
处理方式是给 Mod 目录统一设置权限,并顺手在.gitignore里把.claude/排除掉。这个经验提醒我两件事:第一,Mods 目录默认不该进版本库,除非是团队刻意要共享的标准化 Mod;第二,排查问题先看文件权限和路径,别看规则写法——大部分"规则没生效"都轮不到规则本身出错。
还有一个高频问题值得单独说:Mod 规则被截断。Claude Code 的上下文窗口有限,当项目很大、CLAUDE.md 很长、同时开了七八个 Mod 的时候,后面的 Mod 规则很可能根本进不了活跃上下文。这是纯规则型 Mod 的天然短板。我的应对方式是"少即是多":项目级 Mod 不超过三个,超过的部分合并成一个职责更广的 Mod;CLAUDE.md 里本来就有的内容不要重复写进 Mod,减少上下文膨胀。
6. 实操心得与几个建议
6.1 我踩过的几个坑
第一个坑是过度依赖规则而忽视验证。刚上手 Mods 那两天,我写了不少"必须""禁止""永远"开头的规则,以为写进 mod.md 就万事大吉。实际测试发现,模型对绝对化词汇的服从度并没有想象的那么高,尤其在长任务场景中,后置规则很容易被任务上下文挤掉。后来我把关键规则尽量收敛到挂载点上,比如"必须执行验证"这类要求,直接挂在 action 层做机械拦截,而不是寄希望于模型记到最后。
第二个坑是Mod 目录被 Git 追踪。前面已经提过,这里再强调一次:团队协作项目里,每个人本地的 Mod 配置很可能是私有的。把.claude/加进.gitignore是稳妥做法,除非你明确要共享某个标准化 Mod,那时候应该单独把该 Mod 目录加入例外,并配一份使用文档。
第三个坑是升级时机。Claude Code 的版本迭代速度很快,2.1.287 加了 Mods,后面的小版本也在不停修 Mods 的边角问题。我遇到过某个小版本里 Mods 的挂载点不生效,升级到下一个 patch 又好了的情况。如果你在排查 Mods 问题时实在找不到逻辑错误,可以看看是不是版本本身的 bug,先去官方 changelog 确认一下。
6.2 推荐的 Mod 管理习惯
我个人现在管理 Mods 的方式很简单:用户级放通用 Mod,项目级放专用 Mod。用户级~/.claude/mods/里常驻两三个——一个统一代码风格,一个规范提交信息,一个强制测试验证;项目级只在需要特定流程时才加,用完就禁用,不长期挂着。
另外我养成了一个习惯:每个 Mod 内部写好 README,记录这个 Mod 解决的问题、适用的挂载点、以及和哪些 Mod 有冲突。之前没做这件事的时候,两个月后回头看自己写的 Mod,经常要想半天"这个规则当时是为了解决什么场景"。加了 README 之后,维护成本直线下降。
最后分享一个使用上的小技巧:当你发现 Claude Code 的行为变得奇怪,第一步不是去改规则,而是先/mods看看当前启用了哪些 Mod,然后逐个禁用排查。Mods 的模块化设计本来就该配合"二分禁用"来用——一次禁用一半,很快就能定位到问题出自哪个插件。这个排查方式我在前面提到的冲突场景里反复用到,比反复调整优先级声明高效得多。
从 2.1.287 开始,Claude Code 的扩展性确实上了一个台阶。Mods 把"改行为"从玄学般的提示词调教,变成了可安装、可卸载、可版本管理的工程化操作。工具本身还在快速迭代,但"用模块化插件来定制 AI 代理行为"这个思路,大概率会是后面很长一段时间的演进方向。趁早把 Mods 玩明白,后面不管工具怎么升级,你都能比别人更快地搭出顺手的工作流。