文章目录

AI Agent 核心组件深度剖析:从感知到执行,四大组件如何让 LLM 从"聊天机器"进化为"自主智能体"?

本文从技术架构视角,逐层剖析 AI Agent 的四大核心组件——感知、记忆、规划、执行——以及它们如何协同工作,让 LLM 从"只会聊天"的概率模型,变成一个能自主完成复杂任务的智能体。


前言:为什么 LLM 自己不够用?

在上一篇 LLM 技术架构剖析中,我们得出一个核心结论:LLM 本质上是一个"下一个 Token 预测器"——它没有思考、没有记忆、没有手脚,只会根据上文做概率计算。

这个结论引出一个自然的追问:既然 LLM 有这么多限制,为什么我们还能用它做出能自主完成任务的 AI Agent?

答案是:Agent 不是 LLM 的"升级版",而是 LLM 的"增强架构"——在 LLM 外面包了一层又一层组件,每一层都在补 LLM 的一个先天缺陷。

纯 LLM:输入文本 → 概率计算 → 输出文本(只能聊天)
AI Agent:感知 → 记忆 → 规划 → 执行 → 反馈 → 循环(能自主完成任务)

这篇文章从技术架构的视角,逐一拆解 Agent 的四大核心组件:

  • 感知(Perception):Agent 如何"看懂"用户到底想要什么?
  • 记忆(Memory):Agent 如何"记住"说过的话、做过的事、学过的东西?
  • 规划(Planning):Agent 如何把复杂任务拆成一步步可执行的子任务?
  • 执行(Execution):Agent 如何真正"动手"——调工具、操作文件、执行命令?

读完你会理解:Agent 的每一个组件都不是凭空设计的,而是 LLM 某一个局限性的"工程化补丁"。 理解了这四个组件,你就理解了 Agent 为什么必须是这个架构。


一、Agent 的本质:不是"聪明的 LLM",是"被增强的 LLM"

1.1 Agent 的定义

在 AI 工程中,Agent(智能体) 的定义是:

一个能够感知环境、自主决策、执行行动并基于反馈持续优化的系统。

这个定义里有四个关键词,恰好对应四大组件:

关键词对应组件核心能力
感知环境感知(Perception)理解用户意图、解析输入信息
自主决策规划(Planning)拆解任务、选择策略、动态调整
执行行动执行(Execution)调用工具、操作外部系统
持续优化记忆(Memory)记住历史、从经验中学习

1.2 Agent 的两种经典公式

网上流传最广的 Agent 公式有两个版本:

版本一(Lilian Weng,2023)

Agent = LLM + Memory + Planning + Tool Use

这是 OpenAI 研究员 Lilian Weng 在博客 LLM Powered Autonomous Agents 中提出的公式,也是业界引用最多的版本。它从运行时调度的角度,把 Agent 定义为"LLM 调用了记忆、规划和工具三种能力"——简洁、好记,适合快速建立认知。

版本二(更细粒度拆解)

Agent = LLM + Perception + Memory + Planning + Execution

这个版本在版本一的基础上做了两处细化:

变化为什么拆出来
新增 Perception(感知)版本一中"感知"被隐含在 LLM 的输入处理中;但实际工程中,感知是贯穿整个 Agent 运行周期的独立能力——意图识别、实体抽取、多轮循环中的结果解读,都需要专门的感知逻辑
Tool Use → Execution(执行)Tool Use 只是执行的一种方式(调用 API);Execution 的范围更广——还包括文件操作、Shell 命令、数据库读写、浏览器控制等

本文采用版本二进行深度剖析。原因很简单:版本一适合"记住 Agent 是什么",版本二适合"理解 Agent 每个组件怎么设计"。本文的目标是后者——把每个组件拆开来,讲清楚它的设计动机、底层机制和工程实践。

组件补的是 LLM 的哪个缺陷如果缺了这个组件会怎样
LLM(大脑)——没有推理能力,整个系统无法运转
感知(Perception)不理解"用户到底想要什么"把"帮我查天气"理解成"聊天气话题"
记忆(Memory)上下文窗口有限,聊完就忘每次对话都是"初次见面",无法积累经验
规划(Planning)不会拆解复杂任务遇到多步任务直接"懵掉",输出混乱
执行(Execution)只会说不会做永远停留在"建议你这样做",不会真的动手

Agent 不是一种新技术,而是给 LLM 打了 4 个补丁之后,让它能自主完成任务的工程架构。

