Skip to content

ReAct 模式

什么是 ReAct

ReAct = Reasoning + Acting(推理 + 行动)

这是 AI Agent 的核心思维模式:先思考要做什么,再执行,然后根据结果继续思考。

思考 → 行动 → 观察 → 思考 → 行动 → 观察 → ... → 完成

为什么需要 ReAct

普通 LLM 的问题:

  • 只能一次性生成答案
  • 无法获取实时信息
  • 容易产生幻觉(编造事实)

ReAct 的解决方案:

  • 分步推理,每步可验证
  • 通过工具获取真实信息
  • 基于观察结果调整策略

ReAct 流程示例

用户问:"当前目录有什么文件?"

[思考] 用户想知道当前目录的文件列表,我需要执行 ls 命令

[行动] 调用 shell 工具执行 "ls -la"

[观察] 工具返回:
  total 24
  -rw-r--r--  1 user  staff   156 Jan 15 10:00 package.json
  -rw-r--r--  1 user  staff   892 Jan 15 10:00 README.md
  drwxr-xr-x  4 user  staff   128 Jan 15 10:00 src

[思考] 已经获取到文件列表,可以回答用户了

[回答] 当前目录有 3 个项目:package.json、README.md 和 src 文件夹

Function Calling 实现 ReAct

现代 LLM(如 Gemini、GPT-4)通过 Function Calling 实现 ReAct 模式:

  1. 你告诉 LLM 有哪些工具可用
  2. LLM 决定是否调用工具、调用哪个、传什么参数
  3. 你执行工具,把结果告诉 LLM
  4. LLM 继续推理

gemini-cli 中的 ReAct

gemini-cli 的 Agent 循环就是 ReAct 模式的实现。

核心代码在 packages/core/src/core/client.ts,简化后的逻辑:

typescript
async function agentLoop(userMessage: string) {
  const conversation = [{ role: 'user', content: userMessage }]

  while (true) {
    // [推理] LLM 分析当前状态,决定下一步
    const response = await geminiChat.send(conversation)

    // 检查 LLM 的决定
    const functionCalls = response.functionCalls()

    if (functionCalls && functionCalls.length > 0) {
      // [行动] 执行工具
      for (const call of functionCalls) {
        const tool = findTool(call.name)
        const result = await tool.execute(call.args)

        // [观察] 记录结果,供下次推理使用
        conversation.push({
          role: 'function',
          name: call.name,
          content: JSON.stringify(result)
        })
      }
      // 继续循环,让 LLM 基于观察结果继续推理
    } else {
      // LLM 认为任务完成,返回最终答案
      return response.text()
    }
  }
}

ReAct 的关键点

1. 循环直到完成

Agent 不是一次调用就结束,而是持续循环直到 LLM 认为任务完成。

2. 上下文传递

每次工具执行的结果都加入对话历史,LLM 能看到之前的所有观察结果。

3. LLM 自主决策

LLM 决定:

  • 是否需要调用工具
  • 调用哪个工具
  • 传什么参数
  • 何时认为任务完成

4. 工具结果影响推理

LLM 会根据工具返回的结果调整策略。比如文件不存在时,可能会尝试创建它。

实际例子

用户:"帮我修复 src/index.ts 中的类型错误"

[思考] 需要先看看文件内容和错误是什么

[行动] read_file("src/index.ts")

[观察] 文件内容:
  const num: number = "hello"  // 类型错误

[思考] 发现问题:字符串赋值给 number 类型。需要修复

[行动] edit_file("src/index.ts", 修改内容)

[观察] 文件已修改

[思考] 应该验证修复是否成功

[行动] run_command("npx tsc --noEmit")

[观察] 编译通过,无错误

[回答] 已修复类型错误,将字符串改为了数字类型,编译验证通过

小结

  • ReAct = 推理 + 行动,是 Agent 的核心思维模式
  • 通过 Function Calling 让 LLM 调用工具
  • 循环执行直到任务完成
  • 工具结果作为观察反馈给 LLM

下一步

理解了 ReAct 模式,接下来学习如何与 LLM API 交互:LLM API 交互 →

通过实际源码学习 AI Agent 开发