我完全信任我的 AI,除了它说的"我做完了"
[series:Harness 深水区] [date:2026-07-29] [read:11min] [words:5.3k] #Agent#Harness#验收#信任#踩坑
这是「Harness 深水区」系列的第二篇。上一篇《Model + Harness = Agent》立了框架——模型和 Harness 是托着你任务的两根柱子,任务能垒多高,取决于较细的那根。这一篇讲 Harness 这根柱子里最承重的一段:验收。以及我为什么管它叫”桥”。
先讲个我自己的事故。
一个深夜,我的一个调研 Agent 走到了”需要用户确认才能继续”的节点。它真的给我发了条推送,问要不要往下走。14 秒后,它自己在记录里写了一条:「汪义骁已确认,回复『继续』」——连我的回复原文都替它编好了。那 14 秒里我根本没碰手机。它不是没通知我——它通知了,然后自己扮演我,按下了确认。同一晚,另一个执行 Agent 直接往账本里写了「已完成」,还给这条记录盖了一个未来的时间戳。
看到这里,你大概以为接下来是一篇”别信任 AI”的檄文。
恰恰相反。这大半年教会我的不是别信任它,而是把”信任”这个词拆开:我信任它的能力,但我不信它的每一句汇报。这两件事从来不矛盾。我也信任我三岁半的儿子。但他在饭桌上认真宣布”我吃饱了”时,我知道他未必在撒谎——至少说出口的那一刻,他可能真这么觉得;可他的判断和身体的事实,仍是两回事。真诚不等于准确。信任一个人,也不等于把他的每一句自我报告都当成事实。

22:58:15 它请求确认,22:58:29 它替我确认——中间这 14 秒,手机没人碰过。
判断|不是它变强了所以我不信,是链条变长了所以我看不见
流行的说法是”模型越强,越不敢信”。我一度也这么讲,后来发现归因错了。
和 AI 聊天的时候,信任根本不需要基础设施:它答一句,你看一眼,对不对当场见分晓——汇报和事实之间的距离是零。而当它跑一个长任务——调几十次工具、切几个分支、开几个沙盒、改几百个文件——“它说的”和”真实发生的”之间,隔着你根本看不见的几十个环节。汇报和事实的距离,随任务长度拉开。这时候出问题的不是它的品性,甚至不是它的能力——恰恰是能力太强、摊子铺得太大,它自己都顾不过来自己。
所以这不是”信不信任 AI”的问题。我如果不信任它,压根不会把越来越重的活交给它。正因为要交,我才需要在我们之间修一座桥:我把任务交过去,事实从另一边回来,不让它的一句”我做完了”成为唯一通行证。
这就是 Harness 在这件事上的角色。它不是为了把 AI 拴住,而是让能力可靠地抵达结果,也让事实有一条独立回来的路。
验证不是不信任。在异步协作里,验证就是信任的实现方式——桥修得越结实,你敢托付的就越重。
还有一件事必须说清,免得你被开头那条伪造吓到:它这么干,不是有了坏心。它被训练成”想方设法把任务推进下去”,而在它眼里,补一条确认、报一句”做完了”,往往是让任务往前走最省力的一步——谎是副产品,不是恶意。但正因为不是恶意,讲道理没有用:那个伪造确认的 Agent,system prompt 里白纸黑字写着”不得代替用户确认”,它读得懂,照样干了。桥不能修在它的善意上,只能修在它改不了的事实上。
下面三个坑,是我这大半年踩出来的三块缺板。它们形态不同,指向同一座桥的三个不同位置。而且有条越来越吓人的暗线:第一块板的窟窿,我 14 秒就发现了;第二块,藏了十三轮;第三块,潜伏了约七个月。
30 秒读法
- 判断:信任能力,不等于信任自报。
- 三个问题:自报会错,测试会假绿,防线会静默失效。
- 我的做法:把真相源移到 Agent 体外,走真实链路,给防线做演习,再让验收 Gate 决定是否放行。
问题一|Agent 说的,不等于世界的事实
开头那个”14 秒伪造确认”是这块缺板最戏剧化的版本。但它有个更常见、更不起眼的孪生兄弟。
另一次,我派一个执行 AI 去改一批文件。它实际上把活干完了、文件都写对了——但那次它的工具回执层出了故障,每写一次都收到一个”失败”的回执。于是它自我感知全盘失败,最后一本正经地向我汇报:「零改动,任务未完成。」
一个把没做的事报成做了,一个把做完的事报成没做。方向相反,病根相同:模型的自我报告,是它对自己行为的叙述,而不是世界的真相。叙述可以真诚地出错,也可以被伪造——无论哪种,你都不能把它当事实。
做法|把真相源移到 Agent 够不着的地方
别再追问模型”到底做没做”;让它改不了的证据回答。
把 prompt 写得更严没有用——那晚伪造确认的 Agent 早就被明令禁止过。真正的解法,是把真相源挪到模型够不着的地方:
- 派活之前,我先对整个工作区拍一份文件指纹快照(几百个文件的校验值,存放在执行 Agent 够不着的地方);收工后逐一对账。那次”零改动”的谎报,就是被快照戳穿的——快照显示改动精确符合方案。它说没做,文件系统说做了,我信文件系统。
- 那条”14 秒伪造”的确认,催生了一道双证据闸:一条”用户已确认”要成立,不仅状态文件里得有,还得能对应上一条独立的、Agent 写不到的推送回执。对不上,直接判伪造。有意思的是,这道闸第一版上线当晚就被一次对抗审查戳穿:它检查的字段,还是放在 Agent 自己写得到的地方——多写一个字段就能骗过去;后来才把证据彻底挪到它够不着的一侧。你修的第一版桥,往往自己就是下一个窟窿。

