11. 说说 Single-Agent 和 Multi-Agent 的设计方案?

Single-Agent 适合任务流程清晰、复杂度适中的场景,实现简单、好维护;Multi-Agent 适合需要专业分工、任务量大或者需要并行执行的复杂场景。Multi-Agent 架构上主要有两种拓扑:中心化的 Orchestrator 模式,由一个主 Agent 统一调度各个 Worker;去中心化的 Peer-to-Peer 模式,Agent 之间直接通信。我在工程里用中心化用得更多,因为好控制、好调试,出问题链路清晰。

Single-Agent

先把 Single-Agent 说清楚。它的本质是一个 LLM 加上一套工具,跑一个决策循环:LLM 判断下一步该做什么,调用工具执行,拿到结果,再判断,直到任务完成。

它最大的优势不只是「架构简单」,更核心的是「整条任务链路完全在你掌控之内」。任务怎么走、用什么工具、什么时候结束,所有逻辑都是你在一个地方写清楚的,出了问题链路短,好排查。

类比一下:一个人完全可以独立完成「写一篇博客」,自己查资料、想大纲、写下来,不需要团队协作,单人反而更高效,沟通成本为零。

Single-Agent 真正开始力不从心,是在遇到这几类任务的时候:任务太长、信息量太大,context 撑爆,Agent 开始遗忘;不同步骤需要完全不同的专业能力,什么都塞进一个 Agent,每件事都做得不够专注;任务中有多个独立子任务,理论上可以并行,但单 Agent 只能一个个来。遇到这三类情况,Multi-Agent 就有了真实价值。

但需要强调的是:如果你的任务不属于这三类,Single-Agent 就够了,不要为了「用新技术」而强行引入 Multi-Agent,系统会变复杂、变难维护,但没有带来对应的收益。

Multi-Agent 的中心化方案

Multi-Agent 的中心化方案,核心是一个叫 Orchestrator 的特殊角色。「Orchestrator」直译是「交响乐指挥」,在 Multi-Agent 系统里,它的中文可以理解成「总调度员」或「项目经理」。它是整个系统里最特殊的那个 Agent,因为它不做任何具体工作,它只负责三件事:读懂用户的大目标、把它拆成一个个子任务;判断每个子任务该交给哪个 Worker Agent 去做;收集每个 Worker 的产出,把它们拼成最终答案。

Orchestrator 其实有几种变体,适合不同复杂度的场景。最基础的是静态路由(Static Router),任务拆分和分配规则是预先定义好的,比如「遇到代码任务交给 Coder Agent,遇到搜索任务交给 Researcher Agent」,逻辑简单可预测。进阶一点的是动态规划(Dynamic Planner),Orchestrator 本身是一个 LLM,它会根据用户输入动态生成任务计划,决定需要几个步骤、每步交给谁,计划本身也可以在执行过程中调整。最复杂的是自适应编排(Adaptive Orchestration),Orchestrator 不仅动态规划,还会根据 Worker 的执行结果实时调整后续计划,比如 Researcher 搜回来的信息不够,Orchestrator 会追加一轮搜索任务,而不是硬着头皮往下走。实际项目里,大多数场景用动态规划就够了,自适应编排虽然更强大但调试复杂度也高很多。相对的,Worker Agent 就是「执行者」。每个 Worker 只关注自己那块,它不需要知道整体任务是什么,不需要知道其他 Worker 在做什么,只需要拿到属于自己的那部分指令,做完返回结果,然后退出。它的 context 是干净的,只装着和自己职责相关的信息。

用一个具体任务来走一遍完整流程,帮你真正理解 Orchestrator 是怎么工作的。假设用户说「帮我写一份 AI 行业竞品分析」:

这个流程最大的好处,是每个环节出了问题,你能精准定位。报告内容不够准确?可能是 Researcher 搜的信息不够好。分析逻辑有问题?可能是 Analyst 的对比维度不对。报告格式不符合要求?是 Writer 的输出问题。每个 Agent 职责清晰,排查不需要猜,顺着 Orchestrator 的调度记录一步步追下去就能找到根源。

