AI 基建
0%
第六部分 · 编排 · 第 38 章

智能体架构

作者Changkun Ou
阅读时长约 13 分钟

智能体的本质,是将语言模型放进一个执行循环:行动、看结果、再行动。这个循环通常拆成四块:规划、记忆、工具使用,以及把它们串起来的动作循环。控制流必须把推理和行动交织起来,因为下一步决策要看见上一步行动暴露出的事实;工具使用则是让一个文本生成器真正改变世界的那一块。

2026-06-22T11:57:20.919731 image/svg+xml Matplotlib v3.10.8, https://matplotlib.org/ 0.0 0.2 0.4 0.6 0.8 1.0 自主性 0.0 0.2 0.4 0.6 0.8 1.0 影响半径 聊天 工具使用 规划器 自主运行
图 38.1. 不同智能体架构在自主性与影响半径之间取舍的示意图。更多规划与委托扩大了系统能力,也扩大了出错范围。理想化位置,非实测。

计划遇到真实环境

最直觉的做法,是让模型先把任务读一遍、想清楚,再写出一份完整的计划:第一步跑测试,第二步打开报错的文件,第三步修掉第 40 行的差一错误,第四步重跑;然后照着计划一步步做下去。

这套设计简洁、清楚,但问题也在这里。计划是在任何一步真正运行之前就写好的,也就是说,智能体还没看到这些步骤会暴露出什么,就把后面全定死了。可第一步一跑测试,失败的原因往往不是模型猜的那个:bug 不在第 40 行,也不是什么差一错误。于是计划里往后的每一步,都指向一个根本不存在的局面。智能体拿着一份已经过时的计划,要么继续执行并偏离任务,要么干脆抛弃它。无论哪种,事先把整件事规划周全都没换来任何好处,因为第一次观察就让它作废了。

因此,智能体的骨架是一个循环,而不是一份计划。这个循环的形状解释了为什么思考和行动必须交织,也解释了智能体为什么会拆成规划、记忆、工具使用和动作这几块。

弥合模型与世界之间的缺口

先想清楚为什么非要一个循环不可。基座模型做的事,是把一段提示接成一段续写。答案如果本就藏在权重里,这就够了;可一旦答案取决于世界此刻的状态,它就无能为力:某个文件现在的内容、一次查询返回了什么、改完之后测试过不过。这些状态,模型既读不到,也动不了。它输出文本,然后停下。

智能体要解决的,本质上就是这道缝:让模型能在世界里执行一个动作,看见这个动作产生了什么,再把这次观察送回到下一个决定里。而且得反复地做,因为真实任务往往不止一步那么短:修一个 bug,是读、猜、改、测,还多半要来回好几遍。

在画架构之前,先把这道缝隙两侧的约束说清楚。第一,上下文窗口是有限的,长任务没法把每一次观察都同时摊在眼前。第二,每走一步都要调一次模型,所以这个循环既费时间、又费钱。第三,模型是概率性的,任何一个动作都可能出错,架构因此必须能容错、能从错误中恢复,而不是装作错误不存在。先规划后执行之所以会栽,正栽在第三条上:它默认自己第一次的猜测,经得住真实世界的第一次碰撞。

改改下面的每步成功率和任务步数,就能看出为什么一份事先写死的计划这么脆:没有补救的计划,只有每一步都成了才算成,所以它的总成功率,是每步成功率的「步数」次方。

import numpy as np
n = np.arange(1, 21)               # 任务长度:1 到 20 步
for p in [0.99, 0.95, 0.90, 0.80]: # 每步可靠度
    survive = p ** n               # P(全部 n 步都成功,无恢复)
    import matplotlib.pyplot as plt
    plt.plot(n, survive, marker="o", ms=3, label=f"p={p}")
plt.xlabel("计划步数 n")
plt.ylabel("P(无恢复时计划成功)")
plt.ylim(0, 1); plt.legend(); plt.title("为什么先计划后执行很脆弱")
plt.show()
for p in [0.95, 0.80]:
    print(f"p={p}: 10-step plan succeeds {p**10:.1%} of the time")

