乐于分享
好东西不私藏

一切皆插件.DeepSeek Harness 让 agent 在运行时改装自己

一切皆插件.DeepSeek Harness 让 agent 在运行时改装自己

2026 年 8 月 13 日,DeepSeek Harness 以 v0.1 开发者预览版开源。到这两天,内测组织 dsh-external 下已经有 251 个仓库,反馈板攒了 545 条 issue,单日最多新增过 14 条。社区自建了包管理器、hub 索引和兼容性监控,内测群里流传一句话,官方做得越少,社区越繁荣。

前两篇拆过它的事件溯源和沙箱,这两层分别回答一个问题。agent 的记忆怎么保证不丢,agent 的动作怎么关进笼子。今天拆最深的一层,也是它和其他 agent 框架分道扬镳的地方。

别的框架都有内核,它没有。

一、别的框架都有内核,DSH 没有

Claude Code 有内置的 agent 循环、工具调度和权限模型,你扩展的是它允许你扩展的部分,循环本身不在其列。Codex 同理。Cursor 的 agent 模式再开放,核心执行链是产品自己的。

DeepSeek Harness 的架构文档里有一句原话,产品的每个部分都是插件,包括模型适配器、工具注册表、会话日志和 agent 循环本身,每个部分都可以从配置上替换,没有需要打补丁的特权核心。你扩展 dsh 的方式,是在旁边挂一个插件,而不是修改某段神圣的源码。

这句话不是口号。仓库里 packages 目录下约五十个 workspace 包,发布到 npm 的官方包一百多个,每一个都是插件。模型调用是一个插件,shell 是一个插件,文件系统是一个插件,代码执行是一个插件,语言服务器是一个插件,甚至那个让 agent 一圈圈思考、调用、再思考的主循环,默认实现叫 ReactLoopAgent,它也只是 agent 工厂注册的众多实现之一。消费者只依赖 agent 接口,不依赖具体循环,循环可替换。

这带来一个连锁反应。agent 的循环可以换,会话的日志可以换,模型的适配器可以换,那么理论上,agent 在运行中把自己正在用的循环换掉,也不是不可能的事。DSH 真的把这件疯狂的事做了出来,后面会细讲。先看它凭什么做得到,地基在三层机制上。

二、地基,注册即可逆的 Cordis

DSH 没有自己发明插件框架,它把 Cordis 4 以源码形式整个搬进了仓库,改名成 @deepseek-ai 的命名空间。选 Cordis 的原因,是它提供了三个刚好够用的原语。

第一个原语,ctx 是一个 Proxy。普通属性读取会走服务解析器,派生上下文用原型继承,isolate 给同名服务建独立作用域,intercept 沿原型链注入配置。一个插件拿到的是受限的 ctx,不是整个进程。

第二个原语,插件生命周期叫 fiber。插件是一个函数、一个类或者一个带 apply 方法的对象,配上 Config 校验器和 inject 依赖声明。ctx.plugin 铸造一个 fiber,状态机从 PENDING 走到 ACTIVE,所需服务没齐就停在 PENDING,服务一出现就被唤醒。加载顺序等于服务注入顺序,插件之间不需要手工排优先级。

第三个原语,也是整栋楼的地基,一切注册都是 effect。ctx.on 注册事件监听,ctx.provide 注册服务,ctx.tools.register 注册工具,它们内部全部走同一个机制,effect 立即执行,返回的清理函数被收集,插件卸载时逆序释放。监听器随 fiber 卸载自动移除,服务随 fiber 卸载自动消失,工具随 fiber 卸载自动下架。

这条规则的威力在组合里体现。插件 A 给插件 B 提供服务,B 激活,两者都注册了 effect。把 A 停掉,B 的依赖没了,自动退回 PENDING,它贡献的一切同步回收。不用写一行清理代码,不会留下半死不活的状态。这就是官方文档说的,注册是可逆的 effect,插件卸载时自动解除。

事件系统还有一层。waterfall 类型的派发是洋葱式中间件,监听器收到参数和 next,调用 next 才把结果交给下一层,不调用就是否决。重试、日志、路由、权限拦截,全部以瀑布监听器的形式插进管道,不用改 agent 循环本身。

这套地基决定了两件事。热重载是免费的,改一行配置,插件树重新组合,旧的自动回收,新的自动挂上。agent 自修改是可能的,既然插件的一切贡献都能随 fiber 回收,那么在运行时挂一个插件、停一个插件,就不存在收不干净的问题。

三、组合,配置即插件树

