DeepSeek Harness 核心架构解析

"DeepSeek Harness 不是一个内核加一堆插件"
------ 这句话精准地概括了 DeepSeek Harness 的核心架构思想。
其关键在于彻底的去中心化 ,而这一设计背后依赖一个名为 Cordis 的底层框架。
一、理念核心:无特权内核的"插件树"
传统的"内核+插件"模式,如同一个操作系统------内核是权威且受保护的,其他程序只能通过其开放的 API 工作,几乎无法绕过或替换内核本身。
DeepSeek Harness 彻底颠覆了这种模式:
- 它将整个运行时视为一棵 "插件树"。
- 搭建这棵树的每一块积木(如 Model Adapter、Tool Registry、Agent Loop)都是完全平等的插件。
- Cordis 框架保证了没有需要打补丁的特权核心。扩展 Harness 的方式,仅仅是在这棵树下挂载另一个插件。
实际效果 :
如果你想替换"Agent 循环"这个核心逻辑,无需修改任何官方源码,更无需 Fork 分支维护。只需:
- 编写一个功能相同的插件。
- 在配置中将原插件禁用(
disabled: true)。 - 插入你的新插件(
insert)。
整个过程如同编辑几行配置文件,与添加一个普通小工具完全一致。
二、Cordis、Bundle、Profile 与 Patch实现
Harness 的设计主要依靠以下四个层次的机制协同实现:
1. 底层基石:Cordis 框架
-
一切都是插件
Cordis 定义了插件的工作方式。每个插件可以向共享的"上下文"(Context)提供服务或注册事件。例如:
- 模型适配器挂在
ctx.llm上。 - 工具注册表挂在
ctx.tools上。 - Agent 循环挂在
ctx.agentLoop上。
它们均通过相同机制注册为系统服务。
- 模型适配器挂在
-
可逆副作用(Reversible Effects)
这是实现"安全卸载"的关键。当插件通过
ctx.effect()注册监听器或启动服务时,必须同时提供一个"撤销方法"(inverse)。卸载时,Cordis 会按相反顺序执行这些方法,确保所有影响被彻底清除,避免"幽灵回调"或内存泄漏。这使得热替换(无需重启进程即可替换组件)成为可能。
2. 分发与组合:Bundle 和 Profile
-
Bundle(组合包)
是插件的分发单元 ,一个 npm 包即一个 Bundle。
例如
@deepseek-ai/dsh-base包含了模型适配器、工具、沙箱等基础插件。每个 Bundle 在其
package.json中通过dsh.bundle字段声明插件清单文件(cordis.patch.yml)。 -
Profile(配置档案)
是用户定义的启动配置 ,决定了一个 Harness 实例由哪些 Bundle 按什么顺序组成,类似一个"启动方案"。
例如
web这个 Profile 即由dsh-base和dsh-web-app等 Bundle 组合而成。
3. 动态修改入口:Patch(补丁)机制
Patch 让用户无需修改源码即可调整 Harness。Patch 文件(如 cordis.patch.yml)通过 YAML 格式声明操作,其原理类似 Git 补丁,但作用于插件树而非代码。
-
按顺序叠加
启动时,Harness 按以下顺序将 Patch 层层叠加到空的插件树上:
Bundle → Profile 的 patch → 全局 patch → 命令行 --patch 参数后一层会覆盖前一层,最终形成运行时配置。
-
两种补丁操作(社区文档有清晰说明):
- insert::创建 一个全新的插件条目。若对同一 ID 执行两次insert,会因"重复 ID"而报错崩溃。- 顶层
- id:(不带insert) :按 ID 修改已存在的插件条目 。这是替换或修改逻辑时应使用的方式。系统会找到对应 ID 的插件并替换其配置。 注意 :若id补丁中包含name字段且与目标插件不符,系统会警告并跳过该补丁,导致修改不生效。因此,name在补丁应用时会受严格校验。
三、代码实现:打包 → 组合 → 替换
理解"通过 Bundle 打包,通过 Profile 组合,最后用 Patch 替换"的实现,可拆解为三个紧密关联的步骤:
1. 🎁 打包:把插件打包成 Bundle
Bundle 是一个带有特殊声明的 npm 包。其 package.json 通过 dsh.bundle 字段声明 cordis.patch.yml 配置文件,该文件记录插件如何挂载到插件树上。
标准 Bundle 项目结构:
my-awesome-loop/ # Bundle根目录(npm包)
├── package.json # 声明 dsh.bundle 和插件元数据
├── cordis.patch.yml # 定义插件行的补丁文件
└── index.js # 插件代码实现
package.json 关键声明:
json
{
"name": "my-awesome-loop",
"dsh": {
"bundle": {
"patch": "./cordis.patch.yml"
}
}
}
cordis.patch.yml 示例 (替换官方 agent-loop):
yaml
# 禁用官方插件
- id: agent-loop
disabled: true
# 插入你的新插件
- insert:
- id: my-awesome-loop
name: my-awesome-loop # 对应 index.js 导出的 name
config:
# ... 你的配置
⚠️ 重要 :使用
- id:修改现有插件时,name必须与原插件匹配,否则补丁会被跳过。
2. 🧩 组合:将 Bundle 安装到 Profile
Profile 是用户的启动方案,决定实例由哪些 Bundle 组合而成。
当你在 Profile 中安装 Bundle(如运行 dsh plugin --profile demo add ./my-awesome-loop)时,dsh 命令会:
- 使用包管理器将 Bundle 安装到 Profile 目录。
- 将 Bundle 追加到该 Profile 的
package.json中的dsh.profile.bundles列表,以定义加载顺序。
dsh-base 作为核心 Bundle,是所有 Profile 的第一层,提供模型适配器、工具、Agent 循环等基础插件。
3. 🔧 配置:通过 Patch 进行替换
启动时,Harness 按严格顺序叠加多层 Patch:
空树 → Bundle层 → Profile的patch → 全局home的patch → 命令行--patch参数
你编写的 cordis.patch.yml 即为其中一层。当 Patch 执行到 - id: agent-loop 时,系统会定位到官方 Agent 循环所在行,并用你提供的 config 完整替换其配置对象(非深度合并),从而实现"换掉 Agent 循环"。