1.3 用一个你熟悉的 Agent 来理解四大组件

抽象概念容易忘,我们拿一个很多人实际用过的 Agent 来拆解——豆包(字节跳动)的"AI 编程助手"模式

假设你对豆包说:“帮我写一个 Spring Boot 登录接口,用 JWT 认证。

豆包(作为一个 Agent)在背后做了以下四件事:

┌─────────────────────────────────────────────────────────────────┐
│  用户输入:"帮我写一个 Spring Boot 登录接口,用 JWT 认证"         │
└──────────────────────────────┬──────────────────────────────────┘
                               ↓
┌─ ① 感知(Perception) ──────────────────────────────────────────┐
│  意图识别:用户想"生成代码"(不是问概念、不是改代码)              │
│  实体抽取:技术栈=Spring Boot,功能=登录接口,认证方式=JWT        │
│  上下文消歧:当前项目是 Spring Boot 吗?→ 检查项目文件确认        │
└──────────────────────────────┬──────────────────────────────────┘
                               ↓
┌─ ② 记忆(Memory) ──────────────────────────────────────────────┐
│  短期记忆:刚才用户说了什么?→ "写登录接口,用 JWT"               │
│  长期记忆:用户之前用过什么技术栈?偏好什么代码风格?              │
│  向量记忆:项目中已有的 User 实体类、Security 配置在哪?          │
└──────────────────────────────┬──────────────────────────────────┘
                               ↓
┌─ ③ 规划(Planning) ───────────────────────────────────────────┐
│  这个任务拆成几步?→                                             │
│    步骤 1:先看项目已有的依赖和配置(读 pom.xml)                 │
│    步骤 2:创建 JWT 工具类                                        │
│    步骤 3:创建登录 Controller 和 Service                        │
│    步骤 4:创建 Security 配置类                                   │
│    步骤 5:写单元测试验证                                         │
└──────────────────────────────┬──────────────────────────────────┘
                               ↓
┌─ ④ 执行(Execution) ──────────────────────────────────────────┐
│  步骤 1:read_file("pom.xml") → 发现已有 spring-boot-starter-   │
│           security,需要加 jjwt 依赖                              │
│  步骤 2:write_file("JwtUtil.java", ...) → 写入 JWT 工具类       │
│  步骤 3:write_file("AuthController.java", ...) → 写入登录接口    │
│  步骤 4:write_file("SecurityConfig.java", ...) → 写入安全配置    │
│  步骤 5:执行 mvn test → 验证代码能否编译通过                     │
└─────────────────────────────────────────────────────────────────┘

同样的逻辑,你在 Cursor、Trae、GitHub Copilot、Claude Code 这些编程 Agent 中都能看到——它们不是"一个聪明的 LLM 在回答问题",而是感知 → 记忆 → 规划 → 执行这套组件在背后协同运转。

了解了这个具体例子,我们再逐一深入每个组件的设计细节。


二、感知(Perception):Agent 的"眼睛和耳朵"

2.1 感知组件在解决什么?

LLM 收到的输入只是一段文本。但用户的真实需求往往藏在文本背后——意图、情绪、上下文、隐含条件。感知组件的作用,就是把这些"隐藏信息"从原始输入中提取出来。

原始输入:"上次那个方案客户说还要改一下"
    ↓ 感知组件处理
结构化意图:
  - 意图:修改方案
  - 目标对象:上次提到的方案(需要从记忆中检索)
  - 触发条件:客户反馈
  - 紧急性:隐含为"需要处理"

2.2 感知的三个层次

层次能力技术手段示例
意图识别判断用户想做什么分类模型 / LLM Few-Shot“帮我查天气” → 意图:查询天气
实体抽取提取关键信息NER 模型 / LLM 结构化输出“北京到上海的机票” → 出发地:北京,目的地:上海,类型:机票
上下文消歧结合历史对话理解模糊表达多轮对话状态追踪“上次那个呢?” → 结合记忆定位"上次"是什么

2.3 感知不是"一次性"的

一个关键认知:感知不是只在对话开始时执行一次,而是贯穿整个 Agent 运行周期。

Agent 运行循环中的感知:
  Thought: 我刚才做了什么?结果是什么?
  Observation: 工具的返回结果意味着什么?是成功还是失败?
  Update: 基于新信息,我对任务的理解需要更新吗?

每一次工具返回结果,Agent 都需要重新"感知"——这个结果告诉我什么?下一步应该做什么?(这个循环在第四章规划的 ReAct 范式中会详细展开。)

