「一切皆插件」到底怎么落地?拆解 DeepSeek Harness 的 Cordis 架构

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

「一切皆插件」到底怎么落地?拆解 DeepSeek Harness 的 Cordis 架构

上一篇我们把 DeepSeek Harness 跑了起来,知道它「一切皆插件」、四大模式、四种入口。但口号归口号,工程上到底怎么实现「连 Agent Loop 本身都是插件」?这一篇深入源码结构,拆解它的地基——Cordis 插件元框架,以及那些真正跟别人不一样的设计:可逆副作用、服务与事件、工具注册的遮蔽算法。

DeepSeek Harness 分层架构


一、地基:Cordis 是什么,为什么用它

「Everything is a plugin」的基础,是 Cordis——一个开源的「Meta-Framework for Modern JavaScript Applications」。

先纠正一个常见误解:Cordis 不是 DeepSeek 为了 Agent 专门发明的。它是一个通用的插件框架,处理三件事:

  1. 依赖注入(Dependency Injection)
  2. 作用域服务(Scoped Services)
  3. 生命周期清理(Lifecycle Cleanup)

它跟 Agent、跟 LLM 没有任何直接关系,在 DeepSeek Harness 出现之前就已经存在。最典型的使用者是 Koishi——一个跨平台聊天机器人框架(QQ / Discord / Telegram / 微信都接)。

为什么聊天机器人框架的经验能搬到 Agent 上?因为两个场景在结构上几乎一模一样:

  • 聊天机器人 = 几十个插件拼在一起,热插拔,随时改配置
  • Agent = 模型、工具、技能、沙箱、循环……几十个能力拼在一起,也要热插拔、随时改配置

唯一的区别是:Koishi 没有 LLM,而 Harness 加了一层 LLM。DeepSeek 团队看中了 Cordis 这套经过 Koishi 验证的「插件组织能力」,于是:

  1. 把 Cordis 的源码 vendor 进自己的仓库,改了 scope 叫 @deepseek-ai/cordis
  2. 把自己写的每一个包,都设成对它的 peer dependency。

这比「使用一个第三方库」更进一步——整个产品都构建在 Cordis 之上,而不是把它当做一个依赖引用一下。


二、核心包与 ctx 键:每个能力都是一个服务

在 Cordis 的模型里,插件向一个共享的上下文(context,简称 ctx)贡献服务(service)。要理解 Harness,先认识它的核心包和对应的 ctx 键:

