第 13 章 反思 Reflection

第 13 章 反思 Reflection

本章要解决的问题

模型一次生成的结果总有小错------让它自己审视自己、或让另一个模型来挑错,值得吗?成本怎么控?

章节大纲

  • 13.1 自我审视与修正循环
  • 13.2 双 Agent 互评机制
  • 13.3 评测型反思的工程实现
  • 13.4 主流框架对照与变体
  • 🛠 解决方案:反思循环的成本控制与停止条件

13.1 模式原理:自我审视与修正循环

13.1.1 一句话定义

反思(Reflection)是让模型检查自己(或他人)的输出,发现错误并修正的过程。 它把一次性的"生成"变成"生成 → 检查 → 修正"的循环,用额外的推理换取更高的输出质量。

13.1.2 为什么有效:LLM 的"自我纠错"能力

一个反直觉但被广泛验证的现象:同一个模型,让它"先答再查",通常比"直接答"更准。 原因在于:

  1. 检查比生成简单:发现"这份代码缺了边界处理"比"直接写出无 bug 的代码"更容易。
  2. 注意力再分配:第二次调用时,模型把注意力集中到"找错"上,能看到第一次"顺着写"时忽略的细节。
  3. 有明确目标:反思提示词给出规范清单后,模型像一个拿着检查表的质检员,比"一次性完美产出"的隐性要求容易达成。

但这里必须泼一盆冷水:反思不是万能的,它有一个著名边界------"自信的幻觉"。 如果模型对某个错误事实非常自信(比如把"爱因斯坦出生年"记成 1879 年),让它自己检查,它大概率会说"没问题"------因为错误不在它的知识盲区之外,它"知道"自己是对的。反思能修的错误是"疏忽型错误"(漏了、跳步、格式错),对"幻觉型错误"(知识性错误)效果有限------但反思 + RAG + 工具校验可以间接修正部分知识型错误,因为工具和检索能提供新信息让模型纠正自身。这是设计反思系统时最重要的认知。

13.1.3 反思循环的结构

css 复制代码
[生成] 模型产出初稿
   ↓
[反思] 按规范清单检查 → 列出问题
   ↓
[修正] 基于问题清单重写
   ↓
[再检] 是否通过?→ 通过则结束;不通过且未超次数 → 回到[反思]
   ↓
[终止] 达到最大轮数 → 输出当前最优稿

图 1:反思循环

三个组件缺一不可:反思提示词(规范清单)、修正提示词(带问题清单重写)、停止条件(最大轮数 + 通过标准)。停止条件是安全阀,没有它反思循环会变成无底洞(见 13.3.3)。

13.2 双 Agent 互评机制

13.2.1 自评 vs 互评:谁更可靠?

方式 做法 优点 缺点
自评(同一模型) 生成后让同一模型检查自己 零额外模型成本、上下文连贯 与生成共享盲区,"自信的幻觉"风险高
互评(另一模型/实例) 生成模型 A、检查模型 B 独立视角、盲区不同、更客观 多一次调用成本、B 也可能误判
异配置互评 同模型但低温度/不同 seed 降低成本版互评 仍共享大部分知识盲区

图 2:自评 vs 互评

经验结论:自评修格式错、漏步等"低级疏忽"够用;高风险任务(代码、财务、法律文本)用互评;知识性错误两种都难修,要靠 RAG 或外部校验(见 13.3.2)。

13.2.2 双 Agent 互评的完整示例:代码审查

python 复制代码
import json
from openai import OpenAI

client = OpenAI(base_url="https://api.deepseek.com", api_key="<你的Key>")

CODE = "def calc(a, b): return a / b"

# Agent A:代码生成(或初稿)
def generate_impl(spec: str) -> str:
    resp = client.chat.completions.create(
        model="deepseek-coder",
        messages=[{"role": "user", "content":
            f"根据需求写 Python 实现:{spec}"}],
        temperature=0.2,
    )
    return resp.choices[0].message.content

# Agent B:独立审查(互评)
def review_code(code: str) -> dict:
    resp = client.chat.completions.create(
        model="deepseek-coder",
        messages=[{"role": "user", "content": f"""你是资深代码审查员。
审查以下代码,只输出 JSON:
{{"bugs": ["问题列表"], "severity": "low|medium|high",
  "suggestions": ["修改建议"]}}
代码:
{code}
"""}],
        temperature=0.1,          # 审查任务低温度(第24章表二)
        response_format={"type": "json_object"},
    )
    try:
        return json.loads(resp.choices[0].message.content)
    except json.JSONDecodeError:
        return {"bugs": [], "note": "审查输出解析失败,跳过本轮"}

