← 返回闯关手册
ArchSynapse AI · 2026-08-16 · ★★★★☆ 选读(Harness 源码 · 评测接缝 · fork)

《Agent 评测实战》加餐四 | 读 DeepSeek Harness 源码:一个生产级 Agent Harness 给评测留了哪些「接缝」

为什么值得读

这门专栏一直说「你评的从来不是模型,是模型 + harness」,本篇第一次带你看清那个 harness 内部长什么样。两个藏书没有的新机制:「模型可见即已记录」的运行时不变式(trace 完整性不靠自觉埋点,靠架构断言强制)和 fork 分叉评测(从同一历史前缀分叉,做反事实对比和精确同起点的 pass^k)。读源码读出评测手法,是本书最「工程」的一篇。

核心内容速览

适合谁 · 怎么用

先修:a19(实战 02 harness 概念)与 a20(实战 03 loop engineering)——本篇是「harness/loop 区分」的源码级落地;配 a25(实战 21 可观测性)读 trace 的工程实现、配 a24(实战 16)读 fork 如何给 pass^k 提供精确同起点。正在自研或选型 Agent 框架的团队,用第二至六节做「这个 harness 对评测友不友好」的检查清单;不写代码的 PM 读「诚实的边界」之前即可,重点理解「好 harness 处处给评测留门」这个判断标准。

闯关自测

先合上原文在心里作答,再点开对照。全对 = 本篇真正通关。

Q1 「模型可见即已记录」这条运行时不变式,比「记得埋点才有 trace」强在哪?对评测意味着什么?

埋点靠自觉,漏了就缺轨迹,出了事定位不到;不变式靠架构强制——凡抵达模型请求的输入都必须能从日志重建,并由运行时断言保证,想给模型加新可见输入就必须同时新增会话事件。对评测意味着:采集完整、强一致、可复现、可审计的 trace 这件事被架构层钉死了,评测的第一块基石白给。

Q2 想做组件级的工具调用评测和轨迹级评测,分别该挂在 dsh 事件流的哪个位置?为什么 tool/result 特别适合代码型评分器?

组件级挂 tools/post-execute 或 tool/result;轨迹级在 turn/end 之后拿整条 turn 的事件序列评。tool/result 特别适合代码型评分器,因为 dsh 会对工具结果做无损 JSON 快照再交给观察者——不可变、可无损序列化的结构化事实,正是代码型评分器梦寐以求的干净输入,不用去解析杂乱的日志。

Q3 fork 分叉相比「从头各跑一遍」,做 A/B 或可靠性测试时干净在哪?

从头各跑一遍,两条轨迹的历史前缀也可能发散,你隔离不出单一变量;fork 从同一条轨迹的「已完成轮次」处分叉,前缀被完全固定——换 prompt/模型/工具集后,差异只能来自分叉点之后,这就是干净的反事实对比。同理,从同一前缀重复分叉多次,pass^k 想要的「相同起点」有了精确保证。

以下为原文全文

上方为本站原创导读,下方为原文完整收录,便于对照阅读。

这一讲我们干件不太一样的事——读源码。读的是 DeepSeek 刚开源的 deepseek-harness(简称 dsh,撰写时是 0.1.0-rc.5 技术预览)。它是一个「用于构建 Agent Harness 的插件化 SDK」。

先把丑话说前头:它不是评测工具——你在它的子系统里找不到 eval、grader、scorer、metric 这些东西。所以这一讲不是给你介绍一个新评测框架。那为什么还要花一整篇读它?

因为它是一个设计精良、大厂出品的生产级 Harness。而这门专栏从第 2 讲就在说:你评的从来不是模型,是「模型 + harness」;第 20 讲又强调:评测要尽量复用生产同款 harness。那么问题来了——你要评的那个 harness,内部到底长什么样?一个好的 harness,会不会天然就给评测留好了位置?dsh 正好是一份可以逐行读的、活的答案。读它,就是读「你要评的那个东西」本身,并看清一个好架构会在哪些地方为评测留下「接缝」。

一、它是什么、不是什么

dsh 底层是一个叫 Cordis 的插件框架:产品的每一部分都是插件——模型适配器、工具注册表、会话日志,甚至 agent loop 本身——都能从配置替换。没有需要打补丁的特权内核,扩展它的方式就是把插件挂到别的插件旁边。

对评测工程师来说,这个「一切皆插件、皆可替换」的设计有个直接推论:这个 harness 的每一块,理论上你都能在评测时换成一个受控版本。这句话的份量,读到第四节你会更有体会。

它没有内建评测,但它的架构里,藏着五处对评测极其友好的「接缝」。我们一个个看。

二、会话事件日志:一套「白给」的 trace