这个循环,以及它为什么交错

真正管用的做法,并不会把推理和行动分开,而是将它们结合起来:模型先写一小段推理,接着做一个动作,看结果,再带着这个结果去推理。这就是 先推理后行动(ReAct),由 Yao 等 (Yao et al. 2023) 提出,关键正在于这种结合:推理让模型边走边决策、随时改计划,行动则把那些仅靠内部推理容易想错的事实,带到模型眼前。计划从来不是一次写成的,它每一回合都照着上一个动作的返回去改,上一节那个失败模式,在这里正好反过来成了优点。

模型把任务想一遍,猜 bug 是第 40 行的差一错误。
它不急着认这个猜测,而是调一个工具:跑测试。
测试失败了,却不是它猜的那样:bug 不在第 40 行,也不是差一错误。
这次观察被追加进不断变长的上下文,于是下一步推理看到的是真实的失败,而不是那个猜测。
拿着这个事实,它改掉假设,再选下一个动作;这一回合不断重复,直到测试通过。
图 38.2. 逐步走过一个「推理-行动-观察」回合,看它不断循环:推动下一步推理的是观察,而不是事先那个猜测。
M 模型:推理 A 选择动作 M->A F 最终答案 M->F 完成 T 执行工具 A->T O 观察 T->O O->M
图 38.3. 先推理后行动的循环。每一回合,模型先推理、选一个动作,再把观察折回来重新推理。依据 Yao 等(2023)。

图 38.3 里的循环是整个架构的核心,而真正把智能体和一次单独的模型调用区分开的,正是它具体的形状。后面的内容,要么是这个循环带动的某个部件,要么是把它放到生产里跑所带来的某个后果。

把这个循环落成代码,要遵守的运行时约定其实很小:开一个会话、绑定到某个智能体定义;把上下文交给模型,把它返回的工具调用分发出去,把结果追加回去,如此往复,直到模型示意做完、或者循环被打断。这串动作,就是先推理后行动跑起来的样子。真正难的,是让这份约定在生产里可靠运行,包括跨崩溃的持久化、调度与中断。那些机制属于运行框架,第 41 章 会专门去谈;本章只先把架构边界画清楚。

循环的解剖

这个循环有四个活动的部件。如今主流的拆法,是围绕一个当控制器用的模型,把智能体分成这四块,出自 Lilian Weng (Weng 2023),现在已经是通用说法:规划记忆工具使用,外加把它们串起来的动作循环。

  • 规划把一个目标拆成一连串步骤。最基础的样子,就是模型走一步看一步,临场决定下一步做什么;更结构化的样子,是把任务明确切成若干子目标,还会回头反思走过的步骤、随时纠偏。
  • 记忆是能跨步骤留存下来的东西。短期记忆就是上下文窗口本身,一份「发生过什么」的流水账;长期记忆则是智能体能读能写的外部存储,因为窗口太小,装不下一个长任务。把记忆当成一个系统来看,第 39 章 会专门展开;在这里,它只是循环依赖的四块之一。
  • 工具使用是智能体把手伸到权重之外的办法:一个能调用的函数,用来抓网页、跑代码、查数据库,或者改一个文件。一次工具调用,是智能体读到、或动到外部状态的唯一通道。
  • 动作就是带动另外三者转起来的那个循环:把当前上下文交给模型,让它挑一个工具来调,执行,追加结果,再来一遍。

把这四块按各自所在的位置摆开,会看得更清楚。规划,是模型在自己一次前向传播里做的推理;短期记忆,就是上下文窗口,同样在模型眼皮底下;工具使用,是唯一一条跨出权重、通向世界的边;长期记忆,则待在这条边的另一头。

