你让 Agent 帮你完成一个复杂任务:「分析公司最近的销售数据,找出下滑最严重的产品,并给出改进建议。」
Agent 需要做什么?先查询数据库,再分析数据,然后搜索行业趋势,最后生成报告。这不是单步操作,而是一个规划与执行的过程。
问题来了:Agent 如何规划这些步骤?如何决定下一步做什么?如何知道自己做得对不对?
这就是 Agent 规划架构要解决的核心问题。
本文要点
- ReAct 架构:推理与行动的交替循环
- Plan-and-Execute 架构:先规划后执行的分离模式
- Reflexion 架构:基于自我反思的迭代改进
- 三种架构的对比与选型指南
- 代码实现与实战案例
- 论文解读:ReAct (Yao et al., 2022)
一、为什么需要规划架构?
1.1 单步决策的局限
假设你让 Agent「帮我订一张明天去上海的机票」,如果只用简单的 Function Calling:
用户:帮我订一张明天去上海的机票 ↓LLM:决定调用 book_ticket 工具 ↓执行:book_ticket(destination="上海", date="明天") ↓结果:订票失败——缺少出发地、航班偏好等信息问题: Agent 不知道订票需要哪些信息,也不知道如何获取缺失信息。
1.2 规划架构的价值
规划架构让 Agent 能够:
- 分解任务:把复杂目标拆解为多个子步骤
- 动态调整:根据执行结果调整后续计划
- 自我纠错:发现错误并修正
二、ReAct 架构:推理与行动的交替
2.1 核心思想
ReAct(Reasoning + Acting)是 2022 年由普林斯顿大学和 Google Research 提出的 Agent 架构。核心思想:让 LLM 在「思考」和「行动」之间交替进行。
Thought(思考)→ Action(行动)→ Observation(观察)→ Thought(再思考)→ ...2.2 ReAct 循环详解
2.3 完整示例:市场调研任务
任务:「分析某科技公司 2024 年的市场表现」
=== 第 1 轮 ===Thought: 需要先了解这家公司的基本情况,我应该搜索公司信息Action: search("某科技公司 2024 年财报")Observation: 找到公司 2024 年 Q1-Q4 财报链接
=== 第 2 轮 ===Thought: 有了财报链接,需要读取具体数据Action: read_document("财报链接")Observation: 营收 100 亿(+20%),净利润 15 亿(-5%),研发投入 20 亿(+30%)
=== 第 3 轮 ===Thought: 数据有了,但需要了解行业对比情况Action: search("2024 年科技行业平均增长率")Observation: 行业平均增长 10%,净利润率平均 18%
=== 第 4 轮 ===Thought: 信息足够了,可以总结分析Action: finish("该公司 2024 年营收增长 20%,超过行业平均..."2.4 ReAct 的 Prompt 模板
REACT_PROMPT = """你是一个智能助手,使用 Thought-Action-Observation 循环来完成任务。
可用工具:{tools_description}
使用以下格式:
Thought: 思考下一步应该做什么Action: 工具名称[参数]Observation: 工具执行结果... (重复 Thought/Action/Observation)Thought: 我现在知道最终答案了Final Answer: 最终回答
开始!
任务:{task}"""2.5 ReAct 代码实现
from typing import List, Dict, Anyimport json
class ReActAgent: def __init__(self, llm_client, tools: Dict[str, callable]): self.llm = llm_client self.tools = tools self.max_iterations = 10
def run(self, task: str) -> str: """执行 ReAct 循环""" history = [] tools_desc = self._format_tools()
for i in range(self.max_iterations): # 构建当前上下文 context = self._build_context(task, tools_desc, history)
# LLM 生成下一步 response = self.llm.generate(context)
# 解析 Thought 和 Action thought, action, args = self._parse_response(response) history.append({"thought": thought, "action": action, "args": args})
# 检查是否完成 if action == "finish": return args.get("answer", "")
# 执行工具 if action in self.tools: observation = self.tools[action](**args) history[-1]["observation"] = observation else: history[-1]["observation"] = f"错误:未知工具 {action}"
return "达到最大迭代次数,任务未完成"
def _parse_response(self, response: str): """解析 LLM 响应中的 Thought 和 Action""" lines = response.strip().split("\n") thought = "" action = None args = {}
for line in lines: if line.startswith("Thought:"): thought = line.replace("Thought:", "").strip() elif line.startswith("Action:"): action_part = line.replace("Action:", "").strip() # 解析 Action[参数] if "[" in action_part: action = action_part.split("[")[0] args_str = action_part.split("[")[1].rstrip("]") args = json.loads(args_str) if args_str else {} else: action = action_part elif line.startswith("Final Answer:"): return thought, "finish", {"answer": line.replace("Final Answer:", "").strip()}
return thought, action, args
def _format_tools(self) -> str: """格式化工具描述""" return "\n".join([ f"- {name}: {func.__doc__}" for name, func in self.tools.items() ])
def _build_context(self, task: str, tools_desc: str, history: List[Dict]) -> str: """构建上下文""" context = f"任务:{task}\n\n可用工具:\n{tools_desc}\n\n"
for h in history: context += f"Thought: {h['thought']}\n" context += f"Action: {h['action']}" if h.get('args'): context += f"[{json.dumps(h['args'])}]" context += "\n" if h.get('observation'): context += f"Observation: {h['observation']}\n"
return context
# 使用示例def search_tool(query: str) -> str: """搜索互联网信息""" return f"搜索结果:{query} 的相关信息..."
def calculate_tool(expression: str) -> str: """计算数学表达式""" try: return str(eval(expression)) except: return "计算错误"
agent = ReActAgent( llm_client=openai_client, tools={"search": search_tool, "calculate": calculate_tool})
result = agent.run("某公司去年营收 1000 万,今年增长 20%,计算今年营收")2.6 ReAct 的优势与局限
优势:
- 思考过程透明,可解释性强
- 动态调整策略,适应性强
- 实现简单,易于理解和调试
局限:
- 每步都需要 LLM 推理,成本较高
- 可能陷入无效循环(如反复尝试错误的工具)
- 对于明确可规划的任务,效率不如 Plan-and-Execute
三、Plan-and-Execute 架构:先规划后执行
3.1 核心思想
Plan-and-Execute 将任务分为两个阶段:
- 规划阶段:LLM 生成完整的执行计划
- 执行阶段:按计划逐步执行,失败时可重新规划
3.2 与 ReAct 的区别
| 特性 | ReAct | Plan-and-Execute |
|---|---|---|
| 规划时机 | 每一步动态规划 | 一次性提前规划 |
| 执行方式 | 边思考边执行 | 按计划顺序执行 |
| 调整策略 | 每步可调整 | 失败时重新规划 |
| 适用场景 | 不确定性高的任务 | 结构化明确的任务 |
| Token 消耗 | 较高(每步推理) | 较低(规划后批量执行) |
3.3 Plan-and-Execute 代码实现
from pydantic import BaseModelfrom typing import List, Optional
class PlanStep(BaseModel): """单个计划步骤""" step_id: int description: str tool: str args: dict depends_on: List[int] = [] # 依赖的前置步骤
class Plan(BaseModel): """完整执行计划""" steps: List[PlanStep] expected_output: str
class PlanAndExecuteAgent: def __init__(self, llm_client, tools: Dict[str, callable]): self.llm = llm_client self.tools = tools self.max_replans = 3
def run(self, task: str) -> str: """执行 Plan-and-Execute 流程""" for attempt in range(self.max_replans): # 规划阶段 plan = self._create_plan(task) print(f" 生成的计划:\n{self._format_plan(plan)}")
# 执行阶段 results = {} success = True
for step in plan.steps: # 检查依赖是否满足 if not self._check_dependencies(step, results): success = False break
# 执行步骤 try: result = self.tools[step.tool](**step.args) results[step.step_id] = result print(f"步骤 {step.step_id}: {step.description} -> 成功") except Exception as e: print(f"步骤 {step.step_id} 失败: {e}") success = False break
if success: return self._synthesize_results(plan, results)
print(f" 计划执行失败,尝试重新规划... ({attempt + 1}/{self.max_replans})")
return "任务执行失败,已达到最大重试次数"
def _create_plan(self, task: str) -> Plan: """使用 LLM 生成执行计划""" prompt = f"""你需要为一个任务生成详细的执行计划。
任务:{task}
可用工具:{self._format_tools()}
请以 JSON 格式输出计划,格式如下:{{ "steps": [ {{"step_id": 1, "description": "步骤描述", "tool": "工具名", "args": {{}}, "depends_on": []}} ], "expected_output": "预期输出描述"}}
注意:1. 步骤要有明确的依赖关系2. 每个步骤只调用一个工具3. 参数要具体可执行"""
response = self.llm.generate(prompt) return Plan.parse_raw(response)
def _check_dependencies(self, step: PlanStep, results: Dict) -> bool: """检查步骤依赖是否满足""" return all(dep_id in results for dep_id in step.depends_on)
def _synthesize_results(self, plan: Plan, results: Dict) -> str: """综合所有结果生成最终答案""" prompt = f"""任务:{plan.expected_output}
执行结果:{json.dumps(results, ensure_ascii=False, indent=2)}
请根据以上结果,生成最终答案。""" return self.llm.generate(prompt)
def _format_plan(self, plan: Plan) -> str: """格式化计划输出""" lines = [] for step in plan.steps: deps = f" (依赖: {step.depends_on})" if step.depends_on else "" lines.append(f" {step.step_id}. {step.description} [{step.tool}]{deps}") return "\n".join(lines)
def _format_tools(self) -> str: """格式化工具描述""" return "\n".join([ f"- {name}: {func.__doc__}" for name, func in self.tools.items() ])
# 使用示例def database_query(sql: str) -> str: """执行数据库查询""" return f"查询结果:{sql}"
def web_search(query: str) -> str: """搜索网络信息""" return f"搜索结果:{query}"
def generate_report(data: str) -> str: """生成分析报告""" return f"报告内容:{data}"
agent = PlanAndExecuteAgent( llm_client=openai_client, tools={ "database_query": database_query, "web_search": web_search, "generate_report": generate_report })
result = agent.run("分析公司最近的销售趋势并生成报告")3.4 Plan-and-Execute 输出示例
生成的计划: 1. 查询最近 6 个月的销售数据 [database_query] 2. 搜索行业销售趋势作为对比 [web_search] 3. 生成综合分析报告 [generate_report] (依赖: [1, 2])
步骤 1: 查询最近 6 个月的销售数据 -> 成功步骤 2: 搜索行业销售趋势作为对比 -> 成功步骤 3: 生成综合分析报告 -> 成功
最终结果:根据数据分析,公司销售额...3.5 Plan-and-Execute 的适用场景
适合:
- 任务结构清晰,步骤可预见
- 需要多次执行相同类型的任务
- 对执行效率有要求
不适合:
- 高度不确定性任务(如探索性研究)
- 中间结果可能改变整体策略的任务
四、Reflexion 架构:自我反思与改进
4.1 核心思想
Reflexion(Shinn et al., 2023)在执行循环中加入自我反思环节:
执行 → 评估 → 反思 → 改进策略 → 重新执行核心创新:让 Agent 对自己的输出进行批判性分析,生成”反思文本”指导后续改进。
4.2 Reflexion 的关键组件
4.3 Reflexion 代码实现
from dataclasses import dataclassfrom typing import List, Optional
@dataclassclass Reflection: """反思结果""" attempt: int task: str trajectory: str # 执行轨迹 failure_reason: str # 失败原因 improvement_suggestion: str # 改进建议
class ReflexionAgent: def __init__(self, llm_client, tools: Dict[str, callable]): self.llm = llm_client self.tools = tools self.max_attempts = 3 self.reflections: List[Reflection] = []
def run(self, task: str) -> str: """执行 Reflexion 循环""" for attempt in range(1, self.max_attempts + 1): print(f"\n 尝试 {attempt}/{self.max_attempts}")
# 构建上下文(包含之前的反思) context = self._build_context(task)
# 执行任务 trajectory, result = self._execute(task, context)
# 评估结果 evaluation = self._evaluate(task, result)
if evaluation["success"]: print(f"任务成功完成!") return result
# 生成反思 reflection = self._reflect( attempt=attempt, task=task, trajectory=trajectory, failure_reason=evaluation["reason"] ) self.reflections.append(reflection) print(f" 反思:{reflection.improvement_suggestion}")
print("达到最大尝试次数") return "任务执行失败"
def _execute(self, task: str, context: str) -> tuple: """执行任务并返回轨迹和结果""" # 使用 ReAct 风格执行 trajectory = [] result = ""
prompt = f"""{context}
任务:{task}
请使用 Thought-Action-Observation 格式执行任务。"""
response = self.llm.generate(prompt) trajectory.append(response)
# 解析并执行工具调用 # ... (类似 ReAct 的执行逻辑)
return "\n".join(trajectory), result
def _evaluate(self, task: str, result: str) -> dict: """评估执行结果""" prompt = f"""任务:{task}执行结果:{result}
请评估结果是否成功完成了任务。输出 JSON 格式:{{"success": true/false, "reason": "失败原因(如果失败)", "score": 0-10}}"""
response = self.llm.generate(prompt) return eval(response) # 实际应用中应使用 json.loads
def _reflect(self, attempt: int, task: str, trajectory: str, failure_reason: str) -> Reflection: """生成反思""" prompt = f"""任务:{task}
执行轨迹:{trajectory}
失败原因:{failure_reason}
请分析失败原因并提出改进建议:1. 哪里出了问题?2. 为什么会失败?3. 下次应该如何改进?
输出 JSON 格式:{{"failure_analysis": "...", "improvement_suggestion": "..."}}"""
response = self.llm.generate(prompt) analysis = eval(response)
return Reflection( attempt=attempt, task=task, trajectory=trajectory, failure_reason=failure_reason, improvement_suggestion=analysis["improvement_suggestion"] )
def _build_context(self, task: str) -> str: """构建包含反思的上下文""" context = f"任务:{task}\n\n"
if self.reflections: context += "=== 之前的尝试和反思 ===\n" for r in self.reflections: context += f"尝试 {r.attempt}:\n" context += f"失败原因:{r.failure_reason}\n" context += f"改进建议:{r.improvement_suggestion}\n\n"
return context
# 使用示例agent = ReflexionAgent( llm_client=openai_client, tools={"search": search_tool, "calculate": calculate_tool})
result = agent.run("找出销售额增长最快的产品并分析原因")4.4 Reflexion 执行示例
尝试 1/3Thought: 需要查询销售数据Action: search("公司销售数据 2024")Observation: 找到部分数据,但缺少增长率...评估:失败 - 缺少完整数据
反思:搜索查询不够精确,应该使用更具体的数据库查询工具而非网络搜索
尝试 2/3Thought: 根据反思,应该使用数据库查询获取精确数据Action: database_query("SELECT product, growth_rate FROM sales_2024 ORDER BY growth_rate DESC")Observation: 产品 A 增长率 45%,产品 B 增长率 32%......任务成功完成!4.5 Reflexion 的优势
- 持续改进:每次失败都能学到东西
- 知识积累:反思可以存储为长期记忆
- 提高成功率:论文显示 Reflexion 在多个任务上显著提升成功率
| 任务类型 | 基础成功率 | Reflexion 成功率 |
|---|---|---|
| HumanEval(代码) | 67% | 91% |
| ALFWorld(具身) | 75% | 97% |
| HotPotQA(问答) | 29% | 51% |
五、三种架构对比与选型指南
5.1 架构对比表
| 维度 | ReAct | Plan-and-Execute | Reflexion |
|---|---|---|---|
| 核心思想 | 边思考边行动 | 先规划后执行 | 执行+反思+改进 |
| 规划粒度 | 单步 | 全局 | 单步+迭代 |
| 执行方式 | 串行 | 可并行 | 迭代优化 |
| Token 消耗 | 高 | 中 | 最高 |
| 成功率 | 中 | 中 | 高 |
| 执行速度 | 慢 | 快 | 最慢 |
| 实现复杂度 | 低 | 中 | 高 |
5.2 控制流程对比
5.3 选型决策树
5.4 场景推荐
使用 ReAct 当: - 任务不确定性高,需要灵活调整 - 需要透明的决策过程 - 资源消耗不是首要考虑
使用 Plan-and-Execute 当: - 任务步骤清晰可预见 - 需要高效执行多个子任务 - 任务可以并行化
使用 Reflexion 当: - 任务质量要求高 - 允许多次迭代尝试 - 可以接受更高的资源消耗5.5 组合使用
实际项目中,三种架构可以组合使用:
class HybridAgent: """混合架构:Plan-and-Execute + Reflexion"""
def __init__(self, llm_client, tools): self.planner = PlanAndExecuteAgent(llm_client, tools) self.reflector = ReflexionAgent(llm_client, tools)
def run(self, task: str) -> str: # 先用 Plan-and-Execute 执行 plan = self.planner.create_plan(task) result = self.planner.execute_plan(plan)
# 评估结果 if self._is_satisfactory(result): return result
# 如果不满意,切换到 Reflexion print("Plan-and-Execute 结果不满意,启用 Reflexion 优化...") return self.reflector.run(task)六、论文解读:ReAct (Yao et al., 2022)
6.1 论文基本信息
- 标题:ReAct: Synergizing Reasoning and Acting in Language Models
- 作者:Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Ishaan Gulrajani, Karthik Narasimhan, Yuan Cao (Princeton University, Google Research)
- 发表:ICLR 2023
- 链接:https://arxiv.org/abs/2210.03629
6.2 核心贡献
1. Reasoning + Acting 融合
论文发现:仅推理(CoT)缺乏外部知识,仅行动缺乏规划能力。ReAct 将两者结合:
纯推理(CoT):用户问题 → 思考 → 思考 → 思考 → 回答问题:可能产生幻觉,缺乏事实依据
纯行动:用户问题 → 行动 → 观察 → 行动 → 观察 → 回答问题:缺乏规划,容易盲目行动
ReAct:用户问题 → 思考 → 行动 → 观察 → 思考 → 行动 → 观察 → 回答优势:有规划、有依据、可解释2. 四种模式对比
论文对比了四种模式:
| 模式 | 描述 | 特点 |
|---|---|---|
| Act-only | 只有行动 | 盲目执行,容易走偏 |
| Reason-only (CoT) | 只有推理 | 产生幻觉,缺乏验证 |
| ReAct | 推理+行动交替 | 平衡规划与执行 |
| ReAct + Retrieval | 增加知识检索 | 增强事实准确性 |
3. 实验结果
在 HotPotQA 和 Fever 两个基准测试上:
关键发现:
- ReAct 单独使用时准确率不高(因为缺乏知识)
- 但 ReAct + Retrieval 组合后大幅提升
- ReAct 的决策过程更透明、可解释
4. 错误分析
论文分析了各模式的错误类型:
Act-only 错误:- 搜索词不精确(31%)- 盲目跟随搜索结果(27%)
CoT 错误:- 事实性幻觉(39%)- 推理链断裂(24%)
ReAct 错误:- 工具调用格式错误(21%)- 搜索策略不当(19%)6.3 论文启示
- 推理和行动应结合:不能偏废
- 外部工具很重要:ReAct 需要配套工具才能发挥最大价值
- 可解释性是优势:思维链让决策过程透明
- 仍有改进空间:Reflexion、工具增强等后续工作
七、实战案例:构建智能调研 Agent
7.1 需求描述
构建一个能完成市场调研任务的 Agent:
- 搜索行业信息
- 分析数据趋势
- 生成调研报告
- 质量检查和优化
7.2 选择架构
分析需求特点:
- 步骤相对明确(搜索→分析→生成)
- 输出质量要求高
- 需要迭代优化
决策:使用 Plan-and-Execute + Reflexion 混合架构
7.3 完整实现
from typing import Dict, List, Anyfrom dataclasses import dataclassimport json
@dataclassclass ResearchTask: """调研任务""" topic: str requirements: List[str] deadline: str = None
@dataclassclass ResearchResult: """调研结果""" summary: str key_findings: List[str] data_sources: List[str] confidence_score: float
class ResearchAgent: """智能调研 Agent"""
def __init__(self, llm_client, tools: Dict[str, callable]): self.llm = llm_client self.tools = tools self.reflections = [] self.max_iterations = 3
def research(self, task: ResearchTask) -> ResearchResult: """执行调研任务""" for iteration in range(self.max_iterations): print(f"\n{'='*50}") print(f"第 {iteration + 1} 轮调研") print(f"{'='*50}")
# 阶段 1:规划 plan = self._plan_research(task) self._print_plan(plan)
# 阶段 2:执行 results = self._execute_plan(plan)
# 阶段 3:综合 draft = self._synthesize_results(task, results)
# 阶段 4:质量检查 evaluation = self._evaluate_quality(task, draft)
if evaluation["score"] >= 8: print(f"\n调研完成!质量评分:{evaluation['score']}/10") return self._format_result(draft, results)
# 阶段 5:反思并改进 reflection = self._reflect_on_failure( task, plan, results, evaluation ) self.reflections.append(reflection) print(f"\n 改进建议:{reflection['improvement']}")
print("\n 达到最大迭代次数,返回最佳结果") return self._format_result(draft, results)
def _plan_research(self, task: ResearchTask) -> List[Dict]: """规划调研步骤""" prompt = f"""你是一个市场调研专家。请为以下任务制定详细的调研计划。
调研主题:{task.topic}具体要求:{json.dumps(task.requirements, ensure_ascii=False)}
可用工具:- search_web: 搜索网络信息- query_database: 查询内部数据库- analyze_data: 分析数据趋势- fetch_report: 获取行业报告
请输出 JSON 格式的计划:[ {{ "step": 1, "action": "工具名称", "params": {{"参数": "值"}}, "purpose": "这步的目的" }}]
注意:根据之前的反思调整计划。当前反思历史:{json.dumps(self.reflections[-1] if self.reflections else {}, ensure_ascii=False)}"""
response = self.llm.generate(prompt) return json.loads(response)
def _execute_plan(self, plan: List[Dict]) -> Dict: """执行调研计划""" results = {}
for step in plan: step_num = step["step"] action = step["action"] params = step["params"] purpose = step["purpose"]
print(f"\n 步骤 {step_num}: {purpose}") print(f" 工具: {action}, 参数: {params}")
try: result = self.tools[action](**params) results[step_num] = { "success": True, "data": result, "purpose": purpose } print(f" 成功") except Exception as e: results[step_num] = { "success": False, "error": str(e), "purpose": purpose } print(f" 失败: {e}")
return results
def _synthesize_results(self, task: ResearchTask, results: Dict) -> str: """综合结果生成报告""" prompt = f"""请根据调研结果生成市场调研报告。
调研主题:{task.topic}具体要求:{json.dumps(task.requirements, ensure_ascii=False)}
调研数据:{json.dumps(results, ensure_ascii=False, indent=2)}
请生成结构化的调研报告,包括:1. 市场概况2. 关键发现3. 数据支撑4. 建议结论"""
return self.llm.generate(prompt)
def _evaluate_quality(self, task: ResearchTask, draft: str) -> Dict: """评估报告质量""" prompt = f"""请评估以下调研报告的质量。
调研主题:{task.topic}具体要求:{json.dumps(task.requirements, ensure_ascii=False)}
报告内容:{draft}
请从以下维度评分(1-10 分):1. 完整性:是否覆盖所有要求?2. 准确性:数据是否可靠?3. 可读性:结构是否清晰?4. 洞察深度:分析是否深入?
输出 JSON:{{ "score": 总分, "completeness": 分数, "accuracy": 分数, "readability": 分数, "insight": 分数, "issues": ["问题1", "问题2"]}}"""
response = self.llm.generate(prompt) return json.loads(response)
def _reflect_on_failure(self, task: ResearchTask, plan: List[Dict], results: Dict, evaluation: Dict) -> Dict: """反思失败原因""" prompt = f"""调研任务未达标,请分析原因并提出改进建议。
任务:{task.topic}计划:{json.dumps(plan, ensure_ascii=False)}结果问题:{json.dumps(evaluation["issues"], ensure_ascii=False)}
请分析:1. 计划是否合理?2. 数据是否充足?3. 分析是否深入?
输出 JSON:{{ "root_cause": "根本原因", "improvement": "改进建议", "next_plan_adjustments": ["调整1", "调整2"]}}"""
response = self.llm.generate(prompt) return json.loads(response)
def _format_result(self, draft: str, results: Dict) -> ResearchResult: """格式化最终结果""" # 提取关键信息 return ResearchResult( summary=draft[:200] + "...", key_findings=[], # 从 draft 中提取 data_sources=[str(k) for k in results.keys()], confidence_score=0.85 )
def _print_plan(self, plan: List[Dict]): """打印计划""" print("\n 调研计划:") for step in plan: print(f" {step['step']}. {step['purpose']} ({step['action']})")
# 使用示例def search_web(query: str) -> str: """搜索网络信息""" return f"搜索结果:{query} 的相关信息..."
def query_database(sql: str) -> str: """查询数据库""" return f"查询结果:{sql}"
def analyze_data(data: str) -> str: """分析数据""" return f"分析结果:{data}"
def fetch_report(industry: str) -> str: """获取行业报告""" return f"报告:{industry} 行业分析"
# 创建 Agentagent = ResearchAgent( llm_client=openai_client, tools={ "search_web": search_web, "query_database": query_database, "analyze_data": analyze_data, "fetch_report": fetch_report })
# 执行调研任务task = ResearchTask( topic="新能源汽车市场趋势分析", requirements=[ "市场规模及增长率", "主要竞争者分析", "技术发展趋势", "政策影响" ])
result = agent.research(task)7.4 执行示例输出
==================================================第 1 轮调研==================================================
调研计划: 1. 获取新能源汽车行业报告 (fetch_report) 2. 搜索市场增长数据 (search_web) 3. 分析竞争格局 (analyze_data) 4. 查询政策信息 (query_database)
步骤 1: 获取新能源汽车行业报告 工具: fetch_report, 参数: {"industry": "新能源汽车"} 成功
步骤 2: 搜索市场增长数据 工具: search_web, 参数: {"query": "2024年新能源汽车市场规模增长率"} 成功
步骤 3: 分析竞争格局 工具: analyze_data, 参数: {"data": "前两步的数据"} 成功
步骤 4: 查询政策信息 工具: query_database, 参数: {"sql": "SELECT * FROM policies WHERE industry='新能源汽车'"} 失败: 数据库连接超时
质量评分:6/10- 缺少政策影响分析- 数据来源单一
改进建议:增加政策信息的搜索渠道,不依赖单一数据库
==================================================第 2 轮调研==================================================
调研计划: 1. 获取新能源汽车行业报告 (fetch_report) 2. 搜索市场增长数据 (search_web) 3. 搜索新能源汽车补贴政策 (search_web) ← 调整 4. 分析竞争格局 (analyze_data) ...
调研完成!质量评分:8/10常见问题 FAQ
Q1:ReAct 和 Chain-of-Thought 有什么区别?
A:Chain-of-Thought(思维链)是纯粹的推理,ReAct 是推理 + 行动的结合。CoT 只”想”,ReAct 会”想”也会”做”。
Q2:Plan-and-Execute 的计划失败了怎么办?
A:两种策略:一是重新规划,根据失败原因调整计划;二是回退到 ReAct 模式,动态调整。
Q3:Reflexion 反思多次还是失败怎么办?
A:设置最大迭代次数,多次失败后可以:
- 降低任务复杂度
- 请求人工介入
- 返回部分结果 + 说明
Q4:如何选择合适的架构?
A:
- 简单任务、需要快速响应 → ReAct
- 任务步骤清晰 → Plan-and-Execute
- 质量要求高、可接受多轮迭代 → Reflexion
- 实际项目常组合使用
Q5:这些架构可以和 RAG 结合吗?
A:可以。RAG 作为工具被 Agent 调用。例如在 ReAct 的 Action 步骤中调用 RAG 获取知识,或者在 Plan-and-Execute 的计划中包含 RAG 检索步骤。
小结
Agent 规划架构是 Agent 能力的核心:
| 架构 | 一句话总结 | 适用场景 |
|---|---|---|
| ReAct | 边想边做,灵活适应 | 不确定性高的任务 |
| Plan-and-Execute | 先规划后执行,高效 | 结构化任务 |
| Reflexion | 做完反思,持续改进 | 高质量要求任务 |
选择建议:
- 从 ReAct 开始,理解基本循环
- 需要效率时切换到 Plan-and-Execute
- 需要质量时加入 Reflexion
- 复杂场景组合使用
三种架构不是互斥的,而是互补的。实际项目中,混合使用往往效果最好。
下篇预告
规划架构解决了「怎么做事」的问题,但 Agent 还需要记住之前的对话、拥有专业技能、连接外部数据源。
参考资料
- ReAct: Synergizing Reasoning and Acting in Language Models(Yao et al., 2022)
- Reflexion: Language Agents with Verbal Reinforcement Learning(Shinn et al., 2023)
- Plan-and-Solve: Improving Zero-Shot Chain-of-Thought Reasoning(Wang et al., 2023)
- LangGraph Documentation
- OpenAI Function Calling Guide
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






