第 4 章:反思

反思模式概述

在前面的章节中,我们探讨了基础的Agent模式:顺序执行的链式、动态路径选择的路由以及并发任务执行的并行化。这些模式使Agent能够更高效、更灵活地执行复杂任务。然而,即使采用复杂的工作流,Agent的初始输出或计划也可能并非最优、准确或完整。这正是反思模式发挥关键作用之处。

反思模式涉及 Agent 评估其自身工作、输出或内部状态,并利用该评估来提升性能或优化响应。这是一种自我纠正或自我改进机制,允许 Agent 基于反馈、内部评审或与预期标准的对比,迭代优化其输出或调整策略。反思有时可由专门的 Agent 来促进,其特定职责是分析初始 Agent 的输出。

与简单顺序链(输出直接传递至下一步)或路径选择的路由不同,反思引入了反馈循环。Agent不仅产生输出,还会检查该输出(或其生成过程),识别潜在问题或改进空间,并运用这些洞察生成优化版本或调整后续行动。

该过程通常包含以下步骤:

  1. 执行: Agent 执行任务或生成初始输出
  2. 评估/评审: Agent(通常通过另一个 LLM 调用或规则集)分析上一步结果。此评估可能涉及事实准确性、连贯性、风格、完整性、指令遵循度或其他相关标准
  3. 反思/优化: 基于评审意见,Agent 确定改进方向。这可能包括生成优化后的输出、调整后续步骤参数,甚至修改整体计划
  4. 迭代(可选但常见): 优化后的输出或调整后的方法可继续执行,反思过程可重复进行,直至获得满意结果或达到停止条件

反思模式的关键高效实现是将流程分离为两个逻辑角色:生产者和评审者。这通常称为”生成器-评审者”或”生产者-审查者”模型。虽然单个Agent可执行自我反思,但使用两个专门Agent(或两个不同系统提示的独立LLM调用)通常产生更稳健客观的结果。

  1. 生产者 Agent:此 Agent 的主要职责是执行任务的初始工作。它完全专注于内容生成,无论是编写代码、起草博客文章还是制定计划。它接收初始提示并生成输出的第一版

  2. 评审者 Agent:此 Agent 的唯一目的是评估生产者生成的输出。它被赋予不同的指令集,通常承担特定角色(如”高级软件工程师”、”严谨的事实核查员”)。评审者的指令引导其根据特定标准分析生产者工作,包括事实准确性、代码质量、风格要求或完整性。其设计目标是发现缺陷、提出改进建议并提供结构化反馈

这种关注点分离有效避免了Agent审查自身工作时可能产生的”认知偏差”。评审者Agent以全新视角处理输出,专注于发现错误和改进空间。其反馈传回生产者Agent,生产者以此为指南生成优化版本。LangChain和ADK代码示例均实现这种双Agent模型:LangChain使用特定”reflector_prompt”创建评审者角色,而ADK明确定义生产者和审查者Agent。

实现反思需要在Agent工作流中构建反馈循环,可通过迭代循环或支持状态管理的框架实现。虽然单步评估优化可在LangChain/LangGraph、ADK或Crew.AI链中完成,但真正的迭代反思通常涉及更复杂编排。

反思模式对于构建高质量输出、处理精细任务并展现自我适应性的Agent至关重要。它推动Agent从单纯执行指令转向更复杂的问题解决和内容生成。

值得注意的是反思与目标设定和监控(见第11章)的交叉点。目标为Agent自我评估提供最终基准,监控跟踪其进展。实践中,反思常充当纠正引擎,利用监控反馈分析偏差并调整策略。这种协同使Agent从被动执行者转变为有目的的自适应工作体。

当LLM保持对话记忆(见第8章)时,反思模式有效性显著增强。对话历史提供关键上下文,使Agent能在先前交互和用户反馈背景下评估输出。没有记忆时,反思是独立事件;有了记忆,反思成为累积过程,每个周期基于前一个,实现更智能的上下文感知优化。