cluster_model 模型内部 cluster_world 外部状态 ctrl 控制器 (推理模型) plan 规划 ctrl->plan 决定步骤 stm 短期记忆 (上下文窗口) ctrl->stm 读/写 tooluse 工具使用 ctrl->tooluse 调用 ltm 长期记忆 (外部存储) world 文件、查询、 代码、网络 tooluse->ltm 回忆/持久化 tooluse->world 行动/观察
图 38.4. 把四块按位置看:规划与短期记忆在模型边界之内,工具使用是唯一通向外部状态和长期记忆的边。依据 Weng(2023)。

四块里,真正撑得起「智能体」这个名号的,是工具使用。规划和记忆决定模型怎么想,工具使用却是唯一让它伸过权重去碰到世界的部分,也就是 图 38.4 里唯一跨出边界的那条边。没有它,这个循环只是在文字里空转。

这些部件如何成熟

这套拆法不是一开始就齐整的。这些部件落地的先后,恰好解释了最后的组合为什么长成现在这样。

最先成熟的,是被当成一种习得技能的工具使用。Toolformer (Schick et al. 2023) 证明,模型能用自监督的方式,自己学会什么时候该调一个 API、又怎么把结果接回自己的生成里。由此,工具使用不再只是推断时临时接上的功能,而是一种可以训练出来的能力。

与此同时,推理能力也在发展。思维链提示发现,让模型在给答案之前先把中间步骤写出来,多步问题上的表现就会变好,这条线 第 24 章 有细讲。ReAct 做的,是把这种推理和行动放进同一条交错的轨迹 (Yao et al. 2023),正好补上思维链的短板:一条纯推理链没办法拿自己去和世界核对,只会把自己的错和幻觉一路传下去;而在推理步骤之间穿插一次 Wikipedia 查询,就能让每一步都依据一个刚查到的事实。至于那套四部分拆法,是把这些部件一一命名的那次组合 (Weng 2023):它把规划和记忆抬成和工具使用并列的一等组件,而不再是一段提示里藏着的隐含特征。

最近变动最大的,是推理到底待在哪儿。早期的智能体把推理放在提示里:运行框架叮嘱模型一步步想、把想和做交错开。而被训练成会在内部审思的推理模型(见 第 28 章),正在把这部分工作下沉到模型内部。智能体架构还是那个形状,一个处在先推理后行动循环里的模型,只是规划这一块,越来越多是模型在自己练出来的推理里完成的,而不再靠运行框架用提示一层层支撑。

几处悬而未决的取舍

架构上的每个选择都是一次权衡,各有各要付的代价,值得一一点出来。

  • 显式规划,还是让模型边走边想。 事先把任务分解,好处是给出一份人能审、能看的清楚计划,也能让长任务不跑偏;坏处是,它在任何观察出现之前就把结构定死了,于是一旦遇到意外,这份计划就得推倒重来,正是开头那一幕。反过来,走一步想一步能贴着每次观察走,却没有全局视野,容易东飘西荡。多数生产里的智能体落在中间,也就是先推理后行动:一份轻量的计划,每一步都照上个动作的返回随手改。
  • 工具的数量,还是模型的注意力。 智能体能调的每一个工具,都要在上下文里占一份 schema,也都是它每回合得掂量的一个候选。只有少数经过筛选的工具时,模型还能稳定选择;目录一旦庞大,每个回合都白白吃掉上下文,选得也越来越不准,因为模型的注意力有限,而那些不相关的工具会实实在在地添乱。这股压力,逼出了一套工具选择策略,本节往下和 第 41 章 都会谈。
  • 短期记忆,还是长期记忆。 什么都留在上下文窗口里,窗口没满之前又简单又不丢东西,可一满,任务就卡死。把记忆挪到外面,任务就能没完没了地跑下去,但智能体能记起多少,全看它当初愿意写下多少、又检索得回多少。这条界线,即哪些留在窗口、哪些挪进存储,这里只是点到,第 39 章 会进一步深入。
  • 每回合一次工具调用,还是以代码为动作。 下文的循环每轮分发一次结构化调用,好处是每个动作都清晰可读、可以设卡,也随时能被打断。CodeAct 确立了另一条路:让模型直接输出可执行代码,在沙箱里把多次工具调用、循环与结果过滤组合起来,把好几轮循环压成一个动作,在 17 个模型上把成功率最多提升 20% (Wang et al. 2024)。这笔交易换掉的正是循环自身的形状:动作更少、更大,省下了往返的词元,却更难逐个审查、逐个设卡。这一张力在 第 46 章 里还会遇到一次,那里是代码执行包住 MCP 工具。
