最近在 Agent 相关讨论里,LLM-as-a-Verifier 成了一个高频词。我第一次看到这个名字时,第一反应是“这不就是再让模型检查一遍吗?”但真正把验证流程拆开之后,我发现这件事比想象中复杂得多。它的核心不是多一次检查,而是把验证本身变成一种可以扩展、可以迭代、可以优化的推理过程。这个方向的真正价值,不是让模型更会“答”,而是让模型更会“判断答案对不对”。
围绕这个方向,网上有一篇被反复转发的斯坦福论文,标题里还提到 DeepSeek 自验证能力超过某个基线。我不打算围绕“谁超过谁”去展开,因为如果脱离具体实验环境、模型版本和评测集,这种对比很难给出可靠结论。我更想弄清楚的是:为什么“验证”也能 Scaling?它在 Agent 场景里到底怎么用?落地过程中会遇到哪些坑?这篇文章会把我的理解和踩坑经验整理成一套可以拿去参考的框架。
1. 验证为什么值得单独拿出来研究
1.1 生成和验证的不对称性
我们平时使用大模型,习惯把注意力放在“生成”上:能不能写出一段代码,能不能总结出一篇文章,能不能给出一个方案。生成质量确实重要,但生成能力强,不代表发现错误的能力强。一个模型可以流畅地写出一个看似合理的回答,却在关键步骤里埋着逻辑漏洞。人检查的时候需要逐行读,但很多场景下我们没有精力逐行读,于是就需要另一个模型来帮忙验证。
这里有一个不对称性:生成一个错误答案很容易,但要判断一个答案是否正确,往往更难。举个例子,让模型写一段 SQL,它可能写出语法正确但业务逻辑错误的查询;让模型做一道数学题,它可能步骤完整但中间某个计算错了。如果让模型自己重新做一遍,它可能又掉进同一个坑。这就是传统自洽性检查的局限——它只是多次生成后看答案是否一致,并不能真正发现“所有错误都指向同一个错误答案”的情况。
1.2 传统验证和 LLM 验证的区别
传统方案里,我们验证输出主要靠三类手段:
- 规则校验:检查格式、长度、枚举值、正则匹配。
- 测试用例:代码场景下用单元测试,数据场景下用断言。
- 人工审查:由人阅读并判断。
规则和测试用例都很可靠,但它们只能覆盖“可程序化检查”的部分。对于开放式问答、方案设计、逻辑推理、复杂任务分解,规则往往无从下手。这时候,让 LLM 来当验证器,本质上是用模型的语义理解能力去补充规则覆盖不到的部分。
LLM 验证器的优势在于,它不仅能给一个“对/错”的结论,还能给出理由:“第 3 步缺少边界条件处理”“这里的计算结果和上下文不一致”“这句话与参考资料中的某个事实矛盾”。这种结构化反馈可以回传给生成器,让生成器针对问题做修改,而不是盲目重新生成。这已经不是在“检查”,而是在参与推理。
所以,我的一个核心判断是:LLM-as-a-Verifier 之所以值得单独研究,是因为它把“验证”从附属环节变成了一个独立的、具有推理深度的环节。它不再只是把关,而是能帮助模型在复杂任务里完成自我修正。
2. LLM-as-a-Verifier 的工作原理拆解
2.1 生成器-验证器的基本框架
理解 LLM-as-a-Verifier,可以先从最朴素的框架入手:
- 输入问题。
- 生成器模型产生一个或多个候选答案。
- 验证器模型对候选答案进行判断。
- 根据验证结果,要么输出答案,要么把反馈返回给生成器进行修改。
生成器和验证器可以是两个不同的模型,也可以是同一个模型。如果同一个模型既生成又验证,就是自我验证(Self-Verification)。很多 Agent 框架里,验证器被叫做 Critic、Reviewer、Evaluator 或 Checker,概念都是一样的。
这个框架看起来很简单,但真正落地时,难点在验证器怎么设计。
2.2 三种常见的验证形态
我在实际使用中,遇到过三种主流的验证形态:
第一种:直接判断。把问题、候选答案、评分标准一起给验证器,要求它输出“通过”或“拒绝”,或者给一个 1 到 5 的分数。这种实现最简单,但最容易出现“验证器跟着感觉走”的问题。如果提示词没有明确要求,模型经常会被答案的长度、语气、自信程度带偏。
第二种:多路对比。让生成器为同一个问题生成多个独立答案,再让验证器或模型群体判断哪个答案更好。这种方法能提高稳定性,但成本高,而且如果多个答案都是错的,验证器依然判断不出来。
第三种:逐步骤验证。要求生成器在输出时附带推理步骤,验证器则按步骤检查,指出哪一步错了、为什么错。这种形态最接近人类检查过程,效果通常也最好,但对生成器有要求:它必须把过程展示出来,而且过程本身不能太啰嗦。
自我验证属于以上形态的混合:同一个模型先生成,再自己逐步骤检查。它的最大优点是省去额外模型调用,但它有一个天然风险——模型对自己生成的内容会产生“既得利益式信任”。它倾向于认为自己刚才写的没有错,就像一个人刚写完一段文字,立刻自己校对,往往会漏掉自己思维里的盲区。
这也解释了为什么 DeepSeek 自验证会成为讨论点:它不是在简单地问模型“你刚才答对了吗”,而是通过更细的验证指令、多轮验证、甚至把问题和答案互相转换来增加验证的可靠性。如果只是让模型看一眼自己的回答然后说“是否需要改进”,那基本等于浪费 token。
注意:不要对自我验证抱有不切实际的期待。它的价值在于低成本和可迭代,不保证消除所有错误。
3. Verification Scaling:验证为什么也能吃计算量
3.1 把验证次数当成一种可扩展资源
说到 Scaling,大家通常想到的是增大模型参数量、增加训练数据、延长训练时间。但标题里提出的那个思路,说的是在推理阶段,验证本身的规模也可以增加。
什么意思?就是对同一个生成结果,我们可以用多次验证、多个角度验证、多轮验证,甚至用不同的提示词来验证。每一次验证都会消耗额外的计算资源,但也能提高发现错误的概率。这就像考试后的检查:只看一遍可能发现不了问题,如果换一个思路重看步骤,或者把答案代回到题目里反推,就更容易发现错误。
在工程里,这种“验证计算”是可以独立于生成计算扩展的。生成器只产生一个答案,验证器可以检查三次;也可以生成五个答案,每个只验证一次。调整验证次数、验证候选数量、验证温度,本质上就是在做验证侧的计算分配。
3.2 从单次验证到迭代验证的收益曲线
单次验证的收益通常有限。第一次验证很容易只能发现明显错误,比如格式不对、代码有语法错误、结论和开头矛盾。对于更深的逻辑漏洞,需要多次从不同角度验证。
我通常建议使用“两阶段验证”:
- 第一轮做整体检查,让验证器判断这个答案是否完整、是否有明显硬伤。
- 第二轮做逆向检查,让验证器尝试从结论反推,看能不能还原出前提;或者让验证器扮演一个挑刺的评审,专门寻找潜在矛盾。
如果两轮之间发现问题,就把反馈交给生成器,进入修正循环。
这种迭代验证方式有一个明显的收益曲线:前两三轮收益增长很快,从第四轮开始,大部分时间验证器会在同一个问题上反复纠结,或者干脆把正确的答案改成错误的。因此,在大多数场景里,循环次数不要设置太高,3 轮左右通常是一个合理的平衡点。
3.3 验证计算与生成计算的取舍
这里有一个容易忽略的点:验证计算增加,并不意味着生成计算可以无限制降低。如果生成器输出的候选答案太弱,验证器再怎么努力,也只是在给一个错误答案做花式确认。更好的做法是,保持一定的生成多样性,然后让验证器做筛选。
比如在数学题里,生成器给出三个不同解法,验证器分别判断哪个解法最可靠。这比让验证器反复检查同一个答案更有效,因为多个解法共享同一个错误路径的概率更低。
当然,验证计算也有成本。每多一次验证,就多一次模型 API 调用,延迟和 token 消耗都会线性增长。如果是一个交互式 Agent,用户等不了太长时间,就必须在验证次数和响应速度之间做取舍。
判断标准可以参考:生成失误带来的成本,是否大于增加一次验证带来的成本。如果答案出错会直接影响下游流程,那么多加一轮验证是值得的;如果只是闲聊式问答,单次验证甚至不验证都行。
4. Agent 场景下如何把验证器用起来
4.1 一个最小可用的 Agent 验证流程
在 Agent 场景里,模型不仅要生成答案,还要决定调用什么工具、解析工具结果、规划下一步动作。每一步都可能出错。LLM-as-a-Verifier 可以在两个位置使用:
- 最终答案验证:任务全部完成后再做一次整体检查。
- 中间步骤验证:Agent 每走一步,先验证这一步的结果是否合理,再决定是否继续。
我更推荐从“最终答案验证”开始,因为中间步骤验证会显著增加 Agent 的复杂度和延迟。等流程稳定下来,再考虑中间验证。
一个最小可用的流程可以这样设计:
- Agent 执行任务,生成一个完整的回答。
- 把原始问题、Agent 的回答、相关的工具输出或上下文一起打包,交给验证器。
- 验证器输出结构化结论:
passed或failed,以及一段简要理由。 - 如果
passed,直接返回用户。 - 如果
failed,把理由作为额外上下文,让 Agent 重新修正回答。 - 重复最多 2 到 3 轮,如果依然失败,则进入人工审查。
这个流程并不复杂,难在接口设计和验证提示词。
4.2 关键参数怎么调
验证器本身也是一个 LLM,它的行为受温度、top_p、max_tokens 等参数影响。我一般会把验证器的温度调得比生成器更低,比如生成器用 0.7,验证器用 0.2 或 0。验证器需要稳定输出判断,温度过高容易导致同样的输入给出忽高忽低的结论。
验证提示词也需要专门设计。不要简单写“请判断这个回答是否正确”,因为这样的提示词会让模型倾向于给正面评价。更有效的做法是:
你是一名严格的评审专家。请根据问题要求,检查下面的回答是否满足: 1. 逻辑是否正确; 2. 是否使用了不存在的工具结果; 3. 是否有遗漏的关键步骤; 4. 是否回答用户的实际问题。 如果发现任何问题,请明确指出错误位置和修改建议。 只有在你能完全确认回答无误时,才输出 PASS。 否则输出 FAIL。 输出格式: 结论: PASS 或 FAIL 理由: ...设计原则是:让验证器成为一个“找茬者”,而不是“认可者”。在提示词里明确“只有完全确认时才 PASS”,可以有效减少放行概率。
4.3 单任务、批量任务和持续任务的不同策略
单任务场景,比如一次对话、一次代码生成,验证器只需要判断一个答案。批量任务场景,比如批量生成文案、批量处理数据,验证器可以用来做质量抽检,不需要每一条都验证,而是随机抽取一定比例,检查错误率是否在可接受范围内。
持续任务场景,比如一个长期运行的 Agent,验证器不仅要验证结果,还应该把验证结果记录下来,形成质量日志。这样当任务失败时,可以回查是哪一轮验证漏掉了错误。记录信息包括:
- 任务 ID
- 生成器版本和参数
- 验证器版本和提示词版本
- 验证轮数
- 验证结论
- 最终是否通过人工复查
这些日志是后续调优的基础,也是判断“验证器是否真的有效”的唯一依据。如果没有日志,你可能只是感觉模型变好了,却说不清到底哪一层起了作用。
5. 实际落地中的常见问题和排查链路
5.1 验证器总是放行
这是最常遇到的问题。现象:无论生成器输出什么,验证器都返回 PASS。原因通常有三种:
- 验证提示词太宽松,比如“请评价”比“请严格找问题”更容易通过。
- 验证器模型能力不够,无法发现生成器错误。
- 上下文太长,验证器只读了前面部分就开始判断,后面的关键错误被截断了。
我的排查顺序是:先看验证提示词,确认有没有要求“只有完全确认才能 PASS”;再检查上下文是否被截断;最后换更强的验证模型。如果三者都调整过还是总是放行,可以考虑用两个验证器独立验证,取更严格的结论。
5.2 验证器过度纠错
和总是放行相反,过度纠错表现为验证器把一个正确的回答改成了错误,或者频繁拒绝明明没有问题的输出。常见原因有:
- 验证温度过高,导致判断不稳定。
- 验证提示词要求过于苛刻,比如要求“必须完全符合某个模板”,但实际问题根本不需要模板。
- 验证器把一些风格层面的偏好当成逻辑错误,比如“回答不够简洁”也会被判 FAIL。
解决方法是降低验证器温度,调整验证提示词,明确哪些问题是硬伤、哪些只是建议。也可以让验证器输出“严重程度”,只有出现“严重错误”时才触发重新生成。
5.3 延迟与成本失控
增加验证环节后,一次完整的 Agent 调用会变成多次 LLM 调用。如果每一轮都执行完整验证,响应时间很容易翻倍甚至翻三倍。
可以做的优化包括:
- 简单的任务直接跳过验证,只有复杂任务才启用。
- 验证器使用更小、更快的模型,生成器使用大模型。
- 对验证结果做缓存,相同或相似问题的验证结论可以复用。
- 设置最大验证轮数,比如 2 轮,避免无限循环。
这里有一个容易踩的坑:如果一个任务在“生成 -> 验证失败 -> 重新生成 -> 验证失败”的循环里反复打转,不仅消耗 token,还会让用户体验变得极差。所以必须在代码层面设置最大迭代次数,达到上限后直接返回“需要人工审查”的结果,而不是继续让模型自己折腾。
5.4 验证器判断结果不稳定的排查顺序
如果同一个答案,验证器第一次 PASS,第二次 FAIL,不能只怪模型“随机”。按以下顺序排查:
- 确认输入是否完全一致:问题、答案、上下文、提示词、温度。
- 确认模型是否有缓存,缓存是否命中不一致。
- 确认是否有并发调用导致上下文串批。
- 确认验证器版本是否被无意识更新。
- 最后才是模型本身的随机性。
在实际项目里,很多“不稳定”都是因为上下文拼接方式不同,或者提示词字符串里多了一个空格,导致模型行为差异很大。
6. 要长期使用,先想清楚适用边界
6.1 适合什么场景
LLM-as-a-Verifier 最适合以下场景:
- 任务有明确判断标准,但规则难以穷举,需要语义判断。
- 生成结果会直接影响下游流程,比如 Agent 调用工具前需要确认参数是否正确。
- 生成器容易出错,但错误可以通过验证反馈修正。
- 对成本有一定容忍度,能够接受多轮模型调用。
典型例子包括代码生成器的语法和逻辑校验、结构化数据抽取后的字段合理性检查、多步推理题的答案复核、Agent 工具调用结果的合法性检查。
6.2 不适合什么场景
以下场景不建议引入 LLM 验证器:
- 对延迟极敏感的交互场景,多一次调用都会影响体验。
- 任务本身有严格且可程序化校验的标准,应该用规则而不是模型。
- 验证器模型能力和生成器相差太远,验证会变成“瞎评”。
- 任务属于创造性写作、情感表达等主观领域,没有唯一正确性,验证器很难给出可靠结论。
还有一个容易忽略的限制:LLM-as-a-Verifier 并不能处理“事实性幻觉”中的事实错误,除非你给验证器提供可核对的外部知识库或工具。否则,验证器只是用自己的记忆在判断,依然可能一本正经地认可一个错误事实。
6.3 需要补的工程化能力
从“跑通一个 demo”到“在生产环境长期使用”,还需要补很多工程化能力:
- 验证质量评估:定期用一批已知对错的样本,测试当前验证器的通过率和误判率。
- 验证器版本管理:提示词和模型版本变化都会影响验证结果,要能在日志里回溯。
- 异常回退:验证服务超时或报错时,不能阻塞主流程,要有默认行为,比如“验证失败则直接人工审查”。
- 成本预算:为验证器单独记录 token 消耗,避免验证成本悄悄超过生成成本。
在生产系统里,验证器不是越强越好,也不是验证次数越多越好。它只是一个质量杠杆,用来把低概率的错误进一步压低,而不是保证零错误。
如果沿着这个方向继续深入,我认为最值得关注的是如何让验证器主动发现“证据不足”或“信息缺失”的情况。当前大多数验证器只会评价已有答案,还不会像一个真正的评审那样追问“你有证据吗”。等模型能主动要求更多信息、能自主触发工具核对事实,LLM-as-a-Verifier 才真正从一个辅助模块变成 Agent 可靠性的核心组件。
到那时候再看“验证能不能 Scaling”,答案会更清晰:验证不是简单地多检查几次,而是让模型在判断过程中投入更多推理、更多资源、更多对证据的依赖。这也是我看好这个方向的原因。