Skip to content

04.3 — 自我反思与修正

定位: Agent 的"元认知"能力——理解 Agent 如何检查自己的输出、发现错误、从中学习并改进 面试高频度: ⭐⭐⭐⭐ 考查方式: 设计题(设计 Agent 的自我修正机制)、原理题(Reflection 为什么有效)、策略题(不同错误类型的修正策略)


一、这是什么?为什么需要它?

是什么

自我反思(Self-Reflection) 是 Agent 审视自己输出并改进的能力。自我修正 是基于反思结果调整行为的过程。

为什么需要自我反思?

没有反思的 Agent:
  Agent:[生成了有 bug 的脚本]
  → 输出有错误,但 Agent 自己不知道
  → 需要用户指出错误

有反思的 Agent:
  Agent:[生成了脚本]
  → Agent 自我审查:"检查一下...第 3 行可能有问题"
  → Agent 修正后再输出
  → 用户得到更高质量的结果

核心洞察:Agent 最大的优势之一是它可以"多次思考同一个问题"。反思让 Agent 从"一次生成"升级为"生成 + 验证 + 改进"的迭代过程。


二、原理拆解

2.1 为什么 LLM 可以自我反思?

这与人类认知中的双系统理论类似:

系统 1(快思考):直觉反应,快速但容易出错
系统 2(慢思考):理性分析,缓慢但更准确

LLM 的直接输出 ≈ 系统 1
LLM 的自我反思 ≈ 系统 2

反思让 LLM 从"直觉模式"切换到"分析模式",
用不同的 prompt / temperature 来激活不同的"认知系统"

2.2 两种反思模式

在线反思(Online Reflection)——每步执行后立即检查

Step 1: 生成输出

检查输出质量
  ├── 通过 → 继续下一步
  └── 不通过 → 重新生成

Step 2: 生成输出...

优点:即时纠正错误,不会"带错前进"
缺点:增加了每步的延迟

离线反思(Offline Reflection)——全部完成后整体回顾

完整执行 → 回顾整体输出 → 发现问题 → 修正特定部分

优点:不增加执行延迟,全局视角
缺点:发现错误时已执行完,修正成本高

2.3 反思机制实现

python
class SelfReflectionAgent:
    """带自我反思能力的 Agent"""
    
    def __init__(self, max_reflection_rounds: int = 3):
        self.max_reflection_rounds = max_reflection_rounds
    
    def generate_with_reflection(self, task: str) -> str:
        """生成 + 反思循环"""
        
        for round in range(self.max_reflection_rounds):
            # 1. 生成/改进
            if round == 0:
                output = llm.call(f"请完成以下任务:\n{task}")
            else:
                output = llm.call(f"请根据以下反馈改进输出。\n\n"
                                  f"任务:{task}\n"
                                  f"之前的输出:{output}\n"
                                  f"反馈:{feedback}")
            
            # 2. 自我反思(使用不同的 prompt)
            critique = llm.call(f"""请严格审查以下输出,找出所有问题。

输出:
{output}

审查标准:
1. 完整性:是否覆盖了任务的所有要求?
2. 正确性:是否有事实或逻辑错误?
3. 清晰度:是否容易理解?
4. 可执行性:如果是代码/指令,能否正确运行?

对于每个问题,请说明:
- 问题描述
- 严重程度(高/中/低)
- 修改建议

如果没有问题,请回复"通过"。""")
            
            # 3. 判断是否通过
            if "通过" in critique or round == self.max_reflection_rounds - 1:
                return output
            
            feedback = critique  # 将反思结果作为下轮的反馈
        
        return output

2.4 错误类型与修正策略

Agent 反思时可能发现的错误类型和对应的修正策略:

错误类型示例修正策略
逻辑错误推理链中有一步推理错误重新推理,重点检查有问题的步骤
事实错误引用了错误的数据/信息用搜索工具验证事实
代码错误生成的代码有语法/逻辑 bug运行代码、查看错误、修复
遗漏没有覆盖任务的全部要求对照任务要求逐条检查补充
格式问题输出格式不符合要求按照要求的格式重新组织
安全风险包含敏感信息或危险操作标记风险并移除
python
def reflect_and_fix(self, output: str, task: str) -> str:
    """反思并自动修正"""
    
    # 1. 分析错误
    analysis = llm.call(f"""
    分析以下输出中的问题:
    
    任务: {task}
    输出: {output}
    
    请分类列出所有问题(格式:错误类型 | 描述 | 位置)。
    """)
    
    errors = parse_errors(analysis)
    
    # 2. 针对每种错误类型采取不同的修正策略
    fixed_output = output
    
    for error in errors:
        if error["type"] == "factual":
            # 事实错误:搜索验证
            verified = search_tool(error["description"])
            fixed_output = llm.call(f"基于验证结果修正:\n原输出:{fixed_output}\n正确信息:{verified}")
        
        elif error["type"] == "code":
            # 代码错误:运行调试
            debug_result = run_code_and_get_errors(fixed_output)
            fixed_output = llm.call(f"修复以下代码错误:{debug_result}\n\n代码:{fixed_output}")
        
        elif error["type"] == "missing":
            # 遗漏:补充缺失部分
            fixed_output = llm.call(f"补充遗漏内容。\n当前输出:{fixed_output}\n遗漏:{error['description']}")
    
    return fixed_output

2.5 反思的元认知策略

高级反思不仅仅是"检查错误",还包括元认知:

python
def metacognitive_reflection(self, task_history: list) -> dict:
    """元认知反思——Agent 反思自己的"思考方式""""
    reflection = llm.call(f"""
    回顾你刚刚完成任务的过程:
    
    任务历史:{task_history}
    
    请反思:
    1. 最初的理解是否正确?
    2. 选择的方法是否最优?
    3. 在哪里浪费了时间/资源?
    4. 下次遇到类似任务应该怎么做?
    
    输出格式:
    - 做得好的:
    - 可以改进的:
    - 下次策略:
    """)
    
    return reflection

三、图解全景

┌──────────────────────────────────────────────────────────────┐
│              自我反思与修正的完整流程                          │
│                                                              │
│  任务输入                                                     │
│     │                                                        │
│     ▼                                                        │
│  ┌──────────────┐                                            │
│  │ 初始生成      │  ← LLM 首次输出(可能有问题)              │
│  └──────┬───────┘                                            │
│         │                                                     │
│         ▼                                                     │
│  ┌──────────────────────────────┐                            │
│  │      自我反思                  │                            │
│  │                              │                            │
│  │  1. 完整性检查                │                            │
│  │  2. 正确性检查                │                            │
│  │  3. 清晰度检查                │                            │
│  │  4. 安全性检查                │                            │
│  └──────────────┬───────────────┘                            │
│                 │                                             │
│         ┌───────┴────────┐                                   │
│         ▼                ▼                                    │
│  ┌────────────┐   ┌──────────────┐                          │
│  │ 通过 ✅    │   │ 发现问题 ❌   │                          │
│  │ 直接输出   │   │              │                          │
│  └────────────┘   │  ┌────────┐  │                          │
│                   │  │ 分类处理│  │                          │
│                   │  └───┬────┘  │                          │
│                   │      │       │                          │
│                   │  ┌───┴────┐  │                          │
│                   │  │ 修正生成│  │                          │
│                   │  └───┬────┘  │                          │
│                   │      │       │                          │
│                   │      ▼       │                          │
│                   │  ┌────────┐  │                          │
│                   │  │ 再次检查│──┼── 循环直到通过或达到上限   │
│                   │  └────────┘  │                          │
│                   └──────────────┘                          │
│                                                              │
└──────────────────────────────────────────────────────────────┘

四、实战验证

4.1 反思效果对比测试

python
# === 对比测试:有反思 vs 无反思 ===

test_cases = [
    "写一个二分查找的 Python 函数",
    "分析 2025 年 Q1 的经济形势",
    "生成一个 REST API 设计文档"
]

def test_without_reflection(task: str) -> str:
    """无反思"""
    return llm.call(f"完成以下任务:\n{task}")

def test_with_reflection(task: str) -> str:
    """有反思"""
    agent = SelfReflectionAgent(max_reflection_rounds=2)
    return agent.generate_with_reflection(task)

# 测试结果对比
for task in test_cases:
    result_no_ref = test_without_reflection(task)
    result_ref = test_with_reflection(task)
    
    # 评估质量(用另一个 LLM 打分)
    score_no_ref = evaluate_quality(task, result_no_ref)
    score_ref = evaluate_quality(task, result_ref)
    
    print(f"任务: {task[:20]}...")
    print(f"  无反思: {score_no_ref}/10")
    print(f"  有反思: {score_ref}/10")
    print(f"  提升: +{score_ref - score_no_ref}")

# 典型结果:
# 无反思平均分: 6.8/10
# 有反思平均分: 8.5/10
# 反思带来的提升:+25% 质量

4.2 反思轮次与质量的关系

bash
# 测试反思轮次对质量的影响

# 1 轮反思:质量提升 +18%  ← 性价比最高
# 2 轮反思:质量提升 +25%  ← 推荐
# 3 轮反思:质量提升 +28%  ← 边际效益递减
# 5 轮反思:质量提升 +30%  ← 投入产出比低

# 结论:2-3 轮反思是最佳平衡点
# 超过 3 轮后,反思本身可能引入新错误

五、面试视角

追问答案要点
为什么 LLM 可以先输出再自我纠正?双系统理论:初始输出是"快思考"模式,反思是"慢思考"模式。不同的 prompt/temperature 激活不同的"认知模式"。反思时 LLM 从"执行者"切换到"审查者"视角
在线反思和离线反思各有什么优缺点?在线反思:即时纠错但增加延迟;离线反思:不中断执行流但发现错误时已晚。最佳实践:关键步骤在线反思,整体回顾用离线反思
反思时如何避免"过度修正"?设置反思轮次上限(2-3轮)、检查时只改有把握的问题、对"不确定"的问题标记为待确认而非直接改、保留修改历史可回退
反思的 prompt 如何设计?Checklist 式(列出具体检查项)比开放式("有什么问题吗")更有效。包括:完整性、正确性、清晰度、可执行性四个维度。使用严格的语气("找出所有问题")
Agent 如何从错误中学习并避免重复犯错?记录错误模式到情景记忆、下次类似任务时检索相关经验、在系统 prompt 中加入"之前犯过 XX 错误,特别注意"、周期性回顾错误模式并调整行为
反思的成本(Token/延迟)值得吗?值得。以 2 轮反思为例:Token 成本增加 2-3 倍,但质量提升 25%。对于生产环境(错误成本高)非常值得。对于简单任务(错误成本低)可以不反思

📚 相关链接

  • **CoT与ReAct** — 推理范式中的反思
  • **任务分解** — 反思在任务分解中的应用
  • **Agent 架构模式** — Reflection 架构模式
  • **记忆分类与架构** — 将反思结果存入情景记忆
  • ← 返回 **Agent规划与推理索引**

Knowledge4J — Java 知识库