感知组件是 Agent 循环的"入口"——它决定了 Agent 如何理解世界,进而决定了后续所有决策的质量。


三、记忆(Memory):Agent 的"海马体"

3.1 为什么 LLM 需要记忆系统?

LLM 本身没有记忆——每次调用都是"无状态"的。它之所以看起来"记得"对话历史,是因为你把整个对话历史重新发给了它。

这个机制有三个致命问题

问题后果
上下文窗口有限对话长了就"失忆",前面说过的重要信息被挤出窗口
每次都重新"读"一遍Token 成本随对话长度线性增长
没有长期记忆关掉对话后,所有信息全部丢失,下次"重新认识"

记忆系统就是解决这三个问题的。

3.2 记忆的三层架构

在这里插入图片描述

三层记忆不是互相替代,而是各有分工

记忆类型存什么类比人脑什么时候用
短期记忆当前对话的上下文、本轮任务的中间结果你正在想的事每一轮 LLM 推理都依赖它
长期记忆用户偏好、历史任务总结、关键决策你记住的事跨会话时,需要"回忆"用户之前说过什么
向量记忆文档、代码、知识库的语义片段你学过的东西需要引用外部知识时,通过语义检索找到相关内容

3.3 短期记忆的深入:Context Window 的"暗面"

短期记忆看似简单——不就是把对话历史塞进上下文窗口吗?但这里面有三个容易被忽略的工程问题:

问题一:“Lost in the Middle”(中间丢失)

LLM 对上下文窗口的注意力不是均匀分布的。研究表明,模型对开头和结尾的内容关注度最高,对中间部分关注度最低。这意味着:

上下文窗口: [开头 高注意力] ... [中间 低注意力] ... [结尾 高注意力]

如果把重要信息放在中间 → 模型可能"没看到"
正确做法:核心指令放开头,最新信息放结尾,次要信息放中间

问题二:Token 成本随对话线性增长

每一轮对话都在往上下文窗口里塞东西——用户的问题、LLM 的回答、工具调用的结果。一个 10 轮对话的 Agent 任务,上下文轻松突破 8K Token:

第 1 轮:user(50) + assistant(200) = 250 Token
第 2 轮:user(50) + assistant(300) + tool_result(500) = 850 Token
第 3 轮:user(50) + assistant(400) + tool_result(800) = 1250 Token
...
第 10 轮:累积上下文已超过 10K Token

问题三:信息过载导致的"注意力稀释"

上下文越长,每个 Token 分到的注意力权重越低。当上下文塞入太多信息时,LLM 可能"抓不住重点"——它知道所有信息,但不知道哪个更重要。

短期记忆的核心矛盾信息越多,模型越"看不清";信息越少,模型越"不知道"。 好的短期记忆管理,就是在"信息量"和"注意力"之间找到最优平衡。

3.4 长期记忆的存储与检索

长期记忆解决了"关掉对话后什么都忘了"的问题。但它的工程挑战比短期记忆大得多:

存什么?——记忆的"写入策略"

写入策略做法优点缺点
全量存储每次对话全部保存不丢信息存储膨胀,检索变慢
关键事件存储只保存重要决策、用户偏好、任务结果精准高效可能遗漏"看起来不重要但实际重要"的信息
摘要存储对每段对话做摘要后再保存保留核心信息,压缩存储摘要可能丢失细节

工程实践中通常采用混合策略:关键事件全量存储 + 普通对话定期摘要。

怎么检索?——记忆的"召回管道"

长期记忆不是"把所有存的东西都塞进上下文",而是通过一个检索管道按需召回:

用户当前问题
    ↓
① 关键词提取:从问题中提取关键实体 → "项目方案"、"上周"
    ↓
② 向量检索:将关键词转为向量,在记忆库中做语义相似度搜索 → 粗筛出 Top 50
    ↓
③ 元数据过滤:按时间范围、类型、重要性等标签过滤 → 缩小到 Top 10
    ↓
④ 重排序(Rerank):用 CrossEncoder 模型做精细排序 → 最终保留 Top 3-5
    ↓
⑤ 注入上下文:将召回的 Top 3-5 条记忆写入 System Prompt

这个管道每一步都在缩小范围:全量记忆 → 50 条 → 10 条 → 3 条,最终只有最相关的 3 条记忆进入 LLM 的上下文。

3.5 向量记忆的底层原理

