基于ReAct模式的智能体系统示例
ReActReasoning Acting是让大模型像人类一样“边思考边行动”的提示工程框架。它通过让模型在生成最终答案前先输出推理步骤Reasoning再根据推理调用工具或采取行动Acting来解决复杂问题。ReAct 的核心机制是思考与行动的循环。ReAct 不是一次性输出答案而是构建了一个“思考 → 行动 → 观察 → 再思考” 的循环闭环思考Think模型分析当前状况决定下一步该做什么例如“我需要查询北京的天气来确定穿什么”。行动Act执行决策通常是调用外部工具或 API例如调用search_weather(Beijing)。观察Observe获取工具返回的结果例如“北京今日气温 15°C多云”。循环基于观察结果进行下一轮思考直到问题解决。典型应用场景知识检索先思考关键词再调用搜索工具最后综合信息给出答案。数学计算先制定解题计划再调用计算器工具避免大模型数学计算失误。决策支持在智能体Agent中通过 ReAct 循环决定下一步动作。需求分析构建模块化的工具调用框架下面示例的核心需求是创建一个基于ReActReasoningActing模式的智能体系统使大语言模型能够通过工具调用来解决复杂任务。具体需求包括需要提供一个标准化的工具接口使各种功能函数能够被智能体调用实现一个推理-执行循环让模型在解决问题时能够分步骤思考、调用工具、观察结果需要处理用户输入到最终答案的完整流程包括对模型输出的解析、工具执行和结果整合。代码还需要考虑实际应用中的容错性如工具不存在、参数错误等异常情况。示例中特别展示了对天气查询和百科搜索这两个典型场景的支持体现了系统的实用性。这种架构的需求源于纯语言模型在信息实时性和准确性上的局限需要通过工具来扩展其能力边界。架构设计分层解耦的智能体系统该示例代码采用分层设计理念将系统分为工具层、智能体层和模型适配层。工具层通过Tool类封装功能函数提供统一的接口名称、描述、执行函数这是典型的适配器模式应用。智能体层以ReActAgent为核心实现主要的控制逻辑循环包括提示构建、模型调用、响应解析、工具执行和结果收集采用了模板方法模式来定义算法的骨架。模型适配层通过llm_model回调函数实现将具体的大模型实现与智能体逻辑解耦这是策略模式的应用。设计中特别值得注意的是历史记录机制每次迭代都将思考、行动和结果添加到历史中为下一轮提供上下文这种设计支持了多轮对话和复杂推理。错误处理被分散在各个层级工具级处理执行异常解析级处理格式错误循环级处理超时终止这种分层容错设计提高了系统的鲁棒性。代码实现# -*- coding: utf-8 -*- Created on Tue Jul 1 09:45:23 2025 author: liguo import json from typing import List, Dict, Any, Optional, Callable class Tool: 表示一个可被智能体调用的工具 def __init__(self, name: str, description: str, func: Callable): self.name name self.description description self.func func def run(self, parameters: Dict) - Any: return self.func(**parameters) class ReActAgent: 实现ReasoningActing循环的智能体 def __init__(self, tools: List[Tool], llm_model: Callable): self.tools {tool.name: tool for tool in tools} self.llm_model llm_model self.max_iterations 10 def _parse_llm_response(self, response: str) - Dict: 解析大语言模型的输出提取思考和行动 try: # 简单解析实际应用中可能需要更复杂的解析逻辑 if Thought: in response and Action: in response: thought response.split(Thought:)[1].split(Action:)[0].strip() action_part response.split(Action:)[1].strip() if Action Input: in action_part: action_name action_part.split(Action Input:)[0].strip() action_input_str action_part.split(Action Input:)[1].strip() try: # 尝试解析为JSON action_input json.loads(action_input_str) except json.JSONDecodeError: # 如果不是有效的JSON作为字符串处理 action_input {input: action_input_str} return { thought: thought, action: { name: action_name, parameters: action_input } } except Exception as e: print(f解析LLM响应时出错: {e}) # 默认回退 return { thought: 无法解析行动直接回答, action: None, answer: response } def run(self, query: str) - str: 运行ReAct循环处理用户查询 history [] history.append(f用户查询: {query}) for i in range(self.max_iterations): # 构建提示 prompt \n.join(history) \n思考: # 获取LLM响应 llm_response self.llm_model(prompt) # 解析响应 parsed self._parse_llm_response(llm_response) # 记录思考 history.append(f思考: {parsed[thought]}) # 处理行动 if parsed.get(action): action parsed[action] tool_name action[name] parameters action[parameters] # 记录行动 history.append(f行动: {tool_name}, 参数: {json.dumps(parameters)}) # 执行工具 if tool_name in self.tools: try: result self.tools[tool_name].run(parameters) history.append(f行动结果: {result}) except Exception as e: history.append(f行动执行错误: {str(e)}) result None else: history.append(f错误: 未知工具 {tool_name}) result None else: # 如果没有行动直接返回答案 return parsed.get(answer, 无法生成答案) return 达到最大迭代次数未找到确定答案 # 示例工具实现 def get_weather(city: str) - str: 获取指定城市的天气信息 # 实际应用中这里会调用天气API weather_data { 北京: 晴朗25°C, 上海: 多云28°C, 广州: 小雨27°C } return weather_data.get(city, 未知天气) def search_wikipedia(query: str) - str: 在维基百科上搜索信息 # 实际应用中这里会调用维基百科API # 简化示例返回一些模拟数据 if Python in query: return Python是一种广泛使用的高级编程语言由Guido van Rossum于1989年圣诞节期间创建。 elif 人工智能 in query: return 人工智能是指计算机系统能够执行通常需要人类智能才能完成的任务的能力如视觉感知、语音识别等。 return f关于{query}的信息未找到 # 示例使用 if __name__ __main__: # 定义工具 tools [ Tool(get_weather, 获取指定城市的当前天气, get_weather), Tool(search_wikipedia, 在维基百科上搜索信息, search_wikipedia) ] # 模拟LLM模型 def mock_llm_model(prompt: str) - str: 模拟大语言模型的输出 if 天气 in prompt: return 思考: 用户想了解北京的天气我可以使用get_weather工具获取信息 行动: get_weather Action Input: {city: 北京} elif Python in prompt or 人工智能 in prompt: return 思考: 用户的问题需要百科知识我可以使用search_wikipedia工具查找信息 行动: search_wikipedia Action Input: {query: Python} return 直接回答: 我不知道这个问题的答案 # 创建智能体 agent ReActAgent(tools, mock_llm_model) # 测试运行 weather_query 北京现在的天气如何 print(f查询: {weather_query}) print(f回答: {agent.run(weather_query)}) python_query Python是什么时候创建的 print(f\n查询: {python_query}) print(f回答: {agent.run(python_query)})代码结果C:\Users\xiayu\miniconda3\envs\langgraph\python.exe C:\Users\xiayu\PyCharmMiscProject\AI-Agent-Dev-Practices-Code\第3章代码\3.3-ReAct框架的实现.py查询: 北京现在的天气如何回答: 思考: 用户想了解北京的天气我可以使用get_weather工具获取信息行动: get_weatherAction Input: {city: 北京}查询: Python是什么时候创建的回答: 思考: 用户的问题需要百科知识我可以使用search_wikipedia工具查找信息行动: search_wikipediaAction Input: {query: Python}Process finished with exit code 0代码解析从静态结构到动态流程在具体实现上代码展现了清晰的静态结构和动态执行流程。静态结构上Tool类的__init__方法定义了工具的元信息run方法负责参数解包和函数调用ReActAgent的构造函数建立工具索引设置最大迭代次数。动态流程上run方法实现了完整的ReAct循环首先记录用户查询到历史然后进入最多10次的迭代每次迭代构建包含历史的提示调用大模型解析响应。解析逻辑_parse_llm_response采用字符串分割的简单方法先提取思考部分再尝试提取行动名称和JSON格式的参数最后根据是否有行动决定是执行工具还是直接回答。工具执行时通过工具名索引获取工具对象将参数字典解包传递给工具函数。示例使用中展示了典型的调用链定义工具列表→创建模拟LLM→实例化智能体→执行查询其中模拟LLM根据提示内容返回不同格式的响应演示了从查询到工具调用的完整路径。这种实现虽然简洁但清晰地展示了ReAct模式的核心机制。