职责ctx
core/session仅追加的 SessionEvent 日志 + 内存存储ctx.sessions
core/system-prompt提示词片段与工具 schema 的组装ctx.systemPrompt
core/tools作用域化的工具注册表 + 带把关的执行流水线ctx.tools
core/agentAgent 接口、活跃 agent 注册表、agent/* 事件ctx.agents
core/agent-loop实现 Agent 接口的默认驱动器ctx.agentLoop
core/scope按 agent 划分作用域的注册原语库,无 ctx 键
llm/llm消息与流式词汇表,以及适配器 seamctx.llm

看到没有?连 core/agent-loop(智能体循环本身)都是一个服务、一个插件。这就是「Everything is a Plugin」最硬核的体现——如果你不满意默认的 Agent Loop 怎么写,注册一个自己的 ctx.agentLoop 实现即可,上层调用方不用改一行代码。


三、服务与事件:插件之间怎么协作

Cordis 的协作模型是「服务 + 事件」双轨:

  • 服务(Service):插件向 ctx 贡献一个可被其他插件调用的对象(比如 ctx.llmctx.tools)。这是「调用」的通道。
  • 事件(Event):插件可以监听并拦截类型化的事件(比如 tools/* 事件、agent/turn-stopping 事件)。这是「拦截与扩展」的通道。

这带来一个巨大优势:替换一个能力,不需要改动任何调用方

举一个真实的「设计验证双胞胎」例子:

Harness 定义了一份 llm 服务接口(packages/llm/llm),只规定「怎么发一次流式调用、怎么处理重试」,不关心具体是哪家模型。系统里同时挂着两个实现这份接口的插件:

  • dsh-llm-deepseek:专门适配 DeepSeek 自家模型;
  • dsh-llm-pi-ai:内部包了一个第三方 npm 库 @earendil-works/pi-ai,做多家模型厂商的协议转换(官方近 40 家可选模型厂商,大部分由这个插件支持)。

这两个插件互不知道对方存在。装哪个、换哪个,上层 Agent Loop 的调用方式不用改一行——因为它调的是接口本身,而不是某个具体实现。

官方把这种搭配叫「设计验证双胞胎」:两套完全独立的实现都能满足同一份接口定义,从侧面证明这份接口写得足够通用。这也是判断一个插件化架构是否「真插件化」的试金石——如果你的接口只能被一种实现满足,那它就不是真正的抽象。


四、可逆副作用:Cordis 最反直觉的设计哲学

Cordis 有一篇 88 页的设计论文,叫《A Programming Paradigm for Spatiotemporal Composability》。论文里最核心的一个词,是可逆副作用(reversible side effects)

传统插件系统里,一个插件被卸载时,往往留下一堆「没收拾干净」的副作用:注册的定时器还在跑、挂载的事件监听还在、写入的全局状态还在。这些残留会让「热插拔」变成一句空话。

Cordis 的做法是:插件向上下文贡献的一切,都要是可逆的。加载插件时,它声明自己贡献了什么;卸载插件时,框架按相反顺序自动清理这些贡献——停掉定时器、移除监听、撤销状态。

这有什么用?对 Agent 来说,这个意义是决定性的:

  • Agent 可能在运行中途动态挂载/卸载插件(创造模式就是这样);
  • 一个长时间运行的 Agent 服务,可以在不重启的情况下替换自己的某个组件;
  • 论文里那句「未来的 harness 会在持续服务请求的同时,生成并部署对自己组件的修改」,在 Cordis 上已经开始兑现

对比一下:你在用 Claude Code 或 Codex 时,能想象它运行到一半,把「文件系统」这个能力热替换掉而不重启吗?在 Harness 上,这从架构层面就是支持的。


五、工具注册的「遮蔽算法」:同名工具怎么共存

多个插件可能都想注册同名工具(比如两个插件都叫 bash)。Cordis/DSH 用作用域 + 遮蔽来解决:

  • 工具在 ctx.tools 上注册时,会带上一个作用域(scope)
  • 同一作用域内,后注册的会遮蔽先注册的同名工具;
  • 不同作用域(比如不同 agent 预设、不同 realm)之间互相隔离。

这样,一个「标准模式」的 Agent 和「极简模式」的 Agent 可以同时存在,各自看到各自的工具集合,互不污染。子智能体(subagent)继承父作用域的工具,但可以覆写或遮蔽其中的某些项。

这也是为什么「极简模式」真的能极简到只有两个工具——不是靠删代码,而是靠组装时只挂两个工具插件


六、Profile、Bundle 与三层组装

理解 Harness 的装配,需要认识三个概念:

1. Profile(具名组装)

Profile 是存放在 Harness home 中的具名组装。它列出自己叠放的组合包(bundle),存放自己安装的树外插件,并保存用户自己的 cordis.patch.yml

webheadless 是随发行版交付的两个模板 profile。

2. Bundle(分层)

  • dsh-base:每个 profile 的第一层——模型适配器、工具、持久化、沙箱与审批策略、设置、凭据、遥测;
  • dsh-web-app:在 base 上增加浏览器应用;
  • dsh-headless:增加一次性运行器,且完全不带服务器。

3. cordis.patch.yml(用户补丁)

用户可以在不碰源码的情况下,通过 patch 文件选择、替换、扩展任一能力。这就是官方反复强调的「无需改动源码,即可在配置层选择、替换或扩展」。

三层组装的关系可以理解为:base 是地基,bundle 是楼层,patch 是你的个性化装修


七、自指工具:让 Agent 检查并改造自己

DeepSeek Harness 还提供了一组自指(self-referential)Cordis 工具。它们不会进入标准、PTC 或极简模式,而是通过 Web UI 中的「创造模式」作为明确的高级入口提供。

选择创造模式后,Agent 可以:

  1. 检查当前运行时的插件树(有哪些插件、依赖关系如何);
  2. 动态挂载或卸载临时插件
  3. 据此组合、创作新的模式。

这组工具的工程意义远大于「好玩」。它意味着 Agent 的运行时结构本身成为了 Agent 可操作的数据。当 Agent 能读、能改自己的插件组合时,那个「自进化 Agent」的构想,就从哲学讨论变成了一个可实现的工程目标。


八、小结:真正的可组合性,不是「模块化」

很多框架也号称「模块化」,但它们的模块是编译期静态绑定的——换个模块要重新编译、重新部署。DeepSeek Harness 的「一切皆插件」是运行期动态可逆的:

  • 能力 = 服务(可替换)+ 事件(可拦截)+ 可逆副作用(可卸载)
  • Agent Loop 本身也是插件
  • 界面是插件、会话记录是插件、循环是插件,连 Web UI 都能在持续服务的同时被换掉

这正是梁文锋式哲学——「把定义权交还给开发者」——在工程层最彻底的落地。

下一篇,我会把 Harness 拉出来和 Claude Code、Codex、Pi-Agent 做一次横向对比,看它在「自由」与「易用」之间到底牺牲了什么、又赢得了什么。

九、补充:用一个插件视角读一遍源码目录

光讲概念容易飘,这一节带你用「插件」的视角,把 Harness 源码目录当成地图走一遍。克隆仓库后,你会看到几个关键区域:

packages/ —— 能力积木的仓库

这是整个项目的心脏,230+ 个 workspace 成员大部分住在这里。按前缀可以快速分类:

前缀内容对应 ctx 能力
core/*会话、工具、Agent、循环、系统提示词sessions tools agents agentLoop systemPrompt
llm/*模型调用词汇表与适配器接口llm
dsh-tool-*每个工具一个包(bash、编辑器、终端等)注册进 ctx.tools
dsh-llm-*模型提供方适配器注册进 ctx.llm
dsh-ui-* / apps/*Web UI、Headless 运行器界面层插件

读源码的建议顺序:先看 core/session(数据从哪来)→ 再看 core/tools(能力怎么注册)→ 最后看 core/agent-loop(一切怎么转起来)。这三个包读完,你对「插件化 Agent」的理解会超过 90% 只看过宣传稿的人。

examples/ —— 官方教学样本

里面放着最小可跑的示例配置,包括 jsonrpc-agent(极简模式复现基准用)。想验证某个概念,先跑示例再改。

python/ —— SDK 与评测脚本

Python SDK 的源码和基准复现脚本都在这。做生产集成的人应该从这里入手,而不是从 TypeScript 内核入手。

vendor/ —— Cordis 本体

注意:Cordis 是被 vendor 进来的(改了 scope 叫 @deepseek-ai/cordis)。这意味着 DeepSeek 对插件地基有完全的修改权——遇到框架级问题他们可以直接改底层,而不是等上游发版。这是「一切皆插件」能走得这么极端的工程保障。

一个值得记住的心智模型

把 Harness 想象成一台可编程机床

  • core/* 是机床的控制系统(可刷固件);
  • dsh-tool-* 是可换的刀具(可热插拔);
  • dsh-llm-* 是可换的动力源(电机随便换品牌);
  • profile/bundle 是加工程序(同一台机床跑不同产品);
  • Cordis 是机床的总线协议(保证所有部件即插即用、拔了不留痕)。

成品 Agent(Claude Code / Codex)是「封装好的机床」,你只能按说明书操作;Harness 是把控制系统、刀具、图纸全给你的裸机床。会用的人效率碾压,不会用的人会被零件淹没——这就是下一篇横评的基调。

十、补充:Cordis 核心术语辨析——service、context、plugin、inject 的关系

这四个词是读 Cordis 源码时最容易混淆的概念,可以用一张表先立起边界:

术语在 Cordis 中的含义类比
context(ctx插件的共享宿主,承载服务、事件与生命周期清理总线/机箱
service挂在 ctx 上的具名能力,例如 ctx.toolsctx.llm总线上的标准接口
pluginctx 注册服务或挂载副作用的函数,且可被卸载插上总线的板卡
inject在插件中声明要消费的服务,由框架完成依赖注入板卡取电/接线

四者的关系可以概括为:plugin 通过 inject 声明依赖,从 context 上取得别的 plugin 注册的 service,并再向 context 贡献新的 service。没有 context,服务就失去共享容器;没有 inject,依赖只能靠硬编码 import,插件就无法被自由替换;而没有 service 这一抽象,插件之间只能互相调用函数,所谓热插拔与可逆清理也就无从谈起。理解这层关系,再回头看「Agent Loop 本身也是插件」,会发现它不过是「在 context 上注册了一个名为 ctx.agentLoop 的 service」而已。


标签:#DeepSeek #Cordis #插件架构 #AI Agent #开源框架

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值