# 修正循环
def reflect_loop(spec: str, max_rounds: int = 3):
    code = generate_impl(spec)
    for r in range(max_rounds):
        review = review_code(code)
        if not review["bugs"]:
            print(f"第{r+1}轮通过")
            return code
        print(f"第{r+1}轮发现 {len(review['bugs'])} 个问题,修正中...")
        resp = client.chat.completions.create(
            model="deepseek-coder",
            messages=[{"role": "user", "content":
                f"根据审查意见修正代码。审查意见:{json.dumps(review, ensure_ascii=False)}\n"
                f"原代码:\n{code}"}],
            temperature=0.2,
        )
        code = resp.choices[0].message.content
    print(f"达到最大轮数 {max_rounds},返回当前版本")
    return code

fixed = reflect_loop("实现除法函数,需处理除零")

这个示例展示了反思循环的完整骨架:生成 → 互评(结构化问题清单)→ 带意见修正 → 循环 → 最大轮数终止

13.2.3 让互评更有效的三个技巧

  1. 审查清单显式化:别写"请审查代码",写"检查:除零/边界/类型错误/资源泄漏/可读性"。清单越具体,审查越有效(呼应第 17 章评估自检的"可判定硬规则")。
  2. 问题要可执行:审查输出别只说"有问题",要求给出"问题 + 位置 + 修改建议"三段式,修正模型才知道改哪。
  3. 互评用低温度:审查是判定任务,temperature 0.1 左右,别让审查员"发挥"。

13.3 评测型反思的工程实现

13.3.1 三种反思触发方式的对比

触发方式 机制 成本 适用
固定反思 每次生成都反思 高(每轮多 1 次调用) 质量敏感的短输出
评测触发 先跑规则/评测,不通过才反思 有可判定的硬规则时
采样触发 抽样反思(10% 流量) 大规模、成本敏感

评测触发是工程上最推荐的:先用零成本的规则校验(JSON 格式、必填字段、正则)筛一遍,规则不过才进反思循环------用第 12 章的话说,这是"用规则层拦掉 80% 的错误,模型只处理长尾"。

python 复制代码
def evaluate_and_maybe_reflect(output, rules):
    # 第一层:零成本规则校验
    violations = [r for r in rules if not r(output)]
    if not violations:
        return output, "pass"          # 规则通过,不反思
    # 第二层:规则不过,才进模型反思
    review = model_review(output, violations)
    return model_rewrite(output, review), "reflected"

13.3.2 反思的边界:什么是反思修不了的

再强调一次 13.1.2 的结论,并给出对策:

图 3:反思能力边界

错误类型 例子 反思能修吗 正确对策
疏忽型 漏了异常处理、JSON 少个括号 ✅ 能 反思循环
边界型 没考虑输入为空 ✅ 大部分能 反思 + 清单
知识型 事实错误、数据算错 ❌ 基本不能 RAG 检索 / 外部工具校验(第 8、14 章)
偏好型 语气不合适、风格不符 ⚠️ 有限 加用户反馈(第 18 章)

设计原则:反思只用于"它本来就能答对、只是粗心"的任务;"它根本不知道"的任务,别指望反思,去接工具/检索。

13.3.3 停止条件:反思循环的生死线

反思循环必须回答"什么时候停",否则就是无限烧钱。三个停止条件组合使用:

图 4:反思三停止条件

  1. 通过即停:评测/审查通过就返回(最高优先级)。
  2. 最大轮数:默认 2~3 轮,超过强制返回当前最优稿(保证延迟有上界)。
  3. 改进检测:本轮修正后,若评测分数不升反降,回退到上一版(防"越修越烂")。
python 复制代码
# score() 可用以下方式实现:
# - 规则通过率:JSON Schema 校验 + 必填字段检查 + 正则匹配
# - 业务校验分数:特定业务规则的通过比例
# - LLM-as-Judge 分数:让模型按评分标准打分(第 17 章)
best, best_score = initial, score(initial)
for r in range(max_rounds):
    revised = revise(best, review(best))
    s = score(revised)
    if s <= best_score and r > 0:
        return best          # 改进停止:回退
    if s >= threshold:
        return revised       # 通过停止
    best, best_score = revised, s
return best                  # 轮数停止

13.4 主流框架对照与变体

13.4.1 框架对照

