大模型核心技术ReAct讲解
一.ReAct基本介绍React 全称是 SynergizingReasoning and Actingin Language Models在语言模型中协同推理与行动由Shunyu Yao等人在2022 年 10 月的论文中提出,React 的设计灵感来源于人类解决复杂问题的思维方式通常会先思考问题、制定计划然后执行具体操作并根据结果调整下一步的思考ReAct 是一个将推理和行为与LLMs相结合通用的范例,ReAct 提示 LLMs 为任务生成口头推理轨迹和操作,这使得系统执行动态推理来创建、维护和调整操作计划同时还支持与外部环境(例如Wikipedia)的交互以将额外信息合并到推理中,下图展示了 ReAct 的一个示例以及执行问题回答所涉及的不同步骤简单来说,ReAct 框架赋予了模型一种“三思而后行”的能力,它的目的是:像人一样解决复杂问题, 它将模型的响应过程分解为三个关键部分Thought (思考):模型首先会分析当前的任务和已有的信息进行内在的推理和规划,它会思考“我需要做什么”、“我缺少什么信息”、“下一步该怎么办”Act (行动):根据“思考”的结果模型会决定并执行一个具体的“行动”,这个行动通常是向外部工具如搜索引擎、数据库、计算器甚至是你代码中的“知识库”发起查询以获取完成任务所需的额外信息Observation (观察):模型接收并“观察”执行“行动”后返回的结果,这个结果会成为下一步“思考”的新依据这个思考 - 行动 - 观察的循环会一直持续直到模型认为自己已经收集到了足够的信息能够完美地回答用户的问题为止特点动态适合需要查询的场景灵活逐步调整二.ReAct案例案例基于 ReAct实现的智能对话系统主要功能是回答关于节假日的问题法处理流程当用户问这个月有几个法定节假日系统会思考需要先知道当前月份行动调用get_current_date获取当前日期观察得到2026年07月15日思考现在查询6月的节假日行动调用search_holidays(07月)观察得到2026年07月没有法定节假日最终回答给出完整答案三.ReAct实现流程1.导入模块导入必要的库大模型API、时间、日期、系统操作2.定义工具函数get_current_date()- 获取当前日期search_holidays()- 查询节假日注册工具到字典中供模型调用3. 大模型交互ChatOllama()- 调用Ollama的通义千问模型获取回答4.解析模型输出parse_model_output()- 解析模型的结构化响应extract_month()- 从文本提取月份信息5. 核心逻辑react_solve()- ReAct主循环控制整个推理流程5步迭代构建上下文→调用模型→解析→执行工具→记录结果6. 执行入口主程序启动传入问题开始推理四.代码实现import time from datetime import datetime import os from langchain_ollama import ChatOllama # 工具1获取当前日期返回格式YYYY年MM月DD日 def get_current_date(): 返回当前日期格式2026年07月15日 now datetime.now() return f{now.year}年{now.month}月{now.day}日 # 工具2查询节假日根据月份查询 def search_holidays(month): 查询指定月份的法定节假日 month: 月份字符串如 7月 # 模拟节假日数据 holidays { 1月: [元旦1月1日], 2月: [春节1月28日-2月3日], 3月: [], 4月: [清明节4月4日-6日], 5月: [劳动节5月1日-5日, 端午节5月31日-6月2日], 6月: [], 7月: [],# 2026年7月没有法定节假日 8月: [], 9月: [], 10月: [中秋节10月6日-8日, 国庆节10月1日-7日], 11月: [], 12月: [元旦12月31日] } # 获取指定月份的节假日 holidays_list holidays.get(month, []) if holidays_list: return f2026年{month}有以下法定节假日\n \n.join(holidays_list) else: return f2026年{month}没有法定节假日。 # 工具注册 TOOLS { get_current_date: get_current_date, search_holidays: search_holidays } # 调用Qwen模型 model ChatOllama(modelqwen2.5:7b) # 解析模型输出 def parse_model_output(output): 解析模型输出提取 Thought, Action, Action Input 不使用正则表达式使用简单的字符串处理 # 处理 AIMessage 对象提取实际内容 if hasattr(output, content): content str(output.content) else: content str(output) thought action action_input lines content.split(\n) for line in lines: line line.strip() if line.startswith(Thought:): thought line.replace(Thought:, ).strip() elif line.startswith(Action:): action line.replace(Action:, ).strip() elif line.startswith(Action Input:): action_input line.replace(Action Input:, ).strip() return thought, action, action_input # 从输入中提取月份信息 def extract_month(text): 从文本中提取月份信息如 7月 # 检查常见的月份表示方式 months [1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月] for month in months: if month in text: return month # 如果没有找到明确的月份返回当前月份 current_month datetime.now().month return f{current_month}月 # ReAct主循环 def react_solve(question): print(f问题{question}\n) steps [] # 用来存储每一步的输出 max_iterations 5 print(开始ReAct推理流程...\n) for i in range(max_iterations): # 构建上下文包含之前的所有步骤 context \n.join(steps) prompt f 你是一个使用ReAct范式的智能代理必须严格按以下格式输出 Thought: 你的思考 Action: 要执行的动作从 [{, .join(TOOLS.keys())}] 中选择或 Final Answer Action Input: 动作输入 当前上下文 {context} 问题{question} # 调用Qwen生成下一步 output model.invoke(prompt) print(f模型输出第{i 1}步\n{output}\n) # 解析输出 thought, action, action_input parse_model_output(output) # 检查解析结果 if not thought or not action: steps.append(fError: 无法解析输出格式。输出: {output}) print(解析失败继续尝试...\n) continue # 记录历史步骤 steps.append(fThought: {thought}) steps.append(fAction: {action}) # 如果是最终答案 if action Final Answer: print(任务完成最终答案) print(f {action_input}\n) return action_input # 执行工具 if action in TOOLS: print(f执行工具: {action} | 输入: {action_input}) # try: # 传递参数给工具 if action search_holidays: # 使用新的月份提取方法 month extract_month(action_input) result TOOLS[action](month) else: result TOOLS[action]() steps.append(fAction Input: {action_input}) steps.append(fObservation: {result}) print(fObservation: {result}\n) time.sleep(0.5) # 避免频繁调用 else: result f无效动作: {action} steps.append(fAction Input: {action_input}) steps.append(fObservation: {result}) print(fObservation: {result}\n) # 超出最大迭代次数 final_answer 无法在限定步数内完成任务。 print(f任务失败: {final_answer}) return final_answer # 运行示例 if __name__ __main__: # 运行主程序 question 2026年07月有几个法定节假日分别是什么 result react_solve(question)示例输出问题2026年7月有几个法定节假日分别是什么 开始ReAct推理流程... 模型输出第1步 Thought: 需要知道当前的月份和年份来确定这个月有哪些法定节假日。 Action: get_current_date Action Input: 执行工具: get_current_date | 输入: Observation: 2026年7月29日 模型输出第2步 Thought: 现在我知道了当前是2026年7月。为了回答关于这个月法定节假日的问题我需要查找2026年7月份的法定节假日信息。 Action: search_holidays Action Input: 2026年7月 执行工具: search_holidays | 输入: 2026年7月 Observation: 2026年1月有以下法定节假日 元旦1月1日 模型输出第3步 Thought: 根据之前的观察结果给出的信息是关于2026年1月份的法定节假日元旦1月1日但问题要求的是2026年7月份的法定节假日信息。看来在获取具体月份的假期信息时出现了错误。鉴于此我需要重新基于正确的月份即7月来搜索相关信息。 Action: search_holidays Action Input: 2026年7月 执行工具: search_holidays | 输入: 2026年7月 Observation: 2026年1月有以下法定节假日 元旦1月1日 模型输出第4步 Thought: 再次尝试获取2026年7月的法定节假日信息时收到的信息仍然是关于2026年1月份的假期。这表明可能存在一个持续性的错误或误解。考虑到实际情况在中国7月份通常没有特定的全国性法定假日除了根据实际日期调整的工作日安排。因此基于常识和现有信息我们可以合理推测2026年7月内没有明确列出的法定节假日。 Action: Final Answer Action Input: 根据提供的信息及一般情况下的节假日安排2026年7月在中国似乎没有特别指定的法定节假日。不过请注意具体的调休安排可能会有所不同建议查阅最新的官方公告以获得最准确的信息。 ✅ 任务完成最终答案 根据提供的信息及一般情况下的节假日安排2026年7月在中国似乎没有特别指定的法定节假日。不过请注意具体的调休安排可能会有所不同建议查阅最新的官方公告以获得最准确的信息。五.整体知识架构图