AI Agent开发实战⑤|Agent规划系统:从简单规划到自反思的三种模式实战
AI Agent开发实战⑤Agent规划系统从简单规划到自反思的三种模式实战没有规划能力的Agent和鹦鹉学舌没有本质区别——你问一句它答一句不会提前想清楚步骤更不会在出错时自我修正。本文拆解从One-shot到Self-Reflection三种规划模式的演进以及它们各自的适用场景和实测性能。一、为什么Agent需要规划先看一个没有规划的Agent会怎么崩溃用户请帮我把report.txt的内容复制到backup文件夹然后压缩backup文件夹最后发邮件给teamexample.com 无规划Agent直接执行 → 调用read_file(report.txt) ✅ 读取成功 → 调用write_file(backup/report.txt, content) ✅ 复制成功 → 调用compress_folder(backup) ✅ 压缩成功 → 调用send_email(teamexample.com) ❌ 失败附件是什么 问题出在哪Agent在第三步执行完后没有主动去想压缩后的文件在哪里就直接跳到第四步了。有规划的Agent会怎么做规划层输出 步骤1读取report.txt → 结果文件内容共2.3MB 步骤2创建backup文件夹如果不存在→ 结果✅ 步骤3写入backup/report.txt → 结果✅ 步骤4压缩backup文件夹 → 结果backup.zip路径./backup.zip 步骤5发送邮件附件./backup.zip → 结果✅ Agent在第四步完成后主动从工作记忆中读取了压缩文件的路径 这个信息在第五步被正确使用。结论规划的本质是在执行前把步骤、依赖关系、中间产物说清楚让Agent在执行过程中有据可依。二、三种规划模式对比模式核心理念复杂度适用场景One-shot一次性规划先想好全部步骤再执行低简单任务、可预测流程Plan-and-Execute规划-执行分离先规划大纲再逐个执行中多步骤任务、步骤有依赖Self-Reflection自反思执行评估修正迭代优化高容易出错、目标模糊的任务2.1 One-shot模式简单但脆弱原理Agent接收任务后一次性生成完整执行计划然后按顺序执行。classOneShotPlanner:一次性规划器def__init__(self,llm,tools:list):self.llmllm self.tools{t.name:tfortintools}defplan_and_execute(self,task:str)-str:一次性规划 执行# 阶段1一次性生成完整计划plan_responseself.llm.invoke(f 任务{task}可用工具{list(self.tools.keys())}请生成完整的执行计划格式如下 步骤1[工具名] - [参数] - [预期结果] 步骤2[工具名] - [参数] - [预期结果] ... 注意 1. 明确每个步骤依赖哪个前置步骤的结果 2. 检查参数是否完整 3. 考虑可能的失败点和应对方式 )stepsparse_plan(plan_response)# 阶段2顺序执行results{}fori,stepinenumerate(steps):tool_namestep[tool]argsself._resolve_args(step[args],results)iftool_nameinself.tools:resultself.tools[tool_name].execute(**args)results[fstep_{i1}]{tool:tool_name,result:result,expected:step[expected]}else:results[fstep_{i1}]{error:f未知工具{tool_name}}# 汇总结果returnself._summarize(results)优点延迟低一次LLM调用就完成规划执行的前半部分。缺点计划是静态的执行过程中无法根据实际情况调整。实测适用场景任务步骤固定如查天气→判断→回复步骤之间无数据依赖预期结果明确、可预测2.2 Plan-and-Execute模式先想后做原理规划器先生成高层次计划执行器逐个执行每个步骤每步完成后将结果反馈给规划器。classPlanAndExecuteAgent:规划-执行分离Agentdef__init__(self,llm,tools:list,max_steps15):self.llmllm self.plannerOneShotPlanner(llm,tools)# 复用规划器self.tools{t.name:tfortintools}self.max_stepsmax_stepsdefrun(self,task:str)-str:主循环规划 → 执行 → 检查 → 完成/修正planself._create_plan(task)context{task:task,completed:[],failed:[],observations:[]}step_count0whilestep_countself.max_steps:step_count1# 1. 根据当前上下文决定下一步next_stepself._decide_next_step(plan,context)ifnext_stepisNone:# 计划已全部完成break# 2. 执行该步骤resultself._execute_step(next_step,context)# 3. 观察结果更新上下文context[observations].append({step:next_step,result:result,status:successifresult[success]elsefailed})ifnotresult[success]:context[failed].append(next_step)# 4. 评估是否需要调整计划ifself._needs_replan(plan,context):planself._replan(task,plan,context)# 5. 如果当前步骤已完成从计划中移除ifresult[success]:context[completed].append(next_step)returnself._format_final_answer(context)def_decide_next_step(self,plan:list,context:dict)-dict|None:决定下一步执行什么promptf 当前任务{context[task]}完整计划{self._format_plan(plan)}已完成步骤{[s[name]forsincontext[completed]]}失败步骤{[s[name]forsincontext[failed]]}最近执行结果{self._format_observations(context[observations][-3:])}请从计划中选出下一步应该执行的步骤不能是已完成或正在执行的。 如果计划已全部完成返回完成。 decisionself.llm.invoke(prompt)if完成indecision:returnNonereturnself._parse_step_decision(decision,plan)def_needs_replan(self,plan:list,context:dict)-bool:判断是否需要重新规划# 失败步骤超过2个 → 重规划iflen(context[failed])2:returnTrue# 检查是否有步骤因为前置条件不满足而无法执行failed_reasons[obs.get(error,)forobsincontext[observations]ifobs[status]failed]ifany(条件不满足inrforrinfailed_reasons):returnTruereturnFalsePlan-and-Execute vs One-shot 实测对比任务类型One-shot成功率Plan-and-Execute成功率提升简单3步任务87.3%89.1%1.8pp中等5步任务62.1%78.4%16.3pp复杂10步任务41.8%68.2%26.4pp涉及条件分支35.2%71.5%36.3pp结论任务越复杂Plan-and-Execute的优势越大。尤其是涉及条件分支和动态决策的场景One-shot几乎不可用。2.3 Self-Reflection模式边做边想原理Agent不只执行任务还会在执行后评估结果如果没达到预期就自我修正重新来。classSelfReflectingAgent:带自反思的Agentdef__init__(self,llm,tools:list):self.llmllm self.tools{t.name:tfortintools}defrun(self,task:str,max_attempts:int3)-str:带自反思的主循环forattemptinrange(max_attempts):# 阶段1制定计划planself._plan(task,attempt)# 阶段2执行计划executionself._execute(plan)# 阶段3评估执行结果evaluationself._evaluate(task,execution)ifevaluation[passed]:returnevaluation[answer]# 阶段4反思 → 生成修正计划ifattemptmax_attempts-1:reflectionself._reflect(task,plan,execution,evaluation)taskf{task}\n\n反思结果{reflection}# 用反思修正任务描述return任务在最大尝试次数内未能完成def_evaluate(self,task:str,execution:dict)-dict:评估执行是否达到目标evaluation_promptf 评估以下执行结果是否完成了任务。 原始任务{task}执行结果{execution[results]}执行摘要{execution[summary]}请从以下维度评分0-10 1. 完成度是否覆盖了任务的所有方面 2. 准确性结果是否符合任务要求 3. 质量输出是否完整、专业 只有当三项都≥7分时才算通过。 如果不通过请明确指出 - 具体哪里没做好 - 需要补充什么信息 evaluationself.llm.invoke(evaluation_prompt)passedself._parse_evaluation(evaluation)return{passed:passed,details:evaluation}def_reflect(self,task:str,plan:str,execution:dict,evaluation:dict)-str:生成反思和改进建议reflection_promptf 你是Agent的反思模块。请分析为什么任务没有完美完成。 任务{task}执行计划{plan}执行结果{execution[results]}评估反馈{evaluation[details]}请给出 1. 最可能的问题根源具体到哪一步或哪个决策 2. 下一次执行时需要特别注意什么 3. 是否需要调整执行顺序或方法 回复要具体不要泛泛而谈。 returnself.llm.invoke(reflection_prompt)三、三种模式的选型决策任务开始 ↓ 任务有多少个明确步骤 │ ├── 1-2步 → 【One-shot】够用不需要额外开销 │ ├── 3-10步 → 步骤之间有数据依赖 │ ├── 否 → 【One-shot】 │ └── 是 → 【Plan-and-Execute】 │ └── 10步以上 或 目标模糊 → 【Self-Reflection】 或组合Plan-and-Execute 关键节点反思快速参考表指标One-shotPlan-and-ExecuteSelf-Reflection平均步数1-5步3-15步5-30步LLM调用次数1-2次3-10次3n次n反思次数Token消耗低中高成功率复杂任务~42%~68%~82%适合任务类型固定流程多步骤链式探索式/开放式四、实战如何在一行代码内切换规划模式用LangGraph可以轻松组合不同规划策略fromlanggraph.graphimportStateGraph,END# 切换规划模式 # 模式1简单规划One-shotgraphStateGraph(AgentState)graph.add_node(plan,one_shot_planner)graph.add_node(execute,simple_executor)graph.add_edge(plan,execute)graph.add_edge(execute,END)# 模式2Plan-and-Execute规划-执行分离graphStateGraph(AgentState)graph.add_node(planner,high_level_planner)graph.add_node(executor,step_executor)graph.add_node(checker,execution_checker)# 规划 → 执行 → 检查 → 决定下一步graph.add_edge(planner,executor)graph.add_edge(executor,checker)# 检查通过则结束不通过则回到执行graph.add_conditional_edges(checker,should_end,{True:END,False:executor# 重试当前步骤})# 模式3Self-Reflection带反思的循环graphStateGraph(AgentState)graph.add_node(plan,planner_node)graph.add_node(execute,executor_node)graph.add_node(reflect,reflection_node)graph.add_edge(plan,execute)graph.add_edge(execute,reflect)# 反思后决定重试还是结束graph.add_conditional_edges(reflect,should_retry,{True:plan,# 需要重新规划False:END# 完成})# 编译并执行不同模式共用同一个接口compiledgraph.compile()resultcompiled.invoke({task:用户的任务})五、踩坑警示规划系统最常垮在这三个地方踩坑1规划器生成的计划看起来对但执行不了问题LLM生成的计划中引用了不存在的工具或者参数格式不对。解决规划器必须基于真实的工具列表生成不能凭空创造工具。# 在prompt中明确约束PLANNER_PROMPT 你只能使用以下工具不得创造不存在的工具 可用工具每个工具的完整Schema {json.dumps(tool_schemas, indent2, ensure_asciiFalse)} 如果任务无法仅用以上工具完成请如实说明局限性不要虚构工具。 踩坑2Plan-and-Execute陷入执行-重规划死循环问题Agent不断执行→失败→重规划→再执行始终无法完成。解决设置最大重试次数和失败阈值超出后直接告知用户。MAX_RETRY_SAME_STEP2# 同一步骤最多重试2次MAX_TOTAL_FAILURES3# 总失败次数超过3次则终止MAX_REPLAN_COUNT2# 总重规划次数不超过2次踩坑3Self-Reflection的反思质量不稳定问题反思模块有时候给出有用建议有时候反而把问题搞复杂了。解决限制反思的范围不要让Agent过度反思。# 不要让反思模块修改原始任务目标# 反思只针对执行方式不针对任务本身reflection_promptf 请仅反思执行方式和策略不要质疑任务目标本身。 原始任务不可更改{task}执行结果{execution}评估反馈{evaluation}你的反思应该帮助Agent更好地执行任务而不是改变任务。 六、总结规划能力的演进是Agent智能化的核心One-shot一次性想清楚适合简单固定任务Plan-and-Execute先规划后执行适合多步骤有依赖的链式任务Self-Reflection边做边想边改适合目标复杂、容易出错的场景进阶方向可以把三种模式组合使用——Plan-and-Execute处理常规流程关键节点用Self-Reflection评估是否需要调整。下篇文章预告「Agent工业化指南日志、监控、告警与故障自愈的实战架构」——你的Agent在线上跑的时候你真的知道它在干什么吗一套完整的可观测性方案。需要完整规划模式代码和LangGraph配置模板的同学可以看我主页的付费资源专栏。有问题欢迎评论区留言大家一起讨论