# 拆解 AI Agent 架构:从 ReAct 到 Multi-Agent 到底发生了什么大模型从"聊天窗口"走出来变成"能干活的工具",Agent 架构是背后的关键。这篇文章不讲概念,直接拆实现——每个组件怎么工作、哪里容易踩坑、工程上该怎么选。LLM 本质上一个词一个词往下猜的生成器。写文章、翻译、做摘要,没问题。但让它干点"实在事"就露馅了。你让它"查一下上海明天天气,下雨就帮我加个日历提醒",它会给你编一段看起来挺像那么回事的回答。但它根本查不了天气,也动不了你的日历。知识停在训练数据里,手脚被绑着——这就是 LLM 的能力天花板。Agent 做的事就是给它装上手脚和眼睛:●能动手改变外部状态(写代码、发请求、操作数据库)三件事凑一块,模型就从"知道很多"变成了"能干点事"。2022 年那篇 ReAct 论文提出了一个很简单但效果出奇好的想法:让模型边想边干。循环是怎么跑的:while 任务没完成: 想 = 模型生成("现在什么情况,接下来该干嘛?") 干 = 模型生成("我要执行什么操作?") 结果 = 执行(干) 把想、干、结果拼到一起,继续下一轮
关键在"想"这一步。没有这一步,模型就是一只无头苍蝇——拿到任务直接上手,经常干错。有了这一步,模型被迫停下来组织思路,然后再行动。为什么"想一下"效果这么大?自回归训练的目标是让下一个词尽可能像人写的,而不是让逻辑尽可能正确。所以模型天然倾向于写"读起来顺但经不起推敲"的文本。Thought 等于在生成链路里塞了一个自我校准的环节。模型先把思路理清楚,思路再去指导行动。多了一层缓冲,出错率就下来了。对做工程的人来说,Thought 还有个额外的好处——可观测性。调试的时候你能直接看到模型"脑子里在想什么",比纯黑盒排查问题不知道方便多少。ReAct 的硬伤:第一,只能串行。上一步的输出是下一步的输入,子任务之间哪怕没有任何依赖关系也只能排队等。第二,走错了不回退。某一步选错方向,后面全跟着跑偏。没有"撤回上一步重新选"的机制。第三,上下文越吃越多。想-干-结果每循环一次就吃掉一截上下文窗口,循环多了模型就"忘记"最开始要干嘛。这些问题不是 ReAct 的错——它本身就不打算解决这些。但它确实给后面的架构指明了方向。任务复杂到一定程度,单个 Agent 就会开始力不从心。和做业务系统一样——单体架构扛不住的时候就拆微服务,一个 Agent 扛不住就拆多个。原因和拆微服务几乎一模一样:一个 Agent 同时干规划、写代码、做测试、搞部署,光是上下文切换就够它受的。出了错也不好定位——到底是规划阶段想错了,还是执行阶段做错了?拆开的逻辑很朴素:专业的人干专业的事。几种常见的组织方式:管道型——排成一排,一个传给下一个:流程固定、阶段清晰的场景用这个。实现简单,问题也明显:下游发现问题了,上游得从头再跑一遍。星型——中间一个调度者,四周是干活的:编码 Agent ↑审查 Agent ← 调度者 → 调研 Agent ↓ 测试 Agent
目前用得最多的结构。灵活性和可控性之间取得了一个不错的平衡。调度者负责任务拆分和结果汇总,各个专业 Agent 各干各的。网状——Agent 之间直接对话:A ←→ B ←→ C↑ ↓ ↑D ←→ E ←→ F
理论上最灵活,但调试起来是个噩梦。目前研究用得多,生产环境少见。多 Agent 带来的新问题:token 消耗暴涨。Agent 之间每次消息传递都是一次完整的模型调用。5 个 Agent 协作下来,token 量轻轻松松翻十倍。成本问题绕不开。各说各话。不同 Agent 对同一个概念可能有不同的理解。A 说的"模块"和 B 说的"模块"可能完全不是一回事。需要在架构层面统一术语和约束。死锁。A 等 B,B 等 C,C 在等 A——系统就卡在那儿了。调度者层面必须做依赖分析和拓扑排序。Agent 能干多少活,取决于它能用多少工具。这部分是最"工程化"的,也是系统实用性的关键。两种主流方式:结构化调用(Function Calling):模型输出一个结构化的调用描述,框架解析后执行。OpenAI 和 Anthropic 的 API 都原生支持这种方式。json{ "name": "search_codebase", "arguments": { "query": "authentication middleware", "language": "python" }}
好处是格式固定、容易解析、执行结果能精准反馈给模型。坏处是只能调用预先注册好的工具。代码执行(Code Execution):模型直接生成 Python 或 Shell 代码,在沙箱里跑。灵活性高得多,模型可以自己组合各种库和 API。好处是表达力更强。坏处嘛——安全隐患大(必须有沙箱),调试麻烦,执行结果不可控。模型写了个 rm -rf / 也不是不可能。工具多了以后模型会选错:一个常见但容易被忽略的现象:工具数量上来之后,模型选对工具的概率反而下降。原因不复杂。一是工具描述写得不清楚,两个工具功能差不多,模型自己也分不清该用哪个。二是 prompt 里塞了太多工具描述,模型对每个工具的注意力被稀释了。几个在实践中有效的缓解办法:工具按类别分组,只在与当前任务相关的组里挑。先让模型做一步"工具规划"——确定大方向再选具体工具。给每个工具配 1-2 个使用示例,调用准确率会明显提升。金鱼只有七秒记忆,但 Agent 需要记住东西。这里的记忆不是模型参数里训练出来的知识,而是运行过程中需要保持的状态。短期记忆:短期记忆就是当前的对话上下文。管理策略直接影响 Agent 的表现。三种常见做法:全部留着——信息最完整,但窗口很快爆满,而且后面的信息太多会干扰模型判断。滑动窗口——只保留最近几轮。简单粗暴,但早期的重要信息说丢就丢了。摘要压缩——定期把历史对话压缩成摘要,用更少的 token 装更多的信息。目前性价比最高的方案。长期记忆:长期记忆一般用向量数据库来做,让 Agent 跨会话也能记住关键信息。用户提问 → 检索相关记忆 → 注入上下文 → 模型生成
流程简单,坑不少。向量检索在代码库这种技术场景里召回率经常不够,纯靠语义相似度会漏掉很多关键信息,需要配合 BM25 或者 AST 解析。记忆过期也是个问题。用户换了项目,之前的项目记忆就成了噪声。按时间衰减是最简单的做法,但更好的做法是语义级别的过期检测——判断这条记忆和当前任务还有没有关系。隐私隔离不用说,不同用户、不同项目的记忆必须严格分开。这大概是工程实践中最让人头疼的问题。传统软件跑测试,pass 还是 fail 清清楚楚。Agent 不一样——同样的输入,跑两次可能得到完全不同的输出。几个常用的衡量维度:任务能不能完成,这是底线。但对于"写一个 API"这种开放任务,谁来评判写得好不好?只能靠人工或者再套一个模型来评。完成用了多少步。步骤越多成本越高,出错概率也越大。工具选得对不对。这个可以直接统计。遇到意外情况能不能扛住。给工具调用注入异常,看 Agent 是优雅处理还是直接崩掉。LLM 当裁判:让另一个 LLM 来评判 Agent 的输出质量,现在用得最多。成本低,覆盖面广。但这个方法有几个已知问题。不同的评判模型对同一份输出可能打出完全不同的分数。评判模型倾向于给更长的回答打高分。在多个候选答案里,排在前面的更容易被选中。缓解办法包括:多次随机排序取平均、用多个不同的评判模型交叉验证、给结构化的评分量表而不是让模型自由评价。从技术演进的方向来看,Agent 架构正在往几个地方收敛。规划能力要更强。现在的规划基本就是把任务拆成线性步骤。后面需要条件分支、并行执行、回溯重试这些更复杂的能力。Tree of Thoughts 和 Graph of Thoughts 是早期的尝试,方向是对的。自我修正。让 Agent 能发现自己错了并且主动改。这比在外面再套一个 review Agent 更干净,但也更难——一个能发现自己错误的模型,为什么一开始会犯错?这已经涉及到模型的元认知了。端侧部署。模型越来越小,端侧推理框架越来越成熟,部分 Agent 能力迟早要下沉到设备端。隐私友好是一方面,另一方面是倒逼 Agent 架构在有限资源下也能高效运行。Agent 不是某个具体的产品,它是一种组织 AI 能力的方式。把 Agent 的每个组件——规划、记忆、工具调用、多 Agent 协作——都当作可以测试、可以优化、可以替换的软件模块来看待,AI 系统的工程化才算是真正落地。这也是做工程的应该切入的角度。概念会过时,框架会换代,但底层的架构思维不会。觉得有收获的话,转发给做技术的朋友看看。