Claude Code 引入 Mods:从插件到核心行为的深度定制

Claude 团队刚刚在 Claude Code 中引入了名为 "Mods"(插件/模组)的新功能。这一功能的核心理念是赋予用户直接修改 Claude Code 自身工作方式的能力,而不仅仅是添加外部工具。Mods 允许开发者改变渲染内容、注入提示词(Prompt)、修改工具调用逻辑,甚至添加自定义的用户界面(UI)、技能集和命令。 这意味着 Claude Code 不再是一个黑盒,而是一个可以通过代码进行微观控制的开放平台。

"We just added mods to Cloud Code, and with a mod, you can directly change how Cloud Code itself works."

这种定制能力激发了极大的创意空间。博主首先分享了一个个人案例:为了获得对上下文(Context)更清晰的可见性,他开发了一个 Mod,能够在提示框上方实时渲染上下文的详细分解视图。另一个案例涉及多智能体协作场景,博主希望看到项目中所有的 Agent(代理),而不仅仅是当前正在运行的那些。为此,他创建了一个 Mod,在侧边栏列出所有 Agent,并支持通过单次点击启动任意一个。此外,出于隐私考虑,在录制屏幕时博主不希望邮件地址直接暴露,因此他制作了一个 Mod,将邮件地址隐藏起来,直到鼠标悬停时才显示。这些案例展示了 Mods 在可视化、工作流优化和隐私保护方面的巨大潜力。

Mod 的技术架构:基于 Hooks 的中间件机制

从技术实现的角度来看,Mod 本质上就是一个插件。它与普通插件共享相同的 plugin.json 和 hooks.json 配置文件,唯一的区别在于 hooks.json 中多了一个额外的键(key):modules。这个字段指向一个 TypeScript 文件,该文件即为实际的 Mod 代码逻辑。

在这个 TypeScript 文件中,开发者编写函数,这些函数将在 Claude Code 内部运行。Claude Code 暴露了数十个内部事件(Internal Events),例如工具调用、权限检查、消息渲染、提示词提交等。开发者需要将这些函数注册到特定的事件上,使得每当该事件触发时,注册的函数都会在 Claude Code 执行其默认行为之前运行。

"A mod is just a plugin... the only difference is that hooks.json gets one extra key, modules."

这种机制类似于 Web 开发中常见的 Express.js 中间件模式。每个注册的函数都会接收三个固定的参数,构成了 Mod 的核心交互接口:

  1. $ (Dollar Sign Object): 这是与 Claude Code 通信的主要通道。所有对外的操作,如渲染 UI、调用模型、读取文件等,都通过此对象进行。
  2. event: 当前触发的事件数据。它包含了正在发生的具体事件的详细信息。
  3. next: 这是一个回调函数,用于控制流程的继续。它体现了中间件的特性。

核心逻辑:事件拦截、数据修改与流程控制

理解 Mod 运作的关键在于掌握上述三个参数的协同工作方式。$ 对象提供了连接 Claude Code 内部能力的桥梁,event 参数让开发者知晓当前上下文发生了什么,而 next 函数则决定了 Claude Code 最终执行什么操作。

具体而言,开发者可以在函数体内修改 event 中的数据。例如,如果事件涉及一个命令调用,开发者可以篡改该命令的内容。经过修改后的数据会被传递给 next 函数。无论传入什么给 next,那就是 Claude Code 实际执行的内容。

"If you change the command, that changed command is what runs."

这里存在两种控制路径: 1. 继续执行(Pass-through): 如果开发者调用 next,Claude Code 将继续处理经过修改或原始的事件数据。这是实现“增强”而非“替换”功能的关键。 2. 完全接管(Override): 如果开发者不调用 next,而是直接返回一个值,那么该函数就完全接管了事件的处理权。此时 Claude Code 会忽略其默认行为,直接使用开发者返回的结果作为最终响应。

这种设计允许 Mod 既可以是透明的增强层(如修改 UI),也可以是彻底的替换器(如拦截所有工具调用并自定义逻辑)。$ 对象确保了即使在被接管的情况下,开发者仍能安全地访问 Claude Code 的核心功能。

