智能体设计范式Plan-and-Solve 范式1 核心思想Plan-and-Solve先规划后执行认为直接单步推理容易遗漏或出错更好的做法是先让模型生成一个完成任务的步骤计划然后逐步执行该计划每步可以调用工具最后汇总结果得到最终答案。2 工作原理规划阶段给模型一个问题要求其输出一个分步计划例如1. 搜索2022世界杯冠军\n2. 搜索该冠军的主教练\n3. 综合信息给出答案。执行阶段遍历计划中的每一步将步骤指令作为提示允许模型调用工具类似 ReAct 单步获得该步骤的结果。综合阶段将所有步骤的中间结果提供给模型让它生成最终答案。3 使用场景复杂的多跳推理问题需要分解为多个子任务。数学应用题、需要多步查询的知识问题。需要遵循固定流程的任务如旅行规划、报告生成。4 优缺点优点全局规划减少盲目试探提高效率。任务步骤清晰便于调试和人工干预。可并行执行无依赖的步骤高级实现。缺点计划可能不完善或错误导致执行偏差。依赖模型规划能力对简单问题反而增加步骤数。缺乏动态调整能力静态计划难以应对意外情况。5 Python 实现importreimportrequestsfromtypingimportListclassAliYunLLM:...# 定义与前文相同# ---------- 工具集 ----------defsearch(query:str)-str:真实搜索使用 DuckDuckGo 免费 APItry:urlfhttps://api.duckduckgo.com/?q{requests.utils.quote(query)}formatjsonresprequests.get(url,timeout5)dataresp.json()# 优先返回“AbstractText”摘要abstractdata.get(AbstractText,)ifabstract:returnabstract# 如果没有摘要尝试取第一个关联主题的文本relateddata.get(RelatedTopics,[])ifrelatedandTextinrelated[0]:returnrelated[0][Text]returnf未找到关于{query}的信息。exceptExceptionase:returnf搜索出错{e}defcalculator(expression:str)-str:try:ifre.match(r^[\d\\-\*/\(\)\.\s]$,expression):returnstr(eval(expression))else:return非法表达式exceptExceptionase:returnf计算错误{e}TOOLS{search:search,calculator:calculator}# ---------- Plan-and-Solve Agent ----------classPlanAndSolveAgent:def__init__(self,llm:AliYunLLM):self.llmllmdef_make_plan(self,question:str)-List[str]:system_prompt(你是一个规划助手。请将用户的问题分解为详细的步骤计划每步应简单明确可单独执行。\n输出格式每行一个步骤以数字加点开头如\n1. 搜索X的信息\n2. 计算Y的值\n3. 结合信息得到最终答案\n请只输出步骤不要其他内容。)plan_textself.llm.generate(question,system_promptsystem_prompt)print(f生成计划\n{plan_text})# 解析步骤提取每行数字开头的文本stepsre.findall(r\d\.\s*(.*),plan_text)returnstepsdef_execute_step(self,step_description:str,context:str)-str:执行单个步骤允许调用工具tool_descriptions(- search(query: str): 搜索互联网。\n- calculator(expression: str): 计算表达式。)system_prompt(你是一个执行助手。你需要完成一个子任务。你可以使用以下工具\nf{tool_descriptions}\n\n输出格式如果需要使用工具请严格按照以下格式\nAction: 工具名\nAction Input: 输入参数\n然后你会收到 Observation之后再给出该步骤的最终结果。\n如果你已经可以得出该步骤的结果请直接输出\nStep Result: 结果内容\n)promptf当前任务{step_description}\nifcontext:promptf已知上下文信息{context}\nprompt请完成这个子任务。# 单步骤内部允许最多2次工具调用for_inrange(2):responseself.llm.generate(prompt,system_promptsystem_prompt)print(f步骤执行输出{response})ifStep Result:inresponse:resultresponse.split(Step Result:)[-1].strip()returnresult# 尝试解析 Actionaction_matchre.search(rAction:\s*(.*),response)input_matchre.search(rAction Input:\s*(.*),response)ifaction_matchandinput_match:actionaction_match.group(1).strip()action_inputinput_match.group(1).strip()ifactioninTOOLS:obsTOOLS[action](action_input)promptf{response}\nObservation:{obs}\ncontinue# 无法解析则直接返回模型的回复作为步骤结果returnresponse.strip()returnresponse.strip()defrun(self,question:str)-str:# 阶段1生成计划stepsself._make_plan(question)ifnotsteps:return无法生成计划。# 阶段2逐步执行step_results[]contextfori,stepinenumerate(steps,1):print(f\n执行步骤{i}:{step})resultself._execute_step(step,context)step_results.append(f步骤{i}结果:{result})contextf步骤{i}结果:{result}\nprint(f步骤{i}结果:{result})# 阶段3综合最终答案summary_prompt(f问题{question}\nf以下是各步骤的执行结果\n\n.join(step_results)\n请结合这些信息给出最终的完整答案。)final_answerself.llm.generate(summary_prompt,system_prompt你是一个总结助手请直接给出最终答案。)returnfinal_answer# ---------- 示例运行 ----------if__name____main__:llmAliYunLLM(api_keyyour-api-key,base_urlhttps://dashscope.aliyuncs.com/api/v1,modelqwen-plus)agentPlanAndSolveAgent(llm)question2022年世界杯冠军的现任主教练是谁answeragent.run(question)print(f\n最终答案{answer})