> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/agentic_ai_guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/agentic_ai_guide/di-yi-bu-fen-dan-ti-zhi-neng-jia-gou/02_reasoning/2.4_reflexion.md).

# 2.4 反思与自我修正

如果说 ReAct 解决的是“边做边看、根据观察即时调整”，那么本节讨论的反思机制解决的是“做完一轮之后，如何基于反馈在下一轮做得更好”。广义上，反思（reflection）指模型审视并修正自身输出的能力；狭义上，Reflexion 通常特指一套带语言记忆的试错学习框架。本节先讲狭义的 Reflexion，再把它放回更宽的“测试时自我改进”谱系中，与 Self-Refine、CRITIC 区分开。

> **说明（术语说明）** 在智能体 AI 领域，**Reflexion** 通常特指 Noah Shinn 等人提出的“基于语言反馈的强化学习”框架（Reflexion framework）；而通用英语单词 **reflection** 指的是更广泛的“反思”认知能力。后文若说“狭义 Reflexion”，指的是前者；若说“广义反思”，则指所有基于反馈改进输出的方法族。

## 2.4.1 什么是反思

狭义的 Reflexion 框架由 Noah Shinn 等人在论文 [Reflexion: Language Agents with Verbal Reinforcement Learning](https://arxiv.org/abs/2303.11366) 中提出。它的关键假设是：任务失败后，不先盲目重试，而是先分析“为什么失败、下次如何避免”，再把这段语言化经验写入记忆，注入下一轮尝试。也就是说，Reflexion 的本质是 **把失败经验转化为可复用的语言形式知识，而不是更新模型权重**。

```
尝试 → 失败 → 反思（为什么失败？）→ 总结（学到了什么？）→ 将语言记忆注入下一次尝试
```

## 2.4.2 与人类学习的类比

| 阶段 | 人类学习         | 反思智能体   |
| -- | ------------ | ------- |
| 尝试 | 做数学题         | 执行任务    |
| 反馈 | 发现答案错误       | 收到失败信号  |
| 反思 | “我是在哪一步算错了？” | 分析错误原因  |
| 总结 | “以后要注意检查符号”  | 生成经验总结  |
| 改进 | 下次做题更仔细      | 更新策略/记忆 |

## 2.4.3 反思的三要素

### 执行者

负责执行任务的智能体，通常采用 ReAct 模式：

```python
class Actor:
    def act(self, task: str, memory: List[str]) -> Trajectory:
        """
        执行任务，返回执行轨迹
        memory: 之前反思得到的经验
        """
        prompt = f"""
        任务：{task}

        之前的经验教训：
        {format_memories(memory)}

        请执行任务...
        """
        return execute_with_react(prompt)
```

### 评估者

判断任务是否成功：

```python
class Evaluator:
    def evaluate(self, trajectory: Trajectory, ground_truth: Any) -> Tuple[bool, str]:
        """
        评估执行结果
        返回：(是否成功, 反馈信息)
        """
        result = trajectory.final_result

        if matches(result, ground_truth):
            return True, "任务完成"
        else:
            return False, f"结果不正确，预期 {ground_truth}，实际 {result}"
```

### 反思者

从失败中提取经验：

```python
class SelfReflection:
    def reflect(self, task: str, trajectory: Trajectory, feedback: str) -> str:
        """
        分析失败原因，生成经验总结
        """
        prompt = f"""
        任务：{task}

        执行轨迹：
        {format_trajectory(trajectory)}

        失败反馈：{feedback}

        请分析：
        1. 在哪个步骤出了问题？
        2. 为什么会出这个问题？
        3. 下次应该如何避免？

        请用一句话总结这次的经验教训：
        """
        return model.generate(prompt)
```

## 2.4.4 完整的 Reflexion 循环

```python
def reflexion_loop(task: str, ground_truth: Any, max_trials: int = 3):
    memory = []  # 存储反思经验
    for trial in range(max_trials):
        # 1. 执行任务（带着记忆）
        trajectory = actor.act(task, memory)
        # 2. 评估结果（评估器需要标准答案，见上文 Evaluator.evaluate 签名）
        success, feedback = evaluator.evaluate(trajectory, ground_truth)
        # 3. 如果成功，返回结果
        if success:
            return trajectory.final_result
        # 4. 如果失败，进行反思
        reflection = self_reflection.reflect(task, trajectory, feedback)
        memory.append(reflection)
        print(f"Trial {trial + 1} 失败，反思结果：{reflection}")
    return "达到最大尝试次数，任务失败"
```

**任务**：编写一个函数计算斐波那契数列第 n 项

**第一次尝试**：

```python
def fibonacci(n):
    return fibonacci(n-1) + fibonacci(n-2)  # ❌ 缺少终止条件
```

**评估结果**：`RecursionError: maximum recursion depth exceeded`

**反思**：

> “这次失败是因为递归函数没有设置终止条件（base case），导致无限递归。下次编写递归函数时，必须首先定义 base case。”

**第二次尝试**（带着反思记忆）：

```python
def fibonacci(n):
    if n <= 1:  # ✅ 添加了 base case
        return n
    return fibonacci(n-1) + fibonacci(n-2)
```

**评估结果**：`通过！`

到这里讨论的仍然是“狭义 Reflexion”：它有明确的 trial、评估信号，以及跨轮次保留的语言记忆。理解了这个基准形态之后，再看其它常被并列讨论、但机制并不相同的方法会更清楚。

## 2.4.5 记忆管理策略

### 短期记忆（滑动窗口）

只保留最近 k 次反思：

```python
class ShortTermMemory:
    def __init__(self, max_size: int = 5):
        self.memories = deque(maxlen=max_size)

    def add(self, reflection: str):
        self.memories.append(reflection)
```

### 长期记忆（持久化存储）

将反思结果存入向量数据库进行持久化存储，以便在未来的任务中复用：

```python
class LongTermMemory:
    def __init__(self, vector_store):
        self.store = vector_store

    def add(self, reflection: str, task_type: str):
        embedding = embed(reflection)
        self.store.add(embedding, metadata={"text": reflection, "type": task_type})

    def retrieve(self, current_task: str, k: int = 3) -> List[str]:
        """检索与当前任务相关的历史经验"""
        return self.store.search(embed(current_task), top_k=k)
```

### 经验泛化

从具体经验中提取通用规则，并注入到系统提示词中作为全局准则：

```
具体经验：
- "计算阶乘时忘了处理 n=0 的情况"
- "递归求和时没有设置终止条件"
- "链表遍历时没有检查空指针"

泛化规则：
→ "处理递归或循环结构时，始终先确定边界条件和终止条件"
```

**实现方式**：

```python
def consolidate_memories(memory_store):
    """定期执行的内存整理任务"""
    # 1. 聚类相似的错误记录

    clusters = cluster_similar_errors(memory_store.fetch_all())

    for cluster in clusters:
        # 2. 提取通用规则

        rule = model.generate(f"基于以下失败案例总结一条通用原则：\n{cluster}")

        # 3. 注入到系统提示词中作为全局准则

        agent.update_system_prompt(add_rule=rule)
```

## 2.4.6 与其他技术的结合

### Reflexion + ReAct

ReAct 提供行动能力，Reflexion 提供学习能力。

```python
class ReflexiveReActAgent:
    def run(self, task):
        for trial in range(max_trials):
            # ReAct 风格的执行
            trajectory = self.react_loop(task)
            if self.is_success(trajectory):
                return trajectory.result
            # Reflexion 风格的学习
            reflection = self.reflect(trajectory)
            self.memory.add(reflection)
```

### Reflexion + Tool Learning

从工具使用失败中学习，并更新工具使用知识库。

```
反思："调用 search API 时参数格式错误，应该用 {'q': query} 而不是 {'query': query}"
→ 更新工具使用知识库
```

## 2.4.7 Reflexion、Self-Refine 与 CRITIC 的边界

工程实践里，很多方法都会被口语化地称作“反思”。更稳妥的说法是：它们都属于“基于反馈改进输出”的相关方法，但不是同一个桶。三者在**反馈来自哪里**、**是否跨 trial 保留记忆**、**是否依赖外部工具校验**这三个维度上都不同。

### 1. Reflexion：失败后复盘并写入语言记忆

这是 Noah Shinn 等人在 *Reflexion: Language Agents with Verbal Reinforcement Learning* 中提出的框架。任务失败后，系统基于轨迹和反馈生成一条可复用的经验教训，并把它注入下一轮尝试。

```
失败：递归函数没有终止条件
反思：下次编写递归逻辑时，必须先确认 base case
下一轮：带着这条经验重新生成代码
```

### 2. Self-Refine：同一模型给自己提反馈并迭代改写

Self-Refine 通常指 Aman Madaan 等人在论文 [Self-Refine: Iterative Refinement with Self-Feedback](https://arxiv.org/abs/2303.17651) 中提出的方法。它不一定依赖明确的“失败”信号，而是在得到初稿后，由同一个模型继续扮演反馈者和改写者，主动做一轮或多轮自我审查，再迭代修改。

```
初稿：解释过于笼统
自评：缺少具体例子，抽象概念太多
改写：增加案例、对比和边界条件
```

它特别适合文案、报告、方案设计这类“没有唯一标准答案，但可以持续优化质量”的任务。与 Reflexion 相比，它更强调**当前样本内的连续打磨**，而不是“失败一次 - 总结经验 - 下一轮重试”的跨 trial 学习。

### 3. CRITIC：借助外部工具做客观校验后再修正

CRITIC 通常指 Zhibin Gou 等人在论文 [CRITIC: Large Language Models Can Self-Correct with Tool-Interactive Critiquing](https://arxiv.org/abs/2305.11738) 中提出的框架。它的关键不是“只靠自己想”，而是“先验证，再修正”。模型会调用搜索、代码执行器、数据库或其它校验工具，获得更客观的反馈后再修正输出。

```
初稿：这个 API 会返回 status 字段
校验：实际接口返回中没有 status
反思：我混淆了旧版和新版接口定义
修正：按真实返回结构更新说明
```

相比纯内部反思，这种模式更适合高风险场景，因为它把“自我感觉良好”的空间压缩到了最小。与 Self-Refine 相比，CRITIC 的关键增量不是自反馈本身，而是**把外部工具校验作为批判依据**。

可以把三者的边界收束成下表：

| 方法          | 原始论文                 | 核心反馈来源        | 是否保留跨 trial 记忆 | 典型用途                |
| ----------- | -------------------- | ------------- | -------------- | ------------------- |
| Reflexion   | Shinn et al. (2023)  | 任务成败信号 + 语言反思 | 是              | 失败后总结经验，再次尝试        |
| Self-Refine | Madaan et al. (2023) | 模型自生成的反馈      | 通常否            | 对单个初稿反复润色与改写        |
| CRITIC      | Gou et al. (2023)    | 外部工具校验结果      | 不一定，重点不在记忆     | 事实核验、代码检查、风险较高的输出修正 |

## 2.4.8 反思作为增强层，而不是独立系统

很多团队第一次接触 reflection 时，容易把它理解成一个独立 Agent。更准确的理解是：**广义反思通常是附着在 ReAct 或 Plan-and-Execute 之上的增强层**。同时也要注意，不是每一次读取 Observation、调整下一步动作都算“反思”；只有当系统显式地产生批判、总结或修正规则，并把它带入后续生成时，才进入这一层。

两种常见组合方式：

1. **ReAct + 反思层** 在若干步执行或一次 trial 结束后，额外生成复盘总结，并把结论注入后续决策。
2. **Plan-and-Execute + 反思层** 每完成一个计划节点或整个计划后做阶段复盘，决定是继续执行、局部修正，还是整体重规划。

可以把它理解为：

| 基础范式                 | 负责什么      | 广义反思额外提供什么      |
| -------------------- | --------- | --------------- |
| **ReAct**            | 边想边做、动态试探 | 对失败原因做语言化总结     |
| **Plan-and-Execute** | 全局规划、按步推进 | 发现计划漏洞并触发重规划    |
| **Multi-Agent**      | 分工协作      | 对团队协作失误做复盘与规则沉淀 |

如果没有显式的反思层，系统往往只能“重试”；有了反思层，系统才开始真正“学习”。

## 2.4.9 评估 Reflexion 的效果

### 最小实验

为了准确评估反思机制的效果，工程上应当建立对齐原论文精神的测试基准。以下是一个针对代码生成任务（如 HumanEval 基准）的最小复现实验设定：

* **评估任务**：HumanEval（如 Python 函数补全）。
* **核心指标**：`pass@1`（无反思的单次通过率）对比引入 Reflexion 循环后的最终通过率。
* **最大尝试次数（Max Trials）**：通常严格设置为 3 至 5 次（超过此阈值容易产生幻觉累积或成本衰减）。
* **反馈来源（Feedback Type）**：
  * 代码执行反馈：沙箱执行模型生成的单元测试或真实测试用例（包括通过/失败状态及报错堆栈追踪）。
  * 裁判模型反馈：由另一个隔离的 LLM 实例作为客观裁判，对初步答案给出判定和缺陷描述。
* **记忆结构与注入策略**：将失败输出、报错日志和反思总结组装为结构化数据包（参考 [第3章](/agentic_ai_guide/di-yi-bu-fen-dan-ti-zhi-neng-jia-gou/03_memory.md) 的统一上下文结构），在下一次尝试时强置于编排提示词的末尾。

### 关键评估指标

| 指标    | 说明                  |
| ----- | ------------------- |
| 成功率提升 | 第 n 次尝试的成功率与第 1 次对比 |
| 尝试次数  | 平均需要多少次才能成功         |
| 反思质量  | 反思是否正确定位问题          |
| 知识迁移  | 一个任务的经验是否帮助另一个      |

### 实验结果（参考论文）

部分研究在代码生成等任务上报告：引入 Reflexion 循环（多次尝试 + 反馈 + 经验总结）后，整体通过率会有明显提升。需要注意：不同模型、提示词、评测脚本与尝试次数都会显著影响数值，文中不固定引用具体百分比。

## 2.4.10 局限性与注意事项

* **评估信号的质量**：反思依赖准确的评估信号。如果评估不准确，反思也会出错。
* **反思的准确性**：模型可能错误归因失败原因，导致“错误的经验教训”。
* **计算成本**：多次尝试意味着多次模型调用，成本较高。
* **适用场景**：最适合有明确成功标准的任务（如代码、数学题），对于开放性任务效果有限。

***

**下一节**: [智能体提示词工程](/agentic_ai_guide/di-yi-bu-fen-dan-ti-zhi-neng-jia-gou/02_reasoning/2.5_prompt_engineering.md)