向量记忆是 RAG 体系的核心。它和长期记忆的关键区别在于:长期记忆存的是"Agent 自己的经历",向量记忆存的是"外部知识"

向量的本质:把一段文本(问题、文章、代码)通过 Embedding 模型转成一个固定长度的浮点数数组。语义相近的文本,向量在空间中的位置也相近。

"今天天气怎么样" → Embedding → [0.12, -0.34, 0.78, ..., 0.05]  (1536维)
"今天气温多少度" → Embedding → [0.11, -0.32, 0.80, ..., 0.03]  (1536维)
                               ↑ 两条语义相近,向量距离很近

"Python 怎么安装" → Embedding → [-0.45, 0.67, -0.12, ..., 0.88] (1536维)
                               ↑ 语义不同,向量距离很远

检索原理:在向量空间中,用"距离"衡量"语义相似度"。距离越近,语义越相关。

相似度算法计算方式适用场景
余弦相似度两个向量夹角的余弦值,值越大越相似最常用,不受向量长度影响
欧氏距离两个向量在空间中的直线距离,值越小越相似向量已归一化时效果最好
点积两个向量逐元素相乘再求和向量已归一化时等价于余弦相似度

为什么需要 ANN(近似最近邻)? 精确的最近邻搜索复杂度是 O(N×D),当记忆库有 100 万条记录、每条 1536 维时,精确搜索太慢了。ANN 通过牺牲少量精度换取大幅速度提升,典型方案有 HNSW、IVF 等。

3.6 三种记忆的协作方式

以一个实际场景说明三层记忆如何配合:

用户:"帮我继续写上次那个项目方案"
    ↓
感知层:意图=续写方案,关键实体="上次那个项目方案"
    ↓
记忆层协作:
  ┌─ 短期记忆:检查当前对话中是否提过"项目方案" → 没有
  │   (当前对话窗口里没有这个信息,转长期记忆)
  └─ 长期记忆:从数据库检索用户的"项目方案"相关记录
      → 找到上周的"AI Agent 项目方案 v1"
      → 检索到关键信息:写到第三部分,主题是"工具调用体系"
    ↓
向量记忆:检索"AI Agent 工具调用体系"相关的外部知识
      → 召回 MCP 协议文档、Function Calling 规范等参考材料
    ↓
Agent 综合三层记忆的输出:
  "找到你上周的'AI Agent 项目方案 v1',上次写到第三部分(工具调用体系)。
   我参考了 MCP 最新文档,帮你继续写第四部分……"

3.7 记忆管理的核心挑战

挑战说明解决思路
记忆衰减旧信息和新信息冲突,Agent 倾向"遗忘"旧信息重要性评分 + 定期回顾
记忆污染错误信息记入长期记忆,影响后续决策记忆校验 + 过期机制 + 用户确认
检索精度从海量记忆中精准找到当前任务需要的"那一小段"向量检索 + 关键词过滤 + 重排序
Token 预算每次检索到的记忆都要塞进上下文,占 Token摘要压缩 + 分级存储(热/温/冷)
写入时机什么时候该记?每轮都记会污染,不记会丢失关键决策点写入 + 会话结束总结写入
记忆一致性用户改了偏好,但旧记忆还在,新旧冲突版本化管理 + 冲突检测 + 最新优先

记忆系统的核心矛盾记住的越多,检索越难;检索越精准,Token 越省。 好的记忆系统不是"记住一切",而是"在需要的时候,恰好能找到最相关的信息"。三层记忆架构 + 检索管道,就是解决这个矛盾的最优工程实践。


四、规划(Planning):Agent 的"前额叶皮层"

4.1 为什么 LLM 需要规划能力?

LLM 一次只能输出一个回答。但真实世界的任务往往是多步的:

"帮我做一份 AI Agent 技术调研报告"
  → 不能一步完成,需要:
  ① 搜索 AI Agent 相关论文和文章
  ② 阅读并提取关键信息
  ③ 整理成报告大纲
  ④ 逐部分撰写
  ⑤ 检查引用和格式

规划组件的作用,就是把这个"不能一步完成"的复杂任务,拆成一系列"可以一步完成"的子任务。

4.2 核心范式一:ReAct(推理-行动循环)

4.2.1 ReAct 的起源与设计动机

ReAct 出自 2022 年 Google 的论文 ReAct: Synergizing Reasoning and Acting in Language Models。这篇论文的核心洞察是:

纯 LLM 有两个割裂的能力:推理(Reasoning)和行动(Acting)。 推理能力让 LLM 能做数学题、写分析报告,但无法获取外部信息;行动能力让 LLM 能调用工具,但缺乏全局推理。ReAct 把两者融合成一个循环,让推理指导行动,行动的结果反过来修正推理。

在 ReAct 出现之前,Agent 的做法通常是"一次性推理完,再一次性执行"。这种方式的问题是:推理时没有任何外部反馈,完全靠 LLM 自己"猜"——猜错了就全错。

ReAct 的改进是:让推理和行动交替进行,每一步行动的结果都变成下一步推理的输入。 这就像你做饭时不会一次性把菜谱全背下来再动手,而是看一步做一步,尝一口再调整。

4.2.2 ReAct 的四个阶段
Thought(思考) → Action(行动) → Observation(观察) → 循环判断 → Final Answer
阶段Agent 在做什么本质
Thought(思考)分析当前状态:“我已经掌握了什么信息?还缺什么?下一步应该做什么?”把当前状态翻译成一个"下一步决策"
Action(行动)根据 Thought 的决策,调用对应的工具,执行具体操作把"决策"落地为"执行"
Observation(观察)获取工具返回结果,判断结果是否满足预期把"执行结果"翻译成"新的状态信息"
循环判断基于 Observation,决定是否继续:信息够了就输出 Final Answer,不够就回到 Thought这是 ReAct 的"灵魂"——知道自己什么时候该停下来

关键理解:ReAct 不是"四个步骤按顺序走一遍",而是 Thought → Action → Observation 组成一个原子循环,这个循环可以重复任意多次。每次循环都在缩小"已知信息"和"需要信息"之间的差距。

4.2.3 完整实战:一次多轮 ReAct 执行

下面用一个真实的例子,完整追踪 ReAct 的每一轮循环。假设用户问:

“北京今天适合户外运动吗?”

这个看似简单的问题,实际上需要多个步骤才能回答——Agent 需要先查天气,再根据天气状况判断是否适合户外运动。

═══════════════════════════════════════════════════
第 1 轮循环
═══════════════════════════════════════════════════

Thought: 我不知道北京今天天气如何,需要先查询天气。
         我手头有一个 get_weather 工具可以用。

Action: call get_weather(city="北京")
          ↓
Observation: {"city": "北京", "weather": "阴转小雨", "temp": "18°C",
              "wind": "东北风 4 级", "aqi": 85}

═══════════════════════════════════════════════════
第 2 轮循环
═══════════════════════════════════════════════════

Thought: 获取到了天气数据。阴转小雨 + 18°C + 4 级风 + AQI 85。
         但我知道的信息还不够——"适合户外运动"不只是看天气,
         还需要考虑空气质量对运动的影响。让我查一下 AQI 85 意味着什么。

Action: call search_web(query="AQI 85 适合户外运动吗")
          ↓
Observation: "AQI 51-100 为良,敏感人群应减少户外运动,
              普通人群可以进行户外运动但建议不要长时间剧烈运动。"

═══════════════════════════════════════════════════
第 3 轮循环
═══════════════════════════════════════════════════

Thought: 现在我掌握了全部需要的信息:
         1. 天气:阴转小雨,18°C,东北风 4 级
         2. 空气质量:AQI 85,良,普通人群可运动但不建议长时间剧烈运动
         3. 综合判断:阴转小雨意味着可能下雨,AQI 85 对普通人群无碍
         
         信息已经足够,可以输出最终答案了。

Final Answer: 北京今天不太适合户外运动。原因是:
  ① 天气阴转小雨,有降雨风险,地面湿滑
  ② 气温 18°C 偏低,东北风 4 级体感较冷
  ③ 空气质量 AQI 85(良),普通人群可运动但不宜长时间剧烈运动
  建议改为室内运动,或等天气转好再出门。

来看这个案例中 ReAct 的核心价值:

轮次如果没有 ReAct(纯 LLM)有了 ReAct
第 1 轮编造一个天气数据,或者直接说"我不确定"实际调用了天气工具,拿到真实数据
第 2 轮不会主动去查 AQI 的含义意识到"只知道天气还不够",主动搜索空气质量标准
第 3 轮可能给出一个笼统的"适合"或"不适合"基于两份真实数据,给出具体、有依据的判断

ReAct 的本质:每一步的 Observation 都变成了下一步 Thought 的输入。LLM 不再是在"黑暗中猜测",而是在"一步步逼近真相"。

