从LLM到Agent:ReAct推理模式的底层原理

从LLM到Agent:ReAct推理模式的底层原理

你用过ChatGPT,但你有没有想过:为什么它能回答"今天天气怎么样",却没法真的帮你查天气?这篇文章从零开始,带你理解"聊天机器人"和"智能助手"之间的那道坎------ReAct推理循环------到底是怎么回事。


一、LLM到底是什么?为什么它"四肢瘫痪"?

先从最基本的概念说起。LLM(大语言模型)本质上是一个数学函数:

复制代码
输入文本 → 预测下一个字 → 拼回去 → 输出文本

它做的事就是"根据前面的文字,猜下一个字"。训练了海量数据后,这个"猜"变得极其精准,精准到看起来像是"理解"了问题、"思考"出了答案。但它实际上一次都没有离开过文字的世界。

所以LLM有个致命缺陷:它只能输出文字,不能和外界交互。你问它"今天天气怎么样",它能输出一段看起来很合理的文字,但那不是今天的天气,是它训练数据里见过的"天气预报示例"。

要解决这个问题,需要给LLM装上"手和脚"------让它能够调用外部的工具。比如:

  • 一个"查天气"的工具
  • 一个"发邮件"的工具
  • 一个"搜索文件"的工具

LLM需要自己决定"什么时候调用哪个工具"。这就引出了ReAct。

二、ReAct:LLM的"思考-行动"循环

2.1 问题很简单:LLM怎么知道自己该调工具?

直觉上,我们可以写一个"规则引擎":如果用户说"天气",就调天气工具;如果用户说"计算",就调计算器。

但实际用户说的话千变万化。"这两天出门要不要带伞"------你看到"伞"会想到天气,但关键词匹配很难枚举所有可能。我们需要LLM自己理解 用户意图,自己决定调哪个工具。

这就是ReAct要解决的问题。

2.2 ReAct的核心思想

ReAct这个名字来自两个词的组合:

  • Reasoning(推理):分析当前情况,想清楚该做什么
  • Acting(行动):真正去执行

它不是一步到位,而是一个循环:

复制代码
第1步:看用户问题 → 思考 → 判断需要查天气 → 调用天气工具
第2步:拿到天气结果 → 思考 → 判断信息够了 → 输出回答

这个循环看似简单,但它实现了一个很关键的能力:LLM不需要第一次就答对,它可以一步步来,先获取信息,再基于信息回答。

2.3 用大白话解释ReAct的每一步

假设用户问:"明天北京天气怎么样?适合户外运动吗?"

没有ReAct的LLM(纯文字模式):

复制代码
→ 直接回答:"明天北京晴转多云,气温15-25度,适合户外运动。"
问题是:这个答案是编的!LLM根本不知道明天什么天气,它只是根据训练数据"猜"了一个合理的回答。

有ReAct的Agent:

复制代码
第1轮:
  用户:"明天北京天气怎么样?适合户外运动吗?"
  LLM思考:我不知道明天天气,需要查一下。
  LLM输出:{调用工具: getWeather, 参数: city="北京", date="明天"}

第2轮:
  工具返回:{天气: "晴", 温度: "18-26度", 风力: "2级"}
  LLM思考:天气晴朗,温度舒适,风力小。
  LLM输出:"明天北京晴天,18到26度,风力2级,非常适合户外运动!"

LLM不再需要"编造"答案,因为它拿到了真实数据。

三、Function Calling:ReAct的工程落地

3.1 这不是"回调函数",这是"消息拼接"

很多初学者以为工具调用就是"LLM回调一个Java方法"。不是的。底层发生的事情更简单(也更精妙):

LLM的输入是一串消息。输出也是一串消息。工具的加入,不过是在这串消息中插入了新的消息

整个对话的消息序列是这样的:

复制代码
消息1 [system角色]:  "你是智能助手,以下工具可用:{天气查询, 计算器, 文件搜索...}"
消息2 [user角色]:    "明天北京天气怎么样?"
消息3 [assistant角色]: "{我想调天气工具} {工具名: getWeather, 参数: city=北京}"  ← LLM输出
消息4 [tool角色]:     "{天气: 晴, 18-26度, 风力2级}"  ← 工具执行结果,插入到消息序列中
消息5 [assistant角色]: "明天北京晴天,18-26度,适合户外运动!"  ← LLM基于消息1-4重新推理

关键点:工具调用结果不是"回调"给LLM的,是追加到消息历史里的。LLM看到上下文里多了一条消息(消息4),自然地基于此继续推理。

3.2 这为什么精妙?

