# 深入 ReAct 循环内部：每一步到底是怎么转的

从用户消息到最终答案，逐帧拆解一次 ReAct 迭代——模型如何输出 tool_call，代码如何执行工具，观察结果如何喂回，以及循环为什么不在模型里而在你的代码中

> ReAct 循环 · 工具调用 · function calling · 约 5 分钟 · 07 月 09 日

## 本篇要点

1. 工具调用循环的六步骨架：用户消息 + 工具描述 → 模型决定 → 输出 tool_call JSON → 代码执行真实函数 → 结果喂回 → 模型再决策，重复直到完成
2. Observation 必须来自工具的真实执行结果，不能由模型生成——这是防止智能体版本幻觉的关键安全边界
3. 模型在两次 API 调用之间是'失忆'的，智能体的状态不在模型里，而在你的代码维护的 transcript（对话记录）中
4. 循环不在模型内部，而在你的代码里——是那个 while 语句在驱动每一次迭代

---

上一篇我们讲了智能体的最小定义是「模型 + 循环 + 工具」，也看到了 ReAct 循环的宏观图景。但你可能还有一个疑问：**模型到底是怎么「调用」一个工具的？** 它不就是一个只会输出文本的接口吗？

这一篇我们就打开这个黑箱，把一次 ReAct 迭代的每一步展开来看——从用户消息输入，到模型推理、工具调用、返回结果、再推理，直到最终答案。

## 一次迭代的完整骨架

任何工具调用系统（无论你用的是 OpenAI、Claude 还是 Gemini），都遵循同一个循环：

1. 你把用户消息 + 工具描述（tool schemas）一起发给模型 API
2. 模型决定：是直接回答，还是需要调用某个工具
3. 如果是调用工具，模型输出一个结构化 JSON 块——里面包含**工具名**和**参数**
4. 你的代码（runtime）解析这个 JSON，真正去执行那个函数（查天气、搜索网页、读数据库）
5. 你把工具返回的结果作为一条新消息发回给模型
6. 模型读到结果，要么继续调用下一个工具，要么给出最终答案