争议所在

规划到底该多显式,至今没有定论。一派做的智能体,会把任务拆成一份写下来的子目标计划,还在步骤之间反复反思,理由是计划越清楚,就越可靠、越好审。另一派认为,一个有本事的推理模型,在它自己练出来的推理里隐式地规划,比运行框架外加的任何提示层支撑都强,显式的规划部件反倒给一个模型如今自己就能办到的事添了脆性。同一场争论也贯穿在工具发现上:到底该由运行框架替模型挑好每回合看见的工具,还是给模型一个自己找工具的法子、再信它会选对。两边都没分出胜负,而且随着底层模型推理变强,正确的答案还会随之改变。

循环分发的是什么

循环本身写起来很短,细节却很容易出错。用伪代码看,就是一个绕着模型调用转的 while:

loop:
    response = model(context)
    if response has no tool call:
        return response            # the model is done
    result = execute(response.tool_call)
    context = context + response + result

真正困难的部分,集中在 execute 的边界,以及 context 如何被更新。

循环要分发的工具,彼此并不一样,而一个把它们一律同等对待的循环,多半会把大多数都处理错。按状态来分,工具有三类。无状态工具在智能体这边不留任何状态:抓一次网页、按沙箱 ID 跑一条沙箱命令、一次普通的 REST 调用,都属于这类,简单,扩容也不费劲。有状态连接工具,典型就是 2025 年各修订版形态下的模型上下文协议(MCP) (Model Context Protocol 2026),它把协商好的能力和游标状态,存在一条循环必须跨调用保持的连接里。有状态资源工具,则把状态放在某个外部系统里,一个数据库会话、一个长跑的作业,循环得跨回合一直识别它。架构上的关键在于:对「重启之后会怎样?」这个问题,这三类给的答案各不相同,什么都不用做、重连,或者重新发现。至于怎么让这些连接经过重连和令牌刷新仍然可用,那是运行框架的工程,留到 第 41 章;架构要做的,是认得这三类的存在,不要将它们混淆。这三类划分比其中任何协议的归属都更耐久:2026 年的 MCP 规范工作移除了协议级会话,把这个有状态连接的典型例子推向无状态一类,而分类法本身依然成立 (Model Context Protocol 2026)。图 38.5 按这个问题把三类工具并排展示出来。

q 工具的状态住在哪里? stateless 无状态 网页抓取、REST 调用、 按 ID 的沙箱命令 q->stateless 哪里都不 conn 有状态连接 MCP 会话:能力与游标 保存在一条活的链路里 q->conn 在连接里 res 有状态资源 数据库会话、长跑作业 在一个外部系统里 q->res 在外部系统里 r1 重启时:什么都不做 stateless->r1 r2 重启时:重连 conn->r2 r3 重启时:重新发现 res->r3
图 38.5. 三类工具,按状态待在哪里、以及重启时各自得做什么来分:什么都不做、重连,或重新发现。

有一个动作空间处在这套分类法的边缘:计算机使用(computer use)。它的「工具」是整个图形界面,动作是点击与击键,观测是屏幕截图(Anthropic 于 2024 年 10 月发布这一能力,OpenAI 的 Operator 于 2025 年 1 月跟进 (Anthropic 2024))。它对循环的考验最重:时间跨度长、像素观测嘈杂、没有 schema 可以校验一次调用,这也是 CoAct-1 这类混合系统在 GUI 动作与生成代码之间来回切换的原因 (Song et al. 2025);第 52 章 对这类智能体的评判依据是最终的环境状态。