因为LLM根本不需要任何架构改造。它还是做它最擅长的事------给定一串消息,预测下一条消息。多出来的工具结果只是消息序列中的一个新条目,对LLM来说和用户发的消息没有本质区别。

这个设计让ReAct的实现极其简单:不需要修改LLM,只需要在被调用的工具返回后,把结果塞进消息序列,然后让LLM再跑一次。

3.3 那LLM怎么知道有哪些工具可用?

每个工具都有一个"说明书"(JSON Schema),描述了它的名字、作用、参数。

比如天气工具的说明书:

json 复制代码
{
  "name": "get_weather",
  "description": "查询指定城市明天的天气",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称"
      }
    }
  }
}

所有工具的说明书都放在System Prompt(消息1)里。LLM读取后,就知道有哪些工具、每个工具要什么参数。当它判断需要使用某个工具时,它输出的不是文字,而是一个结构化的JSON对象,指出了工具名和参数值。

四、System Prompt:Agent行为的"控制面板"

4.1 同样的工具,不同的行为

假设Agent有三个工具:查天气、计算器、搜索文件。

用户说:"帮我算3.14 × 256"。LLM可以:

  • 选项A:直接心算"大概是800左右"
  • 选项B:调用计算器,返回准确的"803.84"

选A还是选B,取决于概率。而System Prompt的作用,就是改变这个概率------让"正确的选项"变得更可能。

4.2 一个具体的例子

对比两种System Prompt:

Prompt A(模糊版):

复制代码
你是智能助手,可以使用以下工具:get_weather, calculate, search_file。

Prompt B(精确版):

复制代码
你是智能助手,严格遵守以下规则:
1. 任何数学计算必须调用calculate工具,禁止心算
2. 任何天气查询必须调用get_weather工具,禁止猜测
3. 任何文件操作必须调用search_file工具
4. 调用了工具后,只回复工具返回的精确结果,不要补充或修改

面对同样的用户输入"3.14 × 256":

  • Prompt A下,LLM有约40%概率心算(因为心算"更方便")
  • Prompt B下,LLM几乎100%调用计算器(因为被明确禁止心算)

这就是为什么写Prompt不是"锦上添花",而是Agent开发的核心工作。代码搭建了工具(手脚),Prompt决定了Agent怎么选择使用这些工具。

五、Single Agent vs Multi Agent:架构的分岔路口

理解了ReAct和Function Calling后,你会面临一个选择:所有工具放一个Agent,还是拆成多个专业Agent?

5.1 Single Agent

复制代码
一个Agent,看到所有工具,自己决定调哪个。

优势是简单直接。只要工具数量不超过10个,这个方案工作得很好。

问题是:工具多了之后,LLM会"选择困难"。就像你面前摆了30个工具箱,每次要花很长时间才能找到对的------有时还会找错。

5.2 Multi Agent

复制代码
一个"调度员" + 多个"专家"
调度员分析用户问题 → 决定派哪个专家 → 专家出结果 → 调度员汇总回答

每个专家只看到自己领域内的工具,选择准确率高。而且职责隔离------"搜索专家"根本不知道有"删除文件"这个工具,绝不可能误删文件。

5.3 如何选择?

一个经验法则:工具<10个用Single Agent;工具>15个、或者需要职责隔离(比如有些操作很危险),用Multi Agent。

我们的项目支持两种模式,通过一个配置项切换,方便你对比不同模式下的Agent行为。

六、总结

让我们串联一下今天学到的内容:

  1. LLM的局限:只能输出文字,不能和外界交互
  2. ReAct循环:思考→行动→观察→再思考,让LLM逐步逼近正确答案
  3. Function Calling:通过把工具结果追加到消息序列中,让LLM自然地基于真实数据推理
  4. System Prompt:控制Agent行为的"概率调节器",改变工具选择的准确性
  5. 架构选择:工具少用Single Agent,工具多用Multi Agent

理解了这些,你就理解了所有Agent框架的基石。后面几天的Skill系统、MCP协议、多Agent编排,都是在这个地基上搭建的更高层建筑------它们的本质都是"给LLM装更好的手和脚,让它更精确地判断什么时候用哪个"。


项目链接

项目代码:day6-agent

相关推荐
奔跑中的小象1 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南1 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang1 小时前
LangGraph 状态机实战
人工智能
刹那芳华19921 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作2 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门2 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜2 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟2 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
llwszx2 小时前
【Java/Go后端手撸原生Agent(第十一篇):RAG检索——给Agent加上“查资料“能力】
llm·向量检索·rag·ai智能体·大模型应用·agent开发·后端转ai
天国梦2 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能