从LLM到Agent:Agentic系统的知识地图
LLM 是函数,Agent 是系统——前者强大但孤立,后者用一组组件围绕 LLM 构建出可执行的执行环境。这两者之间的差距不靠"模型变大"自动消解,而是要逐项填上一系列架构层面的缺失。本文从 LLM 的数学本质出发,导出五个无法回避的局限,对应到必须配齐的五件套组件,再到组件之上的控制循环;最后落到一组工程判断——什么时候该用 Agent、什么时候坚决不该用、Agent 工程里哪两件事的投入回报率被最严重低估。读完它,你应该能判断一个 Agent 项目"靠不靠谱",并知道把劲花在哪里最划算。
1. LLM 是函数,Agent 是系统
把所有复杂性剥离,LLM 的数学本质极其简洁:
f(prompt: str) → response: str
它接收文本、返回文本。仅此而已。无论你把这个函数包装成对话框、API 还是 IDE 插件,它在底层始终是这个形态:一个无状态的文本到文本的映射。
但当你试图用它解决真实任务时——客服回答工单、代码助手调试 bug、研究助手做行业调研、运维 Agent 排查事故——会迅速撞上五堵墙:无记忆(跨调用不保留任何信息)、无工具(输出只是 token,无法产生副作用)、无规划(自回归生成不能回头修改)、无状态(不知道执行到第几步)、无反思(confidence 不等于 correctness)。
这五堵墙都不是模型能力变强能撞穿的——它们是架构层面的缺失。GPT-5 比 GPT-3 强很多,但它依然没有记忆、没有工具、没有结构化的状态、不会自我纠错。模型替换能解决推理质量问题,但解决不了系统设计问题。
当真实任务需要多步执行、外部交互、持久记忆、自我纠错时,你需要的不再是"更好的 prompt"或"更强的模型",而是围绕 LLM 构建的系统。这就是 Agent。
2. 五个局限对应五个组件
Agent = LLM + Memory + Tools + Planner + Runtime
这不是隐喻或营销话术,而是对五个局限的逐一回应——每个组件对应一个被填补的能力缺口:
| 组件 | 解决哪个局限 | 职责 |
|---|---|---|
| LLM | — | 语义理解、推理、生成(核心推理引擎) |
| Memory | 无记忆、无状态 | 短期对话窗口 + 长期知识库 + 任务执行状态 |
| Tools | 无工具 | 与外部世界的接口(搜索、查库、调 API、执行代码) |
| Planner | 无规划 | 将复杂任务分解为可执行子步骤、处理分支与回溯 |
| Runtime | 无反思 | 控制循环、错误处理、状态管理、超时控制、退出判定 |
这套分解的价值不在于"组件清单本身",而在于它对应着五种独立的失败模式——出问题时能快速定位是哪一个组件的责任:跨轮失忆是 Memory 问题、调用工具失败是 Tools 描述/参数问题、执行混乱是 Planner/循环问题、反复犯同样错是 Runtime 的反思/退出条件缺失,最后才是 LLM 推理本身。Agent 设计的核心,是承认 LLM 是系统里最不可靠的部分,然后用其他组件围绕它构建可控的执行环境。
至于每个组件具体怎么工作、L1 到 L4 不同自主性等级如何切分、成本结构里 token 为什么是小头——这是另一个独立话题的范围,不在这张地图里展开。
最小可用 Agent 的代码骨架
把这套理解落到代码,一个最小可用 Agent大约长这样——这就是后续 12 篇要逐一深化的"原型":
def minimal_agent(goal: str, tools: list, max_steps: int = 10) -> str:
memory = [] # Memory:累积对话状态
messages = [system_msg(), user_msg(goal)]
for step in range(max_steps): # Runtime:控制循环 + 退出条件
response = llm.complete(messages, tools=tools) # LLM:核心推理
if not response.tool_calls: # Planner(隐式):决定继续还是结束
return response.text
for tool_call in response.tool_calls: # Tools:与外部世界交互
try:
result = invoke(tool_call)
except ToolError as e:
result = f"Tool failed: {e}" # Reflect:错误回传让 LLM 自我纠错
messages.append(tool_msg(tool_call.id, result))
memory.append((tool_call, result))
return safe_terminate("max_steps reached") # Runtime 兜底:防止无限循环
这 14 行里塞了五个组件——LLM 是 llm.complete、Memory 是 messages + memory、Tools 是 invoke(tool_call)、Planner 是 LLM 隐式做的"调工具还是给答案"判断、Runtime 是整个 for 循环 + 错误捕获 + 上限。整个系列就是把这 14 行的每一层都拆开、深挖、给出生产级实现。
3. Observe-Think-Plan-Act-Reflect-Update:循环让 Agent 区别于 Chain
Agent 之所以能完成复杂任务,核心在于它运行一个持续的控制循环:
Observe → Think → Plan → Act → Reflect → Update
这是 Agent 与 Chain(LangChain 早期的核心抽象)最关键的区别。Chain 是 DAG——节点之间的连接在设计时确定。Agent 是循环——每一步执行后,下一步执行什么由 LLM 在运行时决定。这让 Agent 能处理设计阶段无法预见的分支,但也带来了 Chain 没有的所有难题:会不会绕圈?会不会忘了目标?什么时候停?
每个阶段都有独立的设计权衡:
| 阶段 | 关键问题 | 常见失败 |
|---|---|---|
| Observe | 哪些信息进入 LLM 上下文?context 是稀缺资源 | 把所有历史塞进 prompt,前几轮的关键信息被噪声淹没 |
| Think | 理解当前状态和目标 | 没有结构化状态,LLM 每轮都要"重新理解"任务 |
| Plan | 决定下一步——调工具、追问、还是直接回答 | 过早跳到 Act 而没规划;或规划过深导致延迟 |
| Act | 真正执行动作。有副作用 | 工具调用参数错误、网络抖动、权限不足 |
| Reflect | 检查结果是否符合预期。重试?补充?退出? | 没有 Reflect 步,错误结果被当作有效输入传给下一轮 |
| Update | 将本轮观察、决策、结果写入记忆 | 全量写入导致记忆膨胀;不写入导致循环失忆 |
Reflect 这一步在工程实践中被严重低估。很多 Agent 教程把循环画成 Observe → Act → Observe,省掉了 Reflect,本质上是把 Reflect 隐式塞进了 LLM 的下一轮推理。这在简单任务里能跑,但在复杂任务里几乎一定翻车——LLM 没有被显式提示"评估上一步结果",它会默认上一步是成功的,把错误的中间结果当作事实继续推理。
Update 不是简单地把所有内容写进 Memory。一个常见的错误是把每轮的完整观察、推理、动作全部追加到对话历史,几轮之后 prompt 就被噪声淹没了。好的 Update 策略要做摘要、要分层(短期 working memory vs 长期 episodic memory)、要剔除已被后续步骤覆盖的中间结果。
关键设计决策:何时退出循环——这是最容易被忽视的问题。Agent 的循环本质上是"信任 LLM 来决定何时停",而 LLM 并不可靠。生产中通常组合多种策略:
| 退出条件 | 触发逻辑 | 适用场景 |
|---|---|---|
| max_iterations | 步数硬上限 | 防止失控的最低保障,必须有 |
| goal_completion | LLM 显式声明任务完成 | 主退出条件,但需要校验 |
| token_budget | 累计 token 超过预算 | 成本兜底,常被忽视但很关键 |
| loop_detection | 检测到重复行为或无进展 | 防止 Agent 在错误状态里打转 |
| human_intervention | 用户主动叫停 | 长时间运行的 Agent 必须暴露 |
实践中往往是这些条件的"或"——任一触发就退出。只设 max_iterations 不够,因为它无法区分"成功完成"和"打转了 10 圈"。只设 goal_completion 也不够,因为 LLM 可能永远不主动声明完成。
4. 一个调研任务里 Agent 比 LLM 多做了什么
让一个 Agent 完成:"调研 2026 年主流的 Agent 框架,写一份 1000 字技术选型报告"。
纯 LLM(没有 Agent 能力)会直接从训练数据中生成——内容可能过时、引用可能编造、无法保证数据准确,但它会以同样自信的语气输出一份"看起来不错"的报告。这种"以高置信度输出过时或错误信息"的特性,正是 LLM 单独使用时最大的风险。
Agent 会这样工作:
| 轮 | 动作 | 体现的能力 |
|---|---|---|
| 1 | 理解任务,拆为三步:搜索主流框架 → 调研各自特性 → 撰写报告 | Planner |
| 2 | 调用搜索工具,发现 LangGraph、CrewAI、OpenAI Agents SDK 等 | Tools |
| 3 | 分别调用搜索查询每个框架的版本、star 数、特性,调网页抓取拿文档 | Tools + 多步执行 |
| 4 | 发现 Mastra 信息不充分,追加一轮搜索补充 | Reflect + 重新规划 |
| 5 | 综合所有信息撰写报告 | Memory(跨轮整合) |
| 6 | 反思质量——是否覆盖所有框架、数据是否矛盾、字数是否达标。发现缺性能对比,补充一段 | Reflect + 迭代优化 |
| 7 | 输出最终报告 | 退出循环 |
Agent 做了 LLM 做不到的四件事:主动搜索实时信息、在多步骤间传递上下文、把大任务拆成小步骤、发现不足后主动补充——分别对应工具调用、记忆、规划、反思。这四件事每一件背后都不是"模型变强了",而是系统层面的设计:搜索工具是被注册到 Agent 的 ToolRegistry 里的、跨轮上下文是被 Memory 模块持续累积和摘要的、任务拆分是 Planner 在第 1 轮就完成的、补充搜索是 Reflect 在第 6 轮主动触发的。
值得注意的是失败模式:
- 如果工具调用失败而没有 Reflect,第 5 步的"综合"会基于残缺数据写出错误结论
- 如果 Memory 设计不当,第 5 步看不到第 3 步的搜索结果
- 如果没有 max_iterations,第 6 步的"质量反思"可能反复触发"继续优化",永远不出报告
- 如果工具描述不清,第 2 步可能调用错误的工具或参数
这些失败都不是 LLM 的错,而是系统设计的错。这就是为什么 Agent 工程的重心常常不在"用什么模型",而在"循环怎么设计、工具怎么定义、记忆怎么管理、何时退出"。
5. Agent、Chain、Workflow 之辨
社区对这几个概念的边界一直模糊,但工程上的区别清晰且重要:
| 抽象 | 控制流由谁决定 | 适用 | 局限 |
|---|---|---|---|
| Workflow | 设计时由开发者用 DAG/状态机定义 | 步骤固定的业务流程 | 无法处理设计时未预见的分支 |
| Chain | 设计时定义节点连接,节点内可能调 LLM | LLM 作为步骤之一的固定流程 | 节点顺序是死的,遇到异常只能回退 |
| Agent | 运行时由 LLM 决定下一步 | 探索性、分支多、需要试错的任务 | 不可预测、调试困难、成本高 |
判断该选哪种的伪代码:
def choose_abstraction(task: TaskSpec) -> str:
"""三个判断维度,决定 Workflow / Chain / Agent"""
# 维度 1:路径数量
if task.path_count == 1:
return "Chain" # 路径唯一,Chain 最直接
# 维度 2:路径是否可枚举
if task.path_count <= 20 and task.paths_are_enumerable:
return "Workflow" # 路径有限可画 DAG,Workflow 引擎跑
# 维度 3:是否需要根据中间结果决定下一步
if task.requires_intermediate_decisions:
return "Agent" # 路径取决于运行时观察,必须 Agent
# 默认:从最简单的开始
return "Chain"
实践中真正好用的系统往往是混合形态:外层用 Workflow 定义大流程(接收任务 → 路由 → 执行 → 汇总 → 输出),内层在"执行"这一步嵌入 Agent;或者反过来,外层是 Agent,内层把固定流程封装成单个 Tool。
错配的代价很高:用 Workflow 做开放式探索,会发现 DAG 上画出十几个分支也覆盖不全用户的实际问法;用 Agent 做确定性流程,会发现稳定运行十次有一次莫名跑偏。选择抽象的关键是判断任务的不确定性来自哪里——是来自输入的多样性(Workflow 够用),还是来自路径的多样性(必须 Agent)。
6. Agentic 系统的概念分层
一个完整的 Agentic 系统是分层的——每一层处理一类独立的工程问题,层与层之间通过明确接口耦合。理解了这套分层,就理解了 Agent 工程的全部工作面。
| 层 | 解决的核心问题 | 关键判断 |
|---|---|---|
| 模型层 | 哪个 LLM 在跑——选型、采样参数、推理模式 | 模型能力是天花板,但绝大多数项目卡在系统设计而非模型上 |
| 运行时层 | 控制循环怎么跑、工具怎么调、提示词怎么组装 | 80% 的生产 bug 来自这一层——状态机不显式、JSON Schema 不严、Prompt 没版本 |
| 认知层 | Agent 怎么记得住、规划得清、反思得了 | 四层记忆 + RAG 流水线 + 规划/推理/反思的外部脚手架 |
| 编排层 | 单步执行如何组装成多步工作流,单 Agent 不够时如何拆成多 Agent | 工作流编排让步骤拓扑显式化;多 Agent 是用乘法效应换专业化 |
| 生态层 | 用什么框架构建、用什么协议互通 | 厚抽象框架 vs 厂商薄抽象 SDK;MCP 与 A2A 把 N×M 集成降为 N+M |
| 生产层 | 上线后怎么活下去 | 可观测、评估、成本、安全四件事的工程契约——任一缺失都不该上生产 |
| 可信层 | 概率性输出遇上不可逆操作怎么办 | Guardrails 在系统层加确定性过滤,HITL 在关键决策点接入人类判断 |
| 进阶交互层 | 目标系统没有 API 时怎么办;Agent 怎么从经验中改进自己 | Computer Use 是兜底而非替代;学习的三层时间尺度对应三套基础设施 |
| 平台层 | 多 Agent 在同一组织里跑起来需要什么 | Token 是新货币、Session 是新单位、非确定性是新常态——不是微服务复刻 |
这套分层不是先有架构再有问题,是反过来——每一层都是真实工程问题倒推出来的边界。模型层往下是 LLM 厂商的舞台;模型层往上每一层都是 Agent 工程师的战场。一个项目的工程质量,差不多就是它在这每一层上下功夫的总和。
7. Agent 不是银弹
Agent 处理的是"输入是模糊的、路径是不确定的"任务——探索性研究、多工具协作、需要迭代优化、半结构化流程。一旦任务不包含这种模糊性——能用 DAG 画完、要求 100% 确定性、延迟必须秒内、单次价值低于 token 成本——上 Agent 就是用更高代价换更差结果。详细的判断维度(含可枚举/路径/工具选择/容错率五个信号)属于 Agent 选型话题的范畴,本篇地图层只给原则。
地图层值得突出的是关键 Trade-off——升级到 Agent 换来什么、付出什么:
| 维度 | 升级到 Agent 换来 | 付出的代价 |
|---|---|---|
| 自主性 | 减少人工干预 | 不可预测,调试困难 |
| 复杂度 | 能处理更复杂任务 | 系统复杂度指数增长(监控、调试、回归测试、prompt 维护) |
| 成本 | 多步推理 | token 消耗超线性,月账单可能数十万 |
| 延迟 | 多步迭代 | 从毫秒级到分钟级 |
| 可靠性 | 反思和重试机制 | 但每步都可能出错,串联会乘法效应 |
最容易被低估的是复杂度的指数增长。一个调 2 个工具的 Agent 看起来比直接 API 调用复杂 2 倍,但实际工程复杂度可能高出 10 倍——demo 阶段看起来 ROI 很高,跑半年后维护成本可能反超收益。
核心决策原则:用最简单的抽象解决问题。如果 prompt engineering 够用,不要上 Agent;如果 Agent 够用,不要上 Multi-Agent;如果 Multi-Agent 够用,不要上平台。每增加一层抽象,都要问自己:这层抽象带来的能力提升,是否值得它引入的复杂度?这不是保守,而是清醒——大多数失败的 Agent 项目败在"用力过猛"而不是"用力不足"。
8. 工程上最容易被低估的两件事
每一层都重要,但工程实践中有两件事的投入回报率显著高于其他——大多数团队在这两件事上的投入都严重不足。
8.1 Tool Calling 的工程深度
Agent 的可靠性有一半建立在工具调用是否正确上。这听起来像是个简单问题——把函数注册成工具、让 LLM 输出调用、运行时执行——但生产里翻车的细节多得吓人:工具描述写得像内部 API 文档,LLM 看不懂何时该用;参数 Schema 没用 pattern/enum 约束,LLM 经常生成不合法值;错误返回是 stack trace,LLM 完全没办法据此自我纠错;多个工具语义重叠(search vs query vs find),LLM 选择困难;工具数量超过 30 个时 attention 显著下降,选错率飙升。
修这些每一项的回报都比"把主 Prompt 写得再漂亮"高一个数量级。花时间打磨工具描述、参数 Schema、错误返回的结构化格式,是被严重低估的高杠杆工作。一个简单的判断:如果你的工具描述长度还赶不上工具实现代码的注释,多半就投入不够。
8.2 评估体系的早期建设
没有评估就没有改进。你说不出"今天比昨天好",就只能凭感觉迭代——而凭感觉迭代的代价在 Agent 项目里特别高,因为 Agent 的输出是开放的、路径是不确定的、单次成本是不均匀的。改完一版 prompt 后,没有评估你不知道任务完成率涨了还是跌了、平均轮数是变多了还是变少了、工具调用精度和召回有什么变化、单次成本中位数是降了还是升了、安全维度有没有出现新的退化。这五个维度任一关键退化都该回滚,但没有评估系统时你根本看不到。
Agent 评估比传统软件难得多——开放输出、非确定路径、多维度指标——但越难越值得早建。EvalSet 50 条 + 自动化跑批 + 多维度 quality gate,这一套基础设施在 demo 阶段就该上,不是"以后再说"。
工具描述与评估体系——这两件事都不性感、都不像"模型能力"那样直接亮眼,但都是 Agent 工程能不能从 demo 走到生产的硬门槛。
9. 从函数到系统的代价
LLM 是推理能力的来源,Agent 是把推理能力转化为行动能力的系统。从函数到系统的五件套(LLM + Memory + Tools + Planner + Runtime)缺一不可——以 LLM 为核心推理引擎,Memory、Tools、Planner、Runtime 四件围绕它补齐架构缺失,再跑一个循环。也要接受随之而来的代价:每次推理至少 2-3 倍 token 消耗、调试需要看完整 trace 而不是单点日志、回归测试不能只覆盖输入输出还要覆盖路径、prompt 修改等同于代码修改要走完整发布流程。
这些代价不是缺陷,是把"概率性的推理引擎"工程化成"可生产的系统"必须支付的工程税。理解这一点,才能避免两类常见错误:一是低估代价的"用 Agent 解决一切",二是回避代价的"Agent 没法生产化"。真正成熟的工程师走的是中间路线——只在必要时才动用 Agent,动用时把代价算清楚。
LLM 是函数、Agent 是系统——这个判断的全部含义是:构建 Agent 不是写 prompt 也不是调模型,是设计系统。框架会变、API 会变、模型会变,但"哪些局限需要被补上、用什么结构补、付出什么代价"这套设计原理,比任何具体技术栈活得久得多。