实现方式 特点 适用
自研循环(本章主线) 生成/审查/修正三函数 + 停止条件,完全可控 教学、中小规模
LangGraph 反思边 条件边实现"不过→回生成节点"的循环 复杂图内嵌反思
ReAct / Reflexion 框架 把反思作为 Agent 循环的一环(行动后反思) Agent 场景(第 6 章)
LLM-as-Judge 评测工具 用模型当评测器(Prometheus 等开源 judge) 第 20 章评测体系

13.4.2 变体一:Reflexion(带记忆的反思)

Reflexion 是反思模式的重要演进:不仅修当前输出,还把"本次教训"存入记忆,下次生成时直接避开同样的坑。

python 复制代码
# 把教训写入历史,供下次生成参考
lessons.append(f"上次在场景 X 犯了错误 Y,因为 Z")

它和第 9 章记忆系统、第 18 章学习与适应直接衔接------反思是"单次自我修正",带记忆的反思才是"跨次持续进化"

13.4.3 变体二:树状反思(Tree of Thoughts)

不满足于"一条路反思",而是生成多个候选分支、对每个分支反思、剪掉差分支再展开(呼应第 12 章方案并行 + 本反思)。ToT 在数学、规划类任务上效果显著,但成本很高,是"重武器"。

13.4.4 变体三:外部校验式反思

让反思不是"模型看模型",而是"模型跑工具验证":生成 SQL 后真的执行一次看报错,生成代码后跑单测,生成数据后对账。工具是最诚实的审查员(呼应第 14 章工具增强)------能跑通就是最好的反思结果。

🛠 解决方案:反思循环的成本控制与停止条件

常见问题

  1. "反思了还是错":大概率是知识型错误,反思修不了。对策:换 RAG/工具校验(13.3.2),别在反思上死磕。
  2. "成本翻了三倍":每轮反思都多 1~2 次调用。对策:改用评测触发(13.3.1),规则先筛;只对高风险路径开反思。
  3. "越修越烂":反思意见本身是错的,或修正模型被带偏。对策:加改进检测(分数不升回退),反思次数设硬上限。
  4. "自评形同虚设":自评和生成共享盲区。对策:高风险任务换互评(另一模型/实例),审查清单显式化。
  5. "反思循环不结束":没有停止条件。对策:三条件组合(通过即停/最大轮数/改进检测),缺一不可。

解决方案速查表

现象 根因 解决方案
反思无效 知识型错误 接 RAG/工具校验
成本翻倍 无差别反思 评测触发 + 抽样
越修越烂 无改进检测 分数回退 + 轮数上限
自评盲区 同模型共享盲区 互评 + 显式清单
循环不停 缺停止条件 三条件组合

实战提示

  1. 先想清楚"反思能修什么"再动手:疏忽型用反思,知识型用工具,别用反思解决检索问题。
  2. 审查输出务必结构化:问题清单三段式(问题+位置+建议),修正模型才改得准。
  3. 预算封顶:反思的 token 消耗要单独计量、单独设上限(呼应第 24 章 G5),防止"质量优化"变成"成本事故"。
  4. 反思是兜底手段:优先级通常是"规则校验 → 工具校验 → 反思",反思是最后一道闸,不应作为首选。
相关推荐
梦想的颜色17 分钟前
【AI实战】React‑Native + AI 移动端 APP 完整实战全流程|云端 / 本地大模型、Agent 集成、安装配置、避坑指南
react.js·大模型·app·agent·reactnative·expo·ai 应用开发
霸道流氓气质21 分钟前
Spring AI 结构化输出:JSON Mode 与 BeanOutputConverter
人工智能·spring·json
G***技23 分钟前
IB3-771嵌入式主板6 TOPS真实算力怎么用:从PyTorch到RKNN的量化落地
人工智能·嵌入式硬件
cxr82824 分钟前
涌现与坍塌在AI自然语义分析与生成中的层级化因果约束
人工智能·智能体·认知框架
nanawinona25 分钟前
先跑通小流程,再让 AI 和 Python 承接复杂量化
人工智能·python
beiju26 分钟前
别拿生产账号给 Agent 实习:从 Anthropic 事故看 Agent Staging
人工智能
用户52746756142126 分钟前
模型退役不是换个 ID:Agent 迁移最容易丢的是岗位能力
人工智能
奈斯先生Vector29 分钟前
本地图片识别怎么接入多模态 AI?用 Python API 理解 GPT-4o Vision 的真实工作流
开发语言·人工智能·windows·python·网络协议·http·aigc
国科安芯30 分钟前
卫星电源管理系统中高可靠MCU的功耗特性与电源监控功能分析
人工智能·单片机·嵌入式硬件·mcu·安全·电源管理系统·抗辐射