还有一个反复出现的实现问题:某一回合里,到底让模型看见哪些工具。最简单的做法是一份静态的扁平清单,每回合把所有工具都发出去,这套办法大约到三五十个工具就到头了,因为上下文开销和选择准确率,都随目录变大而变差。过了这个坎,选择就只剩几种:每回合检索一个相关子集、每个阶段只露出裁剪过的一组,或者让模型按需自己去发现。这套选择机制是运行框架的零件;而催生它的,是模型的一个属性,也正是下面那个框要点出的约束。

拖一下滑块,就能看到下面那个框讲的约束:上下文里的工具越多,函数调用的准确率越往下掉,这正是为什么扁平目录到了几十个工具之后就不再顶用。

图 38.6. 工具选择准确率随目录变大而下滑,这正是工具 RAG(每回合只检索相关的那几个工具)和分阶段挂载背后,那个被测出来的效应。
下层约束

工具一多,模型的选择准确率就下滑,这是个下层属性,却管住了上层的架构。Berkeley Function Calling Leaderboard (Yan et al. 2025) 和 ACEBench (Chen et al. 2025) 都测到:可用工具越多,函数调用越不准,尤其一旦掺进不相关的工具,鲁棒性就受损。正是这份被测出来的下滑,决定了智能体不能图省事,把可能用得上的工具全注册上、每回合再把整份目录甩出去。模型那点有限的注意力,在架构这一层逼出了工具 RAG、分阶段挂载,或者让模型自己去发现。模型处的一个能力上限,定下了智能体处的一个结构性选择。

延伸阅读

  • Weng, “LLM Powered Autonomous Agents,” 2023. lilianweng.github.io
    Lilian Weng 的博文综述了以大语言模型(LLM)为核心控制器的自主智能体系统,将其分解为规划、记忆与工具使用三个核心组件。
  • Yao et al., “ReAct: Synergizing Reasoning and Acting in Language Models,” 2023. arXiv:2210.03629
    ReAct 提出在 LLM 提示中交替生成推理轨迹与环境动作,减少幻觉并在问答、事实核查和决策任务上超越仅推理或仅动作的基线。
  • Schick et al., “Toolformer: Language Models Can Teach Themselves to Use Tools,” 2023. arXiv:2302.04761
    Toolformer 通过自监督的 API 调用过滤,训练大语言模型自主决定何时及如何调用外部工具,在无需人工标注的情况下实现强零样本性能。
  • Yan et al., “The Berkeley Function Calling Leaderboard (BFCL): From Tool Use to Agentic Evaluation of Large Language Models,” 2025. openreview.net
  • Chen et al., “ACEBench: A Comprehensive Evaluation of LLM Tool Usage,” 2025. aclanthology.org
    ACEBench 是一个全面评测大语言模型(LLM)工具调用能力的基准,涵盖常规、特殊(指令不完整)和智能体(多轮对话)场景,并支持无需 LLM 的自动化评测。
  • Model Context Protocol, “The 2026 MCP Roadmap,” 2026. blog.modelcontextprotocol.io
    MCP 2026 官方路线图将传输可扩展性、智能体通信、治理授权与企业就绪列为推动模型上下文协议(MCP)发展的四大优先领域。
  • Wang et al., “Executable Code Actions Elicit Better LLM Agents,” 2024. arXiv:2402.01030
    CodeAct 让大语言模型智能体以可执行 Python 代码作为动作空间,取代每轮一次的结构化工具调用,在单个动作中组合多次工具调用,在 17 个模型上将成功率最多提升 20
  • Song et al., “CoAct-1: Computer-using Multi-Agent System with Coding Actions,” 2025. arXiv:2508.03923
    CoAct-1 是一个计算机使用多智能体系统,其协调者将子任务分派给 GUI 操作员或程序员智能体,在 OSWorld 上取得 60.76

评论

登录后评论