整理自 2026-07-16 学习记录。
ReAct 是什么
ReAct = Reasoning(推理)+ Acting(行动)交替循环。不再让模型闷头一次答完,而是让它:
思考:我需要查 XX → 行动:调用工具查 XX → 观察:工具返回了结果
→ 思考:根据结果我还需 YY → 行动:... → 最终答案
|-----------|------------|-----------------------|
| 手法 | 模型产出 | 用到工具吗 |
| CoT | 一段推理文字 | 否 |
| 自我批判 | 答案 + 复查 | 否 |
| ReAct | 思考/行动/观察循环 | 格式上预留了行动位(后面接真工具) |
这是「讨论型 → 一体化 Agent」的跃迁点:模型不再只是聊天,而是会调用工具自己干活。
🍅1 提示词版 ReAct(D5 先练格式)
D5 阶段先用纯提示词 演示「思考/行动/观察/最终答案」长啥样,模型输出的「行动」只是文本,并不真调工具。
import requests
API_KEY = "你的key"
url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
system_prompt = """【Role】你是一个会用工具的助手
【Task】严格按下面格式循环:
思考:你现在的推理
行动:要调用的工具名(参数)
观察:工具返回的结果
(重复 思考/行动/观察 直到能回答)
最终答案:xxx
【Constraint】每次只写一个单元,不跳步"""
data = {
"model": "glm-4-flash",
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "上海今天天气怎么样?适合出门吗?"},
{"role": "assistant", "content":
"思考:我需要查上海实时天气。\n"
"行动:weather(上海)\n"
"观察:上海今日25度,多云,微风。\n"
"思考:25度多云适合出门。\n"
"最终答案:上海今天25度多云,适合出门。"},
{"role": "user", "content": "北京到上海的高铁要多久?如果下午2点出发,几点到?"},
]
}
resp = requests.post(url, headers=headers, json=data)
print(resp.json()["choices"][0]["message"]["content"])
⚠️ 结构要点 :few-shot 范例的 assistant 标准答案必须存在 messages 里,真实问题置底。否则模型会把范例当成待答问题顺着答两遍。小澪实测时一度出现「两段都答了」,就是范例的 assistant 行没正确塞入导致的------记住结构即可。
🍅2 真 ReAct 循环骨架(W3 展开)
提示词版「行动」只是嘴上说。真 Agent 让代码接管行动:解析模型输出 → 调真函数 → 把结果喂回去。
import requests, re
def call_llm(messages):
data = {"model": "glm-4-flash", "messages": messages, "temperature": 0}
return requests.post(url, headers=headers, json=data).json()["choices"][0]["message"]["content"]
def run_tool(action): # 真实工具函数,W3 重点
return "真实查询结果" # 解析 "train_schedule(北京,上海)" → 调真接口
messages = [{"role":"system","content":system_prompt},
{"role":"user","content":"北京到上海高铁多久?下午2点出发几点到?"}]
while True:
reply = call_llm(messages)
print(reply)
if "最终答案" in reply:
break # 模型认为能答了,停
m = re.search(r"行动:(.+)", reply) # ① 解析出工具名和参数
obs = run_tool(m.group(1)) # ② 用参数执行真实函数
messages.append({"role":"user", "content": f"观察:{obs}"}) # ③ 返回值喂回去循环
代码侧三步链:解析回复 → 执行真函数 → 返回值喂回,直到模型吐「最终答案」。
🍅3 防死循环 + 与 Function Calling 的关系
防死循环两道保险:
-
正常出口 :回复里出现
最终答案→break(模型自觉答完) -
兜底保险 :设
max_turns(如 5)→ 哪怕模型卡住,到上限强制停(防烧钱卡死)max_turns = 5
for _ in range(max_turns):
reply = call_llm(messages)
if "最终答案" in reply: break
...
ReAct vs Function Calling:
ReAct 是「提示词里手写循环约定」,Function Calling 是「API 原生给的结构化工具调用」------同一件事的两种写法,后者更稳更省心。
D5 用提示词把「边想边做、观察再想」的认知节奏练熟,W3 直接换成 Function Calling 的真工具调度。
本节收尾
|--------|-------------------------------------|--------------------|
| 🍅 | 知识点 | 掌握 |
| 1 | ReAct 四段式(思考/行动/观察/最终答案) | ✅ 格式跑通,真实问题答对 |
| 2 | 真 ReAct 循环骨架(代码接管行动) | ✅ 三步链:解析→执行→喂回 |
| 3 | 防死循环两保险 + ReAct vs Function Calling | ✅ ②③对,①纠正为「最终答案」出口 |