部署与热重载:无缝的开发体验

在开发过程中,Mod 的加载和更新机制非常便捷。对于命令行界面(CLI),用户可以通过启动 Claude Code 时添加 --plugin-dir 标志并指定文件夹路径来加载 Mod。

"To load it, you can start CloudCode with a plugin dir flag on that folder."

对于桌面应用程序(Desktop App),由于不支持命令行参数,用户只需将 Mod 文件夹添加到全局设置文件中即可。更重要的是,该文件夹处于被监听(Watched)状态。这意味着开发者在保存 TypeScript 文件后,当前会话中的 Claude Code 会立即感知到变化并应用更新。这种热重载(Hot Reload)机制极大地提高了开发效率,无需重启服务即可实时调试 Mod 的行为。

实战案例:构建邮件地址隐藏 Mod

为了具体说明开发流程,博主以之前提到的“邮件地址隐藏”功能为例,演示了如何从零构建一个 Mod。

目标需求是:当 Claude 回复中包含邮件地址时,默认在屏幕上隐藏该地址,仅当用户鼠标悬停时才显示。

实现步骤如下: 1. 注册事件: 博主选择监听 render(渲染)内部事件,因为这是消息显示在屏幕前的最后一步。 2. 获取数据: 通过 event 参数,开发者可以访问即将渲染的回复文本。 3. 处理逻辑: 在函数体内,遍历文本中的每个邮件地址。利用 $ 对象构建一个特殊的 UI 块(Block)。这个块的逻辑是:默认状态下不显示文本内容,仅在鼠标悬停事件触发时渲染文本。 4. 拦截返回: 博主没有调用 next,而是直接返回了这个经过处理的 UI 结构。因此,Claude Code 不再渲染原始文本,而是渲染开发者构建的“悬停显示”版本。

"Instead of calling next, I return that, so CloudCode renders my version."

安全性与沙箱隔离:模型数据的完整性保障

这个案例还揭示了一个重要的安全特性:Mod 仅改变视觉呈现,不影响模型底层数据。

当博主询问 "Sam's email" 时,屏幕上隐藏了邮件地址。然而,当随后要求 Claude "write a message"(写一封消息)时,模型依然使用了真实的邮件地址。

这是因为 Mod 仅作用于 render 事件,即数据输出到用户界面的环节。模型在生成回复时从未看到被 Mod “隐藏”后的版本,它看到的始终是原始数据。 此外,Mod 运行在独立的沙箱环境中,所有对外部资源的访问都必须通过 $ 对象进行代理。这种设计确保了 Mod 的灵活性不会以牺牲模型数据的准确性和安全性为代价。Mod 只能看到 Claude Code 暴露的事件,无法直接篡改内存中的核心状态或模型权重。

分发与共享:标准化的插件生态

最后,由于 Mod 本质上就是插件,因此它完全兼容现有的 Claude Code 插件生态系统。开发者可以将 Mod 发布到 Marketplace(市场)仓库中,其他用户只需像安装普通插件一样即可使用。

"A mod is just a plugin, so you can also share it as one."

这种标准化意味着社区可以迅速积累高质量的 Mod。无论是用于提升开发效率的上下文可视化工具,还是用于增强隐私保护的 UI 修饰器,都可以被广泛分发和复用。这种开放架构不仅增强了单个用户的体验,也为整个 Claude Code 社区创造了丰富的插件生态。

结论

Claude Code 引入的 Mods 功能标志着其从一个封闭的代码助手向一个高度可定制的开发者平台转变。通过基于 TypeScript 的中间件机制,用户不仅能扩展功能,还能深入干预渲染、提示词和工具调用等核心流程。这种设计既保留了模型数据的完整性(通过沙箱隔离),又提供了极大的灵活性(如热重载和事件拦截)。最终,Mods 将 Claude Code 的控制权部分交还给用户,使其能够根据个性化需求构建专属的开发环境。