去中心化方案:为什么「听起来更灵活」却很少在工程上用

去中心化的思路是没有总调度,多个 Agent 通过共享的消息队列或状态空间自行协商、直接通信。听起来很美好,像一个能自我组织的团队,不需要领导,大家自动配合,还更灵活。

但实际工程里会遇到什么问题?用一个具体场景来说明。

假设三个 Agent 在处理同一个任务:Agent A 在搜索信息,Agent B 也在搜索类似的信息,Agent C 负责汇总结果,但没有人统筹调度。这时候几个问题会同时出现:首先,没有人告诉 A 和 B 「你们各搜什么范围」,很可能两个人搜了大量重叠的内容,做了重复工作;其次,C 需要等 A 和 B 都搜完才能汇总,但没有人告诉 C「A 和 B 什么时候算搜完了」,C 不知道该等多久,也不知道有没有漏掉某个 Agent 的结果;再者,如果 A 中途出错了,没有中央调度者收到错误通知,B 和 C 可能还在正常运行,最后汇总出来的是一份不完整的结果,但系统甚至不知道这里出了问题。

总结下来,去中心化系统里这几类问题会频繁出现:任务分配没有协调、执行顺序没有保证、失败没有感知、没有人来确认「任务整体完成了」。类比一个没有项目经理的团队:每个人都很能干,但没有人协调时间节点和接口,最后交出来的可能是互不兼容的结果,而且没有人知道整体进度到底怎么样了。

这就是为什么去中心化方案更多停留在学术研究里探索,研究的是「AI 系统能不能实现自主协调」这个更宏观的问题。而生产环境里,几乎所有正经项目都选 Orchestrator 模式,因为可控、可追踪、出了问题能排查,这才是工程上真正需要的。

怎么做选型决策?

选型的逻辑其实可以用两个问题来搞定。

先问第一个问题:你的任务,Single-Agent 能搞定吗?如果任务流程明确、不太长、不需要多种专业分工,Single-Agent 就够了。架构简单、维护成本低、链路透明,不要为了「显得高级」而引入 Multi-Agent。

如果任务确实超出了 Single-Agent 的边界,再问第二个问题:你能接受系统行为不可控的风险吗?生产环境里这个问题的答案几乎一定是「不能」,所以就用 Orchestrator 模式。

实际工程里有一个很实用的策略叫渐进式演进:先用 Single-Agent 把系统跑起来,当你发现某个环节确实成为瓶颈了,比如 context 经常撑满、某类子任务质量不行,再把那个环节拆出来交给一个专门的 Worker Agent。不要一上来就设计一个五六个 Agent 的复杂系统,你可能连哪里是真正的瓶颈都还没搞清楚。从 Single-Agent 演进到 Multi-Agent 是一个自然的过程,而不是一开始就做的架构决策。

另外值得关注的一个行业趋势是 A2A(Agent-to-Agent)协议,Google 在 2025 年提出的开放标准。它要解决的问题是:不同团队、不同框架开发的 Agent 之间怎么互相通信和协作。之前每个 Multi-Agent 框架都有自己的通信方式,Agent 只能在同一个框架内协作。A2A 定义了一套标准化的通信协议,让不同来源的 Agent 能像微服务一样互相调用,这意味着未来你可以把别人开发好的 Agent 当作一个「服务」直接接入你的系统,而不需要了解它内部是怎么实现的。A2A 在 2025 年已经纳入了 Linux Foundation 治理,IBM 的 Agent Communication Protocol(ACP)也已并入 A2A,生态正在快速成熟,长远来看会深刻改变 Multi-Agent 系统的构建方式。

这道题最容易犯的错误有三个,对应开头对话里踩的三个雷。第一,选型标准不能只说「任务复杂就用 Multi-Agent」,要说出具体的三类场景:context 要撑爆了、需要不同专业分工、有子任务可以并行,不属于这三类就用 Single-Agent,盲目引入 Multi-Agent 只会增加系统复杂度,带不来对应收益。第二,Multi-Agent 架构方案要主动提中心化和去中心化两种,而且要明确说出工程里几乎都选 Orchestrator 中心化模式,因为可控、可追踪、出了问题能顺着调度链路排查。第三,去中心化「听起来灵活」但要能说清楚它的实际问题:任务分配没协调、执行顺序没保证、失败没有感知,这才是它在生产环境里不可用的根本原因。

