当前位置: 首页 > news >正文

智能体设计范式:Plan-and-Solve

智能体设计范式:Plan-and-Solve 范式

1 核心思想

Plan-and-Solve(先规划后执行)认为直接单步推理容易遗漏或出错,更好的做法是先让模型生成一个完成任务的步骤计划,然后逐步执行该计划,每步可以调用工具,最后汇总结果得到最终答案。

2 工作原理

  1. 规划阶段:给模型一个问题,要求其输出一个分步计划(例如1. 搜索2022世界杯冠军\n2. 搜索该冠军的主教练\n3. 综合信息给出答案)。
  2. 执行阶段:遍历计划中的每一步,将步骤指令作为提示,允许模型调用工具(类似 ReAct 单步),获得该步骤的结果。
  3. 综合阶段:将所有步骤的中间结果提供给模型,让它生成最终答案。

3 使用场景

  • 复杂的多跳推理问题,需要分解为多个子任务。
  • 数学应用题、需要多步查询的知识问题。
  • 需要遵循固定流程的任务(如旅行规划、报告生成)。

4 优缺点

优点

  • 全局规划减少盲目试探,提高效率。
  • 任务步骤清晰,便于调试和人工干预。
  • 可并行执行无依赖的步骤(高级实现)。

缺点

  • 计划可能不完善或错误,导致执行偏差。
  • 依赖模型规划能力,对简单问题反而增加步骤数。
  • 缺乏动态调整能力(静态计划难以应对意外情况)。

5 Python 实现

importreimportrequestsfromtypingimportListclassAliYunLLM:...# 定义与前文相同# ---------- 工具集 ----------defsearch(query:str)->str:"""真实搜索:使用 DuckDuckGo 免费 API"""try:url=f"https://api.duckduckgo.com/?q={requests.utils.quote(query)}&format=json"resp=requests.get(url,timeout=5)data=resp.json()# 优先返回“AbstractText”摘要abstract=data.get("AbstractText","")ifabstract:returnabstract# 如果没有摘要,尝试取第一个关联主题的文本related=data.get("RelatedTopics",[])ifrelatedand"Text"inrelated[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.llm=llmdef_make_plan(self,question:str)->List[str]:system_prompt=("你是一个规划助手。请将用户的问题分解为详细的步骤计划,每步应简单明确,可单独执行。\n""输出格式:每行一个步骤,以数字加点开头,如:\n""1. 搜索X的信息\n""2. 计算Y的值\n""3. 结合信息得到最终答案\n""请只输出步骤,不要其他内容。")plan_text=self.llm.generate(question,system_prompt=system_prompt)print(f"生成计划:\n{plan_text}")# 解析步骤,提取每行数字开头的文本steps=re.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=("你是一个执行助手。你需要完成一个子任务。你可以使用以下工具:\n"f"{tool_descriptions}\n\n""输出格式:如果需要使用工具,请严格按照以下格式:\n""Action: 工具名\n""Action Input: 输入参数\n""然后你会收到 Observation,之后再给出该步骤的最终结果。\n""如果你已经可以得出该步骤的结果,请直接输出:\n""Step Result: 结果内容\n")prompt=f"当前任务:{step_description}\n"ifcontext:prompt+=f"已知上下文信息:{context}\n"prompt+="请完成这个子任务。"# 单步骤内部允许最多2次工具调用for_inrange(2):response=self.llm.generate(prompt,system_prompt=system_prompt)print(f"步骤执行输出:{response}")if"Step Result:"inresponse:result=response.split("Step Result:")[-1].strip()returnresult# 尝试解析 Actionaction_match=re.search(r"Action:\s*(.*)",response)input_match=re.search(r"Action Input:\s*(.*)",response)ifaction_matchandinput_match:action=action_match.group(1).strip()action_input=input_match.group(1).strip()ifactioninTOOLS:obs=TOOLS[action](action_input)prompt+=f"{response}\nObservation:{obs}\n"continue# 无法解析则直接返回模型的回复作为步骤结果returnresponse.strip()returnresponse.strip()defrun(self,question:str)->str:# 阶段1:生成计划steps=self._make_plan(question)ifnotsteps:return"无法生成计划。"# 阶段2:逐步执行step_results=[]context=""fori,stepinenumerate(steps,1):print(f"\n执行步骤{i}:{step}")result=self._execute_step(step,context)step_results.append(f"步骤{i}结果:{result}")context+=f"步骤{i}结果:{result}\n"print(f"步骤{i}结果:{result}")# 阶段3:综合最终答案summary_prompt=(f"问题:{question}\n"f"以下是各步骤的执行结果:\n"+"\n".join(step_results)+"\n请结合这些信息,给出最终的完整答案。")final_answer=self.llm.generate(summary_prompt,system_prompt="你是一个总结助手,请直接给出最终答案。")returnfinal_answer# ---------- 示例运行 ----------if__name__=="__main__":llm=AliYunLLM(api_key="your-api-key",base_url="https://dashscope.aliyuncs.com/api/v1",model="qwen-plus")agent=PlanAndSolveAgent(llm)question="2022年世界杯冠军的现任主教练是谁?"answer=agent.run(question)print(f"\n最终答案:{answer}")
http://www.jsqmd.com/news/1106244/

相关文章:

  • 16266350800----wLa6twBAf4yVW4gw----dc_sid=b6eb97905a1c240e1675f230d913b6b5;HMACCOUNT=97C7CB558BC7424
  • [RandomRange节点]原理解析与实际应用
  • delete from `后宫佳丽` where age>18
  • Linux网络配置指南
  • H5 到底能不能做视频直播?
  • C++ 纳秒级交易系统设计
  • React路由开发
  • 毕业设计项目 基于深度学习的驾驶行为检测(玩手机)
  • 昇腾AI处理器上下文切换优化实践与性能提升
  • 大众点评23年干了件“蠢”事
  • Go WaitGroup开发实践
  • Unity合批优化:静态与动态合批全解析
  • 报文发送非网络基本功能
  • 冻库低温环境下的机器人搬运技术测评
  • Claude Code 接入第三方模型指南
  • ASP.NET Core 之 Identity 入门(一)
  • React Hooks开发实践
  • 集成,持续交付,持续部署,敏捷开发,DevOps的关系
  • 2026年AI论文软件盘点:12款神器助你高效完成初稿生成、排版和降AI率
  • Android开发转AI Agent:第12天——Function Calling,让LLM从“说话“变成“做事“
  • Spring MVC开发实践教程
  • Python装饰器开发实践
  • step1. 调用摄像头
  • 给阿嬤一封来自云端的信(上)
  • NestJS框架教程
  • STM32与MAX9744实现高效音频放大系统设计
  • 量子计算中的基态制备与经典储层方法解析
  • 终极Win11系统优化指南:免费工具让你的Windows 11运行如飞
  • 游戏编程十年总结(下)
  • AI应用GEO排名优化指南:提升搜索可见性