---
layout: post.njk
source: https://yage.ai/share/claude-code-mods-dsh-20261003.html
speaker: yage.ai
title: |-
  Claude Code 的 mods：向 DSH
  迈了半步，恰好停在那条线上
date: '2026-10-03'
summary: 文章对比了Claude Code的mods机制与DeepSeek的DSH架构。Claude Code通过进程内事件钩子实现了轻量级定制，但未开放主循环热替换，处于命令式架构的初级阶段；而DSH通过复杂生命周期管理实现了主循环可替换。两者虽设计路径不同，但均反映了coding agent从声明式向命令式演进的工程趋势。
area: tech-engineering
category: ai-application
tags:
  - coding-agent
  - plugin-architecture
  - event-driven
  - agent-loop
  - extensibility
people: []
companies_orgs:
  - anthropic
  - deepseek
products_models:
  - claude-code
  - dsh
media_books: []
draft: true
status: evergreen
---

2026 年 8 月 13 日，DeepSeek 开源了自己的 coding agent harness，叫做
DSH（DeepSeek Harness，GitHub
仓库）。当时我对 DSH 做过深度分析，里面提到它和传统 coding agent
最核心的区别：插件直接在宿主框架进程里运行，甚至最关键的主控制循环本身也是一个可热插拔的插件。整个框架搭建的生命周期机制都是围绕着这个可替换的控制循环来设计的。

2026 年 10 月 1 日，Anthropic 在官方博客上发布了一个新的面向 Claude
Code 的特性 mods。在阅读了官方的技术文档之后，我发现 Claude Code
第一次允许第三方的代码在自己的进程里运行。把两者设计上的取舍做一下对照，会发现
Claude Code 所做出的设计和停下来的地方，正好都落在我两个月前那篇 DSH
深度分析划下的分界线上。

## Claude Code
第一次让第三方代码跑进自己的进程

从 Claude Code 的客户端 v2.1.287 开始，Anthropic 正式引入了 mods
机制。在 Anthropic
官方关于 mods 的博客文章里，mods 指的是运行于 Claude Code
进程内部的小型 TypeScript 或 JavaScript 函数，它们可以改写
prompt、拦截工具调用、批准执行权限，甚至接管并绘制终端界面。

在这之前，Claude Code 的所有扩展都在进程外：skills 是注入指令背景的
Markdown 文本，settings hooks 是在外部触发的脚本/HTTP 请求/prompt，MCP
服务器也是独立的外部进程。官方对比表明确指出：mod
是唯一能直接绘制和修改界面的扩展形式。

mod 基于事件驱动。Claude Code 在用户提交
prompt、使用工具、请求授权和渲染界面时都会触发事件。mod
处理函数可以在事件发生前介入、在事件发生后获取结果、完全替代事件或包装在原事件中。

有了这些挂载点，mod 能伸到以往所有扩展机制都够不着的地方。它能在
prompt
送进模型前改写内容，拦截并重试工具调用，在输出交还前把密钥脱敏；在界面上调整工具展示、替换加载提示、定制提问弹窗，或在输入框上方开辟显示区域与交互面板。mod
还能注册不消耗模型轮次的斜杠命令，生成中也能即时调用。同一 mod
内的多个钩子可以通过模块变量共享内存状态，比如一个函数计数、另一个函数显示。多个
mod
挂载同一事件时按加载顺序执行，先加载的先收到事件，后拿到返回结果。用户甚至可以让
Claude 当场编写 TypeScript mod 并热加载生效。

Anthropic
的官方示例 mods 仓库里，token-weather
在输入框上方实时画上下文用量气象图，blast-radius
则在检测到高危命令时立刻拦截并弹出一个评估面板，上面有继续和取消两个按钮。

