DeepSeek Harness

DeepSeek Harness 插件架构与运行原理

DeepSeek Harness 采用 Cordis 驱动的一切皆插件架构,模型适配器、工具、会话日志和 Agent Loop 都能从配置组合或替换。本篇拆解 Profile、Bundle、核心包、轮次与步骤、持久会话事件和能力接缝,帮助插件开发者判断新行为应该挂在哪个扩展点,而不是直接修改运行循环。

写代码 高级

📚 系列导航:上一篇 DeepSeek Harness 多智能体协作教程 已经使用子 Agent、工作流、沙箱与审批;本篇拆解 Cordis 插件树、会话和工具执行原理;下一篇 DeepSeek Harness 插件推荐与安装教程 会从社区清单中筛选插件,并完成安装和验证。

DeepSeek Harness 插件架构的关键结论是:模型、工具、会话、Agent Loop 和界面都不是焊死的内核,而是启动时挂到 Cordis 共享上下文的一棵插件树。 新行为应进入已有扩展点,只有运行语义真的变化时才需要修改循环本身。

DeepSeek Harness Profile、Agent 预设、插件树和运行时架构图

DeepSeek Harness 的 Cordis 插件机制

Cordis 允许插件向共享上下文贡献服务、类型化事件和可逆副作用。模型适配器、工具注册表、会话日志甚至 Agent Loop 自身都按这种方式注册,因此卸载插件时,相应注册也能撤销。

这类似把不同设备插到同一套标准接口上:接口约定电压和插孔,设备负责具体能力。插件化不是简单地把文件拆成很多包,而是要求服务、事件和生命周期有明确边界。

官方强调不存在需要所有扩展都去打补丁的特权内核。开发者要做的是在其他插件旁挂载新插件,并通过配置选择它,而不是复制核心逻辑形成无法同步的分叉。

界面本身也能由插件组合。开发者预览阶段已经出现多种独立 UI 插件,这说明扩展点不只在模型和命令行工具;不过第三方界面能做到什么、是否兼容当前版本,仍要以插件源码和实际安装结果为准。

DeepSeek Harness 多种插件化 Web UI 界面示例

Profile 与 Bundle 如何组合配置

运行中的 dsh 是启动时按层组合的插件树。Profile 是保存在 Harness Home 中的具名组装,记录要叠加的 Bundle、安装的树外插件,以及用户自己的 cordis.patch.yml

Bundle 则是 Cordis 配置行和对应代码的分发格式。webheadless 是随发行版提供的 Profile 模板:前者增加浏览器应用,后者增加不带服务器的一次性运行器。

配置层会按顺序叠加,后层可以通过行 ID 替换整项配置或插入新行。要查看当前机器实际启动了什么,可以执行:

dsh --profile web --dump-config

输出的是最终配置树,不是某一份孤立模板。排查“为什么插件没有生效”时,应看最终树,而不是只检查自己刚改的一个 YAML 文件。

DeepSeek Harness 核心包的职责

核心包不是一个巨型总控类,而是一组向上下文贡献能力的插件。core/session 管仅追加的会话事件日志,core/system-prompt 组装提示词片段和工具 Schema,core/tools 提供工具注册与受控执行流水线。

core/agent 定义 Agent 接口和活跃实例注册表,core/agent-loop 提供默认驱动,llm/llm 定义消息、流式输出和模型适配器接缝。理解职责后,新增能力时就能先判断它属于模型、工具、会话还是运行控制。

最常见的误区是把“Agent 做了什么”全部塞进 Agent Loop。实际上,文件系统、Shell、沙箱、审批、后台任务和 UI 都有各自服务或事件;直接改循环会把本来可替换的能力重新耦合在一起。

Agent Turn 与 Step 运行流程

一个 Step 是一次模型请求加上随后发生的工具调用,一个 Turn 可以包含零个或多个 Step。轮次开始后,驱动器领取输入、组装提示词与工具 Schema,再经过 agent/pre-step 进入模型请求。

模型流式输出会写入助手消息;如果产生工具调用,就经过 tools/pre-executetools/executetools/post-execute,再把结果交回后续 Step。没有待处理输入或工具债务时,轮次才结束。

这个区分解释了为什么一次用户消息可能触发多次模型请求:Agent 先决定调用工具,拿到结果后还要再请求模型整理下一步。统计成本、实现取消或插入策略时,必须分清 Turn 和 Step。

会话日志与上下文重建

模型能看到的上下文从会话日志投影出来。用户消息、助手分块、工具调用和结果等持久事件都写进日志,恢复、分叉、转录、遥测和持久化再从这条事件流派生。

DeepSeek Harness Trajectory 会话日志与工具事件查看界面

官方用一句规则约束实现:模型可见就必须已记录。任何进入模型请求的输入都要能从日志重建,因此新增一种模型可见内容时,不能只在内存里临时拼接;需要扩展会话事件并从日志渲染。

这让调试有了可靠依据。界面显示异常、恢复后上下文不一致或工具结果丢失时,应检查事件是否被记录和投影,而不是只盯着最后一条回答。

如何使用 Capability Seam 扩展能力

能力接缝(Capability Seam)包含三种角色:声明接口的服务定义、实现接口的服务提供者,以及使用能力的消费者。替换一个提供者就能改变整套产品行为,例如把文件系统和进程提供方指向远程沙箱后,Bash、PTY 和 LSP 可以一起迁移执行环境。

新增模型提供方应注册到 ctx.llm,新增面向模型的能力应注册到 ctx.tools,后台工作进入 ctx.jobs,文件访问策略通过文件系统提供方或 fs/* 事件完成。拦截请求、工具和轮次,则使用相应的 agent/*tools/* 事件。

动手前先画清“定义、提供者、消费者”三者,能避免只写出一个没人调用的服务,或让消费方直接依赖某个无法替换的实现。更完整的映射以 DeepSeek Harness 官方架构文档 为准。

常见问题

所有新功能都要修改 Agent Loop 吗?

不需要。模型、工具、文件系统、后台任务和审批都有各自扩展点,优先注册服务或监听事件。

Profile 和 Bundle 有什么区别?

Profile 是一次运行使用的具名组装,Bundle 是一组 Cordis 配置行与挂载代码的分发单元。Profile 可以按顺序叠加多个 Bundle。

为什么会话日志这么重要?

因为模型可见上下文、恢复、分叉和工具记录都从日志派生。没有进入日志的临时状态无法保证重建。