12. Agent 记忆压缩通常有哪些方法?

记忆压缩常见有四种方法:摘要压缩、滑动窗口、重要性过滤、结构化抽取。摘要压缩是把长对话总结成简短摘要;滑动窗口是只保留最近 N 轮对话;重要性过滤是打分筛选,只留重要内容;结构化抽取是把关键信息抽成结构化数据存起来。我在实际项目里最常用的是摘要压缩和滑动窗口,而且经常组合用,滑动窗口丢弃前先做一次摘要,尽量不丢重要信息。

想象这样一个场景:你在用一个 AI 助手帮你推进一个复杂项目,聊了一个多小时,确认了技术方案、梳理了需求、定下了几个重要决策。然后有一刻,AI 突然开始「忘事」了,把你早就敲定的方案搞错,重新提出已经被你否决的思路。你感觉很困惑,明明刚才还在聊,它怎么就不记得了?

这个现象的根源,就是 context window 的限制。

LLM 每次生成回答,并不是像人脑一样有持续的记忆,它依赖的是「每次调用时传入的完整对话历史」。你和它聊的每一句话,都被打包成 messages 列表传进去,模型读完这些内容,才能生成下一条回复。这个 messages 列表是有硬上限的,GPT-4o 是 128K token,Claude Sonnet 4 是 200K token(Claude 4.6 系列已扩展到 1M token),超过了就得截断。默认的截断策略是「从最老的对话开始丢」,于是那个三十分钟前确认的技术方案,就这么被扔掉了。

更现实的压力还有成本。就算没有超过 token 上限,对话越长,每次调 LLM 的费用就越高,因为你把越来越多的历史塞进了输入。高频使用场景下,这是货真价实的成本压力。

记忆压缩要解决的,就是「空间有限、成本有压力」这两件事:在保留关键信息的前提下,减少历史记录占用的 token 数量。

第一种方法:滑动窗口,最简单的方案,也是最粗糙的

滑动窗口是最符合直觉的做法,就像手机聊天记录默认只显示最近 200 条:超出就从最老的开始删,只保留最近 N 轮对话。

好处是实现极其简单,不需要任何额外的 LLM 调用,也没有额外开销。坏处是「硬截断」,对话内容按时间一刀切,三周前确认的关键决策和昨天随口说的一句话,在这个方案里是被同等对待的,超出窗口就都消失了。

可以用一个词概括它的特性:「金鱼记忆」。它只记得最近发生的事,越往前越模糊,再久一点就什么都没了。对于短对话、或者历史信息不重要的场景,这个方案足够用,成本最低。

第二种方法:摘要压缩,丢之前先提炼一遍

摘要压缩是对滑动窗口「硬截断」的改进。核心思路是:不直接丢弃即将超出窗口的历史,而是先让 LLM 把这段历史总结成一段精华摘要,用摘要替换原始对话,再继续往前。

类比一下:你的笔记本快写满了,你没有把前面的页直接撕掉,而是先把前半本的要点重新整理成一页纸的精华总结,然后把前半本收起来,带着这页总结继续记录后面的内容。后来翻回去看,这页总结虽然不如原版详细,但关键脉络都在。

代价是摘要会丢失细节。LLM 在总结时,会按照自己判断的「重要性」来决定保留什么、省略什么。有些细节当时看起来不重要、被摘要略过了,后来却刚好需要,这时候就找不回来了。

这个方案单独用时,通常的做法是「旧的压缩成摘要,近的保持完整」,最近几轮对话往往和当前任务关系最密切,保持原文;更早的历史相关性低,压缩成摘要。

