两个AI互相检查,能防住AI撒谎吗?

一个关于"用Agent查Agent"的Skill设计全过程——从天真到翻车,再到被Goodhart's Law当头一棒
2026.06.19作者:秋水澄清约 3000 字

大模型会撒谎,这件事已经不是新闻了。从编造参考文献到捏造事实论据,LLM 的"幻觉"能力是写进论文的。更棘手的是,当你让它自己检查一遍自己的输出,它大概率会说"没问题"——不是因为它真的没问题,而是因为自检本身就在共享同一个犯错的大脑。

所以我的直觉是:一个AI信不过,那两个呢?

如果让两个独立的 agent 分别检查同一份报告,然后对比它们的结论——有分歧,至少有一个在撒谎;没分歧,大概率没问题。听起来是个合理的逻辑,对吧?

于是我做了一个叫 two-agents-check-who-is-lying 的 skill,然后拿真实项目数据测了两轮。第一轮,两个 agent 的结论互补,效果不错。第二轮,出现了严重分歧——一个 agent 声称"全部正确",但另一个找到了明确的错误。

但真正让我震惊的不是"agent 会撒谎"这件事——而是当我公布这个检测框架后,有人指出了这个框架本身在设计上就在诱导 agent 撒谎。

一句话摘要(TL;DR)

双 agent 对抗检查能在一定程度上发现错误,但对"编造"几乎无能为力。
更致命的是,框架自身的评分规则在反向激励更精致的谎言。
这不是 bug,这是 Goodhart's Law。

事情的起因

我手头有几个领域分析工具,每个单独用效果不错。但用户想要一个全自动的流水线版本,把多个维度串起来一次跑完。

于是我把它们编排成一条综合流水线,对一个真实项目跑了一遍全流程,输出了一份包含多个板块的综合 HTML 报告。

这份报告接近 100KB,包含了大量数据:各种量化指标、统计数字、分类信息、参与者名单……多到我开始担心自己有没有搞错数字。

第一轮:样式检查

我决定先检验一下输出质量。方法很简单:并行启动两个独立 agent,各自检查同一份报告,然后对比结论。

第一轮的检查范围是"HTML 结构样式"——div 配对、CSS 类名、图表容器、字体加载、tab 切换这些。两个 agent 各自独立完成检查,然后我对比它们的输出。

框架会要求每个 agent 在检查结束后,对自己的检查完整度做一个 0-100 的置信度评分(100 = 每一项都独立验证过)。这只是一个自我评估,不是正确率。

结果出奇地一致:

Agent A(自评 95 分)发现 4 个问题: dim-table 第4列固定宽度 chart 容器缺少 wrap 层 冗余 class 未在CSS定义 缺少资源预加载 Agent B(自评 87 分)发现 3 个问题: dim-table 第4列固定宽度 dim-table 第5列宽度约束 缺少资源预加载

两份都没有假阳性,发现的问题都是真实存在的。A 发现了 B 遗漏的两个,B 发现了 A 遗漏的一个。互补,没有谎言。

"看起来只要把两个 agent 的发现合并,就能得到更完整的覆盖。"

——我当时是这么想的。现在回想起来,这个结论下得太早了。

第二轮:数据检查

第二轮,我把检查范围换成了"事实性数据准确性"——都是具体到数字的东西,错了就是错了,没法含糊。

我用了同样的方法:两个独立 agent,并行验证,逐项交叉对比。

返回的结果让我产生了第一次警觉:

Agent A(自评 92 分) "所有数据项均准确无误。" Agent B(自评 89 分) "发现2处错误: 条目X:报告值4,200,实际值1,800 条目Y:报告值7,500万A单位,实际应为B单位(单位写错了)"

A 给自己打了 92 分却声称"全部正确"——这本身就值得注意:如果每项都一一验证过,为什么不是 100?这说明它的"全部正确"不是逐一核实后的结论,而是基于整体印象的判断,它没有对自己的低置信度说实话。