机制立起来后，宿主自己也开始把内置功能往外挪。在 v2.1.287
中，官方把内置的 /diff 命令拆为独立
mod，用户可自行开关或替换。官方文档明确表示，未来将把更多内置功能迁为
mod，将宿主精简为紧凑底座并按需加载。该版本还内置了 You should
know，由旁路 side agent 提醒操作中可能遗漏的信息。

但代码在一个进程中执行，安全边界就弱很多了。mod
没有沙箱，它和当前终端同权：能读写文件、发网络请求、读环境密钥、批准工具调用。虽然企业环境有静态校验命令和先加载的安全防护
mod，但让第三方代码跑在主进程里，本身就是高信任行为。

## 两种插件世界观

目前主流的 coding agent
的定制机制主要有两种形式。一种是插件只是一些文件和配置，宿主程序读取这些配置并在外部启动相应的进程，这种属于声明式的定制机制。另一种是插件以代码模块的形式加载到宿主进程中，并携带自身的状态进行工作，这种属于命令式的定制机制。

声明式的代表是 Codex 和早期的 Claude
Code。插件在这里只是磁盘上的静态文件和配置清单：Markdown 指令、MCP
启动命令或者触发 shell
脚本的规则。宿主读取配置，在外部拉起一个独立的进程。隔离得干净，但插件接触不到宿主内部的机制，要想调上下文压缩、调调度逻辑，只能改宿主源码重新编译。

命令式路线以 8 月开源的 DSH
为代表。插件作为代码模块直接运行在宿主进程中，有自己的生命周期和内存状态，和宿主同生共死。模块装入时就在进程里注册能力，其他插件声明依赖，底层自动接线。

但命令式架构的工程代价不低。进程内常驻的有状态代码让热替换变得复杂，卸载时容易留下悬挂引用，连接和后台任务也不会有人替你清理。为了支撑这一模式，DSH
引入了一整套繁重的生命周期框架，专门追踪副作用、清理资源并在依赖变化时广播通知。

从这个视角看，Claude Code 的 mods
跨越了进程边界，站到了命令式一边：能用 TypeScript
在宿主里直接跑逻辑，还能共享状态和热重载。但相比于 DSH
那套完整的服务注册与依赖装配体系，Claude Code
选的只是命令式路线上最轻巧的子集：事件处理函数。它不提供能力注册或依赖接线，多个
mod 只按加载顺序依次对事件做出响应。

声明式与命令式两种插件世界观在进程边界、执行形态与控制能力上的对比。

## 迈了哪半步，没迈哪半步

把 Anthropic 和 DSH
的工程落地放在一起对比，迈出的半步和没迈的半步一眼就能看出来。迈出的半步是代码进入宿主进程、获得对关键事件的拦截与改写能力，以及会话期的热加载和模块内状态保持。

没迈的那半步，恰好落在系统架构的关键位置上。这里先给一个名词解释：agent
loop 指的是 coding agent
每一轮向模型发出请求、等待响应、执行工具、再循环的主循环代码。Claude
Code
没有提供能力注册机制、依赖拓扑接线和事务性的热替换回滚；更重要的界限在主循环上，根据现有的官方技术文档，mods
没有提供替换 agent loop
的接口。这是一个基于文档现状的判断，但架构上的边界是明显的。

Claude Code mods
开放了进程内的事件钩子，但按公开文档，控制主循环没有开放替换接口。

这又回到了 8 月关于 DSH 的分析里的那个比喻：一整盘饺子和那一碟醋。在
DSH
里，整个生命周期框架（副作用撤销、依赖变动通知、热更新的事务性保护）都是为了一个激进目标服务的：把
agent loop 本身做成一个可热替换的普通插件。DSH 的 agent loop
在核心包里提供循环服务，声明依赖系统提示词和工具集。把单 agent
的循环改成多 agent
协作循环，只要写一个实现同样接口的插件，在配置中替换。框架会自动卸载旧的循环，清理监听，在依赖就位后平滑拉起新的控制流。

这套复杂的运行时框架是一整盘饺子，让主循环可随时热替换才是真正想蘸的醋。依赖通知与回滚设计，全是为了换掉控制循环时宿主不崩溃的副产品。

相比之下，Codex
的开源仓库里能看到它的主循环 run_turn() 直接用 Rust
硬编码在核心中。外部钩子只能在预设点做轻度修饰，无法在运行时调整控制流骨架，既不能将串行工具执行改写为并行，也无法在循环层组装多
agent。

目前的 Claude Code mods
提供了另一种思路：它构建了一套轻量且实用的事件拦截机制，但按公开文档看，完全没碰那碟醋。它把事件拦截和界面定制做到了很高的易用性，却把主循环留在核心内部，并不指向控制流的自进化。

## 这是借鉴吗

两套系统在进程内外轴线上的相似演变，难免让人发问：这是借鉴吗？我看过公开的时间线和设计取舍，倾向于认为不是。

公开时间上，DSH 在 2026 年 8 月 13 日开源，Anthropic 在 2026 年 10 月
1 日发布 mods。往前找 Anthropic 的公开设计痕迹，最早的是 2026 年 9 月 3
日在 claude-code
仓库公开的 mods 设计议题 #91870，标题就叫 Mods - make Claude 10x
more extensible；一周后官方在 issue 里表态 function hooks 将在数周内
shipping。也就是说，能核实的公开设计起点在 DSH 发布三周之后。用于早期测试的
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS
环境变量出现的具体时间没有留下可核实的记录，凭这一点判断不了先后。所以诚实的结论是：设计节奏上两者挨得很近，Anthropic
的设计过程是否受到 DSH
发布的影响，仅凭公开证据无法判定，也说不出谁先谁后。

比时间线更关键的是设计取舍。如果 Anthropic 打算照着 DSH
抄，不会恰恰舍弃 DSH
最具有特色的标志性设计：能力注册中心、依赖注入框架与可替换的 agent
loop。相反，mods
集中改进的都是直观体感：画状态界面、增加快捷指令、拦截高危命令。抄作业的人不会只抄一半，还专挑对方最平常的那一半。

两者都在往同一个方向走，这源于撞上了同一堵工程之墙。定制越往深处走，声明式的外部配置越不够用：微调提示词、干预工具链、重绘终端界面，这些都得让代码进到宿主进程的空间里来。面对同样的约束，两家给出了各自的解答，时间上谁影响了谁说不清，设计上也没有承袭关系，更多是同一个工程问题撞出了两个解。不过要自我校准一句：进程内外只是一条粗粒度的分类轴，两个系统同时落在命令式一侧，很大程度是这条轴本身够粗，不能拿这一点反推两家之间有具体的设计承袭。

## 对你意味着什么

这两套方案适合的人群不同。

对日常使用 Claude Code 的开发者来说，mods
是真正有用的定制工具。我们写业务代码的时候，很少需要动态依赖注入或者替换底层主循环，需要的往往是一些具体的增强：在输入框上方看到上下文消耗（比如
token-weather）、跑高危命令时先弹个面板看影响范围（比如
blast-radius），或者给一个本地操作绑一条斜杠命令。这些 mods
都能做。相比之下，DSH 那套生命周期机制在日常业务开发里基本用不上。

对关注架构演进的 harness 探索者来说，Claude Code
展示了一个清晰的模块化路径。/diff 官方拆成了独立 mod，You should know
也以内置 mod
的形式发布，透露出从单体向小核心加按需加载演进的取向。这个方向很接近可组装架构，但在主循环热替换上依然缺少一整套生命周期治理机制。

这引出一个开放问题：Anthropic 何时会开放 agent loop
的定制？拐点可能在模型能力与需求结合处。当模型能轻松写出数十行工具函数、数百行主循环代码逼近顶尖模型能力上限，且用户确实需要针对任务动态切换调度策略时，这种重型架构才有价值。在此之前，那碟为控制循环动态替换准备的醋，只有
DeepSeek 备齐了。