进阶一点的做法是层级式摘要(Hierarchical Summarization)。不是对所有旧历史做一次性摘要,而是分层处理:最近 10 轮保持原文,10 到 50 轮的历史压缩成一份「中期摘要」,50 轮之前的历史进一步压缩成更精炼的「长期摘要」。每一层的信息密度不同,越久远的越精炼,但核心决策和关键结论始终被保留。这有点像公司的会议纪要体系:今天的会议有详细的逐条记录,上个月的会议只留要点摘要,去年的只留关键决策备忘。层级式摘要的好处是,Agent 既能精确回忆近期细节,也能粗略回忆远期要点,比一刀切的摘要颗粒度更合理。

在实际工程里,这两种方法通常一起用,而不是单独用其中一种。滑动窗口负责控制对话历史的总长度上限,摘要压缩负责在历史被丢弃之前做一次提炼,把关键信息留下来。这样既有长度控制,又不是直接硬截断,是目前最常见的工程方案。

第三种方法:重要性过滤,按价值筛选,不按时间筛选

滑动窗口和摘要压缩有一个共同的思路:都是在「时间维度」处理历史,按照发生的先后顺序来决定保留什么。但时间不等于重要性。三周前的一句关键决策,可能远比昨天的几句闲聊更有价值,但在滑动窗口里它会先被丢掉。

重要性过滤换了一个角度,按内容的实际价值来决定去留:给每条对话记录打一个重要性分数,低于阈值的淘汰,高分的保留。

类比整理房间:一个人不会按照购买时间来决定扔什么东西,而是按照「这个东西现在还有没有用」来决定去留。一件五年前买的工具,如果还在用,就留着;一本上周买的书,如果一页没看还不打算看,就可以扔。

打分的方式有两种。一种是规则打分:包含「决定」「确认」「需求」等关键词的记录加分,被后续对话引用次数多的加分,纯闲聊降分。规则快、没有额外开销,但比较粗糙,边界情况容易判断失误。

另一种是让 LLM 来打分:逐条判断每条记录的重要程度。准确率更高,但每条记录都需要一次 LLM 调用,开销大,通常在批量清理历史时做,而不是实时处理每条消息。

还有一种更激进的重要性过滤思路叫观察遮蔽(Observation Masking)。它的做法不是删除低分内容,而是在构造 prompt 时选择性地「隐藏」某些历史条目。比如当前任务是写代码,Agent 会把之前关于需求讨论的对话标记为「与当前步骤无关」,构造 prompt 时直接跳过这些条目,只把和代码相关的历史传进去。任务进入测试阶段时,再把测试相关的历史「显示」出来,代码实现的细节对话则被遮蔽。这样做的好处是信息没有被真正删除,只是在不同阶段动态选择「当前最需要看到什么」,既节省了 token,又避免了不可逆的信息丢失。

另一个值得了解的概念是主动压缩(Proactive Compression)。前面说的所有方法都是被动触发的,等 context 快满了才开始压缩。主动压缩的思路是,Agent 在每一步执行完之后,主动判断哪些中间过程可以压缩。比如 Agent 调用了一个搜索工具,返回了 2000 token 的原始搜索结果,Agent 在读完之后立刻把搜索结果压缩成 200 token 的要点摘要,替换掉原始内容。这样 context 的增长速度从一开始就被控制住了,而不是等到快满了才临时抱佛脚。主动压缩特别适合工具调用频繁的 Agent,因为工具返回的原始数据往往很长,但真正有用的信息只占一小部分。

第四种方法:结构化抽取,换一种载体存信息

前三种方法有一个共同的前提假设:历史信息最好以「对话文本」的形式保留。结构化抽取的思路完全不同,它先问一个更本质的问题:我们真的需要保留对话文本本身吗?

很多场景里,真正有价值的不是对话文字,而是对话中传递的事实和状态。比如「用户偏好用 Python」「预算上限是 5 万」「已确认方案 B」「需要兼容移动端」。把这些信息主动提取出来,存成结构化字段,后续注入 prompt 时直接用这些字段,比传一大段对话文本要高效得多,信息密度也高得多。类比医生记录病历的方式:医生不会把和病人的所有对话逐字记录下来,而是整理成结构化的病历档案,「主诉:头痛三天,现病史:无发热,过敏史:青霉素,初步诊断:紧张性头痛」。这份档案的信息密度远高于原始对话文字,下次就诊时医生直接读病历,不需要把上次的全程录音重听一遍。

