Claude Code 的 mods 默认开启,无沙箱
开发者可以拦截、改写或接管工具调用与 UI 渲染

Anthropic 于 10 月 1 日发布了 Claude Code Mods,这是一套 TypeScript 与 JavaScript 扩展系统,让开发者能够拦截、改写或接管 Claude Code 智能体循环内部的事件 —— 也就是驱动每一次 Claude Code 会话的、由模型请求、工具调用和结果处理构成的持续循环。Mods 需要 Claude Code v2.1.287 或更高版本,且默认开启,Anthropic 已经把自己的 /diff 命令迁移到了同一套机制上,这是团队所称的一项长期工作的开端:缩减 Claude Code 内置的核心,让用户按需安装具体的能力。
这次发布与 DeepSeek AI 的 DeepSeek Harness 项目负责人 Tianyi Cui 的一则观察同时出现,他称之为「想法的汇合」—— 两个项目都在构建可扩展的、可自我修改的智能体环境。不过,两种做法在架构上的距离相当大:Claude Code Mods 挂接进一个既有的智能体循环;DeepSeek Harness 则让循环驱动器本身成为一个可替换的组件。
三种钩子模式,给了 Mods 中间件级的控制
一个 Claude Code mod 是一个只导出单个 register(on) 函数的插件。其中的 on 函数为具名的 Claude Code 事件安装事件处理器:tool.call、ui.render、session.start、turn.complete、prompt.submit,以及其他事件。一个可选的过滤对象可以收窄范围 —— { tool: "Bash" } 只针对 Bash 工具调用,{ component: "AbovePrompt" } 只针对输入框上方的 UI 渲染槽位。
每个处理器接收三个参数:$(宿主 API 对象)、带类型的事件,以及 next(一个代表中间件链其余部分的函数)。处理器与 next 之间的关系,定义了三种组合模式:
观察: 调用 await next(e),捕获结果并返回。处理器作为副作用运行,不修改任何数据。
改写: 在调用 next(e) 之前修改事件对象。这让 mod 可以在提示词到达模型之前替换它、在执行前改动 Bash 命令参数,或者改变 UI 渲染属性。
接管: 返回一个值,而从不调用 next(e)。整条下游链被跳过;Claude Code 收到的是 mod 的返回值。mod 就是这样取消一条命令的 —— 它返回 { deny: "..." },而那个 Bash 调用根本不会执行。
该 $ 对象暴露了大约 19 个命名空间,涵盖 UI 渲染($.ui)、会话检视($.session)、持久状态($.state)、文件系统访问($.fs)、进程执行($.process)、HTTP 请求($.http)、工具调用、斜杠命令注册($.command),以及模型查询($.model)。通过 $.state 存下的状态能挺过热重载;模块级的 JavaScript 变量则不能。这个区别对那些要跨多个智能体回合累积数据的 mod 很要紧,因为热重载 —— 生成一个 mod 的新版本并在不重启 Claude Code 的情况下加载它 —— 会清空模块作用域,同时保留由宿主管理的状态存储。
延伸阅读:Claude Code 增加 AGENTS.md 支持,mods 系统首次预览
Token Weather、Blast Radius 和 Replay Theater 展示了钩子能做什么
Anthropic 官方的入门教程 演示了三个 mod,覆盖三种钩子模式,以及智能体执行时间线上的三个节点。
Token Weather 挂接到 session.start 和 turn.complete 事件上,用观察模式在每个回合之后通过 $.session.getContextUsage() 读取上下文窗口的占用。它在 $.state 里存下十二个读数的滚动窗口。另有一个独立的 ui.render 钩子,针对 AbovePrompt 组件槽位,读取这份历史,并在输入框上方渲染一个天气隐喻的状态栏:占用低于 25% 是晴空,25% 到 50% 是多云,50% 到 75% 是阵雨,75% 到 90% 是暴风雨,高于 90% 则给出「即将压缩」的提醒。整个实现大约 80 行 TypeScript。因为所有数据都存在 $.state 里,天气栏能挺过热重载 —— 开发者可以让 Claude 调整警告阈值或收紧布局,热加载修改后的 mod,这个栏会继续更新,而不丢失读数历史。
Replay Theater 对 tool.call 事件使用观察模式,过滤到 Edit 和 Write 工具调用,记录每次操作前后的文件状态。它注册了一个 /replay 斜杠命令(通过 $.command),打开一个 UI 面板,按顺序逐条走查记录下来的差异。在教程演示的一次函数重命名中 —— greet 改成 welcome —— 面板记录了跨三个文件的五处编辑。面板一次呈现一条差异,让开发者在不碰文件本身的前提下,回溯 Claude 改了什么。Replay Theater 不撤销编辑;它是一种审计和复核机制,而不是回滚工具。
Blast Radius 对被归类为高风险的 Bash 工具调用使用接管模式。当它检测到像 rm -rf 或 find ... -delete 这样的命令时,它会运行一次演练或状态查询来估算影响,用结果打开一个 UI 面板,并扣住这条链,直到用户确认或取消。在教程的例子里,rm -rf build 本会删除九个文件、共约 1.1 MB;确认面板在任何文件被碰之前就先展示了这份摘要。取消时,mod 返回一个 { deny: ... } 对象,且从不调用 next(e) —— 这条 Bash 命令永远不会被执行。
Mods 带着 Claude Code 的机器权限 —— 不含沙箱
Anthropic 自己的文档 明确写道,mods 以用户的权限运行 —— 可以读写机器上任何位置的文件、启动程序、发起网络请求 —— 并且「mods 没有沙箱」。在一则以演示为主的功能发布里,这句话很容易被忽略,但它界定了整个生态的信任模型:安装第三方 mod,是一种需要高度信任的行为。
在正式发布之前的测试中,来自 Pluto Security 的安全研究者记录了具体的攻击面。一个带默认权限的 mod 可以读取 ~/.claude/.credentials.json(其中存放着 Claude Code 的 OAuth 凭证)以及 ~/.claude/history.jsonl(在他们的测试里,它包含一份 834 KB 的记录,涵盖所有项目和会话中键入的每一条提示词)。一个悄悄外传其中任一文件、同时向用户展示一项有用功能的 mod,通过 $.http 拥有完整的网络访问权,可以把这些数据传到任何地方。Anthropic 的 sec-default mod 在 Team 和 Enterprise 套餐上最先加载到中间件链里,它的设计目的是保护组织所管理的内容不受用户自装 mod 的影响;它并不限制文件系统读取。
对部署 Claude Code 的团队来说,实际含义是:mod 的安装政策需要像对待 npm 包信任政策那样对待,但风险更高 —— 恶意的 npm 包可以破坏一次构建;恶意的 mod 却可以外传开发者机器上每一次 Claude Code 会话的对话历史。Anthropic 的文档建议在安装任何 mod 之前先运行 claude plugin validate,它会在不执行该 mod 的情况下,列出这个 mod 引用的 $ 方法和环境变量。
DeepSeek Harness 把同一个想法下沉到了智能体循环驱动器本身
Tianyi Cui 把他的对比框定得很谨慎。他肯定了两个项目的共同点 —— 让智能体环境可扩展、让智能体自己写扩展、支持分享 —— 然后划出一条精确的架构界线。Claude Code 向一个运行中的循环开放钩子;DeepSeek Harness,由他的团队主导,则让循环驱动器、模型适配器、工具注册表、文件系统服务和子进程服务全都成为可替换的插件。
DeepSeek Harness 建立在 Cordis 之上,这是一个面向基于插件的系统的 Node.js 元框架。在 Cordis 里,插件向一个共享的上下文对象贡献带类型的服务(可注入的依赖)、事件流和可逆的生命周期效应。结果是,智能体框架的每一个架构层都是一个 Cordis 插件:换掉其中一个,只需指向一个满足同一服务接口的新实现。
这个设计在实践上的后果,体现在 DeepSeek Harness 处理执行环境的方式上。它把文件系统和子进程接口抽象成可注入的服务。凡是使用这些服务的工具 —— Bash 执行工具、PTY 终端、LSP 语言服务器 —— 在你替换服务实现时都会自动重定向。把两者都换成远程沙箱的实现,就把整套执行环境 —— Bash、终端和 LSP —— 迁到沙箱里,而无需触碰任何单个工具的代码。在 Claude Code Mods 的架构里不可能有等价的替换:那里执行环境是固定的,钩子只能修改它内部事件边界上发生的事。
这并不是对 Claude Code Mods 的批评 —— 两个项目服务的是不同的受众。Claude Code Mods 是面向每天使用 Claude Code、想扩展它的行为、又不想自建智能体框架的开发者的生产级基础设施。DeepSeek Harness 则是面向想用可替换部件组合出定制智能体系统的开发者的基础设施,以 MIT 许可发布,仍处于开发者预览阶段,不提供稳定性保证。
延伸阅读:Claude Code 由 AI 起草的会话失败报告,预示着反馈方式的转变
自我修改的智能体:现在是热重载,以后是配置持久化
两个系统都包含让智能体在运行时扩展自己的机制。在 Claude Code 里,开发者可以用自然语言描述想要的 mod,让 Claude 生成 TypeScript,通过热重载把它加载进当前会话,并在不重启的情况下迭代。以这种方式生成的 mod 只在会话内有效,直到开发者保存文件并把它安装成持久插件。Anthropic Claude Code 团队的工程师 Thariq Shihipar 演示了一个 next-steps mod:任务完成后,这个 mod 会给出建议的后续动作,附带可运行的技能或命令链接,缩短完成一步与开始下一步之间的间隔。
DeepSeek Harness 通过 Creator Mode 有一个形式化的版本。智能体可以检视当前的插件组合,编写一个新插件或配置包,并通过插件管理器安装。热更新模式让新装的组件在运行中的会话里即刻可用。通过 Creator Mode 保存的配置会持久写入当前 profile、并在重启后保留 —— 这与 Claude Code 不同:那里的持久化要求开发者手动保存并重新安装生成的 mod 文件。
两种做法代表着 Tianyi Cui 指出的同一个底层转变:开发者可以要求智能体做的事情,正从「完成这个任务」扩展到包括「修改用来完成任务的工具」。区别在于这种修改的范围 —— Claude Code 是事件级的拦截,DeepSeek Harness 是组件级的替换 —— 以及由此得到的配置是自动挺过重启,还是需要显式的保存步骤。
近期更值得关注的进展是:Anthropic 所述的计划 —— 瘦身 Claude Code 内置的核心、把更多功能迁移到 Mods 上 —— 推进的速度,是否足以实质性地扩大事件钩子所能触及的范围。/diff 的迁移是第一个数据点。如果工具注册、权限管理和模型选择逻辑也相继迁到 Mods 层,两个系统之间的架构差距就会从两侧同时收窄。