实际应用与用例

反思模式在输出质量、准确性或复杂约束遵循度至关重要的场景中极具价值:

  1. 创意写作与内容生成: 优化生成的文本、故事、诗歌或营销文案
  1. 代码生成与调试: 编写代码、识别错误并进行修复
  1. 复杂问题解决: 评估多步推理任务中的中间步骤或建议方案
  1. 摘要与信息综合: 优化摘要的准确性、完整性和简洁性
  1. 规划与策略: 评估提议计划并识别潜在缺陷或改进点
  1. 对话 Agent: 审查对话历史轮次以保持上下文、纠正误解或提升响应质量

反思为 Agent 系统增加了元认知层,使其能从自身输出和过程中学习,从而产生更智能、可靠和高质量的结果

实操代码示例(LangChain)

实现完整的迭代反思过程需要状态管理和循环执行机制。虽然这些在基于图的框架(如 LangGraph)中内置处理或通过自定义程序代码实现,但单个反思周期的基本原理可通过 LCEL(LangChain 表达式语言)的组合语法有效演示。

此示例使用 Langchain 库和 OpenAI 的 GPT-4o 模型实现反思循环,迭代生成并优化计算数字阶乘的 Python 函数。该过程从任务提示开始,生成初始代码,然后基于模拟高级软件工程师角色的评审反复反思代码,在每次迭代中优化代码,直至评审阶段确认代码完美或达到最大迭代次数。最后打印优化后的代码。

首先确保安装必要库:

1
pip install langchain langchain-community langchain-openai

您还需要使用所选语言模型的 API 密钥配置环境(如 OpenAI、Google Gemini、Anthropic)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage

## --- 配置 ---
## 从 .env 文件加载环境变量(用于 OPENAI_API_KEY)
load_dotenv()

## 检查是否设置了 API 密钥
if not os.getenv("OPENAI_API_KEY"):
    raise ValueError("在 .env 文件中未找到 OPENAI_API_KEY。请添加它。")

## 初始化聊天 LLM。我们使用 gpt-4o 以获得更好的推理。
## 使用较低的温度以获得更确定性的输出。
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)

def run_reflection_loop():
    """
    演示多步 AI 反思循环以逐步改进 Python 函数。
    """
    # --- 核心任务 ---
    task_prompt = """
    你的任务是创建一个名为 `calculate_factorial` 的 Python 函数。
    此函数应执行以下操作:
    1. 接受单个整数 `n` 作为输入。
    2. 计算其阶乘 (n!)。
    3. 包含清楚解释函数功能的文档字符串。
    4. 处理边缘情况:0 的阶乘是 1。
    5. 处理无效输入:如果输入是负数,则引发 ValueError。
    """
    
    # --- 反思循环 ---
    max_iterations = 3
    current_code = ""
    
    # 我们将构建对话历史以在每一步中提供上下文。
    message_history = [HumanMessage(content=task_prompt)]
    
    for i in range(max_iterations):
        print("\n" + "="*25 + f" 反思循环:迭代 {i + 1} " + "="*25)
        
        # --- 1. 生成/完善阶段 ---
        # 在第一次迭代中,它生成。在后续迭代中,它完善。
        if i == 0:
            print("\n>>> 阶段 1:生成初始代码...")
            # 第一条消息只是任务提示词。
            response = llm.invoke(message_history)
            current_code = response.content
        else:
            print("\n>>> 阶段 1:基于先前批评完善代码...")
            # 消息历史现在包含任务、
            # 最后一个代码和最后一个批评。
            # 我们指示模型应用批评。
            message_history.append(HumanMessage(content="请使用提供的批评完善代码。"))
            response = llm.invoke(message_history)
            current_code = response.content
        
        print("\n--- 生成的代码 (v" + str(i + 1) + ") ---\n" + current_code)
        message_history.append(response) # 将生成的代码添加到历史记录
        
        # --- 2. 反思阶段 ---
        print("\n>>> 阶段 2:对生成的代码进行反思...")
        # 为反思 Agent 创建特定提示词。
        # 这要求模型充当高级代码审查员。
        reflector_prompt = [
            SystemMessage(content="""
                你是一名高级软件工程师和 Python 专家。
                你的角色是执行细致的代码审查。
                根据原始任务要求批判性地评估提供的 Python 代码。
                查找错误、风格问题、缺失的边缘情况和改进领域。
                如果代码完美并满足所有要求,
                用单一短语 'CODE_IS_PERFECT' 响应。
                否则,提供批评的项目符号列表。
            """),
            HumanMessage(content=f"原始任务:\n{task_prompt}\n\n要审查的代码:\n{current_code}")
        ]
        
        critique_response = llm.invoke(reflector_prompt)
        critique = critique_response.content
        
        # --- 3. 停止条件 ---
        if "CODE_IS_PERFECT" in critique:
            print("\n--- 批评 ---\n未发现进一步批评。代码令人满意。")
            break
        
        print("\n--- 批评 ---\n" + critique)
        
        # 将批评添加到历史记录以用于下一个完善循环。
        message_history.append(HumanMessage(content=f"对先前代码的批评:\n{critique}"))
    
    print("\n" + "="*30 + " 最终结果 " + "="*30)
    print("\n反思过程后的最终精炼代码:\n")
    print(current_code)

