2026 年 10 月 10 日,我们让 Agent 重写了系统中编排器的一部分代码。编排器负责分配任务、判断 Agent 是否还在运行,以及失败后重新派发任务。代码写完后,我们几乎同时交给了两个独立的验收 Agent。它们都没有参与这段代码的编写。其中一个找了 20 处地方,故意把代码改坏。验收报告显示,有 5 处改坏后,编排器相关的 1621 条测试仍然全部通过。
另一个验收 Agent 只用了 26 分钟,就在沙箱里实际运行编排器,找到了测试一直没有发现的问题。一份报告说测试看不住,另一份说真跑起来不通过,两份合起来才完整。
“测试绿了,工作却没成立”,这种问题无法单靠更严格的提示词解决。我们需要在模型之外建立一套运行和检查机制。这一层现在中文里常被叫作 Agent Harness。本文回答三个问题:Agent Harness 是什么,它和模型、Agent 框架是什么关系,你的项目什么时候需要它。
Agent Harness 是围绕模型建立的一套运行环境和规则。模型负责在一次调用中决定下一步做什么,Harness 则负责让每一步都能衔接起来:谁在什么时间把哪些材料交给了谁,任务进行到哪里,依据什么判断完成,出错后又该怎样继续。它具体包括规则、检查脚本、权限限制、事件记录和调度机制。
目前,行业内还没有对这个词形成统一定义。下面的归纳来自我们做 Flowness 的经历。Flowness 是我们自己做的分布式 Harness,让很多个 Agent 节点共用一份事件记录(按时间记下每个决定和结果),一起完成复杂任务;它已经持续运行超过 6 个月,真实用在生产交付中,烧了粗略估计 1400 亿 Claude token。
写代码的 Agent 不能自己验收:它写的测试,只回答它自己想到的问题。它说“做完了”,自己写的测试又说“通过了”,这两个结论实际上来自同一个来源。
即使再派一个子 Agent(由主 Agent 派出、带着独立上下文完成某项任务的 Agent)复查,也常常不够。主 Agent 在派发任务时,可能把自己的推理一起交过去。复查的 Agent 读到这些内容,就容易接受“为什么这样写是对的”这套解释。如果它还有编辑权限,发现问题后可能顺手修掉,最终报告反而没有记录原来的错误。
因此,我们把验收权从写代码的 Agent 手里独立出来,具体做四件事:
“改坏”用的是软件测试中的变异测试方法。例如,把一个大于号改成大于等于,或者删除一行代码。如果测试仍然全部通过,就很可能说明现有测试没有覆盖这行代码。变异测试要检查的是测试本身有没有发现错误的能力。
10 月 10 日那次验收用上了其中的换人、改坏和走默认入口。两封任务派发信的第一段都写着“你没有起草上下文”,并规定起草报告只能作为线索:验收者读得到起草报告,不能拿它当依据。
验收 A 负责测试这一层,改坏代码是其中一项。它总共用了 5 小时 17 分。改坏时先运行相关的 135 条测试;如果没有报错,再扩大范围,运行编排器相关的 1621 条测试。这 1621 条取自编排器目录和契约测试目录(检查事件记录读写约定的测试),并非全部为这次重写新增。开头提到的 5 处测试盲区,就是这样找出来的。
验收 B 负责从默认入口验证。它在沙箱里启动了一版正在重构的编排器,运行一个 Agent,等它产生运行记录后,再把它停掉。在这一版里,像这样被停掉的 Agent 没有被接着续跑,系统从头另派了一个新的,B 判不通过。
两份报告都有各自的依据。A 检查的是代码出错时测试能否发现,B 检查的是系统实际运行时有没有按设计完成工作。B 发现的问题,也不在 A 找出的测试盲区中。
原因在上游:系统只记得最近一次看到了什么,Agent 像这样被停掉以后,就不在“最近一次”里了,系统便认为它没留下过运行记录。测试环境把每一次看到的都留着,比真环境记性好,所以测试一直绿。
这类错改坏查不出,真跑才撞得上,只派其中一个验收,就只拿到一半。返修时先照 B 的报告修上游,再照 A 的报告补测试,复验重新改坏 10 处,那 5 处都在内,全红。
上面这次验收是在我们自己的系统里派发的,用的不是这套配置。我们为 Claude Code 单独整理了一套最小配置,放在公开仓库中,一共六个文件,包括一个只读的验收 Agent 定义、两道 hook,以及一道 git 推送前的检查。
hook 是 Claude Code 在调用工具之前、Agent 准备结束工作之前自动执行的脚本,可以拦截相应操作。其中一道写入 hook 限制验收 Agent 的写入权限,只允许它写验收结论,不能修改仓库中的其他文件。验收结论分为通过、不通过和查不清三种。
配置放在 Towow-ai/harness-patterns。整套流程已经在 Claude Code 2.1.293 上跑通。这套配置的早先版本和公开的这一版,我们在一个记录待办事项的小程序上一共测试了 10 次。
使用这套配置时,需要先了解收工 hook 的限制。它只能拦截一次并给出提醒。如果验收正在后台运行,Claude 停下来等待结果,此时再次结束工作,就会被放行,界面上只显示一条提醒。
真正负责把关的是推送前检查:没有通过结论,代码就无法推送。不过,这道检查只识别结论文件中的 verdict 和 author 两个字段,因此必须配合写入 hook 使用,才能防止写代码的 Agent 自己填写通过结论。另外,git push --no-verify 仍然可以跳过这道检查。
这套配置也有明确的限制。比如,有人故意绕过 hook,使用 python3 -c 写入文件,hook 就识别不了。这种情况需要在 Agent 无法接触的 CI 环境中重新运行测试。至于验收结论中列出的证据是否真实,脚本也不会核实,需要查看报告的人自行检查。
Harness 的作用,就是尽量把依赖 Agent 自觉执行的步骤改成由机制检查,并明确记录机制目前无法覆盖的范围。
验收只是 Harness 负责的一部分。根据我们的经验,Agent 要长时间持续工作,Harness 大致需要处理六类问题。不同系统的划分方式可能有所不同:
类别 | 要解决的问题 | 我们做过的机制或遇到的事 |
|---|---|---|
任务与交接 | 工作交给别人时,容易丢失代码背后的决定 | 交接时把完成条件和读写范围写进固定文件,让接手者不必从历史对话里重新找 |
上下文 | 每次行动该读取哪些材料,历史记录越长越难查找 | 写过一套代码,按角色(执行、修复、审阅、规划)列必读材料、按可读篇幅排序 |
权限与边界 | 接到任务不代表有权修改设计约定 | 生产入口上的范围检查因为缺少比对基准被跳过,提交仍然通过 |
事件与验收 | “完成了”需要留下可核对的记录 | 把完成声明写成事件,记录谁完成了哪次运行、依据是什么,系统再根据这条事件放行下游 |
调度与成本 | 先做哪个任务、同时运行几个、失败多少次后停止 | 批量派发时优先推进过最长的依赖链;给自动重试设过独立的次数上限,到上限就停止并记录 |
恢复 | 进程可能退出,已经被取代的执行者也可能突然恢复运行 | 写过新一版事件记录的代码:旧执行者被取代后再写入,存储端按递增编号(fencing token)拒绝 |
表中“权限与边界”的例子,和本文开头是同一种问题。
2026 年 6 月 1 日,我们准备把任务启动时生成的任务材料(写明这次任务的范围)接入生产环境,供任务结束时的范围检查比对。材料生成和范围检查都已经写好,测试也通过了。但生产入口没有调用生成材料的步骤,导致范围检查拿到的只是一个占位值,不是真正的材料。因为找不到用于比对的基准,检查被直接跳过。提交照样通过,原本应该执行的检查却没有发生。当天我们接通了三条主入口的启动,再用一次故意越界的提交确认它会被拒。
这六类问题在 towow.net 的 Agent Harness 手册中都有专门的文章,例如《从需求到验收》和《长任务怎样交接、暂停与验收》。
这三者经常被放在一起讨论。按照各自主要负责的工作,可以这样区分:
三者的功能会有重叠。Agent 框架可能已经提供检查点、重试和权限控制,这些也属于 Harness 的功能。Harness 内部同样需要调用模型 API,也需要某种 Agent 循环。
不同团队对 Harness 的划分也有区别。Datawhale 在《从 Agent Framework 到 Agent Harness》中,按 LangChain 技术栈的划分,把 Harness 放在运行时和框架之上,将其理解为预先配置好工具和中间件、可以开箱即用的套件。按照这种划分,Deep Agents、Claude Agent SDK 都属于这一层。
我们的划分来自“工作要持续好几天”这个实际场景。我们关心的是:任务换过执行者之后,现有机制还能不能回答“做到哪里了、凭什么算做完”。判断自己的项目是否需要 Harness,也可以从这个问题入手。
如果一项工作只在一次对话中完成,旁边还有人随时检查,那么 Claude Code 这类工具自带的调用循环、权限和工具管理通常已经够用,无须额外搭建 Harness。
例如,修改几十行代码、编写一次性脚本,或者制作还在探索方向的原型,装上整套验收只会添麻烦,改一行 README 也要被拦。
下面几种情况,更值得认真建设 Harness:
如果暂时只能增加一组机制,建议先把验收 Agent、写入 hook 和推送前检查一起装上,这三样要配合才起作用。之后再根据项目实际遇到的问题,逐步补齐其他机制。
还要考虑验收成本。10 月 10 日那次代码重写,两个验收 5 个多小时,两个复验将近 3 小时,Agent 运行时长相加 8 个多小时。变异测试也会遇到等价变异:有些改法虽然修改了代码,却没有改变程序行为,导致额外增加一轮检查。
我们愿意付这个成本,因为这类错最难发现:程序不报错,只是该做的事没做。
安装配置之前,可以先用跑一遍测试的工夫做个简单实验。找出自己最近一次测试“全绿”的代码改动,从中挑一个新增加的判断,把它删掉,再运行一次测试。
如果没有任何测试报错,说明这个判断很可能没有得到有效的测试覆盖。
harness 的字面意思是马具。中文技术社区里,有人直接使用 Agent Harness 或“Harness 工程”,也有人翻译为“驾驭工程”(见百度百科词条)。目前还没有一种被普遍接受的中文译法。本文沿用英文名称,查找相关资料时,可以把这几种叫法都试一遍。
首发于 towow.net:《Agent Harness 是什么》。1621 条测试那次验收的完整过程,以及六个文件的使用方法,见《别让 Agent 既当运动员又当裁判》。GitHub 目录里的六个文件和那篇的附录逐字相同:01-independent-verifier。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。