对话Agent的核心需求是 知识检索+工具调用,比如:先问时间,然后问告警,再问错误码原因:ReAct会先思考需要调用什么工具 ,再行动调用对应的工具,最终生成答案。这种思考->行动的模式就是ReAct,ReAct是对话Agent的核心技术支柱。
📷 [图片 token=VovJbMlekoaAr9x11oOcZLFYnFc(未能下载,见飞书原文)]
ReAct是什么?
先给定义:ReAct 是 AI 的解题方法论
ReAct = Reasoning(推理)+ Acting(行动),核心是让 AI 像人一样 ** 边想边做、边做边调整 **,通过 ** 思考->行动->观察->再思考 **来解决问题。
📷 [图片 token=JiOwbY24OoqxraxcVi2cLDUpn8e(未能下载,见飞书原文)]
**大白话解释:就像你做饭时查菜谱 **
想象你要做一道没做过的菜(比如 红烧肉 ),你会怎么一步步来?
思考: 我需要知道红烧肉的步骤、调料、火候…… (分析问题,明确要做什么)
行动:打开手机查抖音红烧肉教程(调用 抖音工具 获取信息)
观察:看到教程说 需要炒糖色,用冰糖 (获取工具返回的结果)
再思考: 家里只有白糖,能用吗?再查一下‘白糖代替冰糖炒糖色’ (根据观察结果调整思路,继续行动)
ReAct 就是让 AI 模仿这个过程:遇到问题不直接 瞎猜答案 ,而是先想 该查什么 ,再调用工具(比如计算器、数据库、搜索引擎),拿到结果后判断 够不够 ,不够就继续查,直到能给出最终答案。
技术场景的例子: 地球和火星的质量加起来是多少? (AI 不知道具体数值,需要调用工具)
第1次循环:思考->行动->观察
- 思考:我需要地球和火星的质量,得先查地球质量。
- 行动:调用 查星球质量 工具,输入 地球
- 观察:工具返回 地球质量≈5.97×10²⁴ kg
第2次循环:再思考->行动->观察
- 思考:有了地球质量,还缺火星的,继续查火星。
- 行动:调用 查星球质量 工具,输入 火星
- 观察:工具返回 火星质量≈6.42×10²³ kg
第3次循环:再思考->行动->观察
- 思考:现在有两个数了,需要相加,得用计算器。
- 行动:调用 计算器 工具,输入 5.97e24 + 6.42e23
- 观察:工具返回 ≈6.61×10²⁴ kg
结束循环: 结果够了,可以回答用户了,地球和火星的质量加起来是6.61×10²⁴ kg。
知道了ReAct的原理,接下来我们来看看到底怎么实现ReAct模式
古法 ReAct(手搓字符串解析)
通过严格的 prompt 规范 AI 的输出格式,强制其按 ** Thought->Action->Pause->Observation ** 流程执行
system prompt
我们定义下面这段 system prompt。那么大模型将会严格依据prompt里面的要求返回。
# 中文
system_prompt = """
你是一个反应(推理和行动)代理,遵循思考、行动、暂停和观察的循环来解决问题。
Workflow:
1. Thought: 推理下一步做什么
2. Action: 调用工具(格式:Action:工具名:输入)
3. PAUSE: 等待工具返回
4. Observation: 工具结果分析
可用工具:
- calculation: 数学计算(如 "5*7/4")
- planet_mass: 查询行星质量(如 "Mars")
"""
system_prompt = """
You are a React(Reasoning and Acting) agent that follows a loop of Thought, Action, PAUSE, and Observation to solve problems.
Workflow:
1. Thought: Describe your reasoning or plan for solving the problem.
2. Action: Execute an appropriate action based on your reasoning. The available actions are listed below.
3. PAUSE: Indicate that you are pushing to observe the result of the action. Stop output anything while pause.
4. Observation: Analyze the result of the action and incorporate it into your reasoning.
At the end of the loop, provide a final Answer based on the information gathered.
Your available actions are:
calculation:
e.g. calculation: 5*7/4
run a calculation and return the number using python so be sure to use floating point syntax if needed.
planet_mass:
e.g. planet_mass: Mars
returns the mass of the planet in the solar system
"""
代码执行流程
我们根据大模型的消息,对消息进行字符串解析:
# 伪代码
def query(question):
while 循环(最多 N 轮):
1. 发送 prompt + 问题 + 历史记录 给 AI
print("----------------------")
print(f"step: {i}")
print(result)
2. 解析 AI 返回:用正则匹配 Action(如 `Action:calculation:5*7`)
3. 调用工具函数,获取结果 -> 生成 Observation
print(f"\nObservation: {observation}")
4. 将 Observation 加入新 prompt,进入下一轮循环
5. 若 AI 无 Action,返回最终答案
大模型执行日志
Question: What is the mass of Earth plus Mars? ---这是我们的提问
----------------------
step:1 --- 第一次循环
Thought: I need to find the masses of Earth and Mars, then add them. --- 大模型第一次思考
Action: planet_mass: Earth ---大模型第一次行动
PAUSE
# ---这是我们代码里解析出planet_mass函数与输入Earth,执行函数后返回的内容
Observation: Earth has a mass of 5.972 × 10^24 kg
----------------------
step:2 --- 第二次循环
Thought: Now I have Earth's mass. I need Mars's mass. ---大模型第二次思考
Action: planet_mass: Mars ---大模型第二次行动
PAUSE
# ---这是我们代码里解析出planet_mass函数与输入Mars,执行函数后返回的内容
Observation: Mars has a mass of 6.4171 × 10^23 kg
----------------------
step:3 --- 第三次循环
Thought: Now I can calculate the sum. ---大模型第三次思考
Action: calculate: 5.972e24 + 6.4171e23 ---大模型第三次行动
PAUSE
# ---这是我们代码里解析出calculate函数与输入5.972e24 , 6.4171e23,执行函数后返回的内容
Observation: 5.972e24 + 6.4171e23 = 6.614e24
----------------------
step:4 --- 第四次循环
Answer: The combined mass is approximately 6.614 × 10^24 kg. --- 返回最终答案
总结
所谓的行动,其实是我们根据大模型的输出,解析出应该调用哪个工具(函数),然后代码执行。并将结果告诉大模型。至此ReAct不再神秘,说白了就是字符串的处理。
这种写法是最原始的,举个例子,如果函数的输入输出的map,是map套map,那字符串生成/解析的难度指数级上升。大模型处理这种场景就比较困难,很容易出错。
现代 ReAct(Function Call)
标准化工具交互
大模型厂商推出 Function Call,用 JSON 统一工具定义和调用格式:
工具描述:用 JSON 定义工具名、参数、功能(如
{"name":"calculation", "parameters":{"type":"number"}})调用格式:AI 直接返回 JSON(如
{"action":"calculation", "input":5}),避免字符串解析混乱。
优点:工具描述和回复格式统一,便于针对性训练AI模型,若AI回复错误,服务器端可检测并自动重试,降低用户端开发难度和token开销。
现代ReAct执行流程
将工具信息按照function call要求的格式和用户的输入,一起发送给大模型(这里就不需要像原始的ReAct要求写Action之类的prompt了)
大模型有了上面的tool信息,会自行判断是否需要使用工具,如果要使用,则tool call(模型会按照function call要求的格式生成内容,指定函数名和参数)。
将tool的响应添加到输入中,开始新的一轮循环,直到大模型不再tool call,那么就结束了
不论是古法ReAct还是现代ReAct,核心思想都是一样的,根据工具返回来决定下一步要做什么
这里可能有一点抽象,没关系。知道有这个循环流程就行,下一节就有ReAct代码实战。
📷 [图片 token=KMRJbPiDUoVkftxTBdDcSzPLnid(未能下载,见飞书原文)]
古法与现代的对比
核心差异在于从人工字符串约定升级为机器可理解的结构化协议 ,大幅降低了格式依赖和实现成本。
| 对比维度 | 古法 ReAct | 现代 ReAct |
|---|---|---|
| 工具调用格式 | 自然语言字符串(如 Action: planet_mass: Mars) | 标准化 JSON 结构(通过 Function Call 规范) |
| 工具描述方式 | 依赖用户自定义 Prompt 中的自然语言说明 | 工具信息标准化(如 JSON 对象定义工具名、参数、功能) |
| 解析方式 | 正则表达式解析字符串(易出错,依赖格式严格匹配) | 结构化 JSON 解析(大模型/框架原生支持,可靠性高) |
| 复杂数据处理 | 困难(如嵌套结构的输入输出,字符串解析易混乱) | 可靠(JSON 天然支持复杂参数类型,如嵌套对象) |
| 错误处理 | 需手动实现(如未知 Action 抛出异常) | 框架自动支持(如工具调用格式错误时,大模型/框架自动重试) |
| 依赖技术 | 纯 Prompt 工程 + 字符串处理 | 大模型 Function Call 功能(厂商官方支持) |
| 格式规范来源 | 用户自定义 Prompt 中的格式约束 | 大模型厂商定义的标准化协议 |
| 实现复杂度 | 高(需手动处理字符串生成、解析、异常捕获) | 低(框架封装了格式处理、工具调用逻辑) |
总结:ReAct 的本质
ReAct = Reasoning(推理)+ Acting(行动),先想后做:拆解问题->制定计划。边做边说:调用工具(搜索引擎/数据库)->观察结果->反复验证,核心是** 思考 -> 行动 -> 观察 -> 再思考 **的闭环:
思考:分析问题、执行计划,决定下一步该做什么
行动:根据思考,去调用外部工具来获取信息
观察:查询看行动(工具/函数)的返回结果