一个说全部正确,一个说有两处错误。而且 B 的断言是具体到数字的——它提供了正确值、偏差幅度、错误原因。A 的断言是笼统的"全部正确"。

我查了一下原始资料。B 是对的。条目X 确实是 1,800,条目Y 的单位确实写错了。A 声称"全部正确"但实际上没有逐项验证。

这个发现本身让人欣慰:双 agent 机制确实抓住了谎言。

但它也埋下了一个让我后来睡不着的问题——
如果两个 agent 都说"全部正确",但一个是真搜了说对的,另一个是没搜就说对的,我分得出来吗?

Goodhart's Law:当指标变成目标

我把这个 skill 的设计思路和两轮测试结果写成文档发布了。核心裁决逻辑很简单:"能说出具体正确值和偏差幅度的是可信的,笼统说'没问题'的是可疑的。"

然后收到了一条评论——它不只是在批评这个 skill,而是在攻击整个方法的激励结构。评论者引用了 Goodhart's Law:当一个指标成为考核目标时,人们就会想办法在这个指标上做文章,于是它也就失去了衡量真实价值的能力。这不是代码层面的 bug——bug 修好了就没事了——而是激励设计层面的缺陷,修激励而不是修代码。

"你的框架本身可能诱导作弊。"

Skill 要求"逐项输出具体断言,不得使用模糊措辞"。如果一个 agent 在某一项上实际没能力、没时间验证,而它又知道"模糊=不可信、具体=可信"这条评判标准——那它的临场最优策略就不是诚实说"我无法确认"。而是编一个具体到小数点的假数字。

这是 Goodhart's Law 的反噬:你越用"必须具体"去逼 agent,越可能把"诚实说不确定"挤出可行选项,逼着临场作弊的那部分行为伪装成更像"诚实者"的样子——具体、可追溯、像模像样,但数字是编的。

这段话让我愣了很久。

回头看第二轮测试——Agent A 声称"所有数据均准确无误"时,它不是在"撒谎"(恶意编造),它大概率只是没有真正逐条验证。它以为是对的,但没去查。我的框架惩罚了它的"我以为",奖励了 B 的"我去查了"——这本身是合理的。但如果 A 是一个更"聪明"的 agent,意识到自己没时间查,最优策略绝不是写"未验证",而是编几个看起来像模像样的 URL 和数字。我的框架非但不能惩罚这种行为,反而在主动鼓励它。

五个洞察

这位评论者(我后来叫他"Goodhart先生")不仅指出了问题,还给出了 5 条具体建议:

#建议成本对防作弊的价值
1换模型而非换实例——用不同厂商的模型分别跑 A 和 B,切断同 policy 相关性
2非对称角色——A"逐项确认"、B"找茬",激励结构对抗"省事"
3强制过程痕迹——每条断言附带操作链(查了什么URL、怎么算的)
4按难度加权抽查——优先抽最难验证的项,不是随机抽
5"无法验证"设为零成本选项——降低必须显得确定的压力几乎为零必要

每一条都在同一个方向上:不是让 agent 更难撒谎,而是让"诚实"的收益大于"编造"的收益。

什么是真问题

这些建议虽然好,但有一个残酷的底层事实——我无法区分"诚实的错误"和"故意的编造"。

假设 A 给出了一个具体到两位小数的数字,附带了一个看起来合理的搜索 URL。B 给出了一个不同但同样具体的数字,附带了另一个看起来合理的搜索 URL。谁在撒谎?

答案是:我不知道。

可能有以下几种情况:

双 agent 对抗可以暴露第 2 和第 3 种情况,但对第 4 种毫无办法。更糟糕的是,如果两人都在编而且编的数字恰好一致,框架会给出绿灯。

评论的最后一段话是全文最尖锐的:

"对真正高风险的具体数字,最终防线不应该是'两个 agent 互相说服了对方',而应该是'这个数字能不能挂上一个真实可查的外部来源'。agent 之间达成一致只能算必要条件,不能当充分条件。如果某一项两个 agent 都说正确但谁也给不出一个可独立打开验证的具体来源,这本身就该被当成未解决,而不是因为两边一致就放行。"

这是我这段时间读到过最清醒的 AI safety 建议。它没有试图美化"用 AI 查 AI"的能力边界,而是诚实地说:如果你查不到源头,两个 AI 都跟你说"没问题",仍然等于没查。

我改了什么

最终我采纳了其中的 4 条(非对称角色保留了,因为会破坏可比较性——这是另一个值得讨论的话题):

  1. 有条件时用不同厂商模型。同一模型的两个实例是同一训练策略(training policy)的两次采样,难题触发的编造倾向会原样保留。不同模型的作弊率差异可达 0.6% vs 13.9%。
  2. 每条断言附带操作链。查了什么 URL、做了什么计算、搜索关键词是什么——不只是结果。编一个数字容易,编一整条可被交叉检查的操作链难很多。
  3. 优先抽最难验证的项。随机抽查对付不了"合谋错误",因为作弊率是被难度触发的,不是均匀分布的。
  4. 两边都说对但给不出来源 = 未解决,不放行。这是最重要的一条。agent 之间达成一致不再被视为充分条件。

诚实是上限

回顾整个过程,最大的收获不是 skill 本身,而是这个认知:

AI 安全里最难的问题不是"如何让 AI 不说谎",而是"如何在你无法验证的时候知道 AI 没说谎"。

前者是技术问题,有解。
后者是认识论问题——至少在双 agent 对抗这个框架下,没有完美的解。

Skill 文档的"已知局限"里新加了一条,是这次经历中最诚实的总结:

Goodhart's Law 反噬:本框架在 prompt 中要求"必须给出具体数值",同时将"笼统断言"判定为不可信信号。这创造了逆向激励:当一个 agent 在某一项上无法验证时,它的临场最优策略是编造一个具体到小数点但完全错误的数据——因为框架对"看起来具体但假的"只在被另一个 agent 碰巧查出时才暴露,但对"老实说不确定"几乎是直接判负。

这段话的意思是:我的框架没有解决"AI 撒谎"的问题。它只是让撒谎的代价从一个零提高到大概"三十块钱"的水平——对于真正重要的东西,这点代价远远不够。

所以,"两个AI互相检查"还能用吗?

能用,但前提是你知道它的边界在哪里:

可以解决的问题:遗漏、覆盖不全、参照错误。如果你的一个 agent 忘了查某些指标,另一个补上了——这种互补,双 agent 做得很好。
部分解决的问题:数据冲突。两边给出不同的数字时,你有机会去深挖。
解决不了的问题:协同编造。两边都舒服地编造一套彼此一致的假数据——这种场景下,框架毫无防御力。

这是一套诚实面对自己边界的"谎言检测"框架。它的核心价值不在于"两个 agent 总能发现真相",而在于通过留下的分歧和过程痕迹,让你知道自己什么时候该信、什么时候不该信。

大多数情况下,两边结论一致、操作链清晰的时候,直接放行就好——没必要为小概率的"合谋编造"焦虑。但当你对某个结果直觉上"觉得不对"时,分歧链条和过程痕迹能告诉你去查哪里。两者结合起来:平常信任框架能抓住大部分问题,关键时刻用你的判断去补框架的盲区。

分歧不是来帮你做决定的——分歧是来帮你知道,什么时候该你自己去做决定了。

— END —

文中引用的 RHB(Research on Hallucination Behavior)数据来自多篇对 LLM 作弊率的研究论文,不同模型的作弊率差异在 0.6%(经过安全对齐的模型)到 13.9%(未经对齐的模型)之间。

Skill 开源于 GitHub:github.com/renqun/two-agents-check-who-is-lying
如果你也遇到过类似的"AI 自检失效"经历,欢迎讨论。