4.2.4 ReAct 的底层实现

从代码层面理解 ReAct 并不复杂——它就是一个 while 循环,循环条件是"LLM 还没说停":

# ReAct 的底层实现:while 循环 + 工具调用
def react_agent(user_query, tools):
    messages = [{"role": "user", "content": user_query}]
    max_iterations = 10  # 防止无限循环
    
    for iteration in range(max_iterations):
        # 1. 调用 LLM:这一步是 Thought 还是 Final Answer?由 LLM 自己决定
        response = llm.invoke(messages, tools=tools)
        
        # 2. 如果 LLM 没有调用工具 → 说明它认为信息够了,输出 Final Answer
        if not response.tool_calls:
            return response.content  # ← ReAct 循环的"出口"
        
        # 3. 否则 → LLM 决定调用工具(Action 阶段)
        for tool_call in response.tool_calls:
            tool_name = tool_call.function.name
            tool_args = json.loads(tool_call.function.arguments)
            
            # 4. 执行工具,获取结果(Observation 阶段)
            try:
                result = execute_tool(tool_name, tool_args)
            except Exception as e:
                result = f"工具执行失败:{str(e)}"
            
            # 5. 把结果回传对话历史 → 下一轮循环的 Thought 会基于这个结果
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result, ensure_ascii=False)
            })
    
    # 超过最大迭代次数 → 强制终止
    return "任务超时,未能完成。"

三个关键设计点

设计点为什么重要
max_iterations 上限防止 LLM 陷入"死循环"——反复调用同一个工具拿不到结果,或者永远觉得"信息不够"
工具结果回传 messages这是 ReAct 的"记忆机制"——每一轮的工具结果都追加到对话历史,下一轮 LLM 能看到之前所有的 Thought 和 Observation
LLM 自己决定何时停止不需要外部规则判断"任务是否完成",LLM 在 Thought 中自己判断——信息够了就输出 Final Answer,不够就继续调工具
4.2.5 为什么 ReAct 比纯 LLM 更可靠?
优势原理底层机制
突破知识边界可调用外部工具获取实时数据,不受训练数据截止限制Action 阶段通过 Tool Use 接入外部世界
大幅降低幻觉每一步结论都有工具返回的事实依据,不是模型凭空生成Observation 是真实的工具返回值,不是 LLM 编的
处理复杂任务将复杂问题拆解为多步执行,逐步验证修正Thought 阶段在每轮重新评估"我还缺什么信息"
过程可追溯每一步推理和行动都可回溯,方便调试所有 Thought → Action → Observation 都在对话历史中,像完整日志
自适应纠错工具返回错误时,LLM 能基于错误信息调整策略错误信息作为 Observation 回传,下一轮 Thought 会重新规划
4.2.6 ReAct 的常见失败模式

ReAct 不是万能的,了解它的失败模式才能在生产环境中用好它:

失败模式表现根因解决方案
无限循环Agent 反复调用同一个工具,但每次结果都一样,始终不输出 Final AnswerLLM 的 Thought 判断"信息还不够",但实际信息已经够了设置 max_iterations 上限 + 检测重复调用
选错工具明明有查询天气的 Tool,LLM 却选了搜索网页的 ToolLLM 对 Tool 描述的理解偏差优化 Tool 的 description 字段 + Few-Shot 示例
过早终止任务只完成了一半,LLM 就输出了 Final AnswerLLM 误判"信息够了"在 System Prompt 中强调"确认所有子任务完成后再输出"
上下文溢出多轮循环后,对话历史太长,超出上下文窗口每轮 Observation 都在累积,窗口被撑爆压缩历史 Observation + 只保留关键结论
幻觉型 ActionLLM 调用了一个不存在的工具,或者编造了参数LLM 在概率分布中"幻想"了一个工具名严格校验 tool_call 中的工具名是否在注册列表中

ReAct 是 Agent 规划能力的"基石范式"。理解了 ReAct 的四个阶段、底层实现、可靠性和失败模式,你就掌握了 Agent 规划的核心。后续的 Plan-and-Execute、Self-Reflection、Tree of Thoughts 等进阶范式,都是站在 ReAct 的肩膀上做的改进。

4.3 核心范式二:Plan-and-Execute(先规划后执行)

ReAct 的局限:走一步想一步,缺乏全局视角。对于长链路、多步骤的复杂任务,没有全局规划容易"走偏"。

Plan-and-Execute 的方案:先制定完整计划,再逐步执行,执行中根据反馈动态调整计划。

