第十二章:Agent 的反思、验证与自我改进¶
12.1 什么是 Agent Reflection¶
Agent Reflection 更接近一套反馈驱动的控制机制,而不是抽象的“自省”:
生成或执行 → 评价 → 定位问题 → 定向修订 → 再验证
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
G["Generate / Execute"] --> E["Evaluate"]
E --> D["满足标准?"]
D -->|是| DONE["Finish"]
D -->|否| F["Structured Feedback"]
F --> R["Refine / Retry / Replan"]
R --> G
反思需要足够有用的纠错信号,但不一定每轮都有新外部证据:重新对照明确标准也可能发现遗漏。反馈可以来自:
- Tool Result;
- 编译器;
- 单元测试;
- Schema;
- 规则;
- 模拟器;
- 权威数据;
- 人工审核;
- Critic Model;
- LLM-as-a-Judge。
如果没有新的证据或评价标准,让同一个模型重复生成可能只会得到另一个同样不可靠的答案。
这里的 Reflection 是控制机制的统称,不是一种统一算法。Self-Refine 修改当前候选,Reflexion 在尝试之间保留语言反馈;专门训练自纠错能力的方法则在训练阶段更新参数。已经训练好的自纠错模型在回答当前问题时,通常仍不更新权重,不能把这几种机制都叫作“边运行边学习”。
12.2 为什么需要反思¶
12.2.1 发现生成阶段遗漏的问题¶
模型生成内容时主要关注“完成任务”,不一定同时覆盖:
- 事实正确性;
- 约束完整性;
- 引用一致性;
- 安全要求;
- 输出格式;
- 边界条件。
单独评价阶段可以把注意力集中到这些维度。
12.2.2 阻止错误继续传播¶
在强依赖任务中,早期错误可能成为后续步骤的输入:
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
A["错误搜索词"] --> B["错误资料"]
B --> C["错误分析"]
C --> D["错误结论"]
如果在关键节点验证:
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
A["搜索结果"] --> V["来源与相关性通过?"]
V -->|是| B["继续分析"]
V -->|否| R["修改查询并重试"]
就有机会在错误进入后续分析前拦住它;前提是验证器确实检查了来源和相关性,而不只是检查搜索接口是否返回成功。
12.2.3 改善一次难以完成的高质量输出¶
适合:
- 代码生成;
- 研究报告;
- 翻译;
- 法律或商业文本;
- 复杂数据分析;
- 有明确评分标准的内容生成。
12.2.4 将失败转化为可复用经验¶
经过验证的失败原因可以:
- 改善当前重试;
- 更新当前任务计划;
- 形成 Episode;
- 晋升为长期记忆;
- 转化为 Skill、规则或测试。
未经验证的反思不应直接成为长期规则。
12.3 Reflection 与 Verification 的区别¶
| Reflection | Verification |
|---|---|
| 解释哪里可能有问题及如何改 | 判断是否满足明确标准 |
| 通常由模型生成反馈 | 可以由程序、规则、环境或人执行 |
| 可能具有主观性 | 只在检查标准及其覆盖范围内提供结论 |
| 用于指导修订 | 用于接受、拒绝或阻止 |
更稳妥的做法是让 Verification 判断问题是否成立,再由 Reflection 把这些问题转成可执行的修订动作。
例如:
- 单元测试指出函数在空输入时失败;
- Critic 将失败归纳为“缺少空输入分支”;
- Refiner 修改代码;
- 测试再次验证。
12.4 Verifier 的优先级¶
先问“这条要求能用什么证据判定”,再决定由谁检查,而不是给所有验证器排一个固定名次:
| 要判定的要求 | 优先采用的证据 | 仍需补充的检查 |
|---|---|---|
| 工具是否完成写入 | 目标系统的业务状态与操作回执 | 对象、版本、重复副作用 |
| 代码是否满足已知行为 | 编译器、测试、约束求解器 | 未覆盖需求与回归风险 |
| 格式是否符合契约 | Schema 与确定性规则 | 字段内容是否真实、合法 |
| 事实是否有依据 | 可追溯的权威数据源 | 时效、适用范围与来源冲突 |
| 表述是否清晰、方案是否适用 | 领域人工审核或经校准的模型评价 | 评分一致性与证据覆盖 |
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
RESULT["Candidate Result"] --> DET["Deterministic Verifier"]
DET -->|可验证| DECISION["Pass / Fail"]
DET -->|无法完全验证| HUMAN["Human or Domain Review"]
HUMAN -->|仍需辅助| JUDGE["LLM Judge"]
语言模型评价适合处理难以完全形式化的质量维度,但不应替代可用的客观验证。
HTTP 200 可能只代表受理,真实系统也可能返回过期状态;编译通过不保证业务正确,生成测试也可能写错预期值。选择验证器时要说明它验证了什么、漏掉什么,以及失败时能否阻止交付。对不可逆动作,审批必须在执行前,事后反思不能补回缺失的授权。
12.5 反思的四种触发粒度¶
除了步骤级和任务级,还可以加入里程碑级与跨任务 Consolidation。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart LR
R["Reflection<br/>Granularity"] --> S["Step-level"]
R --> M["Milestone-level"]
R --> T["Task-level"]
R --> C["Cross-task<br/>Consolidation"]
12.6 Step-level Reflection¶
Step-level Reflection 在 Tool Call、推理步骤或状态转移后检查结果。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
S["Execute Step"] --> O["Observation"]
O --> V["Step Valid?"]
V -->|是| N["Next Step"]
V -->|否| F["Feedback"]
F --> R["Retry or Replan"]
R --> S
12.6.1 适用场景¶
- 步骤之间强依赖;
- 早期错误会影响大量后续工作;
- Tool 结果容易验证;
- 操作具有高风险或副作用;
- 局部重试成本较低。
例如:
- 搜索结果是否与问题相关;
- API 是否返回成功状态;
- 代码是否通过编译;
- 数据是否满足 Schema;
- 高风险操作执行前,审批是否有效并绑定当前参数。
12.6.2 优势¶
- 错误发现早;
- 失败影响范围小;
- 可以局部重试;
- 状态更容易保持正确;
- 适合强依赖任务。
12.6.3 代价¶
- 增加验证延迟;
- 增加模型或 Tool 调用;
- 可能过度检查低风险步骤;
- Critic 可能不断提出非关键修改;
- 任务吞吐下降。
12.6.4 不一定每步增加一次 LLM 调用¶
“十步任务加步骤级反思就需要二十次 LLM 调用”不是必然规律。
步骤验证可以由:
- Tool 自身状态码;
- Schema Validator;
- 单元测试;
- 规则引擎;
- 当前 Agent 的下一轮决策;
- 批量 Critic;
- 只在异常时触发的模型评价。
只有在每个步骤都单独调用 LLM Critic 时,调用次数才可能接近翻倍。
12.7 Milestone-level Reflection¶
Milestone-level Reflection 在一个阶段完成后评价,而不是检查每个微步骤。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
S1["Stage Steps"] --> M["Milestone Artifact"]
M --> V["Milestone Valid?"]
V -->|是| NEXT["Next Milestone"]
V -->|否| FIX["Repair Affected Stage"]
这种做法减少了检查次数,但不保证总成本一定更低:阶段末才发现错误时,可能要重做更多步骤。它通常比只看最终结果更容易尽早发现偏差,前提是阶段有清晰产物,可以整体验收和修复。
适合:
- 一个阶段内部步骤较多;
- 阶段能产生独立 Artifact;
- 每步验证过于昂贵;
- 阶段之间依赖明显。
例如:
- 资料收集完成后统一检查来源覆盖;
- 功能实现完成后运行整组测试;
- 报告提纲完成后检查结构。
12.8 Task-level Reflection¶
Task-level Reflection 在完整任务结束后进行整体评价。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
TASK["Complete Task"] --> OUT["Final Candidate"]
OUT --> E["Holistic Evaluation"]
E --> D["Pass?"]
D -->|是| DONE["Deliver"]
D -->|否| R["Revise Result or Replan"]
12.8.1 适用场景¶
- 步骤相对独立;
- 单步错误影响有限;
- 更关注整体一致性;
- 最终结果容易统一评价;
- 中间验证成本较高。
例如:
- 报告结构和结论是否一致;
- 文案风格是否统一;
- 多章节是否重复或矛盾;
- 最终方案是否满足全部要求。
12.8.2 优势¶
- 额外调用较少;
- 能观察全局一致性;
- 适合发现跨部分问题;
- 实现简单。
12.8.3 代价¶
- 错误发现晚;
- 可能浪费前期执行成本;
- 很难只修复一个局部;
- 根因可能被最终输出掩盖。
12.9 Cross-task Consolidation¶
跨任务反思更像一次复盘,重点是总结:
- 哪种策略有效;
- 哪种错误反复出现;
- 哪些规则值得长期保留;
- 哪些 Tool 或 Prompt 需要改进。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
T1["Task 1"] --> C["Consolidation"]
T2["Task 2"] --> C
T3["Task N"] --> C
C --> M["Validated<br/>Memory"]
C --> S["Skill /<br/>Workflow<br/>Update"]
C --> E["Evaluation<br/>Set"]
跨任务经验必须经过验证、去重和适用范围检查,不能把模型的一次自我评价自动提升为永久规则。
12.10 如何选择反思粒度¶
| 任务特征 | 推荐粒度 |
|---|---|
| 强依赖、错误会层层传播 | Step-level |
| 阶段有独立输出 | Milestone-level |
| 各步骤相对独立,关注整体质量 | Task-level |
| 需要积累重复任务经验 | Cross-task Consolidation |
| 高风险动作 | Step-level + Human Gate |
| 成本敏感 | Triggered Milestone / Task-level |
生产系统通常混合使用:
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
STEP["Low-risk Steps"] --> MILESTONE["Milestone<br/>Verification"]
RISK["High-risk Step"] --> IMMEDIATE["Immediate<br/>Verification"]
MILESTONE --> TASK["Task-level Review"]
IMMEDIATE --> TASK
TASK --> CONS["Optional<br/>Consolidation"]
12.11 Adaptive Reflection¶
不必在每一步都反思。可以根据风险和异常动态触发。
触发信号包括:
- Tool 返回错误;
- 输出不符合 Schema;
- 经校准的置信信号较低,或缺少必需证据;
- 多个来源冲突;
- 重复调用同一 Tool;
- 计划偏离目标;
- 即将执行高风险动作;
- 阶段耗时或成本异常;
- Verifier 分数低。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
O["Observation"] --> R["Risk / Anomaly Detector"]
R -->|正常| NEXT["Continue"]
R -->|异常| REFLECT["Reflect / Verify"]
REFLECT --> FIX["Repair / Replan"]
相比固定“每一步一次 Critic”,自适应触发通常更容易把成本控制住。
12.12 反思系统的基本组件¶
一个完整实现通常包含:
- Generator / Executor;
- Verifier / Critic;
- Feedback Formatter;
- Refiner;
- Stop Controller;
- Optional Memory Writer。
产生证据与结构化反馈。
%%{init: {"flowchart": {"nodeSpacing": 10, "rankSpacing": 16, "padding": 6}}}%%
flowchart TB
G["Generator / Executor"]
A["Artifact + Trace"]
V["Verifier / Critic"]
F["Structured Feedback"]
S["Stop Controller"]
G --> A
A --> V
V --> F
F --> S
停止控制器选择修订或退出。
flowchart TB
S{Stop Controller}
R[Refiner]
G[Generator / Executor]
S -->|允许修订| R
R --> G
控制器的其他结果退出这条修订路径:通过时完成,预算耗尽时报告未完成,需要人工判断时转人工审核。
可选写入前先校验可复用经验。
flowchart TB
DONE[Finish]
MV[Validate Reusable Experience]
MW[Optional Memory Writer]
DONE --> MV
MV -->|通过| MW
Stop Controller 先判断是否允许继续,再调用 Refiner,避免停止信号发出后仍触发修订。原始反馈可以留作任务内诊断记录;写入长期记忆的是经过验证、带适用范围的经验,不是所有 Critic 意见。
12.13 区分 Evaluate 与 Refine 的职责¶
反思至少需要两个逻辑阶段:
12.13.1 Evaluate¶
只负责:
- 对照标准检查;
- 找出具体问题;
- 提供证据;
- 判断严重程度;
- 给出可操作建议。
12.13.2 Refine¶
负责:
- 读取原始任务;
- 读取原始输出;
- 读取结构化反馈;
- 定向修改;
- 保留正确内容;
- 返回可再次验证的结果。
这两个角色可以由:
- 两个不同 Prompt;
- 两次模型调用;
- 不同模型;
- LLM + 确定性验证器;
- 同一 Agent 的不同 Workflow 节点;
实现。
重点是职责和输入输出边界,而不是必须恰好存在两个 Prompt 文件。
12.14 Critic Prompt 应包含什么¶
12.14.1 原始任务与成功标准¶
Critic 必须知道什么才算完成。把成功条件拆成可检查的评价标准(Rubric),并说明哪些是不可被其他优点抵消的硬性要求。
12.14.2 具体检查维度¶
例如:
- Correctness;
- Completeness;
- Evidence;
- Consistency;
- Safety;
- Format;
- Efficiency。
12.14.3 可验证证据¶
要求每个 Finding 引用:
- 输出片段;
- Tool Result;
- 测试;
- 来源;
- 明确规则。
12.14.4 PASS 出口¶
如果结果已经满足要求,Critic 必须能够返回 PASS。否则它会为了完成“找问题”的指令不断制造低价值意见。
12.14.5 结构化输出¶
{
"verdict": "REVISE",
"score": 0.78,
"findings": [
{
"criterion": "evidence",
"severity": "high",
"location": "section-3",
"problem": "关键市场份额结论没有来源",
"evidence": "报告第 3 节第 2 段",
"suggestion": "补充权威来源,或删除该具体数字"
}
],
"next_action": "revise"
}
score 是教学占位值,不是校准后的正确概率;应定义评分尺度、Rubric 版本及证据范围。PASS 也只表示该 Critic 在职责范围内未发现问题,不能覆盖确定性测试失败、安全拒绝或审批缺失。
允许的 Verdict 可以是:
PASS;REVISE;REPLAN;BLOCKED;NEEDS_HUMAN_REVIEW。
12.15 Refiner Prompt 应包含什么¶
Refiner 需要:
- 原始任务;
- 当前候选;
- Critic Findings;
- 不可改变的约束;
- 允许修改的范围;
- 输出 Schema。
推荐要求:
- 只处理有效 Finding;
- 保留已经正确的部分;
- 不引入无来源新事实;
- 返回修改后的完整 Artifact 或明确 Patch;
- 说明哪些 Finding 无法解决。
不要只说“请根据意见优化一下”,否则修改方向不稳定。
12.16 Stop Controller¶
不能依赖模型自己无限反思直到满意。
停止条件包括:
- 所有必需的硬性验收通过,且所需质量检查通过;
- 达到软质量阈值且没有未解决的硬性失败;
- 达到最大轮数;
- Token 或费用预算耗尽;
- 超时;
- 连续多轮没有显著改善;
- 相同 Finding 重复出现;
- 需要人工判断;
- 用户取消。
设第 r 轮评分为 sᵣ,改进量为:
如果连续若干轮满足:
可以触发“没有可测改善”的停止策略,不必继续消耗预算。
前提是各轮使用可比较的评分尺度,并按 Judge 的随机波动设置容差;单次小分差不足以证明真实质量没有变化。应保存候选与验证记录,不能简单交付“最后一版”:修订可能让原本正确的部分回归。阈值未达标或存在硬性失败时,停止表示未完成或转人工,而不是成功。
12.16.1 如何确定最大轮数¶
没有适用于所有任务的默认最优轮数。可以选择少量轮次作为实验起点,但不能把“一到三轮”当作已有普遍收益的结论。
轮数应根据:
- 单轮成本;
- 任务风险;
- Verifier 可靠性;
- 每轮平均提升;
- 用户延迟目标;
- 是否存在确定性成功条件;
通过评估确定。
高风险操作可能只允许一次修订后转人工;可自动测试的代码修复则可能允许更多受限迭代。
12.17 反思成本¶
若每轮包含 Evaluate、Refine 和 Verify,总成本可表示为:
这里把定位问题的 Evaluate、修改候选的 Refine、修订后的 Verify 分开计费;如果一次检查同时承担两个职责,不应重复计算。每阶段还应计入它消耗的:
- Tool 执行;
- 测试;
- Context;
- Critic Agent 通信;
- Artifact 存储;
- 人工审核。
降低成本的方法:
- 只在异常或高风险时触发;
- 使用确定性验证器;
- 用小模型初筛;
- 批量检查多个步骤;
- 在 Milestone 而非每个微步骤反思;
- 达到阈值立即停止;
- 只修复受影响部分。
12.18 Self-Reflection¶
Self-Reflection 使用同一模型或同一 Agent 评价自己的结果。
12.18.1 优势¶
- 实现简单;
- 无需额外 Agent;
- Context 传递成本低;
- 适合低风险初步检查。
12.18.2 局限¶
- Generator 与 Critic 共享模型偏差;
- 容易重复原来的假设;
- 可能偏好自己的表达;
- 缺少真正的新证据;
- 可能产生表面修改。
Self-Reflection 可以作为初筛,但不能当成客观验证。
实验结论要带上范围:Huang 等人的研究【503】发现,当时所测模型在没有外部反馈的推理纠错中经常无收益甚至退化;这不是“模型永远无法自纠错”的定理。SCoRe【505】随后用多轮在线 RL 专门训练自纠错,测试时不要求外部纠错反馈。这与只给冻结模型加一句“检查一下”不同:训练阶段确实使用奖励并更新了参数。
12.19 Critic Agent¶
Critic Agent 专门检查 Executor 的 Artifact 或轨迹。
%%{init: {"sequence": {"width": 75, "height": 45, "actorMargin": 10, "diagramMarginX": 5, "messageMargin": 18, "wrap": true, "wrapPadding": 5}}}%%
sequenceDiagram
participant E as Executor Agent
participant C as Critic Agent
participant V as Verifier
E->>C: Candidate + Rubric +<br/>Evidence
C-->>E: Structured Findings
E->>E: Refine
E->>V: Revised Candidate
V-->>E: Pass or Fail
12.19.1 为什么可能更好¶
- Critic 使用独立 Prompt;
- Critic 不承担生成任务;
- 可以隐藏 Generator 的解释,减少 Anchoring;
- 可以使用不同模型和 Tools;
- 可以只关注某个质量维度;
- 可以访问独立验证数据。
12.19.2 为什么不一定更客观¶
如果 Critic:
- 使用相同模型;
- 看到相同上下文;
- 使用模糊 Rubric;
- 没有外部证据;
- 只被要求“找问题”;
它仍可能与 Generator 共享错误,或为了批评而批评。
拆成独立 Critic Agent,不会自动带来独立证据,也不会自动消除共享误差。
提高独立性的方式:
- 使用不同模型或模型版本;
- 使用不同数据源;
- Blind Review;
- 明确 Rubric;
- 提供测试和事实来源;
- 对 Critic 本身做评估。
12.20 Multi-Critic¶
可以让多个 Critic 分别检查:
- 事实;
- 安全;
- 逻辑;
- 格式;
- 领域合规。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart LR
OUT["Candidate"] --> F["Fact Critic"]
OUT --> S["Safety<br/>Critic"]
OUT --> L["Logic Critic"]
OUT --> D["Domain<br/>Critic"]
F --> J["Finding<br/>Aggregator"]
S --> J
L --> J
D --> J
优势:
- 每个 Critic 更聚焦;
- 可以并行;
- 权限和数据隔离更清晰。
代价:
- 成本增加;
- Findings 可能冲突;
- 需要聚合和优先级;
- 多个相同模型仍可能共享偏差。
12.21 Debate¶
Debate 让多个 Agent 对候选方案进行对抗式讨论。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
P["Proposer"] --> O["Opponent"]
O --> R["Rebuttal"]
R --> J["Judge / Verifier"]
J --> D["通过?"]
D -->|否| P
D -->|是| OUT["Final Decision"]
适合:
- 存在多个合理观点;
- 需要暴露假设;
- 需要风险分析;
- 结论无法完全用确定性规则验证。
12.21.1 Debate 的风险¶
- 更善辩不等于更正确;
- Judge 可能偏好表达方式;
- Agent 可能共享相同知识盲区;
- 讨论可能循环;
- Token 和延迟成本高;
- 对事实问题不应以投票替代数据。
关键商业或法律决策仍需要权威事实、领域专家和明确责任人。
12.22 Self-Refine¶
Self-Refine 的基本流程是:
Generate → Feedback → Refine
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
G["Generate"] --> F["Self Feedback"]
F --> R["Refine"]
R --> V["Pass?"]
V -->|否| F
V -->|是| OUT["Output"]
Self-Refine 原方法使用同一 LLM 生成、反馈、修订,不要求额外训练或 RL,主要优化当前候选而非模型权重。原论文在七类任务上报告收益,但任务使用的评价标准、模型与停止方式不同,不能把其平均增益当作任意业务的普遍提升。
它的自反馈可以发现风格、格式或显式约束问题,不保证补充缺失事实。没有外部反馈时也可能改善输出,但事实和逻辑纠错是否有效仍需独立测试。
适合:
- 文本质量优化;
- 格式修正;
- 有 Rubric 的生成任务;
- 低风险迭代。
12.23 Reflexion¶
Reflexion 将任务反馈转化为自然语言反思,并保存在 Episodic Memory 中,供后续尝试使用。原论文允许标量或文本、外部或内部模拟的反馈;“Verbal Reinforcement Learning”指以语言记忆影响后续策略,不是通过梯度更新 Actor 权重。
经典组件包括:
- Actor;
- Evaluator;
- Self-Reflection;
- Episodic Memory。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
A["Actor"] --> ENV["Environment"]
ENV --> TRAJ["Trajectory + Reward"]
TRAJ --> E["Evaluator"]
E --> D["Success?"]
D -->|是| DONE["Finish"]
D -->|否| SR["Self-Reflection"]
SR --> MEM["Episodic Memory"]
MEM --> A
12.23.1 原始 Reflexion 的记忆范围¶
原始方法重点是在同一任务的多次 Trial 之间保留 verbal reflection,从而让下一次尝试避免重复错误。
试次可以重新初始化环境,而保留有界反思记忆。它不同于在同一答案上继续润色,也不同于自动获得跨任务长期技能。论文 HumanEval 的最终单候选 pass@1 包含生成测试与多次修订,不能理解为一次模型调用成功率;该论文 MBPP Python 上也出现退化,详见第四章 §4.6.2:HumanEval 结果应如何解读。
它不要求:
- 必须使用 Vector DB;
- 必须进行跨任务语义检索;
- 自动把所有经验永久保存。
生产系统可以扩展为跨任务记忆,但需要:
- 经验验证;
- 适用范围;
- 去重;
- 来源;
- 相似任务检索;
- 过期和删除策略。
12.23.2 从 Reflection 晋升为 Skill¶
如果一条经验:
- 多次验证有效;
- 具有跨任务价值;
- 适用范围明确;
- 不包含敏感信息;
可以晋升为:
- Skill;
- Workflow;
- Rule;
- Test;
- Runbook。
12.24 LATS¶
LATS(Language Agent Tree Search)将:
- Tree Search;
- Action;
- Environment Feedback;
- Value Evaluation;
- Reflection;
结合在同一个基于蒙特卡洛树搜索(MCTS)的过程中。Selection 在继续探索访问较少的分支与利用已有高价值分支之间取舍,Expansion 生成动作,模拟轨迹(rollout)或环境执行得到反馈,价值估计与回报再回传到树节点;这不是神经网络梯度回传,原方法不靠在线微调更新 LLM 参数。
%%{init: {"flowchart": {"nodeSpacing": 10, "rankSpacing": 16, "padding": 6}}}%%
flowchart TB
ROOT["Current<br/>State"] --> A["Action A"]
ROOT --> B["Action B"]
ROOT --> C["Action C"]
A --> OA["Observation<br/>A"]
B --> OB["Observation<br/>B"]
C --> OC["Observation<br/>C"]
OA --> VA["Value +<br/>Reflection"]
OB --> VB["Value +<br/>Reflection"]
OC --> VC["Value +<br/>Reflection"]
VA --> SELECT["Tree Policy"]
VB --> SELECT
VC --> SELECT
SELECT --> EXPAND["Expand<br/>Promising<br/>Path"]
12.24.1 核心价值¶
- 同时探索多个行动路径;
- 使用环境反馈评价路径;
- 从失败轨迹中提取反思;
- 将评价用于后续搜索。
12.24.2 成本¶
成本取决于:
- 分支数;
- 搜索深度;
- Rollout 数;
- Value Evaluation;
- Reflection 调用;
- Tool 执行。
它可能远高于线性 ReAct 或简单 Reflection,不能用固定倍数概括。
多分支比较隐含环境可重置、克隆或安全模拟的条件;从节点 B 回溯到节点 A 不会撤销真实外部写入。对不可逆操作,应先在隔离环境评价候选,再对获准方案执行一次,不能把真实支付或发信当成 rollout。
12.24.3 工程定位¶
LATS 是重要的研究型架构,其思想可以用于:
- 候选方案搜索;
- 代码修复;
- 可模拟环境;
- 高价值决策辅助。
若单轮请求的延迟预算无法承担多分支执行,可以先比较受限 Beam Search、Best-of-N、Verifier 和局部重试。是否需要完整 MCTS + Reflection,应由同预算对照决定,而不是由架构名称决定。
12.25 反思与规划的关系¶
Reflection 可以作用于不同对象:
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart LR
R["Reflection"] --> OUT["Output Reflection"]
R --> STEP["Step Reflection"]
R --> PLAN["Plan Reflection"]
R --> TRACE["Trajectory Reflection"]
R --> MEMORY["Memory Reflection"]
- Output Reflection:结果是否正确;
- Step Reflection:当前步骤是否有效;
- Plan Reflection:计划是否仍适用;
- Trajectory Reflection:整条执行路径是否合理;
- Memory Reflection:哪些经验值得保留。
Plan-and-Execute 中,反思结果可能触发 Replanner,而不仅是重写当前答案。
12.26 反思与 Agentic Workflow¶
生产系统通常将反思限制在 Workflow 节点中:
确定性检查失败时直接修复。
flowchart TB
IN[Input]
G[Generate]
DET[Deterministic Checks]
FIX[Direct Repair]
C[Critic]
IN --> G
G --> DET
DET -->|通过| C
DET -->|失败| FIX
FIX --> DET
修订后返回确定性检查。
flowchart TB
DET[Deterministic Checks]
C[Critic]
D{Verdict}
R[Refiner]
DET -->|通过| C
C --> D
D -->|REVISE| R
R --> DET
重规划后返回生成。
flowchart TB
C[Critic]
D{Verdict}
P[Planner]
G[Generate]
C --> D
D -->|REPLAN| P
P --> G
其他结论对应输出或人工审核。
flowchart TB
D{Verdict}
OUT[Output]
H[Human Review]
D -->|PASS| OUT
D -->|HUMAN| H
图中修复与重规划都受同一个 Stop Controller 限制;修订后重新跑必需检查,不能因 Critic 返回 PASS 而跳过。发送、部署、付款等动作另设执行前准入门,不能只在事后进入这个质量循环。
Workflow 负责:
- 最大轮数;
- 允许的 Verdict;
- 权限;
- 预算;
- 人工审批;
- 最终停止。
LLM 负责:
- 找出难以形式化的问题;
- 生成具体反馈;
- 定向修订。
12.27 代码 Agent 示例¶
目标:
修复一个导致空输入崩溃的函数。
先用空列表复现 IndexError,再查看失败位置。如果异常来自直接访问首元素,下一步也不应立刻决定“空输入返回 0”:要先查函数契约,确认应返回空结果、抛出约定异常,还是采用默认值。反思负责提出根因与修复假设,测试负责检查这个假设是否满足需求。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
G["Generate Patch"] --> T["Run Tests"]
T --> D["Tests Pass?"]
D -->|是| R["Code Review"]
D -->|否| F["Extract Failure"]
F --> REF["Reflect on Root Cause"]
REF --> G
R --> Q["Review Pass?"]
Q -->|是| DONE["Finish"]
Q -->|否| G
关键点:
- Test 是 Verifier;
- 测试失败提供新证据;
- Reflection 总结根因;
- Refiner 修改 Patch;
- 最大尝试次数由 Runtime 控制;
- 测试通过后仍需 Review 检查未覆盖风险。
12.28 研究报告示例¶
12.28.1 Step-level¶
- 搜索结果是否相关;
- 来源是否可信;
- 关键数字是否来自原文。
12.28.2 Milestone-level¶
- 每个竞品是否覆盖相同维度;
- 是否存在缺失资料;
- Artifact Schema 是否完整。
12.28.3 Task-level¶
- 结论是否前后一致;
- 引用是否支持论点;
- 是否区分事实、推断与建议;
- 报告结构是否完整。
12.28.4 Cross-task¶
- 哪些来源长期可靠;
- 哪种检索策略经常失败;
- 哪些检查规则应加入 Skill。
12.29 反思记忆的数据结构¶
{
"reflection_id": "ref-42",
"task_id": "task-101",
"scope": "step",
"trigger": "test_failure",
"evidence": {
"test": "test_empty_input",
"error": "IndexError"
},
"diagnosis": "函数在访问首元素前没有检查空列表",
"recommended_action": "增加空输入分支并补充测试",
"verified": false,
"verification_needed": ["复现失败", "确认修补后的目标测试与相关回归测试通过"],
"applicability": "functions that access the first list element",
"retention": "task-local"
}
错误消息本身只证明某次执行失败,不足以证明根因和修复建议成立。示例保持 verified: false;验证后应记录候选版本、测试版本和结果,由可信流程设置验证状态,而不是由生成反思的模型自行宣称已验证。
关键字段:
- Scope;
- Trigger;
- Evidence;
- Diagnosis;
- Action;
- Verification;
- Applicability;
- Retention。
12.30 防止 Reflection Loop¶
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 16, "padding": 10}}}%%
flowchart TB
R["Reflection<br/>Round"] --> V["Verify"]
V --> P["Pass?"]
P -->|是| DONE["Finish"]
P -->|否| B["Budget<br/>Remaining?"]
B -->|否| STOP["Stop and<br/>Report"]
B -->|是| I["Finding<br/>Changed?"]
I -->|否| ESC["Escalate /<br/>Human"]
I -->|是| FIX["Refine"]
FIX --> R
硬性机制包括:
- 最大轮数;
- 最大 Token 和费用;
- 超时;
- Finding 去重;
- 无改进检测;
- 同一错误重复阈值;
- 人工升级;
- 不可修复状态。
停止时应明确报告:
- 已解决问题;
- 未解决 Finding;
- 停止原因;
- 当前 Artifact;
- 下一步建议。
12.31 如何评估反思系统¶
| 指标 | 含义 |
|---|---|
| First-pass Success | 不反思时的成功率 |
| Post-reflection Success | 反思后的成功率 |
| Finding Precision | Critic 提出的问题中真实问题比例 |
| Finding Recall | 已知问题被发现的比例 |
| Fix Success | 反馈是否促成正确修复 |
| Regression Rate | 修订是否破坏正确内容 |
| Average Rounds | 平均反思轮数 |
| Cost per Success | 每个成功任务的总成本 |
| Time to Detect | 错误被发现的时间 |
| Escalation Rate | 需要人工处理的比例 |
评估时更该看反思是否以可接受成本提高最终任务成功率,并减少风险,而不是只统计 Critic 提了多少意见。
特别要同时统计“错改对”和“对改错”。只在已知错误样本上测修复率,会掩盖 Critic 将正确结果误判并破坏的风险;实际系统没有 oracle 告诉它哪些答案需要修订。
12.32 A/B 评估¶
按待验证假设选择对照,不必一次运行全部组合:
- 无 Reflection;
- Self-Reflection;
- Deterministic Verifier;
- Critic Agent;
- Verifier + Critic;
- Step-level;
- Milestone-level;
- Task-level。
观察:
- 质量提升;
- 延迟;
- Token;
- Tool 成本;
- False Positive;
- Regression;
- 用户满意度。
如果 Critic 只增加成本而没有稳定提升,就不应保留。
增加等 Token、等工具调用或等时延预算的重采样/仅测试修复对照,才能分清收益来自反思内容还是更多尝试。修订循环使用开发测试,最终计分使用独立保留集;不能把隐藏测试答案或最终 Judge 的详细反馈泄漏给 Refiner。
12.33 常见反模式¶
12.33.1 只说“请检查有没有问题”¶
缺少 Rubric,反馈容易流于表面。
12.33.2 Critic 只能返回问题¶
没有 PASS 出口,会无限挑毛病。
12.33.3 Refiner 看不到原始任务¶
只根据批注修改,可能偏离用户目标。
12.33.4 同一个模型反复重写¶
若既没有有效检查标准,也没有新证据,可能只产生文本变化;不能用“改过了”代替质量评估。
12.33.5 每个步骤都调用大型 Critic¶
低风险步骤成本过高。
12.33.6 Critic Agent 被假设为客观真相¶
独立角色仍可能共享模型偏差。
12.33.7 反思自动写入长期记忆¶
错误经验会形成 Memory Poisoning。
12.33.8 没有最大轮次¶
形成无限修订。
12.33.9 Debate 用于替代事实查询¶
多个 Agent 讨论不能替代权威数据。
12.34 推荐生产架构¶
flowchart TB
EXEC[执行器] --> DV[必需检查]
DV -->|通过且需主观评价| CRITIC[评审器]
DV -->|硬性失败| REFINE[修订器]
CRITIC -->|REVISE| REFINE
REFINE --> GATE[预算与权限检查]
GATE -->|重新校验通过| EXEC
每个任务都先检查预算与继续执行的条件,再检查执行时权限与审批。预算耗尽或不允许继续时报告未完成;缺少授权时转人工审核或拒绝,重新获得授权后仍须再次通过权限门控。
执行器将产物与轨迹交给确定性验证器。硬性失败必须记录,并生成反馈交给修订器。必需检查通过后,如果不需要主观质量评价就结束;否则由评审器给出 PASS(完成)、REVISE(修订)、REPLAN(重规划)或 BLOCKED(人工审核)。修订与重规划都须先返回预算检查,再经过权限门控,才能重新执行。
完成后,只有值得沉淀且反思校验通过的经验,才能成为记忆或 Skill 候选;未证实或无需保留的经验直接结束,不写入记忆。
图中硬性失败没有通向 Critic PASS 的捷径。入口展示了整体准入检查,Runtime 还必须在每个模型/工具调用前检查剩余预算,包括 Critic、Refiner 和 Replanner;任何修改都要绑定新候选版本重新验收。这里的 Executor 消费当前候选或计划,不应在 Refiner 修改后无条件丢弃它重新生成。
推荐原则:
- 先使用确定性 Verifier;
- 只在必要维度调用 Critic;
- 使用结构化 Finding;
- 将 Evaluate 与 Refine 分开;
- 对高风险和强依赖步骤提前验证;
- 对整体输出进行 Task-level Review;
- 硬性限制轮数、预算和时间;
- 只有经过验证的经验才能进入长期记忆。
12.35 本章总结¶
Agent Reflection 是反馈驱动的质量控制环:
执行 → 验证 → 反馈 → 修订或重规划 → 再验证
触发粒度包括:
- Step-level:尽早阻止错误传播;
- Milestone-level:平衡成本和纠错速度;
- Task-level:检查整体一致性;
- Cross-task:提炼可复用经验。
落地时要看几件事:
- Critic 具有明确 Rubric;
- 输出结构化 Finding;
- 允许 PASS;
- Refiner 保留原始任务和正确内容;
- 优先使用客观 Verifier;
- 设置硬性停止条件;
- 不把未经验证的反思直接写入长期记忆。
Self-Refine、Reflexion、Critic Agent、Debate 和 LATS 提供的是不同深度的反馈机制。它们有用,但都会增加成本,也都不能替代真实环境、测试、权威数据和人工责任。
参考资料¶
本章的参考资料、阅读建议与来源说明见集中参考资料章节。