if __name__ == "__main__":
    run_reflection_loop()

代码首先设置环境,加载 API 密钥,并使用低温度初始化强大的语言模型(如 GPT-4o)以获得专注输出。核心任务由提示定义,要求创建计算数字阶乘的 Python 函数,包括文档字符串、边界情况(0 的阶乘)和负输入错误处理的特定要求。run_reflection_loop 函数协调迭代优化过程。在循环中,第一次迭代时语言模型根据任务提示生成初始代码,后续迭代中则基于前一步的评审优化代码。单独的”反思者”角色(同样由语言模型扮演但使用不同系统提示)充当高级软件工程师,根据原始任务要求评审生成的代码。此评审以问题项目符号列表或短语 ‘CODE_IS_PERFECT’(如无问题)形式提供。循环持续至评审指示代码完美或达到最大迭代次数。对话历史被维护并在每一步传递给语言模型,为生成/优化和反思阶段提供上下文。最后,脚本在循环结束后打印最终生成的代码版本

实操代码示例(ADK)

现在让我们看一个使用 Google ADK 实现的概念性代码示例。具体而言,代码通过采用生成器-评审者结构来展示,其中一个组件(生成器)产生初始结果或计划,另一个组件(评审者)提供批判性反馈或评审,引导生成器朝向更优化或准确的最终输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from google.adk.agents import SequentialAgent, LlmAgent

## 第一个 Agent 生成初始草稿。
generator = LlmAgent(
    name="DraftWriter",
    description="生成关于给定主题的初始草稿内容。",
    instruction="撰写关于用户主题的简短、信息丰富的段落。",
    output_key="draft_text" # 输出保存到此状态键。
)

## 第二个 Agent 评审第一个 Agent 的草稿。
reviewer = LlmAgent(
    name="FactChecker",
    description="审查给定文本的事实准确性并提供结构化评审。",
    instruction="""
    你是一个细致的事实核查员。
    1. 阅读状态键 'draft_text' 中提供的文本。
    2. 仔细验证所有声明的事实准确性。
    3. 你的最终输出必须是包含两个键的字典:
       - "status": 字符串,"ACCURATE" 或 "INACCURATE"。
       - "reasoning": 字符串,提供对你的状态的清楚解释,如果发现任何问题则引用具体问题。
    """,
    output_key="review_output" # 结构化字典保存在这里。
)

## SequentialAgent 确保生成器在审查者之前运行。
review_pipeline = SequentialAgent(
    name="WriteAndReview_Pipeline",
    sub_agents=[generator, reviewer]
)

