[智能体设计模式] 第4章:反思(Reflection)
目录
反思模式:智能体自我优化核心机制
典型流程
核心实现模型:生成者-批评者
实践应用与场景
1. 创意写作与内容生成
2. 代码生成与调试
3. 复杂问题求解
4. 摘要与信息整合
5. 规划与策略制定
6. 对话智能体
实战代码示例(LangChain)
代码解析
反思模式:智能体自我优化核心机制
即使拥有复杂的工作流,智能体的初始输出或计划也可能并不理想、准确或完整。这时,反思(Reflection)模式就发挥了作用。
反思模式指的是智能体对自身的工作、输出或内部状态进行评估,并利用评估结果来提升性能或优化响应。这是一种自我纠错或自我改进机制,使智能体能够根据反馈、内部批判或与目标标准的对比,反复优化输出或调整策略。反思有时也可以由专门负责分析初始智能体输出的独立智能体来实现。
典型流程
- 执行:智能体完成任务或生成初始输出。
- 评估/批判:智能体(通常通过另一次LLM调用或规则集)分析上一步结果,检查事实准确性、连贯性、风格、完整性、是否遵循指令等。
- 反思/优化:根据批判结果,智能体决定如何改进,可能生成优化后的输出、调整参数,甚至修改整体计划。
- 迭代(可选但常见):优化后的输出或调整后的方案再次执行,反思过程可重复,直到达到满意结果或满足终止条件。
核心实现模型:生成者-批评者
一种高效的反思实现方式是将流程分为两个逻辑角色,即“生成者-批评者”或“生产者-审阅者”模型。虽然单一智能体可以自我反思,但采用两个专门智能体(或两次LLM调用,分别使用不同系统提示)通常能获得更客观、更结构化的结果。
- 生产者智能体:负责任务的初步执行,专注于内容生成,如编写代码、撰写博客或制定计划。它根据初始提示生成第一版输出。
- 批评者智能体:专门评估生产者生成的输出,拥有不同的指令和角色设定(如“你是一名资深软件工程师”“你是一名严谨的事实核查员”)。批评者根据特定标准(如事实准确性、代码质量、风格要求、完整性等)分析生产者的工作,发现问题、提出改进建议并给出结构化反馈。
实践应用与场景
1. 创意写作与内容生成
优化生成的文本、故事、诗歌或营销文案。
- 应用场景:智能体撰写博客文章。
- 反思过程:生成初稿,批判其流畅度、语气和清晰度,然后根据批判重写。重复直到达到质量标准。
- 优势:产出更精致、更有效的内容。
2. 代码生成与调试
编写代码、发现错误并修复。
- 应用场景:智能体编写Python函数。
- 反思过程:编写初始代码,运行测试或静态分析,发现错误或低效之处,然后根据发现修改代码。
- 优势:生成更健壮、功能更完善的代码。
3. 复杂问题求解
在多步推理任务中评估中间步骤或方案。
- 应用场景:智能体解逻辑谜题。
- 反思过程:提出一步方案,评估是否更接近解决方案或引入矛盾,如有问题则回溯或选择其他步骤。
- 优势:提升智能体在复杂问题空间中的导航能力。
4. 摘要与信息整合
优化摘要的准确性、完整性和简洁性。
- 应用场景:智能体总结长文档。
- 反思过程:生成初步摘要,与原文关键点对比,优化摘要以补充遗漏信息或提升准确性。
- 优势:生成更准确、全面的摘要。
5. 规划与策略制定
评估方案并发现潜在缺陷或改进点。
- 应用场景:智能体制定达成目标的行动计划。
- 反思过程:生成计划,模拟执行或根据约束评估可行性,依据评估结果修订计划。
- 优势:制定更有效、现实的方案。
6. 对话智能体
回顾对话历史,保持上下文、纠正误解或提升响应质量。
- 应用场景:客服聊天机器人。
- 反思过程:用户回复后,回顾对话历史和上一条消息,确保连贯性并准确回应用户最新输入。
- 优势:实现更自然、更有效的对话。
实战代码示例(LangChain)
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 key 是否设置
if not os.getenv("OPENAI_API_KEY"):raise ValueError("OPENAI_API_KEY 未在 .env 文件中找到,请添加。")# 初始化 Chat 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. 包含清晰的 docstring,说明函数功能。4. 处理边界情况:0 的阶乘为 1。5. 处理无效输入:若输入为负数则抛出 ValueError。"""# --- 反思循环 ---max_iterations = 3current_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.contentelse:print("\n>>> 阶段 1:根据批判优化代码...")# 消息历史包含任务、上次代码和批判# 指示模型应用批判意见优化代码message_history.append(HumanMessage(content="请根据批判意见优化代码。"))response = llm.invoke(message_history)current_code = response.contentprint("\n--- 生成代码(第 " + str(i + 1) + " 版)---\n" + current_code)message_history.append(response) # 将生成代码加入历史# --- 2. 反思阶段 ---print("\n>>> 阶段 2:对生成代码进行反思...")# 为批判者 Agent 创建专用提示# 要求模型以资深代码审查员身份批判代码reflector_prompt = [SystemMessage(content="""你是一名资深软件工程师,精通 Python。你的职责是对提供的 Python 代码进行细致代码审查。请根据原始任务要求,严格评估代码。检查是否有 bug、风格问题、遗漏边界情况及其他可改进之处。若代码完美且满足所有要求,仅回复 '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 未发现进一步批判,代码已达要求。")breakprint("\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 key加载和强大语言模型初始化(如GPT-4o,低温度保证输出专注)。核心任务通过提示定义,要求编写一个计算阶乘的Python函数,需包含docstring、边界处理(0的阶乘)、负数报错等。
run_reflection_loop函数负责迭代优化流程:
- 循环中,首次迭代根据任务提示生成代码,后续迭代根据上一步批判意见优化代码;
- 批判角色(同样由语言模型扮演,但系统提示不同)以资深工程师身份,针对原始任务要求批判生成代码,若无问题则回复
CODE_IS_PERFECT,否则以项目符号列出问题; - 循环直到代码被认定为完美或达到最大迭代次数;
- 每步都维护对话历史,确保生成/优化和反思阶段有完整上下文;
- 最后输出最终优化后的代码版本。