步骤 2–6 可以重复多次，直到模型认为任务完成[[1]](#ref1)。

这就是智能体循环的实质：**LLM 只负责输出指令，你的代码负责执行，然后把真实世界的反馈喂回给 LLM，让它据此决定下一步。**

## 从用户消息到最终答案：一个完整跟踪

假设我们有一个智能体，它有两个工具：`search_web`（搜索）和 `get_weather`（查天气）。用户说：

> "北京明天适合跑步吗？"

让我们逐帧播放这个循环的内部过程。

### 第 1 轮

**你的代码发送给模型 API：**
- 系统提示（包含工具描述）
- 用户消息："北京明天适合跑步吗？"

**模型 API 返回：**
- 文本内容（Thought）：*"我需要先查一下北京明天的天气，才能判断是否适合跑步。"*
- 工具调用块（tool_call）：
  ```json
  {
    "tool": "get_weather",
    "args": { "city": "北京", "date": "2026-07-08" }
  }
  ```

注意：模型**没有**去查天气。它只是输出了一个结构化的"我想调用 get_weather 这个工具，参数是北京和日期"的指令——它仍然在生成文本，只是这段文本恰好是 JSON 格式且有约定含义[[2]](#ref2)。

### 步骤 1.5：执行工具

**你的代码收到这个 tool_call 之后：**
1. 解析 JSON，取出工具名 `get_weather` 和参数 `{city: "北京", date: "2026-07-08"}`
2. 调用真实的天气 API（或查询数据库）
3. 拿到结果：`"气温 25°C，湿度 80%，有雨"`
4. 构造一条新消息，角色为 `tool`，内容是上述结果

### 第 2 轮

**你的代码再次发送给模型 API：**
- 系统提示（不变）
- 用户消息
- 上一条助手回复（含 tool_call）
- 工具消息（含天气结果）

**模型 API 返回：**
- 文本内容：*"北京明天有雨，湿度 80%，不太适合户外跑步。建议改去室内健身房。"*

此时模型决定不再调用工具，直接输出最终答案。循环结束。

## 为什么 Observation 必须来自真实世界

上面这个例子中有一个关键细节：**观察结果（Observation）不是模型生成的，而是工具执行后由你的代码插入的。**

假设我们允许模型自己生成观察结果，会出现什么情况？模型可能说：

```
Action: get_weather("北京", "2026-07-08")
Observation: 天气晴朗，温度 25°C，非常适合跑步
```

但真实天气其实是有雨的。模型可以编造一个"看起来合理"的观察结果——这就是智能体版本的幻觉。因此，**Observation 必须来自工具的真实执行，不能由模型生成**。这是 ReAct 循环设计中最重要的一条安全边界[[3]](#ref3)。

## 模型是"失忆"的，Transcript 才是状态

还有一个不细看就容易误解的地方：**模型在两次 API 调用之间什么都不记得。**

每次你调用模型 API，它看到的只是你这次发给它的全部消息。它没有"记忆"，不会记得上一次调用时它想了什么、做了什么。所谓"记忆"，是你**在代码里把每次调用前后的消息都追加到同一个对话历史中，下次调用时再把整个历史发过去**。

换句话说，智能体的状态不在模型里，而在你的代码维护的那份 transcript（对话记录）里。你可以在第 1 轮用 Claude，第 2 轮用 GPT，第 3 轮换一个本地模型——只要 transcript 完整，模型就能接上之前的上下文继续推理[[4]](#ref4)。

## 所以循环到底在哪里？

很多人第一次理解 ReAct 时，会以为循环在模型内部——模型自己在"思考→行动→观察→思考"。

不是。**循环在你的代码里。** 模型每次只做一件事：接收一段文本，输出下一段文本。是你的代码在检查输出——如果是 tool_call 就执行工具、把结果追加回去、再次调用模型——直到输出是最终答案为止。

把这段逻辑写成伪代码，大概是这样：

```
while not finished:
    response = call_llm(messages + tools)  # 模型输出
    if response.has_tool_call():
        tool_name = response.tool_call.name
        args = response.tool_call.arguments
        result = execute_tool(tool_name, args)  # 你的代码执行
        messages.append(tool_result(result))    # 追加结果
        # 继续循环
    else:
        final_answer = response.text
        finished = True
```

循环不在模型里。循环是你的代码里那个 `while` 语句[[4]](#ref4)。

## 小结

把这一篇和上一篇连起来，完整的画面就清晰了：

- **上一篇**：智能体 = 模型 + 循环 + 工具。ReAct 循环让模型从"一次回答完就停"变成"持续执行直到完成"。
- **这一篇**：循环的具体机制——模型输出 tool_call 指令，你的代码执行工具，把真实结果喂回去，模型据此决定下一步。模型每步都"失忆"，但 transcript 让一切连贯。

下一期我们会更进一步：当你注册多个工具时，模型怎么决定"该用哪个"？工具描述（tool schema）的写法会如何影响模型的选择？

## 来源

1. [How LLMs Call Tools — Complete Guide for AI Engineers — 工具调用循环的完整分步说明](https://agenticprep.ai/topics/how-llms-call-tools)
2. [OpenAI Function Calling 官方文档 — API 交互流程与 tool_call 格式](https://developers.openai.com/api/docs/guides/function-calling)
3. [ReAct Inside — From Message to State — 解释 Observation 必须来自真实世界执行而非模型生成](https://dev.to/eyanpen/react-inside-from-message-to-state-understanding-how-ai-agents-really-work-3epf)
4. [Inside the ReAct loop: how agents actually iterate — 模型无状态性、transcript 即状态、循环在代码中的详细分析](https://mickdelaney.com/posts/inside-the-react-loop/)

---

原文：https://pangzhengboyin.com/articles/inside-the-react-loop-6815c23b

> **庞征博引** · 想学的，慢慢都会
>
> 庞征博引是把想学的东西写成连载的 AI 学习工具。说出想学什么，它会先了解你的基础，再把主题写成一篇篇 5–10 分钟能读完的文章；边读边问，接下来学什么跟着你走。这篇就是这样写出来的。
>
> 开始你自己的连载 → https://pangzhengboyin.com
