第4章:反思
实现自我评估和迭代改进机制以增强AI智能体输出质量
第4章:反思
反思模式概述
在前面的章节中,我们探索了基本的智能体模式:用于顺序执行的链接、用于动态路径选择的路由,以及用于并发任务执行的并行化。这些模式使智能体能够更高效、更灵活地执行复杂任务。然而,即使有复杂的工作流,智能体的初始输出或计划也可能不是最优的、准确的或完整的。这就是反思模式发挥作用的地方。
反思模式涉及智能体评估自己的工作、输出或内部状态,并使用该评估来改善其性能或完善其响应。这是一种自我纠正或自我改进的形式,允许智能体基于反馈、内部批评或与期望标准的比较来迭代完善其输出或调整其方法。反思偶尔可以由一个单独的智能体促进,其特定角色是分析初始智能体的输出。
与简单顺序链(输出直接传递给下一步)或路由(选择路径)不同,反思引入了反馈循环。智能体不仅产生输出;它还检查该输出(或生成它的过程),识别潜在问题或改进领域,并使用这些洞察生成更好的版本或修改其未来行动。
该过程通常涉及:
- 执行: 智能体执行任务或生成初始输出。
- 评估/批评: 智能体(通常使用另一个LLM调用或一组规则)分析前一步的结果。此评估可能检查事实准确性、连贯性、风格、完整性、对指令的遵守或其他相关标准。
- 反思/完善: 基于批评,智能体确定如何改进。这可能涉及生成完善的输出、调整后续步骤的参数,甚至修改整体计划。
- 迭代(可选但常见): 然后可以执行完善的输出或调整的方法,反思过程可以重复,直到达到满意的结果或满足停止条件。
反思模式的一个关键且高度有效的实现将过程分为两个不同的逻辑角色:生产者和批评者。这通常被称为"生成器-批评者"或"生产者-审查者"模型。虽然单个智能体可以执行自我反思,但使用两个专门的智能体(或具有不同系统提示的两个独立LLM调用)通常产生更健壮和公正的结果。
-
生产者智能体: 此智能体的主要职责是执行任务的初始执行。它完全专注于生成内容,无论是编写代码、起草博客文章还是创建计划。它接受初始提示并产生输出的第一个版本。
-
批评者智能体: 此智能体的唯一目的是评估生产者生成的输出。它被给予不同的指令集,通常是不同的角色(例如,"你是一名高级软件工程师","你是一名细致的事实检查员")。批评者的指令指导它根据特定标准分析生产者的工作,如事实准确性、代码质量、风格要求或完整性。它被设计为发现缺陷、建议改进并提供结构化反馈。
这种关注点分离是强大的,因为它防止了智能体审查自己工作的"认知偏见"。批评者智能体以全新的视角接近输出,完全专注于发现错误和改进领域。然后批评者的反馈被传递回生产者智能体,生产者使用它作为指导生成输出的新的、完善的版本。提供的LangChain和ADK代码示例都实现了这种双智能体模型:LangChain示例使用特定的"reflector_prompt"创建批评者角色,而ADK示例显式定义生产者和审查者智能体。
实现反思通常需要构建智能体的工作流以包含这些反馈循环。这可以通过代码中的迭代循环实现,或使用支持状态管理和基于评估结果的条件转换的框架。虽然评估和完善的单个步骤可以在LangChain/LangGraph、ADK或Crew.AI链中实现,但真正的迭代反思通常涉及更复杂的编排。
反思模式对于构建能够产生高质量输出、处理细致任务并表现出一定程度的自我意识和适应性的智能体至关重要。它将智能体从简单执行指令推向更复杂的问题解决和内容生成形式。
反思与目标设定和监控(见第11章)的交集值得注意。目标为智能体的自我评估提供最终基准,而监控跟踪其进展。在许多实际情况下,反思然后可能充当纠正引擎,使用监控反馈分析偏差并调整其策略。这种协同作用将智能体从被动执行器转变为有目的的系统,自适应地工作以实现其目标。
此外,当LLM保持对话记忆时(见第8章),反思模式的有效性显著增强。这种对话历史为评估阶段提供关键上下文,允许智能体不仅孤立地评估其输出,而且在前次交互、用户反馈和不断发展的目标的背景下评估。它使智能体能够从过去的批评中学习并避免重复错误。没有记忆,每次反思都是自包含的事件;有了记忆,反思成为累积过程,每个周期都建立在前一个之上,导致更智能和上下文感知的完善。
实际应用和用例
反思模式在输出质量、准确性或对复杂约束的遵守至关重要的场景中很有价值:
- 创意写作和内容生成:
完善生成的文本、故事、诗歌或营销文案。
- 用例: 撰写博客文章的智能体。
- 反思: 生成草稿,批评其流程、语调和清晰度,然后基于批评重写。重复直到文章达到质量标准。
- 好处: 产生更精致和有效的内容。
- 代码生成和调试:
编写代码、识别错误并修复它们。
- 用例: 编写Python函数的智能体。
- 反思: 编写初始代码,运行测试或静态分析,识别错误或低效,然后基于发现修改代码。
- 好处: 生成更健壮和功能的代码。
- 复杂问题解决:
在多步推理任务中评估中间步骤或提议的解决方案。
- 用例: 解决逻辑谜题的智能体。
- 反思: 提议步骤,评估它是否更接近解决方案或引入矛盾,如果需要则回溯或选择不同步骤。
- 好处: 提高智能体导航复杂问题空间的能力。
- 总结和信息综合:
完善摘要的准确性、完整性和简洁性。
- 用例: 总结长文档的智能体。
- 反思: 生成初始摘要,与原始文档的关键点比较,完善摘要以包含缺失信息或提高准确性。
- 好处: 创建更准确和全面的摘要。
- 规划和策略:
评估提议的计划并识别潜在缺陷或改进。
- 用例: 规划一系列行动以实现目标的智能体。
- 反思: 生成计划,模拟其执行或根据约束评估其可行性,基于评估修订计划。
- 好处: 制定更有效和现实的计划。
- 对话智能体:
审查对话中的先前轮次以维护上下文、纠正误解或改善响应质量。
- 用例: 客户支持聊天机器人。
- 反思: 在用户响应后,审查对话历史和最后生成的消息以确保连贯性并准确回应用户的最新输入。
- 好处: 导致更自然和有效的对话。
反思为智能体系统添加了元认知层,使它们能够从自己的输出和过程中学习,导致更智能、可靠和高质量的结果。
实践代码示例(LangChain)
完整迭代反思过程的实现需要状态管理和循环执行的机制。虽然这些在基于图的框架(如LangGraph)中或通过自定义程序代码原生处理,但单个反思周期的基本原理可以使用LCEL(LangChain Expression Language)的组合语法有效演示。
此示例使用Langchain库和OpenAI的GPT-4o模型实现反思循环,迭代生成和完善计算数字阶乘的Python函数。过程从任务提示开始,生成初始代码,然后基于模拟高级软件工程师角色的批评反复反思代码,在每次迭代中完善代码,直到批评阶段确定代码完美或达到最大迭代次数。最后,它打印结果完善的代码。
首先,确保安装了必要的库:
pip install langchain langchain-community langchain-openai您还需要设置环境,使用您选择的语言模型的API密钥(如OpenAI、Google Gemini、Anthropic)。
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: 反思生成的代码...")
# 为反射器智能体创建特定提示。
# 这要求模型充当高级代码审查员。
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实现的概念代码示例。具体来说,代码通过采用生成器-批评者结构来展示这一点,其中一个组件(生成器)产生初始结果或计划,另一个组件(批评者)提供关键反馈或批评,指导生成器朝着更完善或准确的最终输出。
from google.adk.agents import SequentialAgent, LlmAgent
# 第一个智能体生成初始草稿。
generator = LlmAgent(
name="DraftWriter",
description="在给定主题上生成初始草稿内容。",
instruction="写一个关于用户主题的简短、信息丰富的段落。",
output_key="draft_text" # 输出保存到此状态键。
)
# 第二个智能体批评第一个智能体的草稿。
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中使用顺序智能体管道生成和审查文本。它定义了两个LlmAgent实例:generator和reviewer。生成器智能体设计为在给定主题上创建初始草稿段落。它被指示写一个简短和信息丰富的作品,并将其输出保存到状态键draft_text。审查者智能体充当生成器产生的文本的事实检查员。它被指示从draft_text读取文本并验证其事实准确性。审查者的输出是一个包含两个键的结构化字典:status和reasoning。status指示文本是"ACCURATE"还是"INACCURATE",而reasoning为状态提供解释。此字典保存到状态键review_output。创建名为review_pipeline的SequentialAgent来管理两个智能体的执行顺序。它确保生成器首先运行,然后是审查者。整体执行流程是生成器产生文本,然后保存到状态。随后,审查者从状态读取此文本,执行其事实检查,并将其发现(状态和推理)保存回状态。此管道允许使用单独智能体进行内容创建和审查的结构化过程。注意: 对于感兴趣的人,也提供了利用ADK的LoopAgent的替代实现。
在结束之前,重要的是要考虑虽然反思模式显著增强了输出质量,但它带来了重要的权衡。迭代过程虽然强大,但可能导致更高的成本和延迟,因为每个完善循环可能需要新的LLM调用,使其对时间敏感的应用程序不是最优的。此外,该模式是内存密集的;每次迭代,对话历史都会扩展,包括初始输出、批评和后续完善。
一览
什么: 智能体的初始输出通常不是最优的,存在不准确、不完整或未能满足复杂要求的问题。基本智能体工作流缺乏内置过程让智能体识别和修复自己的错误。这通过让智能体评估自己的工作或更健壮地引入单独的智能体充当批评者来解决,防止初始响应成为最终响应,无论质量如何。
为什么: 反思模式通过引入自我纠正和完善机制提供解决方案。它建立了一个反馈循环,其中"生产者"智能体生成输出,然后"批评者"智能体(或生产者本身)根据预定义标准评估它。然后此批评用于生成改进版本。这种生成、评估和完善的迭代过程逐步增强最终结果的质量,导致更准确、连贯和可靠的结果。
经验法则: 当最终输出的质量、准确性和细节比速度和成本更重要时使用反思模式。它对于生成精致的长篇内容、编写和调试代码以及创建详细计划特别有效。当任务需要高客观性或专门评估(通用生产者智能体可能错过)时,使用单独的批评者智能体。
视觉总结

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