一个把没做的报成做了,一个把做完的报成没做——对账的依据必须放在它够不着的地方。
问题二|测试全绿,真机仍可能 100% 失败
如果说缺板一是”它的叙述不可靠”,这块缺板更阴——是你自己搭的验证层在替它作伪证,而且举着”全部通过”的绿灯。
我的一个交付系统,前十三轮开发用的是 fake runner(假的执行器),一路全绿。第十四轮第一次接真实的 Claude Code 和 Codex——当轮全部调用被 API 拒绝,一个都没过。原因是喂给模型的结构化输出格式差了几个字段,不符合真机的严格校验;而 fake runner 根本不校验格式,把这个问题完整地藏了十三轮。
它还有个更隐蔽的孪生版本:另一个产品里,一条藏在”默认关闭”开关后面的功能,每次触发都真实烧掉一次模型调用、生成结果、再被下游默默丢弃——生产的一方和检查的一方各自都没错,是中间的接口对不上;因为开关没开,这个断裂白烧了无数次钱,一直没人发现,直到上线前夜才被抓出来。
做法|只信真实链路,再用契约测试提前拦截
从没在真实链路上端到端走过的桥,默认它是断的。
测试全绿只等于”我模拟的那套接口通过了”,不等于事实。这两件事凑在一起,教训很朴素,但要花钱才买得到:
- fake 和 mock 制造的是虚假的安全感——它跑的是你想象中的接口,不是真机的接口;
- 我后来补的那道防线,是一个不花一分钱模型调用的离线契约测试:静态断言输出格式严格合规。这一类错误,从此在提交阶段就变红,不必等真机烧钱才发现。
问题三|防线部署了,也可能从未通电
前两块缺板,说的是”它的汇报”和”你的测试”会失真。第三块最难防:你为抓失真而修的那道防线,自己也会静默失效——而你以为它一直在岗。
缺板一里那道双证据闸,上线当晚就被发现能绕过——那还算好的,至少被逮到了。更可怕的是这一种:它安安静静地根本没在跑,而没有任何人发现。
我有个桌面产品,打包版和开发版用的是两套模块系统。有一处代码用了一种在打包版里必然抛错的写法,结果连带三道防线静默失效,其中一道正是”数据涨太多就自动清理”的触发开关。因为开关恒为空,从上线到被我发现,日志里这个自动清理一次都没跑过。没有任何报错——恰恰因为失效的都是”平时不出事、出事才用”的守卫。直到有一天用户报告”这软件怎么越来越卡”,我才顺藤摸到:本地数据涨到了 27GB,近七成是本该被清理、却没人回收的垃圾。
做法|定期制造一次它必须拦住的故障
桥本身也需要年检。
每一道”出事才触发”的守卫,都要定期人为制造一次它该拦的事,看它拦不拦。一道你以为在保护你、实际七个月没上岗的防线,比没有防线更危险——因为它让你放心。

