Agent AtlasAI Agent 知识库
03.04架构模式 · Architecture

反思、验证与自我修正

Reflexion、Self-Refine 与验证器模式:让 Agent 学会检查自己的输出,而不是盲目重试。

「让模型检查一下自己的答案」听起来很合理,但在没有新信息的情况下,它大概率会告诉你:没问题。

为什么大多数自我反思没用

让同一个模型、同一份上下文、同一个提示,再评价一次自己的输出,会发生三件事:

  1. 它倾向于肯定自己:生成的答案已经在上下文里,模型更容易为它找理由;
  2. 它看不到自己的盲区:如果它不知道某个事实,它也不知道自己不知道;
  3. 它没有新的判据:没有测试、没有检索、没有规则,评价只能靠「读起来对不对」。

所以有效反思的前提是:引入模型之外的新信号。

图 1 · 反思需要外部信号
生成初稿、计划、代码
→
验证测试、检索、规则、独立评审
→
定位问题具体到哪一行、哪个事实
→
修正只改有问题的部分

四种可用的验证信号

1. 可执行测试

代码、SQL、配置、正则,都可以用测试验证。这是最强的信号,因为它客观、可重复、能定位到具体失败点。

text
生成补丁 → 运行单元测试 → 失败 → 把 traceback 喂回模型 → 修正 → 再跑

2. 检索与证据

对事实性回答,要求每个结论都有来源。验证器检查:

  • 来源是否存在;
  • 引用的段落是否真的支持该结论;
  • 是否存在与结论矛盾的资料。

这比「你觉得这段准确吗」有效得多。

3. 规则与 Schema

金额是否超限、日期是否合法、枚举是否在允许范围、必填字段是否齐全。确定性代码能做的检查,不要交给模型。

4. 独立评审者

换一个模型、换一份提示、甚至换一个角色(「你是挑刺的审稿人」),能减少自我肯定。但要注意:

  • 评审者也可能错;
  • 不同模型可能共享同样的偏见;
  • 评审成本会叠加。

独立评审适合主观质量(写作、方案),不适合有客观答案的任务。

四种常见模式

Verify-then-Fix

先生成,再用确定性验证器检查,失败则带着错误信息修正。适合代码、结构化输出、数据转换。

Generate-Critique-Revise

生成 → 批评 → 修改。批评要有明确的评分维度和标准,而不是「请改进」。适合文章、方案、邮件。

Reflexion

任务失败后,把失败原因写成一段「经验」存入记忆,下次尝试时检索。关键不是重试,而是带着教训重试。

json
{
  "task": "修复登录接口的超时问题",
  "attempt": 1,
  "failure": "修改了数据库连接池大小,但测试仍然超时",
  "lesson": "先确认慢查询日志,不要盲目调大连接池",
  "next": "检查 /login 的 SQL 执行计划"
}

Self-Consistency

同一问题采样多次,取多数答案。适合有明确答案的推理题,不适合开放式生成。成本随采样次数线性增长。

一个测试驱动的修正循环

python
def repair_code(task: str, repo_path: str, max_rounds: int = 3) -> str:
    patch = generate_patch(task)
    for round_no in range(1, max_rounds + 1):
        apply_patch(repo_path, patch)
        result = run_tests(repo_path)

        if result.ok:
            return patch

        # 只把失败摘要喂回去,避免上下文爆炸
        feedback = {
            "failed": result.failed_tests[:5],
            "traceback": result.traceback[-2000:],
            "hint": "只修改与失败测试相关的代码,不要重写整个文件。",
        }
        patch = revise_patch(task, patch, feedback)

    rollback(repo_path)
    raise RuntimeError("三轮修复仍未通过,转人工")

这个循环有效的关键在于:

  • 测试是客观的:不依赖模型判断;
  • 反馈是具体的:失败测试名 + traceback;
  • 修改范围受控:要求只改相关部分;
  • 有回滚:失败不会留下半成品。

反思的提示词怎么写

差的写法:

text
请检查你的答案是否正确,如有问题请修改。

好的写法:

text
你是严格的审稿人。根据以下标准逐条检查:
1. 每个事实性陈述是否有来源?没有来源的列出来。
2. 数字是否与引用资料一致?逐一核对。
3. 是否存在绝对化表述(一定、必然、所有)?改为有条件的表述。
4. 结论是否回答了原问题?如果没有,指出缺什么。

只输出问题清单,不要重写全文。每条问题注明位置和原因。

先让模型找问题,再让它改,比一步到位更可靠。找问题时不要给它「这是你写的」的暗示,可以减少自我肯定。

什么时候不值得反思

  • 任务本身没有验证信号:再反思也只是换个说法;
  • 延迟敏感:多一轮就多几秒;
  • 简单任务:一次就能做对,反思是浪费;
  • 错误代价低且可快速重来:直接重跑比反思便宜。

一个粗略的判断:如果反思不能带来新信息,它最多只能改善表达,不能改善正确性。

如何评估反思是否有效

不要只看「感觉更好了」。做 A/B:

指标无反思有反思
任务通过率??
平均修正轮数0?
额外 token 成本0?
P95 延迟??
过度修改率(把对的改错)??

最后一项经常被忽略:反思可能把原本正确的答案改坏,尤其是没有外部信号时。评估必须包含「原本正确」的样本。

反模式

无限反思

「再检查一遍」循环到预算耗尽。必须限制轮数,并在无新信息时停止。

让模型给自己打分

「你觉得这个答案能打几分」几乎总是高分。用外部标准、测试或独立评审。

只改表面

把「一定」改成「可能」,但没有修正错误事实。反思要定位到事实与逻辑,而不是措辞。

没有回滚

修正后的版本更差,却已经覆盖了原文件。保留版本,能回退。

小结

  • 没有外部信号的自我反思,多数是自我肯定。
  • 有效信号来自测试、检索、规则和独立评审。
  • Verify-then-Fix 适合可验证任务;Reflexion 适合跨尝试积累经验。
  • 反思要看通过率、成本、延迟和「把对的改错」的比例。
  • 限制轮数、保留回滚、只改有问题的地方。

下一篇进入多智能体:什么时候分工真的有用,什么时候只是把问题变复杂。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →