摘要:DeepSeek Harness 值得研究的重点,是把 Agent 的组合关系做成运行时系统。Cordis 管当前能力拓扑,Session Log 管已发生事实,Agent Loop 在两者之间执行推理和工具调用。
组合复杂度已经超过 Loop 复杂度
Agent 产品化之后,最难维护的往往已经不是那条 loop。
图:运行时组合把插件拓扑、事实日志和执行循环连接起来
组 prompt、调模型、执行工具、回填结果,这条主循环并不复杂。
复杂的是另一件事:哪些能力在当前会话里生效,依赖谁,何时启动,怎么替换,谁负责清理,UI 和恢复逻辑又该相信哪一份状态。
DeepSeek Harness 值得研究的地方就在这里。它新增的是 Agent 组合关系的运行时系统:Cordis 管"系统现在由什么组成",Session Log 管"系统刚才做过什么",Agent Loop 连接这两条事实线。
最小 Agent Loop 只有四步:
- 组装 prompt
- 调用模型
- 执行工具
- 把结果送回模型
做 demo 时,这就够了。进入产品形态后,复杂度会转移到其他地方:多模型和凭证、工具审批、会话恢复、上下文压缩、沙箱与远程执行、多宿主、子 Agent、插件生命周期,以及 UI 如何观察同一份运行事实。
这时问题不再是"怎么写一个 loop"。真正的问题是"怎么知道当前 loop 具备哪些能力,以及这些能力从哪里来"。
Cordis 是横向事实面,回答系统当下由哪些 Profile、Bundle、Patch、Preset、Service、Fiber 和 Effect 组成。Session Log 是纵向事实面,保存用户消息、assistant 输出、模型流、tool call、tool result、turn 和 step。Agent Loop 夹在中间,一边读取当前能力,一边把执行过程写回事件流。
Cordis 把配置变成运行中的插件图
DSH 启动时,会把多层配置装配成插件树,而不是把一份静态配置读进内存就结束。
| 对象 | 作用 |
|---|---|
| Bundle | 分发一组 Cordis 配置和插件代码 |
| Runtime Profile | 决定进程堆叠哪些 Bundle,内置 web 和 headless |
| Patch | 按配置行覆盖或插入能力,用于用户和命令行定制 |
| Agent Preset | 在会话作用域决定工具、提示词和局部能力组合 |
Loader 的输出是一棵运行中的插件树。源码 import 图只能说明"可能加载什么",最终配置树才说明"当前机器和当前会话实际由什么组成"。
这让 Provider 替换从开发期改代码,变成部署期装配能力。前提是系统真的有清晰 seam:Service Definition、Provider、Consumer 三者要分开。
Consumer 依赖能力接口,Provider 提供实现,Definition 固定公共语义。只有做到这一步,替换才不是换个文件名。
Cordis 管生命周期所有权
普通插件表能注册工具,但很难表达作用域、依赖满足、Provider 替换和退出责任。Cordis 把这些关系放进运行时模型。
| 机制 | 解决的问题 | 边界 |
|---|---|---|
| Context / Realm | 决定当前作用域可以解析哪些 Service,支持会话或子树隔离同名能力 | 这是依赖可见性,不是操作系统级权限 |
| Service | 让 Consumer 依赖接口,而不是具体实现 | Definition、Provider、Consumer 要齐全 |
| Fiber | 记录一次插件挂载的配置、依赖绑定、生命周期和资源所有权 | Provider 变化可能触发一串卸载和重载 |
| Effect | 把监听器、进程、句柄、注册项和 disposer 归到同一生命周期节点 | 只能清理登记过的资源,不能回滚外部事务 |
| Event | 观察、决策或包裹请求、模型流、工具执行和停止流程 | 持久 Session Event 要和运行中事件分层 |
这里要特别注意安全边界。Context 的 inject 约束不是沙箱。
同进程代码仍然可能访问 Node API。不可信插件需要进程、虚拟机、WebAssembly 或容器级隔离。
Session 先追加事实,再投影上下文
Session Log 的设计思路很明确:先保存发生过的事实,再决定哪些事实进入下一轮模型上下文。
它会记录 turn、step、用户消息、模型流、最终 assistant message、工具调用和工具结果。下一轮模型看到的是 deriveMessages() 投影出来的 model-visible history,而不是完整日志。
这样做有几个关键收益:
| 设计 | 目的 |
|---|---|
| 流式 chunk 只用于回放和 UI 轨迹 | 避免和最终 assistant message 重复进入模型历史 |
| turn / step / 统计事件不直接进模型 | 保留审计信息,但不污染上下文 |
| compaction 以 replacement 节点追加 | 改变模型可见面,同时保留原始事实 |
| UI、恢复、分叉、重放从同一日志派生 | 减少多份状态互相漂移 |
核心原则可以概括为:model-visible means logged。真正进入模型请求的输入,应该能从规范日志重建。它不要求每轮保存完整 prompt 副本,也不等于把所有历史事件原样重发给模型。
代价也很清楚:日志格式迁移、存储治理、隐私治理都会变重。日志只能证明模型请求过一次外部操作,不能保证重放仍然安全。副作用仍然需要幂等、检查点和"结果未知"处理。
Harness 改善的是有效质量
评价 Harness 时,最容易犯的错是把"执行完整性"和"模型判断质量"混在一起。
Harness 不会让模型天然更会推理。它改善的是执行完整性。
具体看五件事:工具有没有按正确策略调用,跨轮上下文有没有保持,超时和取消有没有处理,结构化终态有没有解析成功,失败能不能归因。
| 观察到的问题 | Harness 的价值 | 优先动作 |
|---|---|---|
| 任务完整执行,但仍漏判、误判 | 低 | 优先改模型、prompt、context、工具能力、Verify / Selection |
| 任务因超时、工具失败、上下文溢出、终态解析失败而中断 | 中到高 | 先做失败分类,再验证新 Harness 是否减少执行损失 |
| 分叉维护困难、执行链臃肿、状态难归因 | 有工程价值 | 先抽稳定 runtime seam,证明能净删除旧代码和依赖 |
更准确的拆法是:
- 内在质量:模型在拿到相同信息且完整执行时,能不能判断正确
- 有效质量:真实运行中,有多少任务拿到足够信息,并以正确终态交付
DSH 主要作用在后者。它减少执行损失,但不能替代模型能力、领域策略和验证体系。
轻量 Harness 与 DSH 的复杂度落点不同
Pi Agent Core 与 DSH 的差异,不是简单的强弱关系。关键是复杂度落在哪里。
| 方向 | 组织中心 | 优势 | 代价 |
|---|---|---|---|
| Pi Agent Core | Agent 状态、模型调用、工具循环与事件流 | 内环短、接口直接,适合嵌入为单次任务执行器 | 不会自动建立通用 scoped runtime graph |
| DSH + Cordis | 运行时插件图、会话事件流、配置装配 | 统一作用域、依赖、生命周期和部署替换 | 动态间接层更深,诊断和学习成本更高 |
如果复杂度主要集中在单次 Agent Loop,轻量执行内核更合适。如果主要矛盾来自多宿主、多 Provider、会话级隔离、运行时重组和第三方插件生态,Cordis 的统一运行图才开始有直接价值。
还要区分当前可用能力和设计接口。Pi 的 Agent Core 已经可用;新导出的 AgentHarness 虽然定义了 Session、Lane、Compaction 和恢复接口,但在所引用 commit 中,prompt、resume、watch 等核心方法仍未实现。不能把接口草图当成可落地能力。
先借鉴,不急着整套迁移
DSH 的设计可以拆开吸收,不必一开始完整迁移。
| 可借鉴点 | 落地方式 |
|---|---|
| 领域编排和 Agent Runtime 分离 | 业务层只描述阶段输入、工具、Schema、限制和终态 |
| 能力 seam | 定义公共语义,分开 Service Definition、Provider 和 Consumer |
| 规范事件流 | UI、恢复、分叉、遥测和模型上下文从同一事实层投影 |
| 生命周期所有权 | 创建监听器、后台任务、句柄时同步登记 disposer |
| 运行拓扑可检查 | 能看到最终配置、当前 Provider、依赖绑定和终态 |
| 迁移控制变量 | Current 与 Candidate 在相同 case、model、prompt、toolset、schema、超时和阈值下 paired eval |
迁移路径也应该克制:
这样做的价值是排除外部变量。否则换了 Harness 后效果变好或变差,都很难知道原因来自模型、prompt、工具、schema,还是 runtime 本身。
什么时候值得采用完整 DSH
可以用下面这张表判断:
| 场景 | 适配度 | 判断 |
|---|---|---|
| 单一宿主、固定 loop、少量稳定工具 | 低 | 显式插件图可能增加概念和诊断成本 |
| 多个 Provider 需要部署时替换 | 中到高 | Service seam、晚绑定和 Patch 有直接价值 |
| 不同会话需要不同工具、提示词、沙箱或执行世界 | 高 | Context Realm 与 Agent Preset 能减少 Consumer 分叉 |
| 运行时装卸、热更新、第三方插件生态成为产品目标 | 高,但风险也高 | 要承担插件质量、安全边界、依赖收敛和资源回收 |
| 目标只是提升模型判断质量 | 低 | 应先投模型、prompt、context、工具和领域验证 |
DSH 目前仍有风险:开发者预览阶段 API 可能破坏兼容;动态图会增加诊断成本;Effect 不等于事务;插件化不等于安全。
Cordis 根 Context、Registry、Events、Fiber、Boot 和 Loader 仍然是先于业务插件图存在的元内核。公开资料里也缺少足够的运行时开销和大规模插件图基准。
本地 vendored Cordis 还有额外取舍:固定和审计更容易,但会带来上游同步成本和语义差异。
结语
DeepSeek Harness 的重点是把 Harness 的组合关系系统化。
Cordis 让系统知道自己现在由什么组成,Session Log 让系统知道自己刚才做过什么,Agent Loop 在两者之间执行任务。它能提升的是执行完整性、状态可归因和工程可维护性,不会自动提升模型的内在判断质量。
当前更务实的做法,是先吸收能力 seam、事件日志、生命周期所有权和运行拓扑可检查性。除非多宿主、多 Provider、会话级隔离、运行时装卸和第三方生态已经成了主要矛盾,否则不要默认迁移到完整 DSH。