## 执行流程:
## 1. generator 运行 -> 将其段落保存到 state['draft_text']。
## 2. reviewer 运行 -> 读取 state['draft_text'] 并将其字典输出保存到 state['review_output']。

此代码演示了在 Google ADK 中使用顺序 Agent 管道生成和审查文本。它定义了两个 LlmAgent 实例:generator 和 reviewer。generator Agent 设计用于创建关于给定主题的初始草稿段落,被指示撰写简短信息丰富的文章,并将其输出保存至状态键 draft_text。reviewer Agent 作为生成器产出文本的事实核查员,被指示从 draft_text 读取文本并验证其事实准确性。评审者的输出是包含两个键的结构化字典:status 和 reasoning。status 指示文本为”ACCURATE”或”INACCURATE”,reasoning 则提供状态解释。此字典保存至状态键 review_output。创建名为 review_pipeline 的 SequentialAgent 来管理两个 Agent 的执行顺序,确保生成器先运行,然后是评审者。整体执行流程为:生成器产出文本并保存至状态,随后评审者从状态读取文本,执行事实核查,并将其发现(状态和推理)保存回状态。此管道允许使用独立 Agent 进行结构化内容创建和审查过程。注意: 对于感兴趣者,还提供了利用 ADK 的 LoopAgent 的替代实现。

结束前需考虑,虽然反思模式显著提升输出质量,但也带来重要权衡。迭代过程虽强大,但可能导致更高成本和延迟,因为每个优化循环可能需要新的 LLM 调用,使其对时间敏感应用并非最优选择。此外,该模式内存密集;随着每次迭代,对话历史扩展,包含初始输出、评审和后续优化

概览

是什么: Agent 的初始输出通常次优,存在不准确、不完整或未满足复杂要求的问题。基础 Agent 工作流缺乏 Agent 识别和修复自身错误的内置流程。这通过让 Agent 评估自身工作,或更稳健地引入独立逻辑 Agent 充当评审者来解决,防止无论质量如何初始响应都成为最终结果

为什么: 反思模式通过引入自我纠正和优化机制提供解决方案。它建立反馈循环,其中”生产者” Agent 生成输出,然后”评审者” Agent(或生产者自身)根据预定义标准进行评估。随后使用此评审生成改进版本。这种生成、评估和优化的迭代过程逐步提升最终结果质量,从而产生更准确、连贯和可靠的结果

经验法则: 当最终输出的质量、准确性和细节比速度和成本更重要时使用反思模式。它对生成精炼长篇内容、编写调试代码以及创建详细计划等任务特别有效。当任务需要通用生产者 Agent 可能遗漏的高客观性或专门评估时,使用独立评审者 Agent

视觉摘要

图 1:反思设计模式,自我反思

图 2:反思设计模式,生产者和评审者 Agent

关键要点

结论

反思模式为 Agent 工作流中的自我纠正提供关键机制,实现超越单次执行的迭代改进。这是通过创建循环实现的:系统生成输出,根据特定标准评估,然后使用该评估产生优化结果。此评估可由 Agent 自身(自我反思)执行,或通常更有效地由不同评审者 Agent 执行,这代表了模式内的关键架构选择

虽然完全自主的多步反思过程需要强大的状态管理架构,但其核心原理可在单个生成-评审-优化周期中有效演示。作为控制结构,反思可与其他基础模式集成,以构建更健壮和功能更复杂的 Agent 系统

参考文献

以下是有关反思模式和相关概念的一些进一步阅读资源:

  1. Training Language Models to Self-Correct via Reinforcement Learning, https://arxiv.org/abs/2409.12917
  2. LangChain Expression Language (LCEL) Documentation: https://python.langchain.com/docs/introduction/
  3. LangGraph Documentation:https://www.langchain.com/langgraph
  4. Google Agent Developer Kit (ADK) Documentation (Multi-Agent Systems): https://google.github.io/adk-docs/agents/multi-agents/