DeepSeek Harness (DSH) 插件机制解析:一切皆插件的 Agent 运行时

DeepSeek Harness (DSH) 插件机制解析:一切皆插件的 Agent 运行时

基于 deepseek-ai/deepseek-harness 仓库源码分析


一句话结论

dsh(DeepSeek Harness)是一个 Agent harness,核心设计是**「一切皆插件」**------它没有把功能写死在框架里,而是构建在基于 source-vendored 的 Cordis 4.0(vendor/cordis/,重命名 @deepseek-ai/cordis)之上,所有能力都以插件形式挂载。理解 dsh 的插件机制,就理解了整个 harness 的运行逻辑。


一、总体架构

六层结构:界面层(web/cli)→ 启动层(app-boot)→ 组合层(bundle patch)→ 核心层(约 50 个功能包)→ 能力层(工具、记忆、会话等)→ 框架层(vendor 的 Cordis/loader/include)。


二、插件机制的 4 个核心概念

1. Context 是 Proxy,不是普通对象

vendor/cordis/src/reflect.tsget 陷阱 :读 ctx.xxx 时沿 fiber 链向上查找,找不到就报 cannot get property "X" without inject

含义:插件不能随便读全局状态------每个属性都必须能追溯到注入来源。这保证了依赖关系的显式化。

2. Fiber 生命周期状态机

graph LR P[PENDING] --> L[LOADING] --> A[ACTIVE] L --> F[FAILED] A --> U[UNLOADING] --> D[DISPOSED] A --> F

PENDING → LOADING → ACTIVE / FAILED → UNLOADING → DISPOSED。epoch 依赖串fiber.ts _refresh())驱动自动 reload/unload------依赖版本变化时,相关 fiber 自动刷新。

3. ctx.effect() 是唯一注册原语

  • 所有副作用(监听事件、注册工具、创建资源)都必须通过 ctx.effect() 注册
  • disposers 逆序执行:卸载 = 精确回滚
  • 好处:无论插件以什么顺序加载/卸载,清理都不会泄漏

4. 事件 5 种分发方式

方式 语义 典型场景
emit 广播,不等待 通知类事件
parallel 并行执行 无依赖的监听者
serial 串行执行 有顺序要求的监听者
bail 短路返回 审批/校验,可拒绝
waterfall 逐个传递返回值 策略注入点

waterfall 是插件机制的关键:返回值可以修改后传给下一个监听者。dsh 的策略注入点全部用 waterfall:

  • tools/pre-execute(工具执行前拦截)
  • agent/request(组装请求前修改)
  • llm/stream(流式输出逐段加工)
  • internal/config(配置合并)

三、Profile 与 bundle 贴纸叠层

Profile = $DSH_HOME/profiles/<name>/,内容是一份 bundle 有序列表 + cordis.patch.yml

bundle 补丁顺序(后贴赢)

  1. bundles(按配置顺序)
  2. profile patch
  3. home patch
  4. --patch overlays(命令行)

就像贴纸叠层:后贴的覆盖先贴的。调试命令:dsh --profile web --dump-config 可离线打印最终插件树。


四、Loader 与 Include:插件的加载与配置