这种方案的信息损失最小,只要字段定义合理,重要信息全部被精确保留,没有摘要带来的模糊化。代价是开发成本最高:你需要预先定义「什么是重要字段」,这需要对业务场景有深入理解,而且不同类型的任务所需的字段可能完全不同,通用性较低。

四种方法的关系梳理

这四种方法不是互斥的,也不是按优劣排列的,而是从三个不同维度来解决问题的。

滑动窗口和摘要压缩解决的是「历史太长,怎么截」的问题,前者直接截,后者截之前先提炼。重要性过滤解决的是「内容不等价,怎么挑」的问题,打破时间顺序,按价值筛选。结构化抽取解决的是「对话文本本身是不是最佳载体」的问题,换一种更高效的形式来存储信息。

这三个维度可以组合:比如先用重要性过滤筛掉低价值内容,再用摘要压缩处理剩余历史,同时对特定类型的关键信息做结构化抽取。实际系统里,往往是多种方法配合使用的。

Prompt Caching:在「计算层」的互补手段

除了上面这些「信息层」的压缩策略,还有一个工程上值得了解的技术叫 Prompt Caching,Anthropic 的 Claude 和 OpenAI 都已支持。

理解它之前,先知道一个背景:LLM 每次处理请求,都需要把输入的所有 token「过一遍模型」来做计算,这个过程叫 prefill,是延迟和成本的主要来源之一。一个常见的场景是:你有一段固定的 system prompt 加上越来越长的对话历史,每次调用时这段历史都会被重新计算一遍,哪怕它和上一次调用时完全一样。

Prompt Caching 的思路是:如果 prompt 的前缀部分在多次请求之间是一样的,就把这部分的计算结果缓存起来,下次请求如果前缀匹配,直接复用缓存,不重新计算。费用和延迟都大幅降低,某些场景下能降到原来的十分之一。

具体到费用上,以 Anthropic Claude 为例,命中 Prompt Cache 的 token 费用大约是正常输入 token 的十分之一,写入缓存时会有一次性的额外费用(5 分钟有效期的缓存大约是正常费用的 1.25 倍,1 小时有效期的大约是 2 倍),但只要这段 prompt 在后续被复用两次以上,总体成本就已经回本了。对于 Agent 这种场景来说,system prompt 加上长期记忆注入的部分在多轮对话中基本不变,天然适合被缓存,收益非常可观。

这和前面的记忆压缩是两个不同层次的优化。记忆压缩在「信息层」工作,决定哪些内容值得被保留在对话历史里;Prompt Caching 在「计算层」工作,对已经决定要带进去的内容减少重复计算的开销。两者解决的不是同一个问题,可以同时使用,是互补关系,不是替代。

工程实践决策参考

选方案的时候,可以按这个思路来判断:对话不长、业务简单的场景,滑动窗口就足够了,实现成本最低;对话会很长但不想硬截断的场景,摘要加滑动窗口的组合是最稳健的工程选择;如果业务里有明确定义的「关键信息」(用户偏好、确认事项、状态字段),结构化抽取的信息密度最高,效果也最好;高频调用、长 prompt、成本敏感的系统,Prompt Caching 的收益非常可观,值得优先考虑。

这道题的坑在于,很多人只知道滑动窗口,回答到这里就停了。面试官想考的是你对「压缩」这件事有没有完整的认识。回答时要覆盖四种方法,并且能说清楚它们解决的是不同维度的问题:滑动窗口和摘要压缩解决「历史太长怎么截」,前者直接硬截,后者截之前先提炼;重要性过滤解决「内容不等价怎么挑」,打破时间顺序按价值保留;结构化抽取解决「对话文本是不是最佳载体」,换一种信息密度更高的形式存储。另外,Prompt Caching 要和记忆压缩区分清楚,它是「计算层」的优化,对已经决定带进去的内容减少重复计算,和「信息层」的压缩是互补关系,不是替代关系,这个区别如果能主动点出来,会给面试官留下很好的印象。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