Plan-and-Execute 四角色架构            
  用户 → Agent 主程序(调度全流程)               
            ├── Plan 模型(生成初始执行计划)       
            ├── 执行 Agent(独立完成单步任务)     
            └── Re-Plan 模型(根据结果更新计划)    

实战案例:查询澳网男单冠军的家乡

轮次当前计划执行结果Re-Plan 更新
初始① 查当前日期 → ② 查澳网冠军 → ③ 查冠军家乡
第 1 轮执行第一步查到当前日期是 2025 年将第二步细化为"查 2025 年澳网冠军"
第 2 轮执行更新后的第二步查出冠军:Jannik Sinner只剩最后一步
第 3 轮执行最后一步查出家乡:意大利南蒂罗尔任务完成,输出最终答案

4.4 两种范式对比

维度ReActPlan-and-Execute
执行模式走一步想一步,边想边做先整体规划,再分步执行,动态调优
适合任务中等复杂度、不确定性高的操作型任务高复杂度、长链路、多步骤调研类任务
灵活性极高,随时调整方向中等,在计划框架内调整
上下文消耗逐步累加计划 + 结果,结构更清晰
实现难度高,需要多模型/多 Agent 协作
类比while + switch 循环工作流编排引擎(Flowable)

4.5 规划能力的进阶方向

技术核心思想解决问题
Self-Reflection(自我反思)让 Agent 在执行后检查自己的输出质量“我刚才的回答对吗?要不要再查一下?”
Tree of Thoughts(思维树)在每个决策点生成多个候选方案,评估后选择最优避免"一条路走到黑"
Hierarchical Planning(分层规划)先制定高层目标,再逐步细化到可执行步骤超复杂任务的分层拆解

规划是 Agent 从"工具"变成"智能体"的关键一步。 没有规划的 Agent 只是一个"能调工具的聊天机器人",有了规划的 Agent 才真正具备了"自主完成任务"的能力。


五、执行(Execution):Agent 的"手和脚"

5.1 执行组件在解决什么?

LLM 最根本的限制之一:输入输出都是文本,没有"执行"能力。 它能告诉你"应该用 mv 命令重命名文件",但不会自己去执行。

执行组件的作用,就是给 LLM 接上"手"——让它能真正操作外部世界。

5.2 执行的三层能力

在这里插入图片描述

5.3 工具调用的完整生命周期

一次完整的工具调用,从 LLM 决策到执行完成,经历了以下流程:

# Agent 工具调用的完整生命周期
def agent_tool_call_cycle(user_input, tools):
    messages = [{"role": "user", "content": user_input}]
    
    while True:
        # 1. LLM 推理:是否需要调用工具?
        response = llm.invoke(messages, tools=tools)
        
        # 2. 判断:LLM 决定直接回答还是调用工具
        if not response.tool_calls:
            return response.content  # 无工具调用,返回最终答案
        
        # 3. 遍历所有工具调用(支持并行调用多个工具)
        for tool_call in response.tool_calls:
            tool_name = tool_call.function.name
            tool_args = json.loads(tool_call.function.arguments)
            
            # 4. 参数校验 + 执行
            try:
                result = execute_tool(tool_name, tool_args)
            except Exception as e:
                result = f"工具执行失败:{str(e)}"
            
            # 5. 结果回传对话历史
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result)
            })
        # 6. 循环:LLM 基于工具结果继续推理

5.4 执行层的工程要点

工程要点说明为什么重要
参数校验在调用工具前验证参数类型和范围防止 LLM 生成非法参数导致工具崩溃
超时熔断设置工具调用超时时间,超时自动中断防止某个工具卡住拖垮整个 Agent 链路
错误重试工具调用失败后,将错误信息回传 LLM,让它重新决策LLM 看到错误信息后会调整策略,而不是直接失败
结果裁剪工具返回结果过长时,截断或摘要后再回传避免工具返回的"废话"占满上下文窗口
权限控制限制 Agent 可调用的工具范围和操作权限防止 Agent 误操作——rm -rf / 绝对不能执行

执行层是 Agent 的"最后一公里"——规划再好、记忆再准,如果执行层崩了,前面的努力全部白费。工程上,执行层的健壮性直接决定了 Agent 是"生产可用"还是"演示玩具"。


六、从单 Agent 到多 Agent:当一个人不够用时

6.1 单 Agent 的三大瓶颈

当任务复杂度继续上升,单 Agent 架构会暴露出三个瓶颈:

瓶颈表现根因
上下文过载一个 Agent 处理多种任务,Prompt 越来越长,信息互相干扰所有信息都在同一个上下文窗口里
能力分散一个 Agent 既要做代码审查又要做文档生成,两个都不精通用 Prompt 无法在多个领域同时达到专家水平
单点故障一个 Agent 出错,整个任务失败没有冗余和备份机制

6.2 Multi-Agent 架构:分而治之

Multi-Agent 的核心思想很简单:把一个大任务拆给多个专业化的小 Agent 各自处理,最后由一个总调度 Agent 汇总。

用户请求 → Lead Agent(总调度)
              ├── Sub Agent A(垂直专家:代码审查)
              ├── Sub Agent B(垂直专家:文档生成)
              └── Sub Agent C(垂直专家:安全扫描)
              → Lead Agent 汇总 → 输出最终结果

6.3 Multi-Agent 的三大核心优势

优势说明类比
上下文隔离各 Sub Agent 上下文独立,互不干扰微服务独立数据库,一个挂了不影响其他
专业分工每个 Agent 专注一个领域,Prompt 可高度定制单一职责原则,每个类只做一件事
避免信息过载单个 Agent 不需要处理全部信息拆分担,避免单点瓶颈

6.4 主流 Multi-Agent 框架

框架语言核心特点适用场景
CrewAIPython角色定义简单,上手快快速原型,多 Agent 协作入门
AutoGenPython微软出品,支持灵活对话模式企业级多 Agent 对话
MetaGPTPython模拟软件公司角色(PM、架构师、工程师)软件开发全流程自动化
LangGraphPythonLangChain 生态,支持复杂图状工作流需要精细控制 Agent 交互流程

Multi-Agent 不是"把多个 Agent 放在一起跑",而是"用架构设计规避单 Agent 的上下文过载和能力分散问题"。 它的核心价值不在"多",而在"分"——把复杂问题分解为多个简单问题,逐个击破。


七、核心要点速查

要点 1:Agent 的本质是什么?

Agent 不是 LLM 的升级版,而是 LLM 的增强架构。Agent = LLM + 感知 + 记忆 + 规划 + 执行,每个组件都在补 LLM 的一个先天缺陷。

要点 2:感知组件解决什么问题?

感知组件负责从用户的原始输入中提取意图、实体、上下文。它不是一次性执行的,而是贯穿 Agent 整个运行周期——每次工具返回结果,Agent 都需要重新"感知"。

要点 3:记忆系统为什么需要三层架构?

短期记忆(上下文窗口)保证即时响应,长期记忆(持久化存储)保证跨会话积累,向量记忆(语义检索)保证精准召回。三者协作,解决 LLM"记不住"的先天缺陷。

要点 4:ReAct 和 Plan-and-Execute 怎么选?

ReAct(边想边做):适合中等复杂度、不确定性高的任务。Plan-and-Execute(先规划后执行):适合长链路、多步骤、步骤间有依赖的任务。前者灵活,后者稳健。

要点 5:执行层的工程要点有哪些?

参数校验 → 超时熔断 → 错误重试 → 结果裁剪 → 权限控制。执行层是 Agent 的"最后一公里",健壮性直接决定"生产可用"还是"演示玩具"。

要点 6:什么时候需要 Multi-Agent?

当单 Agent 出现上下文过载、能力分散、单点故障三大瓶颈时,就需要 Multi-Agent 架构。核心价值不在"多",而在"分"——把复杂问题分解为多个简单问题,逐个击破。


八、写在最后

理解 Agent 的核心组件,是理解整个 AI Agent 体系的关键一步。

回顾整个系列文章,从 LLM 底层原理到 Prompt Engineering,再到工具调用体系(FC / MCP / CLI / Skill),最后到 Agent 核心组件——每一层都在解决上一层的痛点,每一层都是对 LLM 概率本质的"工程化补丁"

LLM 本质(概率预测器)
  → Prompt Engineering(用指令引导概率分布)
    → Tool Use(给 LLM 接上"手脚")
      → Agent(感知 + 记忆 + 规划 + 执行,让 LLM 自主完成任务)

把这个逻辑链吃透,再去学具体的 Agent 框架(LangChain、CrewAI、AutoGen),你会发现它们只是在用不同的方式实现同一套架构——感知、记忆、规划、执行。万变不离其宗。


参考资料


追光而遇,沐光而行,一起持续精进。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