1. 多 Agent 系统面试的底层逻辑拆解
1.1 为什么面试官总爱问多 Agent 架构
这两年只要简历上写了“智能体”“Agent”“大模型应用”,面试里几乎绕不开多 Agent 系统这道坎。很多人第一反应是背概念:什么 ReAct、Plan-and-Execute、AutoGen、CrewAI,名词一大堆,但面试官真正想听的并不是你记住了几个框架名,而是你有没有真正想过一个问题——单个 Agent 搞不定的事情,到底卡在哪里,多 Agent 又是怎么把它拆开的。
我面过也带过人,发现一个规律:能把多 Agent 讲清楚的人,通常对单 Agent 的边界也很清楚。单 Agent 的核心痛点其实就三个:上下文窗口有限、工具调用容易串味、复杂任务缺乏分工。你让一个 Agent 既当产品经理又当程序员还当测试,它最后往往三头都做不好,因为它的“注意力”被稀释了。多 Agent 的本质,就是把这三种压力通过角色拆分、流程编排、消息传递重新分配。
所以面试里回答多 Agent,第一步不是急着画架构图,而是先讲清楚:这个任务为什么需要拆,拆的依据是什么。拆分的依据通常来自任务的可并行性、角色的专业性、以及验证的独立性。比如一个“写行业分析报告”的任务,可以拆成资料检索、数据整理、观点提炼、成稿润色四个角色,这四个角色之间既有依赖又能部分并行,这就是多 Agent 的用武之地。
1.2 面试官真正在考察的三个维度
我把多 Agent 面试的考察点归纳成三层,你可以对照着自查。
第一层是架构认知:你知不知道主流的几种协作模式,能不能说清楚它们各自的适用场景和代价。这一层是门槛,答不上来基本就凉了。
第二层是工程落地:你知不知道多 Agent 系统在真实项目里会遇到什么问题,比如死循环、消息爆炸、角色越权、成本失控。这一层是分水岭,能答出来说明你真做过。
第三层是取舍判断:给定一个具体场景,你能不能判断该不该上多 Agent,该用哪种架构,为什么不用另一种。这一层是加分项,也是高级岗位和普通岗位的分界线。
很多人卡在第二层,因为他们的多 Agent 经验只停留在跑通 Demo。Demo 里三个 Agent 互相聊几句就出结果了,但真实项目里,Agent 之间会互相甩锅、会重复劳动、会在一个死循环里烧掉几百块 token。面试官一问“你怎么控制成本”“怎么防止无限循环”,就露馅了。
提示:面试时如果被问到没做过的架构,不要硬编。可以说“这个架构我了解原理,但实际项目里我用的是另一种,因为当时场景的特点是……”,把话题引到你熟悉的领域,同时展示你的判断力。
1.3 四种经典架构的定位地图
在展开细节之前,先给四种架构一个整体定位,方便你建立全局观。这四种分别是:流水线式、主管调度式、辩论评审式、黑板协作式。它们不是互斥的,真实系统里经常混用,但面试时你要能分别讲清楚。
流水线式适合步骤明确、前后依赖强的任务,像工厂流水线,每个工位干一件事。主管调度式适合任务可以动态分配、需要统一决策的场景,主管 Agent 负责拆解和派活。辩论评审式适合需要高质量输出、容错要求高的场景,多个 Agent 互相挑刺。黑板协作式适合探索性强、没有固定流程的任务,所有 Agent 共享一块“黑板”,谁有想法谁往上写。
下面这张表可以先帮你建立快速对照,后面每个架构我会展开讲实现细节和踩坑经验。
| 架构类型 | 核心特征 | 适用场景 | 主要代价 |
|---|---|---|---|
| 流水线式 | 固定顺序,逐级传递 | 流程标准化任务 | 灵活性差,单点阻塞 |
| 主管调度式 | 中心决策,动态派活 | 任务可拆解可并行 | 主管成为瓶颈 |
| 辩论评审式 | 多角色互评,迭代收敛 | 高质量内容生成 | token 消耗大 |
| 黑板协作式 | 共享状态,自由贡献 | 探索性开放任务 | 难以收敛和调试 |
2. 四种经典架构的深度解析与实操要点
2.1 流水线式架构:最稳但最容易踩坑的起点
流水线式是多 Agent 里最容易理解的:Agent A 的输出是 Agent B 的输入,B 的输出给 C,像一条装配线。它的优势是确定性高、调试简单、成本可控,因为每一步的输入输出边界都很清晰。我第一个上线的多 Agent 项目就是流水线式,做的是“原始需求 → 结构化需求 → 技术方案 → 测试用例”这条链。
但流水线式的坑也很集中。第一个坑是错误累积:如果 A 的输出有偏差,B 会基于偏差继续加工,到 C 的时候已经偏到姥姥家了。解决办法是在每个环节加校验,比如让 B 在开始前先判断 A 的输出是否满足自己的输入要求,不满足就打回。第二个坑是格式漂移:A 输出的是 JSON,B 期望的是 Markdown,中间没有转换就会崩。所以流水线式一定要定义严格的接口契约,每个 Agent 的输入输出格式必须固定。
实操上,我建议用结构化输出约束每个 Agent。比如用 JSON Schema 强制 Agent 返回固定字段,这样下游解析就不会出错。下面是一个简化的接口定义示例:
# 定义每个 Agent 的输入输出契约 pipeline_contract = { "requirement_agent": { "input": {"raw_text": "str"}, "output": {"title": "str", "goals": "list[str]", "constraints": "list[str]"} }, "design_agent": { "input": {"title": "str", "goals": "list[str]", "constraints": "list[str]"}, "output": {"modules": "list[dict]", "tech_stack": "list[str]"} } }每个 Agent 在调用大模型时,把对应的 output schema 作为约束传进去,模型返回后先做一次 schema 校验,不通过就重试。这一步看起来麻烦,但能省掉后面 80% 的调试时间。
注意:流水线式不要超过 5 个环节。超过 5 个之后,错误累积和延迟都会变得难以接受。如果任务真的很长,考虑在中间加一个“汇总 Agent”做阶段性收敛。
2.2 主管调度式架构:像项目经理一样派活
主管调度式的核心是一个“主管 Agent”,它负责理解总任务、拆解子任务、分配给合适的“工人 Agent”,最后汇总结果。这个架构最接近人类团队的工作方式,也是面试里最常被问到的。它的优势是灵活:任务来了才决定怎么拆、派给谁,不像流水线那样写死顺序。
主管 Agent 的关键能力有三个:任务拆解、角色匹配、结果验收。任务拆解要拆到“一个工人 Agent 能独立完成”的粒度,太粗了工人做不了,太细了调度开销大。角色匹配要根据子任务的性质选择对应的工人,比如代码任务给代码 Agent,文案任务给文案 Agent。结果验收是主管要判断工人交回来的东西合不合格,不合格要打回重做或换人。
我踩过最大的坑是主管被自己的拆解能力限制。如果主管 Agent 本身能力不够,它拆出来的子任务质量就很差,后面工人再努力也救不回来。所以主管 Agent 通常要用更强的模型,或者给它更详细的拆解指引。另一个坑是无限派活:主管发现工人做得不好,就再派一个工人去修,修不好再派,最后陷入循环。必须给主管设置最大重试次数和总预算上限。
实操上,主管调度式建议用“任务队列 + 状态机”来管理。每个子任务有明确的状态:待分配、进行中、待验收、已完成、失败。主管只负责状态流转,不直接操作内容。下面是一个状态流转的示意:
task_states = ["pending", "assigned", "running", "review", "done", "failed"] def dispatch(supervisor, task): if task.retry_count > MAX_RETRY: task.state = "failed" return worker = supervisor.select_worker(task) result = worker.execute(task) if supervisor.review(result): task.state = "done" else: task.retry_count += 1 task.state = "pending"这个模式的好处是,任何一步出问题你都能定位到具体是哪个状态卡住了,而不是面对一团乱麻。
2.3 辩论评审式架构:用“吵架”换质量
辩论评审式的思路很直接:让多个 Agent 对同一个问题给出各自的答案,然后互相评审、辩论,最后收敛到一个更优的结果。它特别适合主观性强、容错要求高的任务,比如方案评审、内容创作、风险分析。一个 Agent 容易有盲区,多个 Agent 从不同角度挑刺,盲区就被补上了。
这个架构的关键参数是辩论轮数和收敛条件。轮数太少,辩论不充分;轮数太多,成本爆炸且可能陷入无意义的争吵。我的经验是 2 到 3 轮比较合适,第一轮各自陈述,第二轮互相质疑,第三轮修正收敛。收敛条件可以是“所有 Agent 都同意”或者“多数 Agent 不再提出新异议”。
辩论评审式最大的坑是同质化。如果所有 Agent 都用同一个模型、同一个提示词,它们会给出高度相似的答案,辩论就变成了复读。解决办法是给每个 Agent 不同的角色设定和关注点,比如一个关注可行性,一个关注成本,一个关注风险。角色差异越大,辩论越有价值。
提示:辩论评审式一定要设置“主持人 Agent”来控场。主持人负责控制轮数、总结分歧、判断是否收敛。没有主持人的辩论很容易跑题或者无限循环。
2.4 黑板协作式架构:最灵活也最难驾驭
黑板协作式来自经典的 AI 架构,核心是一块共享的“黑板”,所有 Agent 都能读写黑板上的内容。每个 Agent 根据自己的专长,在合适的时候往黑板上贡献信息,或者从黑板上获取信息继续加工。它没有固定的流程,适合探索性强、步骤无法预先确定的任务,比如复杂问题诊断、开放式研究。
这个架构的优势是涌现性:你不需要预先设计好所有步骤,Agent 们会根据黑板上的当前状态自主决定下一步做什么。但代价也很明显:难以收敛、难以调试、成本不可控。我见过一个黑板系统跑了两个小时还没结束,因为 Agent 们一直在互相补充信息,没人喊停。
实操上,黑板协作式必须加两个约束:终止条件和贡献度评估。终止条件可以是“黑板上某个目标字段被填满”或者“连续 N 轮没有新增有效信息”。贡献度评估是给每个 Agent 的贡献打分,低贡献的 Agent 降低其后续发言权重,避免无效 Agent 一直刷屏。
这个架构我不建议新手直接上,因为它的调试成本太高。如果你非要用,先用小规模任务验证收敛性,再逐步扩大。
3. 实操过程与核心环节实现
3.1 从零搭一个主管调度式系统的完整步骤
光讲架构不够,我拿主管调度式走一遍完整流程,因为它在面试里出现频率最高,也最能体现工程能力。假设我们要做一个“竞品分析报告生成”系统。
第一步是定义角色和职责。主管 Agent 负责拆解任务和验收,检索 Agent 负责收集竞品信息,分析 Agent 负责对比分析,撰写 Agent 负责成稿。每个角色的系统提示词要写清楚它的职责边界,尤其是“不做什么”,防止越权。
第二步是定义消息协议。Agent 之间传什么、怎么传,必须提前定好。我一般用 JSON 作为消息载体,包含 sender、receiver、task_id、content、status 五个字段。content 里再根据任务类型放具体内容。
第三步是实现主管的拆解逻辑。主管拿到“生成竞品分析报告”这个总任务后,要拆成子任务列表。拆解可以用大模型来做,但提示词里要给出拆解模板,比如“先检索、再分析、后撰写”,避免拆得太离谱。
supervisor_prompt = """ 你是任务主管。请将以下总任务拆解为子任务列表。 总任务:{task} 拆解要求: 1. 每个子任务必须能由一个专业角色独立完成 2. 子任务之间标明依赖关系 3. 输出 JSON 格式,包含 subtasks 列表 """第四步是实现工人执行和主管验收。工人执行时,主管要监控状态;工人交回结果后,主管要判断是否合格。验收可以用规则(比如字段是否齐全)加模型判断(比如内容是否切题)结合的方式。
第五步是加熔断和降级。设置最大重试次数、最大总 token 消耗、最大执行时间。任何一个超限,系统就降级到“返回当前已有结果并标注未完成”,而不是无限跑下去。
3.2 关键参数的计算与选择过程
多 Agent 系统里几个关键参数不能拍脑袋定,我给你我的计算思路。
最大重试次数:取决于任务的容错要求。如果任务失败代价高,重试次数可以设 3 次;如果只是生成内容,2 次就够了。重试次数每加 1,成本大约增加 30% 到 50%,因为要重新调用模型。
辩论轮数:我一般设 2 到 3 轮。设 2 轮时,第一轮出答案,第二轮互评修正;设 3 轮时,多一轮收敛确认。超过 3 轮,边际收益急剧下降,成本却线性上升。
Agent 数量:不是越多越好。我的经验是,一个多 Agent 系统里活跃 Agent 数量控制在 3 到 7 个。少于 3 个,分工不够;多于 7 个,协调开销超过分工收益。如果任务真的需要更多角色,考虑分层,用子主管管理子团队。
上下文预算:每个 Agent 的上下文窗口要预留 30% 给系统提示词和历史消息,剩下 70% 给任务内容。如果任务内容经常超,就要做摘要压缩,把历史消息压缩成要点再传给下游。
3.3 消息传递与状态管理的实现细节
多 Agent 系统最容易出问题的地方就是消息传递。我见过太多系统因为消息格式不一致、消息丢失、消息重复而崩溃。我的做法是所有消息走统一的消息总线,Agent 不直接互相调用,而是往总线发消息、从总线收消息。
消息总线的好处是解耦和可观测。任何一条消息都能被记录、被回放、被审计。出问题的时候,你把消息日志拉出来一看,就知道是哪个 Agent 在什么时候发了什么消息导致的问题。
状态管理上,我用一个中心化的状态存储,每个 Agent 的状态变更都要写回存储。这样主管 Agent 随时能查到全局状态,不会出现“主管以为工人在干活,其实工人早就挂了”的情况。
class MessageBus: def __init__(self): self.messages = [] self.state_store = {} def publish(self, sender, receiver, content, task_id): msg = { "sender": sender, "receiver": receiver, "content": content, "task_id": task_id, "timestamp": time.time() } self.messages.append(msg) return msg def update_state(self, agent_id, state): self.state_store[agent_id] = state这套东西看起来简单,但它是多 Agent 系统稳定的基石。面试时如果你能讲出消息总线和状态存储的设计,面试官会知道你确实做过真东西。
4. 常见问题与排查技巧实录
4.1 多 Agent 系统高频问题速查表
下面这张表是我在实际项目和面试辅导中整理的高频问题,基本覆盖了 90% 的翻车场景。
| 问题现象 | 根本原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| Agent 之间无限循环 | 缺少终止条件或重试上限 | 看消息日志,找循环起点 | 加最大轮数和预算熔断 |
| 输出格式不一致 | 接口契约未定义或未校验 | 检查每个 Agent 的输出 schema | 强制结构化输出并校验 |
| 成本失控 | 无 token 预算和监控 | 统计每个 Agent 的 token 消耗 | 设预算上限,超限降级 |
| 主管成为瓶颈 | 主管串行处理所有任务 | 看主管的调用频率和耗时 | 主管只做决策,执行下放 |
| 辩论变成复读 | Agent 同质化 | 对比各 Agent 的输出相似度 | 差异化角色和关注点 |
| 黑板无法收敛 | 缺少终止条件和贡献评估 | 看黑板状态是否持续变化 | 加终止条件和权重机制 |
| 错误逐级放大 | 流水线无中间校验 | 逐环节对比输入输出 | 每环节加校验和打回机制 |
4.2 三个我踩过的真实坑与修复过程
第一个坑是主管 Agent 的“过度自信”。我早期做的一个系统,主管 Agent 在验收时总是说“通过”,哪怕工人交回来的东西明显不完整。后来我发现是主管的提示词里写了“尽量让任务通过”,模型就倾向于放水。修复方法是把验收标准写死,让主管逐条对照检查,而不是凭感觉判断。
第二个坑是消息爆炸。一个辩论系统里,5 个 Agent 每轮互相发消息,3 轮下来产生了 200 多条消息,其中大部分是重复的“我同意”。修复方法是给消息加去重和摘要,相同观点的消息合并,只保留有差异的部分。
第三个坑是降级策略缺失。有一次线上系统因为模型接口超时,整个多 Agent 流程卡死,用户等了十分钟没结果。后来我加了超时降级:任何 Agent 超过 30 秒没响应,就跳过它,用已有结果继续。虽然结果可能不完美,但至少用户能拿到东西。
注意:多 Agent 系统的调试成本远高于单 Agent。我的建议是,先用单 Agent 跑通核心逻辑,确认任务本身可行,再拆成多 Agent。不要一上来就上多 Agent,那是给自己找麻烦。
4.3 面试回答的实战话术与避坑指南
最后说回面试。被问到多 Agent 架构时,我建议按这个顺序回答:先说场景特点,再说为什么选这个架构,然后讲实现细节,最后讲踩过的坑和怎么解决的。这个顺序能让面试官看到你的完整思考链。
比如你可以这样说:“我当时做的场景是竞品分析,特点是步骤相对固定但需要多角色配合,所以我选了主管调度式。主管负责拆解和验收,三个工人分别做检索、分析、撰写。实现上我用了消息总线和状态存储来保证可观测。踩过的坑主要是主管验收放水,后来我把验收标准写死才解决。”
这个回答里有场景、有选型理由、有实现、有反思,比单纯背架构定义强十倍。面试官要的不是你记住多少名词,而是你有没有真正想过、做过、改过。
避坑方面,有几个话千万别说。别说“多 Agent 一定比单 Agent 好”,这显得你没判断力。别说“我用的是某某框架所以不用管细节”,这显得你没深度。别说“没遇到过问题”,这显得你没真做过。真实项目一定有问题,关键是你能不能讲清楚怎么发现的、怎么解决的。
我个人在实际操作中的体会是,多 Agent 系统的价值不在于 Agent 多,而在于分工是否合理、协作是否顺畅、失败是否可控。把这三点想清楚,面试怎么问都不慌。