Verification Loop
- 1、引言
- 2、Verification Loop 到底解决什么问题?
- 3、Verification Loop 核心原理
- 3.1 四个零件:Judge / Rubric / Feedback / Retry
- 3.2 跟"人工 review"比,差在哪
- 4、生产级实现(LangGraph + 结构化 Rubric)
- 5、2026 年的关键改进点
- 5.1 从"一句话打分"到多维结构化评分
- 5.2 裁判与运动员不同模型
- 5.3 Budget-Aware Retry:不是无限重写
- 6、适用场景与性能基准
- 7、总结
1、引言
小屌丝:鱼哥,上回你教我那 Agent Loop 是真好用,我让它"写一份本季度的运营复盘",它吭哧吭哧查数据、拉表格、写稿子,三分钟就给我整出来了。
小鱼:那不是挺好?
小屌丝:好个屁。我直接把它贴到部门群里,@了老板。结果十分钟后,老板私聊我:"小李,这个’DAU 同比增长 47%',你自己去后台看一眼,到底是 4.7% 还是 47%?"我一查——4.7%。它小数点都给我吃了。
小鱼:(笑)你这就是把 Agent Loop 当成流水线工人,货一出来直接装车,没经过质检。
小屌丝:那我咋办?我自己审?它一分钟出一篇,我审一篇十分钟,我一天啥也别干了。
小鱼:你再给它套一层循环——Verification Loop。让另一个(或者同一个)AI 当质检员,按一份评分表(Rubric)去打分,不合格就把"错在哪、怎么改"当反馈塞回去,让原 Agent 重写。直到过审为止。
小屌丝:这不就是"AI 检查 AI"吗?那它俩串供怎么办?我写它判,它肯定放水啊。
小鱼:问到点子上了。2026 年这套东西已经进化出一堆套路——裁判用更大的模型、按维度拆 Rubric、跟标准答案对照、多个裁判投票。今天我就给你讲讲,怎么让质检员不摸鱼。
2、Verification Loop 到底解决什么问题?
上一篇的 Agent Loop 解决的是"把活干完",这一篇解决的是"干出来的活能不能直接用"。
对应素材里的"循环 2":
Agent 输出 ↓ Grader(评分器)—— LLM as a Judge ↓ 符合标准? ├─ 是 → 通过,交付 └─ 否 → 反馈错误(具体改进建议)→ 回到 Agent 输出,重写为什么必须要有这一层?因为 LLM 有三个天生毛病:
- 幻觉:它会把 4.7% 写成 47%,语气还特别自信;
- 格式漂移:你要 JSON,它给你加一段寒暄;你要三段,它给你写五段;
- 风格不稳定:今天写得像资深总监,明天写得像刚入职的实习生。
Agent Loop 越自主,这三个毛病放出去的代价越大。Verification Loop 就是出货前的那道闸。
| 阶段 | 没有 Verification | 有 Verification Loop |
|---|---|---|
| 内容生成 | 一次生成,直接交付 | 生成 → 评审 → 不合格重写 |
| 错误代价 | 直接发给用户/老板 | 在系统内部被拦下来 |
| 质量一致性 | 看模型当天心情 | 按 Rubric 量化打分,可回归 |
| 成本 | 看起来省了一步 | 多花 1–2 倍 token,但事故成本下降一个数量级 |
一句话总结:Verification Loop = LLM as Judge + Rubric + 可执行反馈 + 有限次重试,把"AI 写的"从"看起来还行"变成"敢直接发出去"。
3、Verification Loop 核心原理
3.1 四个零件:Judge / Rubric / Feedback / Retry
拆开看就四样东西:
- Grader / Judge(评分器):一个 LLM 调用,输入"任务 + 原始要求 + Agent 输出",输出"过还是不过,理由是什么"。
- Rubric(评分表):把"好"这件事拆成几个可判断的维度,比如:事实准确性、数字是否与来源一致、格式是否合规、语气是否对、有没有遗漏关键要点。
- Feedback(反馈):不过的时候,不能只说"重写",必须具体到"第 3 段那个 47% 来自哪个数据源,请核对后改成 4.7%,并在末尾加上环比说明"。
- Retry(重试):把 Feedback 作为新的上下文塞回 Generator,让它重写,而不是从头再来。
关键:Feedback 的质量直接决定重试能不能收敛。你给一句"写得不行",它重写十遍还是不行;你给一句"第三段数字与源数据不符,源数据是 4.7%,请修正并补一句环比",它一遍就能改对。
3.2 跟"人工 review"比,差在哪
| 维度 | 人工 review | Verification Loop |
|---|---|---|
| 延迟 | 几小时~几天 | 几秒~几十秒 |
| 成本 | 资深工程师几百块/小时 | 一次 Judge 调用几分钱 |
| 一致性 | 不同人标准漂移 | 同一份 Rubric,每次口径一致 |
| 覆盖量 | 抽检 5% 顶天 | 100% 全量 |
| 缺点 | 慢、贵、漏 | 会被模型偏见影响,需要工程手段对冲 |
所以 2026 年的玩法不是"AI 替代人",而是:AI 拦掉 95% 的低级错误,人只看那 5% AI 拿不准的。
4、生产级实现(LangGraph + 结构化 Rubric)
下面这套是 2026 年的标准做法:Generator 出稿 → Grader 按 Pydantic 定义的多维 Rubric 打分 → 不过就把结构化反馈塞回去重写,最多 2 轮,防止死循环。
# verification_loop.pyfrom__future__importannotationsimportoperatorfromtypingimportAnnotated,Literal,Sequence,TypedDictfromlanggraph.graphimportStateGraph,ENDfromlangchain_openaiimportChatOpenAIfrompydanticimportBaseModel,Field# ---------- 1. 状态 ----------classVState(TypedDict):task:str# 原始任务draft:str# 当前 Agent 草稿source_facts:str# 参考资料(用于事实核对)attempts:int# 已重试次数max_attempts:int# ---------- 2. Rubric:把"好"拆成结构化维度 ----------classRubricScore(BaseModel):factual:int=Field(ge=1,le=5,description="事实准确性:数字/引用是否与 source_facts 一致")format:int=Field(ge=1,le=5,description="格式合规:是否按要求的结构输出")tone:int=Field(ge=1,le=5,description="语气:是否符合目标读者")coverage:int=Field(ge=1,le=5,description="要点覆盖:有没有漏掉 task 要求的关键点")pass_:bool=Field(description="综合判定是否通过")feedback:str=Field(description="不通过时,必须给出具体到段落/数字的修改建议")# ---------- 3. Generator:出稿 ----------defgenerator(state:VState)->VState:llm=ChatOpenAI(model="gpt-5-mini",temperature=0.3)prompt=f"""你是运营分析师。任务:{state['task']}参考资料:{state['source_facts']}{'上一版未通过评审,请按下面反馈修改:'+state.get('feedback','')ifstate.get('feedback')else''}直接输出最终稿。"""resp=llm.invoke(prompt)return{"draft":resp.content,"attempts":state["attempts"]+1}# ---------- 4. Grader:审稿(用更大/不同的模型) ----------defgrader(state:VState)->VState:# 关键:裁判用比 generator 更强的模型,避免"学员改作业给学员打分"judge_llm=ChatOpenAI(model="gpt-5",temperature=0)judge=judge_llm.with_structured_output(RubricScore)score:RubricScore=judge.invoke(f"任务:{state['task']}\n参考资料:{state['source_facts']}\n待审稿件:{state['draft']}")return{"draft":state["draft"],"feedback":""ifscore.pass_elsescore.feedback,"rubric":score.model_dump(),}# ---------- 5. 路由 ----------defroute(state:VState)->Literal["pass","retry","give_up"]:ifstate.get("rubric",{}).get("pass_"):return"pass"ifstate["attempts"]>=state["max_attempts"]:return"give_up"# 别死循环,交给人return"retry"# ---------- 6. 构图 ----------defbuild_verification_loop():g=StateGraph(VState)g.add_node("gen",generator)g.add_node("judge",grader)g.set_entry_point("gen")g.add_edge("gen","judge")g.add_conditional_edges("judge",route,{"pass":END,"retry":"gen","give_up":END,# 上线时这里通常接 human-in-the-loop 队列})returng.compile()if__name__=="__main__":app=build_verification_loop()out=app.invoke({"task":"写一段本季度运营复盘,包含 DAU 同比","source_facts":"本季度 DAU 123 万,去年同期 117.4 万,同比 +4.7%","draft":"","attempts":0,"max_attempts":2,})print(out["draft"])注意几个工程细节:
- Grader 用强模型,Generator 用快模型——审贵写便宜,整体成本才可控;
source_facts同时喂给 Generator 和 Grader,Grader 才有"对照标准答案"的能力,不然它只能凭感觉打分;give_up分支在生产上不要直接 END,要扔到人工审核队列,而不是把不合格的稿子发出去。
5、2026 年的关键改进点
5.1 从"一句话打分"到多维结构化评分
2024 年的 Judge 提示词长这样:
请判断下面这段输出是否合格,回答"是"或"否": ...这种 judge 有两个毛病:标准漂移、反馈没法用。2026 年的做法就是上面代码里的RubricScore——每个维度 1–5 分,每个分数都有明确锚点,最后一个pass_字段做综合判定,一个feedback字段装可执行建议。
更进一步,生产里会把 Rubric 放进版本管理(LangSmith Prompt Hub / Promptfoo),每次改评分标准都留 diff,跟代码 review 一个待遇。
5.2 裁判与运动员不同模型
"自己写自己判"在学术上叫self-preference bias——模型倾向于给自己写的东西打高分。2026 年的对冲手段:
- 大小模型错配:生成用
gpt-5-mini/Claude Haiku,评审用gpt-5/Claude Opus; - 同模型不同温度:评审
temperature=0,生成temperature=0.3–0.7; - 多裁判投票:关键场景起 3 个 judge(不同厂商模型),2:1 多数决,能显著降低单模型偏见;
- Reference-guided grading:有标准答案时,把参考答案一起塞给 judge,它就不敢乱打。
一个经验值:judge 模型比 generator 大一级,事实性错误的拦截率能从 ~60% 提到 ~85%。
5.3 Budget-Aware Retry:不是无限重写
Verification Loop 最容易被忽略的成本是"重试风暴"。2026 年的标准做法:
- 最多 N 次重试(一般 2–3 次),超过就转人工;
- 重试时把上次的 Rubric 分数一起喂回去,让模型知道"上一轮 factual 只有 2 分,这轮重点改数字";
- 指数退避 + 熔断:同一个 task 连续 3 次都不过,直接报警,不要继续烧钱;
- 失败样本自动进 golden dataset——这就接到了第 4 篇的 Hill Climbing Loop。
6、适用场景与性能基准
| 场景 | 推荐度 | 说明 |
|---|---|---|
| 客服话术 / 对外文案 | ⭐⭐⭐⭐⭐ | 错误直接面对客户,必须过审 |
| 代码生成 / PR 描述 | ⭐⭐⭐⭐⭐ | 配合单元测试当硬 judge,比 LLM judge 还靠谱 |
| 周报 / 复盘 / 邮件 | ⭐⭐⭐⭐ | 事实性和格式问题高频 |
| 创意写作 / 头脑风暴 | ⭐⭐ | 过度审核会扼杀多样性,建议只审事实错误 |
| 实时聊天(<1s 延迟) | ⭐ | 多一轮 judge 延迟翻倍,不适合 |
一组 2026 年参考数字(GPT-5 系列,LangGraph):
- 单次评审延迟:1–3 秒;
- 评审本身的 token 开销:约生成成本的30%–50%;
- 一次平均重试次数:1.2–1.8 次;
- 事实性错误拦截率:80%–90%(有参考资料时);
- 综合任务通过率(含重试):从裸生成的 ~55% 提升到 ~85%;
- 单条总成本:约裸生成的1.8–2.5 倍,但事故成本下降一个数量级。
7、总结
Verification Loop 是 Loop Stack 的第二层——它不替 Agent 干活,它保证 Agent 干的活敢拿出去见人。
核心记忆点:
- 没有 Verification 的 Agent 是"裸奔的打工人",越自主事故越大;
- Rubric 必须拆成维度,别让 judge 凭感觉说"行不行";
- Feedback 要具体到段落和数字,不然重试十遍也没用;
- Judge 模型要比 Generator 强一档,关键场景多裁判投票;
- 重试有预算,超限转人工,别让 Loop 自己把自己烧穿;
- 失败样本自动沉淀,这是下一篇 Hill Climbing Loop 的燃料。
下一篇我们再往上爬一层:Agent 会干活了、活也能过审了,那它能不能自己被事情叫醒,而不是等用户来戳一下?这就是 Event-Driven Loop。
我是小鱼:
- CSDN 博客专家;
- AIGC 技术MVP专家;
- 阿里云 专家博主;
- 51CTO博客专家;
- 企业认证金牌面试官;
- 多个名企认证&特邀讲师等;
- 名企签约职场面试培训、职场规划师;
- 多个国内主流技术社区的认证专家博主;
- 多款主流产品(阿里云等)评测一等奖获得者;
关注小鱼,学习【人工智能与大模型】最新最全的领域知识。