图2:反思设计模式,生产者和批评者智能体
关键要点
- 反思模式的主要优势是其迭代自我纠正和完善输出的能力,导致显著更高的质量、准确性和对复杂指令的遵守。
- 它涉及执行、评估/批评和完善的反馈循环。反思对于需要高质量、准确或细致输出的任务至关重要。
- 强大的实现是生产者-批评者模型,其中单独的智能体(或提示角色)评估初始输出。这种关注点分离增强了客观性并允许更专门、结构化的反馈。
- 然而,这些好处以增加的延迟和计算费用为代价,以及超过模型上下文窗口或被API服务限制的更高风险。
- 虽然完整的迭代反思通常需要有状态工作流(如LangGraph),但单个反思步骤可以在LangChain中使用LCEL实现,将输出传递给批评和后续完善。
- Google ADK可以通过顺序工作流促进反思,其中一个智能体的输出被另一个智能体批评,允许后续完善步骤。
- 此模式使智能体能够执行自我纠正并随时间增强其性能。
结论
反思模式为智能体工作流内的自我纠正提供了关键机制,使迭代改进超越单次执行成为可能。这通过创建系统生成输出、根据特定标准评估它,然后使用该评估产生完善结果的循环来实现。此评估可以由智能体本身(自我反思)或通常更有效地由不同的批评者智能体执行,这代表了模式内的关键架构选择。
虽然完全自主的多步反思过程需要健壮的状态管理架构,但其核心原理在单个生成-批评-完善周期中有效演示。作为控制结构,反思可以与其他基础模式集成以构建更健壮和功能复杂的智能体系统。
参考文献
以下是关于反思模式和相关概念的进一步阅读资源:
- 通过强化学习训练语言模型自我纠正,https://arxiv.org/abs/2409.12917
- LangChain Expression Language(LCEL)文档:https://python.langchain.com/docs/introduction/
- LangGraph文档:https://www.langchain.com/langgraph
- Google Agent Developer Kit(ADK)文档(多智能体系统):https://google.github.io/adk-docs/agents/multi-agents/