from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain.agents import AgentExecutor, create_react_agent from conf import settings # 创建模型 llm = ChatOpenAI( base_url=settings.base_url, api_key=settings.api_key, model=settings.model_name, temperature=0.1 ) # 2.定义工具 @tool def multiply(numbers_str: str) -> int: """用于计算两个整数的乘积。 参数: numbers_str (str): 包含两个整数的字符串,用逗号分隔,例如:"100,25"。 返回: int: 两个整数的乘积。 """ print(f"正在执行乘法: {numbers_str}") try: a_str, b_str = numbers_str.split(',') a = int(a_str.strip()) b = int(b_str.strip()) return a * b except ValueError: return "输入的格式不正确,请确保是两个用逗号分隔的整数,例如:'100,25'" @tool def search_weather(city: str) -> str: """用于查询指定城市的实时天气。""" print(f"正在查询天气: {city}") if "北京" in city: return "北京今天是晴天,气温25摄氏度。" elif "上海" in city: return "上海今天是阴天,有小雨,气温22摄氏度。" else: return f"抱歉,我没有'{city}'的天气信息。" # 将工具列表放入一个变量 tools = [multiply, search_weather] # 3.定义规划器 (Planner) 和执行者 (Executor) 的 Prompt # 3.1 规划器的 Prompt # 规划器的职责是分析用户任务,并将其分解成一系列简单的、可执行的子任务。 planner_prompt = ChatPromptTemplate.from_template( """你是一个任务规划师,你的工作是将用户提出的一个复杂任务分解成一系列清晰、可执行的步骤。 你的输出应该是一个简单的任务列表,每行一个任务。 例子: 用户任务: "请先查上海的天气,然后计算20乘以30。" 任务列表: - 查找上海的天气 - 计算20乘以30的结果 用户任务: {user_input} 任务列表: """ ) # 规划器链,它只负责生成文本化的任务列表 planner_chain = planner_prompt | llm | StrOutputParser() # 3.2 执行者的 Prompt # 执行者的职责是执行单个任务。在这里,我们使用 ReAct 模式作为执行者,因为它能根据任务描述选择并调用正确的工具。 # 注意:我们使用一个简化版的 ReAct Prompt,因为它只需要处理单个任务。 executor_react_prompt_template = """你是一个专业的工具执行者,可以访问以下工具: {tools} 根据你的思考(Thought)决定下一步的行动(Action)。你的行动必须遵循以下格式: Thought: 我需要思考如何完成任务。 Action: [工具名称] Action Input: [工具的输入参数,对于multiply工具,请使用'100,25'这样的格式] 可用的工具名称有: {tool_names} 当你获取了所有必要信息并可以给出最终答案时,请以以下格式结束: Thought: 我已经有了最终答案。 Final Answer: [最终答案] 请执行以下任务: {input} {agent_scratchpad} """ executor_prompt = ChatPromptTemplate.from_template(executor_react_prompt_template) # 4.创建 ReAct Agent 作为执行者 executor_agent = create_react_agent(llm, tools, executor_prompt) executor_executor = AgentExecutor( agent=executor_agent, tools=tools, verbose=True, handle_parsing_errors=True # 启用错误处理,自动重试解析错误 ) # 5.定义并运行规划模式的工作流 def execute_planning_pattern(query: str): print("--- 启动规划模式 ---") # 规划器分解任务 print("\n规划器正在分解任务...") plan = planner_chain.invoke({"user_input": query}) tasks = [task.strip() for task in plan.split('\n') if task.strip()] print("规划器生成的任务列表:") for i, task in enumerate(tasks): print(f" {i + 1}. {task}") # 执行者逐一执行任务 print("\n执行者正在逐一执行任务...") for i, task in enumerate(tasks): print(f"\n--- 执行任务 {i + 1}: {task} ---") executor_executor.invoke({"input": task}) print("\n--- 所有任务执行完毕!---") if __name__ == "__main__": test_query = "请先计算 50 乘以 60 的结果,然后告诉我上海的天气怎么样?" execute_planning_pattern(test_query)