有了插件原语,还要回答一个问题。一个运行的 DSH,从哪一行代码变成一棵插件树。答案是分层组合,全程不写代码。

DSH 里有三个概念。profile 是 home 目录下一个具名组合,列着要叠加的 bundle 和用户的补丁文件,web 和 headless 是随附模板。bundle 是一个 npm 包,在 package.json 的 dsh 字段里声明自己导出哪份补丁,比如基础能力包 dsh-base 一份补丁就挂进全部核心行。patch 是插件行的增删改,和 cordis.yml 同一个格式。

启动时,所有层按顺序压扁成一个补丁列表,在空根上应用一次。bundle 层在最底下,profile 自己的补丁在上,home 级机器偏好再上,命令行 --patch 覆盖在最上。用户编辑永远挤不开系统层。

这里有个反直觉的实现细节。应用补丁的算法被显式导出,离线 dump 命令和真实启动用的是同一份代码。dsh --profile web --dump-config 打印出来的树,和进程实际启动的树不可能漂移。配置怎么来的,机器就怎么跑,中间没有第二套解释。

平台差异也在这个层面处理。基础包补丁里,bash 沙箱和 bash 工具在 Windows 上被表达式禁用,powershell 沙箱反之。!!js 表达式在插件激活时对自身上下文求值,一行 YAML 就能按平台开关能力。

补丁文件支持热重载。改 profile 的补丁文件,进程监视到变更,重新组合整棵树的补丁列表,事务性地更新,失败回滚。新增一个 bundle 需要重启,改组合不用。开发插件时,改配置的反馈循环是秒级的。

四、重头戏,AI 在运行时改装自己

前三层机制合起来,产生了一个别的框架给不了的副产品。extensions 子系统让 agent 在自己正运行于其中的插件树上工作,官方文档的原话是,agent 修改自身的运行时。

具体怎么做。官方 cordis 预设里装配了五个工具。cordis_inspect 做只读检查,列出当前进程里注册的服务、事件、工具、动态插件,以及反射出的接口契约。cordis_define 登记一个新插件包,分成宿主半段代码和浏览器半段代码,先做语法预检,此时不运行。cordis_run 把宿主半段放进沙箱求值,作为子 fiber 挂进运行时,含浏览器半段的包走人工确认流程。cordis_stop 把宿主半段安静地回收,定义保留可再跑。cordis_undefine 先停再忘。

用这五个工具,agent 可以在对话里让 AI 现场写一个注册工具的插件,定义、运行、看诊断、修改、再运行,整个调试循环不需要你碰文件。这就是"插件开发插件"的方式,官方技能文档推荐在 cordis 预设会话里先把这个循环跑通,验证 API 用法,稳定后再搬进正式包。

动态插件的代码形态是纯 JavaScript,禁 import、禁 JSX、禁 TypeScript,浏览器半段用 React.createElement,硬依赖声明 inject,可选依赖用 ctx.get 判空。所有副作用挂在 ctx.on 或 ctx.effect 上,随 fiber 自动清理。这些约束保证了一个动态插件可以被安全地反复定义和回收。

生命周期只在进程内存。动态插件跨轮次存活,能影响同进程的其他会话,但不写任何插件文件、不装包、不改 cordis.yml,stop 或 undefine 或重启之后彻底消失。session 日志只记录定义调用的元数据,绝不记录代码本身。官方文档对存储姿态的说法是,进程内存是唯一事实源。

安全边界要说清楚。动态插件的沙箱是 node 的 vm 新 realm,Node 全局被禁或重定向到 Cordis 服务,timer 服务、fs、web、bash 都要走服务接口。但官方文档原话,它是诚实代码的围栏,不是安全边界,宿主域的助手可以逃逸。使用信任级别约等于授予 bash 工具。在受信任环境里用,这句话要记住。

五、插件不止一种形态

动态插件适合快速验证,不适合分发。DSH 的插件生态其实有三条路,加上技能一共四种形态,对应不同的生命周期和上手成本。

动态插件是第一条路,会话内、进程内存里的 Package,定义到运行到停止到删除,重启即失,上手成本最低,适合实验和调试。官方 cordis 预设就是为此设计的,让 AI 自己写插件改运行时。

正式 bundle 插件是第二条路,一个 npm 包加一份 dsh.bundle 声明,永久,随 profile 启动,适合发布给他人使用。包结构固定,package.json 声明 bundle 补丁,补丁文件把插件行插进组合,index.js 导出 name、inject、Config、apply,可选一个 client.js 做浏览器半段,可选 skills 目录随包分发。命名导出是硬规则,默认导出会丢 inject 元数据,官方事后分析里有一条案底。

