「让模型检查一下自己的答案」听起来很合理,但在没有新信息的情况下,它大概率会告诉你:没问题。
为什么大多数自我反思没用
让同一个模型、同一份上下文、同一个提示,再评价一次自己的输出,会发生三件事:
- 它倾向于肯定自己:生成的答案已经在上下文里,模型更容易为它找理由;
- 它看不到自己的盲区:如果它不知道某个事实,它也不知道自己不知道;
- 它没有新的判据:没有测试、没有检索、没有规则,评价只能靠「读起来对不对」。
所以有效反思的前提是:引入模型之外的新信号。
四种可用的验证信号
1. 可执行测试
代码、SQL、配置、正则,都可以用测试验证。这是最强的信号,因为它客观、可重复、能定位到具体失败点。
生成补丁 → 运行单元测试 → 失败 → 把 traceback 喂回模型 → 修正 → 再跑2. 检索与证据
对事实性回答,要求每个结论都有来源。验证器检查:
- 来源是否存在;
- 引用的段落是否真的支持该结论;
- 是否存在与结论矛盾的资料。
这比「你觉得这段准确吗」有效得多。
3. 规则与 Schema
金额是否超限、日期是否合法、枚举是否在允许范围、必填字段是否齐全。确定性代码能做的检查,不要交给模型。
4. 独立评审者
换一个模型、换一份提示、甚至换一个角色(「你是挑刺的审稿人」),能减少自我肯定。但要注意:
- 评审者也可能错;
- 不同模型可能共享同样的偏见;
- 评审成本会叠加。
独立评审适合主观质量(写作、方案),不适合有客观答案的任务。
四种常见模式
Verify-then-Fix
先生成,再用确定性验证器检查,失败则带着错误信息修正。适合代码、结构化输出、数据转换。
Generate-Critique-Revise
生成 → 批评 → 修改。批评要有明确的评分维度和标准,而不是「请改进」。适合文章、方案、邮件。
Reflexion
任务失败后,把失败原因写成一段「经验」存入记忆,下次尝试时检索。关键不是重试,而是带着教训重试。
{
"task": "修复登录接口的超时问题",
"attempt": 1,
"failure": "修改了数据库连接池大小,但测试仍然超时",
"lesson": "先确认慢查询日志,不要盲目调大连接池",
"next": "检查 /login 的 SQL 执行计划"
}Self-Consistency
同一问题采样多次,取多数答案。适合有明确答案的推理题,不适合开放式生成。成本随采样次数线性增长。
一个测试驱动的修正循环
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;
- 修改范围受控:要求只改相关部分;
- 有回滚:失败不会留下半成品。
反思的提示词怎么写
差的写法:
请检查你的答案是否正确,如有问题请修改。好的写法:
你是严格的审稿人。根据以下标准逐条检查:
1. 每个事实性陈述是否有来源?没有来源的列出来。
2. 数字是否与引用资料一致?逐一核对。
3. 是否存在绝对化表述(一定、必然、所有)?改为有条件的表述。
4. 结论是否回答了原问题?如果没有,指出缺什么。
只输出问题清单,不要重写全文。每条问题注明位置和原因。先让模型找问题,再让它改,比一步到位更可靠。找问题时不要给它「这是你写的」的暗示,可以减少自我肯定。
什么时候不值得反思
- 任务本身没有验证信号:再反思也只是换个说法;
- 延迟敏感:多一轮就多几秒;
- 简单任务:一次就能做对,反思是浪费;
- 错误代价低且可快速重来:直接重跑比反思便宜。
一个粗略的判断:如果反思不能带来新信息,它最多只能改善表达,不能改善正确性。
如何评估反思是否有效
不要只看「感觉更好了」。做 A/B:
| 指标 | 无反思 | 有反思 |
|---|---|---|
| 任务通过率 | ? | ? |
| 平均修正轮数 | 0 | ? |
| 额外 token 成本 | 0 | ? |
| P95 延迟 | ? | ? |
| 过度修改率(把对的改错) | ? | ? |
最后一项经常被忽略:反思可能把原本正确的答案改坏,尤其是没有外部信号时。评估必须包含「原本正确」的样本。
反模式
「再检查一遍」循环到预算耗尽。必须限制轮数,并在无新信息时停止。
「你觉得这个答案能打几分」几乎总是高分。用外部标准、测试或独立评审。
把「一定」改成「可能」,但没有修正错误事实。反思要定位到事实与逻辑,而不是措辞。
修正后的版本更差,却已经覆盖了原文件。保留版本,能回退。
小结
- 没有外部信号的自我反思,多数是自我肯定。
- 有效信号来自测试、检索、规则和独立评审。
- Verify-then-Fix 适合可验证任务;Reflexion 适合跨尝试积累经验。
- 反思要看通过率、成本、延迟和「把对的改错」的比例。
- 限制轮数、保留回滚、只改有问题的地方。
下一篇进入多智能体:什么时候分工真的有用,什么时候只是把问题变复杂。