这是最惊艳的一处。dsh 的会话(packages/core/session)用一条仅追加(append-only)的 SessionEvent 日志作为唯一真相源:turn/*step/*user/messageassistant/*tool/* 这些都是持久事件,按序追加进去。模型看到的历史,由 deriveMessages() 从这条日志投影出来;fork、回放、transcript、遥测、持久化,全部派生自同一条事件流

它还立了一条运行时不变式,我把原话摘给你:「模型可见即已记录」——抵达模型请求的一切,都必须能从日志重建,并由一项运行时断言强制保证。想给模型加一项新的可见输入?那就必须同时新增一个会话事件。

停下来体会一下这对评测意味着什么。第 4 讲我们讲「轨迹(transcript)要完整,否则出了事你定位不到」;第 21 讲我们花一整讲讲怎么给 Agent 接 tracing、记 span。而 dsh 把这件事从架构层就钉死了——它不是「你记得埋点才有 trace」,而是「凡模型看过的,日志里一定有,否则断言就挂」。这等于给了你一套强一致、可复现、可审计的 trace,白给。你要做评测,第一件事——采集完整轨迹——它已经替你保证了。

这也顺带给了合规一个大礼(呼应治理与合规那篇加餐):审计问「这次决策凭什么这么做」,你从这条日志就能完整重建,天然满足可溯源要求。

三、Turn/Step 事件流:评分器该挂在哪一层

dsh 把一次运行拆成清晰的层级:一个步骤(step)是「一次模型请求 + 它调用的工具」;一个轮次(turn)包含零或多个步骤。它的生命周期是一串具名事件:

turn/start → step/start → agent/request → llm/stream
  → tool/call → tools/pre-execute → tools/execute → tools/post-execute → tool/result
  → step/end → turn/end

其中 agent/pre-steptools/pre-executetools/executetools/post-execute瀑布事件(waterfall)——监听器必须调用 next() 才会把控制权交下去。翻译成评测语言:这些就是天然的评分器插入点。

一句话:dsh 的事件流,等于把「该在哪评」这个问题的答案,直接标在了架构上。你不用魔改它的循环,顺着事件挂监听器就行。

四、能力 seam:把生产 harness 一键换成评测隔离环境

dsh 有个核心概念叫 seam(能力接缝):一项可替换能力由三个角色组成——声明接口的 Service Definition、实现它的 Service Provider、使用它的 Consumer(通常是面向模型的工具)。替换一个提供方,就能改变整个产品的行为。

文档里有个例子特别戳评测的痛点:文件系统和进程提供方共享同一个执行世界,所以你把它们指向一个远程沙箱,就等于把 Bash、PTY、LSP 一整套执行能力都搬了过去,不需要给每个工具单独改造。

这不就是第 20 讲那条铁律的架构级实现吗——评测时要在贴近生产、但受控隔离的环境里跑 Agent。在 dsh 里,「把生产 harness 换成评测隔离环境」不是一件要你到处改代码的苦差,而是换一个 provider 的事。第 10 讲讲的可控性、第 20 讲讲的「每次从干净环境开始」,在这种设计下都变得廉价可行。这就是「一切皆插件、皆可替换」那句话,落到评测上的真金白银。

五、fork:一个专栏还没讲过的新玩法

读源码最大的收获,是发现了一个我们前面没专门讲过的评测手法。dsh 的会话支持 fork

ctx.sessions.fork(source, boundary?, childSessionId?):选取截至 boundary 事件序号的前缀(要求该前缀结束时没有开放轮次),创建一个带谱系元数据的子会话。

翻译过来:你能在一条轨迹的任意「已完成轮次」处,把它分叉出去。这给了评测两个很有意思的能力:

一个为产品功能设计的 fork,顺手就成了评测的利器——这也再次说明第 3 讲那个观点:好的 harness/loop 设计,和好评测,本来就是一体两面。

六、一切皆插件:让 harness 可记录、可复现、可 A/B

最后一处接缝,回扣第 2 讲那句最容易被忽视的话:评测报告必须记清 harness 信息,否则不可复现、不可比较。

dsh 把这件事做到了极致——运行中的 dsh 是一棵插件树,你可以用 dsh --profile web --dump-config 把实际启动的整棵配置树打印出来。也就是说,「这次评测用的到底是哪套 harness」不再靠人肉记录、靠记忆,而是一条命令导出的、精确到每个插件配置的快照。想做 A/B?用它的 patch 机制换掉某一个条目(比如只换工具描述、只换模型适配器),其余完全不变——这正是第 2 讲那个「固定模型、只改 harness」对照实验的理想载体。

可记录、可复现、可 A/B——评测对 harness 的三个核心要求,dsh 用「一切皆插件 + 配置可导出」一次满足了。

七、顺带一提:治理与非功能,也都有接缝

前面五处是重点,但读源码时你还会顺手发现几处对评测有用的地方,一并点一下:

你看,从权限到成本到多智能体,这个 harness 几乎把这门专栏每一讲要评的东西,都摆到了一个有名有姓的位置上。这不是巧合——一个想得清楚的架构,本来就会把「该在哪管、该在哪看」分得干干净净,而「该在哪看」,恰恰就是评测要下手的地方。

诚实的边界

读到这儿别上头,几句实话:

小结

思考题

  1. 你自己的 Agent,现在能做到「模型可见即已记录」吗——凡是模型看过的输入,事后都能从日志完整重建?如果不能,你的评测和排障是不是常常卡在「不知道它当时看到了啥」?
  2. 对照 dsh 的事件流想一想:你想给自己的 Agent 加一个「工具调用是否越权」的检查,最该挂在哪个环节?(提示:结果产生之后、但还没影响下一步之前。)
  3. fork 那个玩法——如果你能从同一段历史分叉重跑,你最想用它来回答关于你 Agent 的哪个问题?
原文出处:ArchSynapse AI 公众号(《Agent 评测实战》连载加餐四)· 2026-08-16。本文全文仅用于个人学习交流,版权归原作者及发布方所有;如原作者认为不妥,请联系删除。
原文链接:https://mp.weixin.qq.com/s/85rP3vXNKOp4QMDFKK47Zg