组合编辑和 Agent Preset 是第三条路,纯 YAML。往现有 profile 加一行插件,编辑补丁文件即可,修改即热生效。想要一个专属能力集的 agent,复制一份预设再改,校验通过后再开真实会话。预设里发布服务必须包进隔离组,消费宿主服务的行必须裸放,这条边界规则写得很清楚。

技能是轻量扩展点,一个带 frontmatter 的 SKILL.md 文件,放在技能目录或随 bundle 分发,给 agent 加一份操作手册。上手只要几分钟,是生态里最活跃的部分。

四条路径的选择逻辑一句话。先用动态插件验证想法,成熟后按 bundle 打包发布,需要定制某个 agent 的能力集时写组合,只想加指令文档时写技能。DSH 把从验证到分发的每一级都留了入口,这也是它和"给你一个写死的 agent"最大的区别。

六、什么时候值得用

到这一步可以给判据了。DSH 现在还是 v0.1 开发者预览,官方明说会有破坏性变更,API 和配置格式可能随版本演进,不建议直接上生产。想尝鲜和做开发,条件已经成熟,Web UI、CLI、插件开发、Python SDK 都已发布。

值得用的人群分三种。想组装自己的 agent 能力集的人,preset 和补丁的组合模型比在别人的框架里抠配置自由得多。需要可编程运行时的人,SDK 和 ACP 两条通道都是 stdio 上的标准协议,TS 和 Python 客户端是设计孪生,适合 CI 流水线和批量任务。想研究 agent 架构的人,这个仓库几乎是教材,事件溯源、能力缝、组合系统、安全模型每一层都有独立的包和文档,逐文件百分百测试覆盖,文档过期会阻断 CI。

慎用的人群也说清楚。需要稳定生产环境的人,等正式版。需要开箱即用成熟产品的人,Claude Code 和 Codex 的打磨程度更高。想让它跑在不可信输入上的人,动态插件不是安全边界,这一点官方反复强调。

上手路径三步。npx @deepseek-ai/dsh web 启动 Web UI,默认地址是 127.0.0.1 的 3080 端口。切到 cordis 预设,用五个工具让 AI 现场写一个注册工具的插件,把定义到运行到停止的完整循环跑通。稳定之后,抄官方示例打包成正式 bundle,装进自己的 profile,发布到 npm 给全世界用。

七、拉远看

回到开头那句社区的话,官方做得越少,社区越繁荣。DSH 把这句落到架构上。它没有给你一个固定形态的 agent,它给了你一棵可以任意改装的插件树,连树根都能换。

agent 框架的竞争正在从模型能力转向外层系统。模型权重冻结之后,循环、记忆、工具、权限这些外层部件决定 agent 能走多远。DeepSeek Harness 选的路线是把外层的每一块都做成可替换的积木,让模型、让开发者、让整个生态共同组装。251 个仓库和 545 条 issue 说明这条路有人走。

模型负责思考,harness 负责让思考在受控环境里执行。当 harness 本身没有内核,思考的边界就由你画。

参考资料

[1] DeepSeek Harness 官方仓库,github.com/deepseek-ai/deepseek-harness,2026-08-13 开源,可访问路径 github.com/deepseek-ai/deepseek-harness[2] DeepSeek Harness 官方文档站,deepseek-harness.github.io/deepseek-harness,含架构与子系统文档,2026-08[3] 本地源码研究报告《DeepSeek Harness 源码深入研究》,G 盘 /DSH研究/DeepSeek-Harness-源码研究报告.md,2026-08-13[4] 本地源码研究报告《DSH 组合机制与 Cordis 插件机制》,G 盘 /DSH研究/DeepSeek-Harness-Cordis-组合机制研究报告.md,2026-08-13[5] 本地源码研究报告《DSH 插件开发路径》,G 盘 /DSH研究/DSH插件开发路径研究报告.md,2026-08-16[6] 本地源码研究报告《DSH 能力族源码》,G 盘 /DSH研究/deepseek-harness-能力族源码研究报告.md,2026-08-13[7] ai-indeed 百科,什么是 DeepSeek Harness,ai-indeed.com/encyclopedia/29655.html,2026-08[8] evomap 博客,DeepSeek Harness 插件架构详解,evomap.ai/zh-hk/blog/what-is-deepseek-harness-plugin-architecture,2026-08