Loader(vendor/loader/

  • 核心模型:EntryTree / Entry
  • name 动态 import 模块 → ctx.registry.plugin() 开 fiber
  • internal/plugin 监听绑定 fiber↔entry
  • 插件自我 dispose 时写回 disabled: true(下次启动不加载)

Include(vendor/include/

  • cordis.yml 是 YAML 方言,!!js 表达式延迟求值(配置值可以引用运行期对象)
  • applyEntryPatchesid 整体替换 / insert 追加,不做深合并
  • 理解:patch 是「替换或追加」,不是「递归合并」------避免歧义

五、类型声明合并机制

  • 103 个文件 declare module '@deepseek-ai/cordis' 扩充 Context/Events 接口
  • 156 个文件用 import type {} from '@deepseek-ai/dsh-xxx' 空类型导入拉声明(编译后擦除)
  • augmentation 跟着声明它的包走,不在 cordis 包里;外部插件作者必须显式拉取

引用服务 3 件事:

  1. 类型层:拉声明(import type {}
  2. 运行层:装 provider(ctx.provide
  3. 依赖层:inject

六、一次对话的回合流程

会话日志是唯一事实来源------所有事件在发生时立刻追加(不是最后统一写)。

graph TD A[turn/start] --> B[认领输入] --> C[组装提示词] --> D[agent/pre-step] D -- 被拒 --> E[回合无 step 直接结束 turn/end] D -- 通过 --> F[step/start] --> G[user/message 落盘] G --> H[从日志推导历史] --> I[agent/request] --> J[llm/stream] J --> K[assistant/chunk*] --> L[assistant/message] --> M[tool/call] M --> N[tools/pre-execute] --> O[execute] --> P[post-execute] --> Q[tool/result] Q --> R[step/end] R -- 工具要再问一次 --> F R -- 完成 --> S[turn-stopping] --> T[turn/end]

持久事件清单turn/startuser/messageassistant/chunkassistant/messagetool/calltool/resultstep/endturn/end


七、动手理解:一个最小插件长什么样

核心 API 只有三样:

js 复制代码
// 1. defineTool:声明一个工具
const tool = defineTool({
  name: 'demo-hello',
  execute: async (args) => { /* 干活 */ }
})

// 2. ctx.tools.register:挂载到 Context
ctx.tools.register(tool)

// 3. ctx.on('session/event'):订阅会话事件
ctx.on('session/event', (event) => { /* 观察 */ })

写插件 = 注册工具 + 订阅事件 + 用 effect 管理副作用。这就是「一切皆插件」的全部要义。


八、小词典(关键术语)

术语 含义
Harness Agent 的「运行容器」,管生命周期/依赖/事件
Cordis 插件化运行时框架(dsh 的 vendored 底座)
Fiber 单个插件的运行实例,有完整生命周期
Context (ctx) 插件的运行环境,Proxy 实现,属性需注入
effect 副作用注册原语,卸载时逆序回滚
epoch 依赖版本标识,变化时驱动 fiber 自动刷新
bundle 一组插件的打包单元,可被 patch
patch 对 bundle/配置的覆写(id 替换 / insert 追加)
Profile 一份运行配置:bundle 列表 + patch
waterfall 事件分发方式,返回值逐级传递(策略注入点)
Entry/EntryTree Loader 的加载单元模型
cordis.yml 配置方言,!!js 表达式延迟求值
声明合并 declare module 扩充 Cordis 接口的机制
provider 通过 ctx.provide 提供的服务实例
inject 依赖注入声明
dump-config 离线打印最终插件树的调试命令

推荐学习资源


参考

  • 仓库:deepseek-ai/deepseek-harness
  • 源码依据:vendor/cordis/src/reflect.tsvendor/cordis/src/fiber.tsvendor/loader/vendor/include/docs/architecture.md
相关推荐
用户9983834541132 小时前
给 Agent 加一个「挑刺的审稿人」——Critic 与自纠错回环
agent
用户9983834541132 小时前
用LLM + Neo4j 给生物医学文献建知识图谱
agent
用户9983834541132 小时前
从研究到可交付产物——报告生成、导出与容器化部署
agent
Lear2 小时前
MinerU:把文档变成大模型能"读"的样子
agent
武子康2 小时前
GPT-Live 分析研究:从回合式语音到连续交互循环
人工智能·llm·agent
小帅不太帅3 小时前
给大家推荐一个特别好用的专为 AI Agent 打造的最快浏览器
前端·agent·浏览器
莫逸风3 小时前
【AgentScope 2.0】10-总结回顾详解
java·ai·agent·springai·agentscope
武子康4 小时前
给 Pi 增加能力时,应该写 Prompt、Skill、Tool 还是 Extension?
人工智能·llm·agent
怕浪猫12 小时前
第1章:认识 DeepSeek Harness——一个插件化的 Agent Runtime 平台
agent·natural language toolkit·deepseek