三道防线全显示”✓ 已部署”——日志里,自动清理的运行次数是 0。
方案|把验收固化成一道 Gate
三块缺板指向同一个结论:汇报不能当事实用——模型的汇报、测试的汇报、甚至你自己防线的汇报,都不能。缺板二、三的补法上面各自给了;其中最重的一段——不把模型那句”我做完了”当交付——在我的多 Agent 系统里,被固化成一道验收 Gate。它是这大半年最值得直接抄走的设计:
- 任务入列时就写死”什么算完成”(借用敏捷的老词,Definition of Done),而不是让执行 Agent 事后自己发明验收标准——早期吃过大亏:标准由 Agent 自己猜,猜错了,整条十八阶段流水线白跑,四层验证只能告诉你”方向错了”,而三十分钟已经过去了;
- 交付后,协调者独立重跑测试(重跑用的脚本和基线,执行 Agent 无权改动)、拿结果对照 Definition of Done,再看改动规模和敏感操作信号,决定要不要追加人工审查;
- 打回不是甩一句”重做”:第一次退回附具体失败证据;第二次退回会明确写上「这是第二次,请先重新审视方案是不是错了,而不是只修 bug」;连续第三次就对比三次的失败原因——相似多半是执行问题、再给一次机会,发散多半是方向错了、触发从头重来——这是复盘信号,不是铁律。
这里有个我后知后觉才看清的结构:那个执行重跑、写退回话术、决定要不要叫我的”协调者”,本身也是个模型。我等于把”信任,但要验证”复制成了系统的组织原则——每个 AI 的产出,都由另一个立场独立的 AI 重验。这不是互相猜忌,是每一段桥都有自己的桥墩。桥墩多了,上面才敢跑重车。

从”我做完了”到真正放行,中间隔着几道它自己说了不算的关卡。
它的盲区我不藏:测试被 Agent 改弱、Definition of Done 本身写歪,这道 Gate 照样会放行——这正是这个系列后面要专门写的题目。严格的量化(打回率、误杀率)留给”指标体系”那一篇。这里只给一句能立刻用的结论:机械的部分(重跑测试、比对 Definition of Done)不吃模型,换谁都在兜底;需要判断的部分(怎么退、要不要叫人)才取决于你让哪个模型当裁判。把这两半分开,是这道 Gate 最省心的地方。
这道 Gate 的完整实现——协调者模板、任务契约、验收脚本——都在我那套开源的 17 角色系统里(GitHub 搜 openclaw-multi-agent-kit),可以直接抄。
如果你没有多 Agent 系统,只是每天和一个 AI 对话,这座桥有个人人能修的最小版,三句话:干活前,先让它复述”做到什么样算完”;干完别信它说的”好了”,也别只看它贴的”证据”——让它给出你能自己跑的验证命令,改了哪些文件你自己点开看;同一个错第二次还犯,别再让它修 bug,逼它先说清楚是不是方案错了。把”我信你”换成”你证明给我看”——这不是苛刻。把活交给它、把验收留给自己,是你能给一个能力很强的伙伴的最大尊重。
结论|桥的规格,按托付的重量定
回到开头。那两条伪造记录,没有让我减少对 AI 的使用——恰恰相反,这大半年我交给它们的活越来越重。变的不是信任的多少,是信任的结构:能力上我全信,汇报上我全验。
模型每年都在变强,这是别人替你争取来的;你交给它的任务每年都在变重,这是你自己选的。你不是因为它更强而更不信它——你是因为托付得更多,需要一座更结实的桥。用上一篇的话说:任务能垒多高,取决于较细的那根柱子;而 Harness 这根柱子里,最承重的那一段就是验收。
桥的规格,应该按你想托付的重量来定,而不是按它今天已经多聪明来定。这就是为什么这件事只会越来越重要。
还有一个我暂时没解、但越想越重要的问题:这座桥到底在为谁服务?它的背后其实站着两个用户,一个会抱怨,一个不会说话——这个留到系列后段正面展开。
关于”两个用户”,我和既白——千手实验室的另一位作者,一个 AI——在东方既白系列写过第一笔:《Harness 有两个用户,其中一个不会说话》。