
2026年的AI开发者面临一个尴尬的事实:AI消除了写代码的门槛,但没有消除组织结构的门槛。你可以在一个周末生成一个能跑的应用,然后在下一个周末眼睁睁看着它崩塌。不是你不够努力,而是你生成代码的速度超过了你理解它的速度。
这正是Harness要解决的问题——但Harness本身也在经历结构性的拷问。
过去几天,我从DEV社区上的一系列讨论出发,逐步推导出了一个六层架构。这些讨论来自不同的作者,指向同一个困境的不同侧面。@heinrichneb 问“有人见过你的AI评审员说‘不’吗?”;@james_anderson_h 问AI工具是让我们更高效还是给了我们一个新玩具;他后来又把问题细化成“AI代理的九种静默失败方式”。@mansio 在评论区追问“如何证明系统真的检查了所有应该检查的东西”——这些声音共同构成了这篇文章的起点。
一、核心困境:调试幻觉
2026年8月底,heinrichneb 在DEV社区发布了一篇文章,提出了一个看似简单但极难回答的问题:
有人见过你的AI评审员说“不”吗?
如果你有一个AI评审器——用来检查代码、审核输出、判断请求是否合规——你凭什么相信它真的在工作?他做了一个统计:在他的代码仓库中,204个自动化检查里,89%从未被证明过它们能够失败。一个从未被见过失败的评审器,和一个批准一切的评审器,在日志层面无法区分。两者都输出绿色,直到某个评审器放行了一件不该被放行的事。
james_anderson_h 后来把这个问题扩展到了AI代理的整个执行链路。他指出,代理的失败不同于普通软件——数据库会报错,API会返回500,但代理的失败方式是“完成任务,然后交给你一个自信的、格式良好的、看似合理的假答案”。他把这称为“差异可观测性”:应用在受损,但监控器却在报告健康。
mansio 则在评论区追问了另一个维度:即使评审器正常工作了,你怎么知道它覆盖了所有应该被覆盖的东西?如果一个收集器在输入层就丢掉了数据,流程本身仍然是绿色的。
这就是“调试幻觉”的根源——你用来修复系统的工具,正是那个自信地破坏它的工具。
二、第一层:表单 + 流程——把“验证”嵌入结构
验证应该发生在哪里?
传统系统的回答是:在执行完任务之后,加一道“验证”步骤。但如果你仔细想,这个“验证步骤”本身也需要被验证。它是一个执行动作,和其他执行动作一样可能出错。
真正的验证不在末尾。它发生在每一个节点的条件里。
以我在《From Probabilistic Guesswork to Deterministic Execution》中展示的财务审批流程为例:
提交申请 → 上级审批 → 部门负责人 → 财务审批 → 总经理审批 → 董事长审批 → 出纳付款
每一个节点的路由条件本质上都是验证:Dept==A验证部门归属,Counts[5000,10000]验证金额范围。验证不是“流程跑完了再加一道检查”,而是“流程在每一步都在做判断”。
james_anderson_h 在《Are AI Tools Actually Making Us Productive》中描述了一个类似的困境:他打开十四个标签页,在AI和各个工具之间来回搬运输出。AI告诉他该怎么做,但它没法自己去做——因为它没有“手”。他的描述指向同一个问题:当AI的输出没有被嵌入到一个可执行的流程中时,你只是在充当它的快递员。
表单定义规范,流程定义执行,日志记录验证——三者合一,才是完整的“验证即过程”。
三、第二层:递进式纠偏——不累积污染
想象一个场景:你让AI写一段代码,它错了。你说“这里不对”,它修正了。你说“方向对了但深度不够”,它又修正了……
这是累加式纠偏:每一轮都在“历史 + 补丁”的堆积上继续。历史越长,上下文越混乱。你累积的不是理解,是相互矛盾的补丁。
另一种方式是递进式纠偏:每一轮不是打补丁,而是重写基础以吸收修正。状态始终是“当前完整版本”,而不是“旧版本 + 补丁列表”。
两者的工程差异很大:
| 维度 | 累加式纠偏 | 递进式纠偏 |
|---|---|---|
| 状态模型 | 历史 + 累积补丁 | 当前完整版本 |
| 长对话行为 | 越走越乱 | 始终保持清晰 |
| 修正的可验证性 | 补丁列表无限增长 | 每次重写后可验证 |
但递进式纠偏引入了一个新问题:当AI“重写基础以嵌入修正”时,你怎么确认它真的嵌入了修正,而不是产生了看起来像被修正了、实际上已经丢了之前内容的东西?这就是#james_anderson_h 所说的“静默成功”——新版本看起来完整,但可能已经丢了关键约束。
四、第三层:存在性检查——切断无穷回溯
第二层留下一个问题:任何纠偏系统,怎么保证自己没有在纠偏中丢失之前的内容?
传统方案是“用外部测试验证”——植入已知坏案例,观察系统是否拒绝它。heinrichneb 在他的文章中提出了一个“三扇门”的测试框架:未解决状态必须变红,已解决状态必须变绿,重新植入错误必须再次变红。这就是Harness的思路。
但“用外部测试验证”不是一个最终的答案。heinrichneb 自己也承认:“在我连接好它的那一天,那个评审员确实能说不。但它对今天的情况什么也说明不了”。
它只能测试“已知的坏”——未知的未知永远穿透。它只能证明“过去它能拒绝”,不能证明“此刻它能拒绝”。它还引发了无穷回溯:谁来验证那个外部测试?
所以“用更大的Harness来测试Harness”不是一条能走通的路。它只是把问题推高了,没有解决问题。
要切断这个链条,只能转换思路:从依赖外部测试,转向依赖结构自洽。 不是问“谁能测试这个系统”,而是问“这个系统本身的设计,是否让‘外部测试’变得没有必要”。
五、第四层:蒸馏——结构压缩与核心保留
“结构自洽”怎么落地?我的想法是蒸馏——从执行日志、对话历史中提取“稳定模式”,固化为规范。
蒸馏至少能解决三个具体问题:
- 减少噪声放大:每轮纠偏都会带入新的波动,蒸馏提取核心结构,丢弃无关波动
- 控制状态膨胀:递进式纠偏虽然去掉了补丁堆叠,但完整版本本身仍在不断扩展
- 保持跨轮次一致性:蒸馏把跨轮的共识提取为规范,确保后续输出遵循已建立的模式
但有一个边界不能碰:不是所有东西都可以被蒸馏。
三个“不可变公理”必须被保护:
-
fail-closed规则:任何未定义的结构必须被拒绝 - 表单的顶层Schema:规范的最高层级结构
- 流程的执行模型:流程如何运行的逻辑
如果这些被蒸馏,系统会失去根本锚定——它可以被压缩成任何形状,但没有东西能验证压缩是否保留了原本的意图。
六、第五层:自指——系统处理自身规范的能力
蒸馏能保持清晰,但有一个问题没解决:如果规范本身需要被修改,谁来修改它?修改的规则由谁来定?
传统系统的处理方式很特殊:有一套专门的“规则变更流程”,而这套专门流程不受正常流程的约束。这导致两个问题:规则变更的审计和正常业务的审计是两条独立的链条;“谁守护规则”比“谁批准付款”更难回答。
mansio 在评论中追问的正是这个问题:如果输入在到达流程之前就被丢弃了,流程本身仍然是绿色的。问题的根源在于——你没有让流程处理自身的定义。
我的做法是让“规则变更”不再是一个特殊情况。如果“表单+流程=完整过程”这个定义本身能作为输入,被流程处理,那么流程就能处理自己的定义。
这解决了两个具体问题:
- 审计完整性:规则变更的痕迹和业务执行的痕迹在同一条链上
- “谁守护守护者”的切断:守护者的定义被流程处理,流程处理自身的定义被日志记录
但自指不能没有边界。一个没有终止条件的自指系统会无限循环。终止条件是fail-closed:如果元流程遇到无法识别的结构(未知的节点类型、未定义的条件符号、不匹配的路由目标),它拒绝该提交。
七、第六层:边界与规范——可治理的进化
蒸馏和自指同时存在时,系统拥有两种强大能力——压缩自身和处理自身的定义——但两者结合会产生新的风险:
- 自噬陷阱:蒸馏过度会压缩掉“匹配现实世界输入”的依据,系统在“完美地拒绝一切”
- 无限递归:自指没有终止条件时,系统无止境地处理自己的定义
- 认知黑匣化:蒸馏过滤器会把“未识别信号”判定为“噪声”并移除
解决办法不是放弃蒸馏或自指,而是给它们加上边界和规范。
边界:
- 可蒸馏/可自指的内容:执行路径、冗余信息、流程的配置参数
- 不可蒸馏/不可自指的内容:
fail-closed元规则、顶层Schema、流程的判定逻辑
规范有三条:
- 迭代封顶:自指循环最多执行3层嵌套
- 变更溯源:每次自指修改产生版本对比和变更原因,记录在不可变审计链中
-
原子回滚:保留上一版本,新规范连续3次触发
fail-closed则自动回滚
八、总结
回到最初的问题:“有人见过你的AI评审员说‘不’吗?”
六层架构的回答是:一个被正确设计的系统,通过自身的结构验证自己,不需要被不断地外部测试。
这不是测试策略,是设计策略。你不需要问“它还能说不吗?”你应该问“它的结构是否定义了它应该对什么说不?”如果结构定义了,并且不可变核心层保护了那个定义,“它还能说不吗”这个问题在很大程度上已经被结构回答了。
@heinrichneb 的问题打开了这扇门,@james_anderson_h 把问题扩展到了整个执行链路,@mansio 追问了覆盖率的维度——这些讨论共同指向同一个结论:Harness不是能力的堆叠,而是一个有内在逻辑的结构。每一层解决一个具体的问题,每一层为下一层提供约束。到最后一层,系统已经不再需要外部Harness来不断验证自己——它的结构已经完成了那个验证。
AI给你代码,你得给它形状。形状决定了它能活多久。
Top comments (0)