多智能体与框架面试题
这一类题最容易被答成“我会用某某框架”。真正要讲的是:什么时候拆 Agent、怎么通信、怎么处理冲突、框架帮你省了哪段代码。
答题主线
以“调研—写作—审校”的内容任务为例:调研员交来源,写作者交草稿,审校员交问题清单。若只是问今天北京天气,拆成三个 Agent 只会多三次协调和更多出错点。
回答这类题时,建议按这条线展开:
先判断是否需要多 Agent -> 再选协作模式 -> 再设计通信和状态
-> 再处理冲突和 ownership -> 再选框架或裸 API -> 最后做评估和成本控制面试官最关心的不是“你知道多少框架名”,而是:
- 什么时候拆多个 Agent。
- 怎么把职责划清。
- 如何处理结论冲突。
- 如果多个 Agent 改同一个文件,怎么避免互相覆盖。
- 裸 API、图编排、SDK 各自省掉了什么。
一、什么时候用多智能体
Q1:什么时候该用多智能体?
回答脉络
先给原则:能单 Agent 就别拆,只有职责清晰、可独立验收、上下文隔离有价值时才拆。
参考答案
我会在这些情况下考虑多智能体:
- 任务可以明确拆成几个子问题。
- 每个子问题有独立输入输出。
- 每个子问题可以单独验收。
- 不同子任务需要不同上下文。
- 并行执行能明显提速。
比如“调研 -> 写作 -> 审校”很适合拆多 Agent,因为阶段清晰、结果可验收、职责也容易隔离。相反,如果只是一个简单问答,拆多 Agent 只会增加协调成本。
Q2:为什么多智能体不一定更好?
回答脉络
讲成本、延迟、冲突和调试复杂度。
参考答案
多智能体不一定更好,因为它会带来四类额外成本:
- 协调成本:要分派、交接、收口。
- 延迟:Agent 之间来回传递会更慢。
- 冲突:多个 Agent 可能结论不一致。
- 调试难度:trace 更长,问题更难定位。
所以多智能体的价值在分工和隔离,不在数量。只要单 Agent 能稳定完成,就不要为了“看起来高级”硬拆。
二、协作模式
Q3:常见的多智能体协作模式有哪些?
回答脉络
把模式、适用场景、风险讲清楚。
参考答案
常见模式有四类:
| 模式 | 适合场景 | 风险 |
|---|---|---|
| 主管-工人 | 任务动态、需要收口 | 主管成瓶颈 |
| 流水线 | 阶段固定,比如调研 -> 写作 -> 审校 | 前一阶段错误会传下去 |
| 并行评审 | 多个候选方案、多视角审查 | 合并和裁决成本高 |
| 辩论 / 互审 | 想发现漏洞和冲突 | 容易拖长、成本上升 |
如果面试官问“你会优先推荐哪种”,我通常先推荐流水线,因为它最容易理解、最容易评估、最容易做 trace。
Q4:Agent 之间应该传什么,不应该传什么?
回答脉络
传结构化结果,不传整段噪声。
参考答案
Agent 之间应该传:
- 任务目标。
- 当前阶段。
- 已确认结论。
- 证据编号。
- 约束条件。
- 未确认项。
- 下游需要做什么。
不应该传:
- 全部聊天记录。
- 无关思考过程。
- 大段冗余文本。
- 没有结构的自由输入。
结构化交接的好处是可追踪、可验证、也更容易做后续的冲突处理。
三、冲突处理
Q5:多智能体输出冲突时怎么处理?
回答脉络
先区分冲突类型,再按证据、职责和权威性裁决。
参考答案
多智能体冲突通常分三类:
| 冲突类型 | 典型情况 | 处理方式 |
|---|---|---|
| 结论冲突 | 两个 Agent 对事实判断不同 | 比证据、看权威性、看更新时间 |
| 职责冲突 | 互相改了不该改的内容 | 明确 ownership,谁负责事实,谁负责表达 |
| 文件冲突 | 同一个文件被多个 Agent 同时编辑 | 单写者原则、版本检查、patch 合并 |
结论冲突时,我不会让模型“再想想”就完事,而是要求双方都给出证据,然后按规则裁决。职责冲突时,要先把边界设计好,避免写作 Agent 自己补事实、调研 Agent 自己改结论。
Q6:如果多个 Agent 同时编辑同一个文件,怎么解决?
回答脉络
这是很典型的真实工程追问,要讲出“单写者 + patch + 版本检查 + 主管合并”。
参考答案
我会采用下面这套规则:
- 单写者原则:同一时间只允许一个 Agent 拥有文件写权限。
- 其他 Agent 只产出 patch 或评论:不直接覆盖文件。
- patch 必须带 base version:明确它是基于哪一版内容生成的。
- 应用前检查版本是否变化:如果文件已经被别人改过,就不能直接合并。
- 冲突由主管 Agent 或人工 review 裁决:必要时把不同 patch 合并成新的版本。
如果你要把这个说得更工程化,可以补一句:
我会把“写文件”当成一种受控资源,而不是谁想写就写。这类回答能明显区分“真做过协作系统”和“只会讲多 Agent 概念”的人。
Q7:怎么避免多个 Agent 互相覆盖成果?
回答脉络
讲 ownership、版本号、锁、提交接口。
参考答案
常见做法包括:
- 每个文件只有一个 owner。
- 变更只能通过 patch 提交。
- patch 先进入队列,再由主管合并。
- 合并前做 diff 和版本检查。
- 有必要时对关键文件加写锁。
如果是生成型产物,比如报告、代码、文档,最稳的方式是“一个写、多个看”。让多个 Agent 同时读、互相评审可以,但同时写通常风险很高。
四、状态、通信与框架
Q8:多智能体系统里状态应该怎么设计?
回答脉络
共享状态越少越好,字段要结构化、职责要明确。
参考答案
我会把共享状态设计成结构化对象,而不是大段自由文本。常见字段包括:
- 任务 ID。
- 当前阶段。
- 用户目标。
- 已确认事实。
- 证据列表。
- 草稿。
- 审校意见。
- 最终结果。
- 成本和 trace。
每个 Agent 只写自己负责的字段,别的字段尽量只读。这样状态清晰,调试也容易。
Q9:checkpoint、handoff、state 各解决什么问题?
回答脉络
把三个概念分开。
参考答案
- state:当前共享数据是什么。
- checkpoint:把状态保存下来,方便恢复和回放。
- handoff:把当前任务的控制权交给下一个 Agent。
如果没有 checkpoint,复杂流程中间挂了就难恢复;如果没有 handoff,多 Agent 只能靠一堆消息硬传;如果没有 state,所有上下文都会混成一团。
Q10:裸 API、图编排和官方 SDK 怎么选?
回答脉络
先看复杂度,再看你需要哪些工程能力。
参考答案
| 方案 | 适合什么时候 | 代价 |
|---|---|---|
| 裸 API | 学底层机制、原型、小系统 | 要自己写更多样板 |
| 图编排 | 流程有分支、循环、checkpoint | 需要理解状态图 |
| 官方 SDK | 想快速接 tools、guardrails、handoff、trace | 受框架约束更多 |
我的原则是:先搞清楚业务流程,再看哪个工具帮你少写重复代码。不要一上来就“我用某框架”,而要说“我需要状态、分支、恢复、追踪,所以选它”。
Q11:A2A、MCP、tool calling 有什么区别?
回答脉络
说明它们关注层级不同。
参考答案
- tool calling:单个模型调用本地工具。
- MCP:一种工具和上下文的协议,方便模型连接外部能力。
- A2A:Agent 之间的互操作和协作协议,更偏 Agent-to-Agent 通信。
你可以把它理解成不同层次:
- tool calling 解决“怎么让模型调工具”。
- MCP 解决“怎么统一接工具”。
- A2A 解决“怎么让多个 Agent 互相协作”。
五、成本与评估
Q12:多智能体系统怎么控成本?
回答脉络
讲预算、并行度、职责隔离和共享结果复用。
参考答案
控成本我会做这些事:
- 限制 Agent 数量。
- 限制每个 Agent 的轮数。
- 让可并行的任务并行。
- 避免重复检索和重复思考。
- 共享证据和中间结果,不重复跑同样的步骤。
- 给总任务设预算。
多智能体的成本不是只看单个 Agent,而是看总调用量、总上下文和总延迟。拆得越细,不代表越省。
Q13:怎么评估多智能体系统是否真的比单 Agent 好?
回答脉络
用基线比较,而不是只看“感觉更强”。
参考答案
我会先做一个单 Agent 基线,再比较多 Agent 方案在以下维度上的表现:
- 任务成功率。
- 关键事实正确率。
- 冲突率。
- 人工介入率。
- 平均成本和 P95 成本。
- 平均延迟和 P95 延迟。
- trace 可读性。
如果多 Agent 只让系统更复杂,却没有在质量、稳定性或可调试性上明显提升,那就不值得上。
六、框架与动态协作追问
Q14:手搓一个 Agent 系统最少要写哪些东西?
回答脉络
不要只说“调用模型 API”,要把循环、状态、工具、日志都讲出来。
参考答案
手搓最小 Agent 至少要写:
- messages 组装。
- 模型调用。
- tool schema 定义。
- tool call 解析。
- 工具执行和参数校验。
- tool 结果回传。
- 最大轮数和错误处理。
- usage、cost、latency 日志。
如果要做成可用系统,还要加状态管理、权限、缓存、trace、eval 和配置管理。框架的价值,很多时候就是把这些样板和边界帮你标准化。
Q15:什么时候应该从裸 API 迁到框架?
回答脉络
当流程开始有状态、分支、恢复、多人协作时再迁。
参考答案
我会在这些情况考虑迁到框架:
- tool loop 变复杂。
- 有多个分支和循环。
- 需要 checkpoint 和恢复。
- 需要多 Agent handoff。
- 需要统一 tracing 和 eval。
- 需要团队协作维护流程。
如果只是一个小型 demo 或简单工具调用,裸 API 更清楚、更轻量。框架不是为了显得高级,而是为了解决复杂度。
Q16:多 Agent 的动态切换应该由谁决定?
回答脉络
可以由主管、路由器、规则或模型共同决定。
参考答案
常见方式有:
- 规则切换:确定性强,比如“涉及退款就转客服主管”。
- 主管 Agent 切换:主管根据任务状态决定交给谁。
- Router 模型切换:用户意图复杂时用模型路由。
- 状态机切换:流程固定但分支较多时最稳。
高风险切换不要完全交给模型,比如权限、付款、删除、发布,应该由代码规则兜底。
Q17:Manager、Router、Critic、Executor 分别是什么角色?
回答脉络
这些是常见职责,不是固定框架名。
参考答案
- Manager:拆任务、分派、收口。
- Router:判断下一步该交给哪个 Agent 或工具。
- Critic / Verifier:检查结果、发现问题、给修正建议。
- Executor:执行具体任务,比如检索、写作、代码修改。
系统不一定每个角色都要有。小系统可以一个 Agent 兼多个职责;复杂系统才拆开。
Q18:Agent 之间通信为什么不能只靠自然语言长文?
回答脉络
自然语言灵活但不稳定,结构化字段更可控。
参考答案
自然语言长文的问题是:
- 难验证。
- 容易丢字段。
- 容易混入噪声。
- 不利于 trace。
- 下游 Agent 容易误解。
所以我会用结构化通信,比如:
task_id
stage
objective
evidence_ids
result
open_questions
next_action自然语言可以作为补充解释,但关键状态必须结构化。
Q19:LLM Gateway 在 Agent 系统里有什么用?
回答脉络
网关解决模型接入、路由、限流、观测和成本控制。
参考答案
LLM Gateway 常见作用包括:
- 统一模型接口。
- 按任务路由不同模型。
- 做限流和重试。
- 记录 usage、latency、cost。
- 管理 API key 和权限。
- 做缓存和降级。
当系统里有多个模型、多个团队、多个 Agent 时,网关会比每个服务自己接模型更好维护。
七、通信协议、共享状态与一致性
Q20:多智能体之间的通信协议应该怎样设计?
考察点
考察是否能把“Agent 发消息”设计成可验证、可追踪、可演进的工程接口。
回答脉络
先定义消息 envelope,再定义业务 payload、状态语义、幂等键和版本兼容策略。
详细参考答案
我不会让 Agent 直接互发没有约束的自然语言。通信消息至少应该有统一 envelope:message_id、conversation_id、task_id、sender、receiver、message_type、created_at、trace_id、schema_version、deadline 和 idempotency_key。业务 payload 再根据消息类型定义,例如任务请求、任务结果、事件、审批请求和冲突报告。
协议要明确消息是命令还是事件。命令表示“请你完成某事”,通常需要成功或失败响应;事件表示“某事已经发生”,消费者可以异步处理,不一定需要直接回复。还要规定状态值、错误码、重试语义和是否允许重复消费。这样下游才知道收到消息后应该执行、等待、忽略还是转人工。
传递结果时,关键事实、证据 ID、未解决问题和下一步动作要用结构化字段表达,自然语言只用于补充说明。对于大段文档和文件内容,应传引用或 artifact ID,而不是每次复制全文,避免上下文和网络负担。
工程落地
定义类似 TaskRequest、TaskResult、ReviewRequest、ConflictReport 的 schema,并做 JSON Schema 或 protobuf 校验。生产消息进入队列后,消费者先校验 schema 和权限,再按 idempotency_key 去重。消息 schema 采用向后兼容策略:新增可选字段,废弃字段保留过渡期,不能随意改字段类型。
常见追问及答案
追问:Agent 返回一段 Markdown 不行吗?
简单原型可以,但生产系统的控制字段不能依赖 Markdown 解析。Markdown 可以作为 result_text,任务状态、证据和动作必须结构化。
追问:同步 RPC 和消息队列怎么选?
需要立即得到结果、流程短且失败要同步反馈时可用 RPC;长任务、可并行任务、需要削峰或断点恢复时用消息队列。也可以 RPC 提交任务、队列异步执行,再通过事件或查询接口获取结果。
扣分点
- 只说“用 JSON 通信”,没有消息 ID、超时和幂等。
- 把命令和事件混为一谈。
- 每次传完整聊天记录或完整文件。
- 没有 schema 版本和兼容策略。
Q21:多 Agent 的共享状态应该怎么划分?
考察点
考察是否理解共享状态、私有上下文和持久化状态的边界。
回答脉络
按所有权拆字段,默认最小共享;区分事实、工作产物、控制状态和审计数据。
详细参考答案
我会把状态分成四类。第一类是任务控制状态,例如任务 ID、当前阶段、deadline、重试次数和整体状态;第二类是共享事实,例如已验证实体、证据 ID 和用户约束;第三类是阶段产物,例如检索结果、草稿、审校意见和 patch;第四类是运行审计,例如 token、费用、工具调用、trace 和错误。
每个字段都应有 owner、读写权限和更新方式。例如调研 Agent 可以写 evidence_set,写作 Agent 只能读它并写 draft,审校 Agent 写 review_findings,主管或状态机写 stage。Agent 的完整对话上下文应尽量私有,只有经过筛选的摘要和结构化结果进入共享状态。
共享状态也不能只存一个不断追加的大 JSON。需要区分当前快照和不可变事件,关键变更记录版本或 revision,便于恢复、审计和重放。状态大小要受控,过期的中间结果归档或只留引用。
工程落地
用状态 schema 描述字段类型、owner、写入条件和敏感级别。状态更新采用带 expected_revision 的条件写入,成功后产生事件和新 checkpoint。私有上下文保存在 Agent 运行记录中,共享状态只存下游真正需要的内容。
常见追问及答案
追问:为什么不把所有对话历史放进共享状态?
因为会扩大 token、泄露不必要信息、让不同 Agent 受到噪声干扰,还会增加并发写冲突。应通过摘要、证据引用和字段化结果共享必要信息。
追问:状态和数据库记录有什么区别?
状态是任务在某一时刻可继续执行所需的业务快照;数据库是存储实现。状态可以由快照加事件组成,不能把“存进数据库”本身当成状态设计。
扣分点
- 所有 Agent 都能修改所有字段。
- 共享状态就是完整聊天记录。
- 没有字段 owner、版本和敏感级别。
- 只保存最终答案,没有中间状态和恢复依据。
Q22:多个 Agent 同时编辑同一个文件时,如何设计完整的冲突解决流程?
考察点
这是多智能体面试中很容易暴露实践深度的一题,考察资源 ownership、乐观并发控制、语义合并和人工接管。
回答脉络
先从“默认单写者”降低冲突,再讲 patch、revision、锁、合并、验证和恢复,不要只回答“加锁”。
详细参考答案
我会把文件视为受控资源,为每个文件维护 owner、revision、写锁状态和变更历史。最稳的默认规则是同一文件同一时刻只有一个 Agent 负责写入,其他 Agent 只能提交 review comment、结构化修改建议或基于某个 revision 的 patch。这样并行发生在分析和评审阶段,最终写入仍有单一入口。
写入流程可以是:Agent 读取文件得到 base_revision;生成带文件路径、上下文、修改原因和校验信息的 patch;提交到变更队列;写入服务检查当前 revision 是否仍等于 base;一致则应用 patch 并生成新 revision,不一致则拒绝直接覆盖,重新计算 diff 或进入合并流程。
如果确实需要多个 Agent 并行编辑,可以按文件、目录或逻辑区块分配 ownership,尽量让 patch 互不重叠。文本层冲突可以用三方合并,但自动合并成功不代表语义正确,所以合并后还要跑格式化、解析、测试和必要的静态检查。若两个 patch 都修改同一个函数、配置项或文档章节,即使文本没有冲突,也要做语义冲突检查。
锁只能作为并发控制的一层,必须有租约、过期时间和持有者信息,避免 Agent 崩溃后永久锁死。锁失效或版本冲突时,系统应保留原文件、两个候选 patch 和冲突上下文,交给主管 Agent 或人工处理,不能静默丢弃一方成果。
工程落地
一个文件变更记录至少包括 artifact_id、base_revision、patch、author_agent、intent、affected_symbols、validation_results 和 status。写入服务提供 apply_patch(expected_revision, patch) 接口,成功返回新 revision;失败返回 STALE_BASE,调用方必须 rebase 或重新生成 patch。重要仓库可以用临时分支或 worktree 隔离 Agent 的修改,最终通过受保护的合并队列进入主工作区。
常见追问及答案
追问:有了 Git merge,为什么还需要 Agent 层的控制?
Git 能处理文本版本和部分三方合并,但不知道任务 ownership、权限、工具副作用和语义约束。Agent 层要决定谁有权写、patch 基于哪一版、合并后要跑什么验证,以及冲突何时转人工。
追问:两个 Agent 改了同一段但内容都合理怎么办?
不能随机选,也不能只看最后写入者。根据任务优先级、事实权威性、变更范围和验证结果裁决;如果都是可接受方案,交给明确的 owner 选择,并保留未采用 patch 以便追溯。
扣分点
- 只回答“加分布式锁”,没有租约、超时和恢复。
- 允许 Agent 直接覆盖工作区。
- 只检查文本冲突,不检查语义冲突。
- 版本冲突时静默重试并覆盖最新内容。
Q23:多 Agent 并发执行时,怎样避免重复工作和竞态?
考察点
考察并发任务的拆分、任务认领、去重和结果汇聚。
回答脉络
任务可独立才并行;用任务键和租约认领;用 barrier 或依赖图汇聚;对共享资源做条件更新。
详细参考答案
并发的前提是子任务之间低耦合、输入边界清楚、结果可以独立验收。主管先把任务拆成带唯一 subtask_id 的工作项,声明输入、输出、依赖和 deadline。Worker 通过原子操作认领任务,认领成功才执行;其他 Worker 看到已认领或已完成就不重复处理。
对于可能重复投递的队列,执行器不能假设“消息只到一次”,而要让任务处理幂等。结果写入使用条件更新或唯一键,汇聚器等待所有必需依赖完成,或者根据策略允许部分结果并显式标记缺失。共享计数器、文件、发布状态等资源必须使用事务、版本检查或单独的串行写入服务。
并发度要受控。过高并发会打爆模型额度、工具服务和向量库,还可能让同一用户的请求互相影响。需要设置全局、租户、任务和 Agent 级别的并发上限,并让优先级和 deadline 参与调度。
工程落地
任务表保存 status、lease_owner、lease_expire_at、attempt、dedupe_key 和 dependency_ids。认领使用带条件的数据库更新;租约过期后由调度器回收。汇聚器依据依赖图推进状态,结果写入以 subtask_id + output_version 去重,超过并发或预算时进入排队或降级。
常见追问及答案
追问:并行执行一定比串行快吗?
不一定。并行会节省独立子任务的等待时间,但会增加调度、汇聚、限流和冲突成本;如果后续必须串行依赖,或者模型服务本身排队,收益可能很小。要比较 P95 延迟、成本和成功率。
扣分点
- 只说“用 asyncio 并发”,没有任务认领和幂等。
- 不设置并发上限和租户隔离。
- 没有依赖关系和部分失败语义。
- 结果汇聚靠最后到达者覆盖共享状态。
八、可靠性:超时、重试、幂等与恢复
Q24:多智能体调用超时应该怎样处理?
考察点
考察是否能区分连接超时、模型生成超时、工具执行超时和整体 deadline。
回答脉络
设置分层 timeout,传播 deadline;先取消或隔离执行,再决定重试、降级、替代 Agent 或人工接管。
详细参考答案
我会设置至少三层时间限制:单次模型或工具调用 timeout、单个 Agent 的阶段 timeout,以及整个任务的 deadline。下游请求要携带剩余时间,不能每一层都从零开始计时,否则局部重试会把全局预算耗尽。
超时后先判断操作是否已经在服务端完成。对于查询类操作可以安全重试;对于写文件、发邮件、下单等副作用操作,不能因为客户端没收到响应就盲目重试,必须通过幂等键查询执行状态或走补偿流程。长任务可以异步化,立即返回 task ID,由用户查询进度。
降级策略要和任务类型匹配:检索 Agent 超时可以使用已有缓存或有限候选,审校 Agent 超时可以标记为未完成并转人工,关键发布操作超时应阻断发布。不能把所有超时都变成“让另一个 Agent 再做一次”。
工程落地
请求上下文携带 deadline_at、attempt、trace_id 和 idempotency_key。调用包装器区分 CONNECT_TIMEOUT、READ_TIMEOUT、TOOL_TIMEOUT 和 DEADLINE_EXCEEDED,记录实际耗时和服务端状态。超时事件写入状态机,只有符合策略的状态才允许重试或转移。
常见追问及答案
追问:超时后取消真的能停止模型或工具吗?
不一定。客户端取消可能只停止等待,服务端仍在执行,所以副作用工具必须支持服务端取消、状态查询或幂等提交。系统要区分“调用方放弃等待”和“服务端确认未执行”。
扣分点
- 所有超时都无限重试。
- 没有整体 deadline,只设置单次 timeout。
- 不区分读操作和副作用操作。
- 超时后直接换 Agent,可能造成重复写入或重复扣费。
Q25:多 Agent 的重试策略怎么设计?哪些错误不应该重试?
考察点
考察错误分类、退避、预算和幂等之间的关系。
回答脉络
按瞬时错误、永久错误、业务拒绝和不确定执行结果分类,再结合指数退避、抖动和最大预算。
详细参考答案
网络短暂断开、服务端 5xx、限流和部分依赖不可用,通常可以有限重试;参数校验失败、权限拒绝、资源不存在、策略禁止和模型明确拒绝,重试同一个请求通常没有意义。模型输出格式错误可以做一次结构化修复或重新请求,但要限制次数,避免“格式修复循环”。
重试应使用指数退避和随机抖动,防止多个 Agent 同时重试形成雪崩。每次重试都要消耗任务预算,并记录原因。对于 LLM 调用,如果重试会重新产生 token 成本,应先判断是否真的能提高成功率;可以切换更小或备用模型,但切换策略要可观测。
最关键的是“不确定执行结果”。例如工具请求已经发送,但响应丢失,此时不能简单认为失败。要用幂等键查询状态,确认未执行后再重试;无法确认时进入待核验状态或人工队列。
工程落地
定义错误分类和重试策略表:retryable、max_attempts、backoff、fallback、requires_status_check。重试包装器接收剩余 deadline 和 cost budget;达到任一上限就终止。对模型 JSON 解析失败保存原始响应和 schema 错误,避免只记录“重试失败”。
常见追问及答案
追问:为什么要加 jitter?
多个 Worker 如果同时按相同时间重试,会形成同步流量尖峰;随机抖动能把重试分散到时间窗口内。
追问:模型输出不稳定,能不能一直重试直到满意?
不能。要有结构校验、质量阈值、最大次数和成本上限;超过后应降级、澄清或人工处理。
扣分点
- 只会说指数退避,不会分类错误。
- 对写操作无幂等地重试。
- 不计算重试的 token 和工具成本。
- 把模型质量不佳当成可以无限重试的问题。
Q26:如何保证 Agent 工具调用和任务执行的幂等性?
考察点
考察是否理解“同一个请求执行两次”的业务后果,以及模型层和工具层要分别控制。
回答脉络
请求生成业务幂等键,服务端持久化执行状态;区分纯查询、可重复写和不可重复副作用。
详细参考答案
幂等不是“让模型记住不要重复”,而是工具服务端对重复请求给出相同业务结果。入口根据用户请求、任务 ID 和业务对象生成幂等键,调用工具时携带;工具服务保存 key -> status/result。第一次执行成功后,重复请求直接返回原结果;第一次执行中则返回处理中;失败是否允许重试要由状态决定。
纯查询通常天然幂等,但也要考虑时间窗口和权限变化。创建订单、发送邮件、修改文件等副作用操作需要业务唯一键、去重表或数据库唯一约束。跨系统操作不能只靠本地事务,要用 outbox、状态机、补偿动作或人工核验处理部分成功。
Agent 层还要防止同一个子任务被多个 Worker 同时执行,可以用 subtask_id 作为 dedupe key。模型可能生成两个语义相同但字符串不同的工具调用,因此关键资源还需要业务层唯一约束,不能只对 JSON 文本 hash。
工程落地
工具接口统一包含 idempotency_key、request_id 和 dry_run(适用时)。执行记录保存参数摘要、权限主体、开始结束时间、状态和结果引用。状态迁移采用条件更新:只有 PENDING 才能转 RUNNING,只有持有 lease 的执行者才能提交结果。
常见追问及答案
追问:幂等键应该包含什么?
要能区分一次业务意图,又不能因无关字段变化而失效。通常包括租户、业务对象、操作类型、用户请求或任务版本;敏感原文不直接写入日志,可用安全摘要。
扣分点
- 认为重试库自动解决幂等。
- 只在客户端生成 request ID,服务端不落库。
- 不区分查询和副作用。
- 用完整参数字符串作为唯一业务语义。
Q27:Agent 任务中途失败后,怎样从 checkpoint 恢复?
考察点
考察状态机、checkpoint、事件日志和副作用恢复,而不是简单“从上次对话继续”。
回答脉络
持久化可恢复状态 -> 恢复前校验 revision 和权限 -> 跳过已确认的纯计算 -> 核验未确认副作用 -> 从安全节点继续。
详细参考答案
checkpoint 应保存任务状态、已完成子任务、输出 artifact 版本、证据引用、重试次数、预算、权限上下文版本和未完成动作。恢复时先确认 checkpoint 本身完整,并检查依赖的文件、索引、工具状态是否仍有效。不能盲目把旧对话重新发给模型,因为模型可能再次执行已经完成的工具调用。
对纯计算或查询,可以依据不可变结果直接跳过;对外部副作用,要先通过幂等键查询状态。如果状态是已完成,就把结果重新装入上下文;如果是未执行,才允许继续;如果不确定,则暂停并人工确认。恢复后的新执行应该产生新的 attempt 和 trace,但保留与原任务的关联。
checkpoint 的频率要和任务风险、成本以及状态大小平衡。关键写操作前后必须保存,长时间检索或多跳任务可以按阶段保存。checkpoint 还要有 schema version,系统升级后提供迁移或拒绝恢复并转人工。
工程落地
采用“事件日志 + 周期性快照”的方式:事件记录状态迁移和工具结果,快照减少恢复时重放量。恢复器按状态机重新计算可执行节点,使用 expected_revision 写入,避免旧 Worker 恢复后覆盖新状态。保存敏感上下文时按租户和加密策略隔离。
常见追问及答案
追问:checkpoint 和消息队列重放有什么区别?
消息重放重建事件过程,checkpoint 是某个可恢复快照。两者通常结合使用:从最近快照开始重放之后的事件,既保证可追溯又降低恢复成本。
扣分点
- 只保存聊天记录,不保存任务状态和副作用结果。
- 恢复时重复执行所有工具。
- 没有 schema 版本和权限校验。
- 旧 Worker 恢复后可以覆盖新状态。
九、冲突仲裁与安全边界
Q28:多个 Agent 结论冲突时,怎样设计可解释的仲裁机制?
考察点
考察是否能把“让一个大模型投票”升级为基于证据、权限、版本和任务规则的裁决。
回答脉络
先区分事实冲突、方案冲突、权限冲突和文件冲突,再设优先级、证据要求、仲裁者和人工升级条件。
详细参考答案
首先要让每个 Agent 输出结论、证据、假设、置信度和未解决问题,而不是只有一句结论。对于事实冲突,比较来源权威性、更新时间、适用范围和证据是否直接支持;对于方案冲突,比较目标函数、约束、风险和实验结果;对于权限冲突,代码策略优先于模型意见;对于文件冲突,按 artifact owner 和 revision 流程处理。
仲裁规则应尽量先代码化。例如安全策略、审批权限、金额阈值和发布门禁不能交给模型投票。剩余的开放性判断可以由专门的 verifier 或 manager 读取候选及证据后裁决,但要保留裁决理由和未采纳意见。证据不足、来源同等权威且结论影响较大时,应输出不确定并升级人工,而不是强行多数表决。
“多数票”也不一定可靠,因为多个 Agent 可能共享同一个模型偏差,或者重复看到同一错误资料。投票可以作为一个信号,但不能替代独立证据和业务规则。
工程落地
定义 CandidateResult:包含 claim、evidence_ids、assumptions、confidence、risk_level 和 agent_version。仲裁器按规则生成 Decision,记录采用的候选、反对原因、策略版本和是否人工升级。高风险决策设置双人或人机审批门槛。
常见追问及答案
追问:怎样判断两个答案是真冲突还是表达不同?
先做实体、时间、单位和适用范围归一化,再比较关键 claim。很多表面冲突来自版本不同或一个答案更具体;归一化后仍然互斥,才进入冲突裁决。
扣分点
- 冲突时只让主管模型“选一个”。
- 没有要求候选附证据和适用条件。
- 让模型裁决权限和高风险动作。
- 没有不确定和人工升级路径。
Q29:多 Agent 系统怎样防止 Agent 互相越权或被工具诱导?
考察点
考察身份、能力、工具权限和不可信输入隔离。
回答脉络
最小权限 -> 服务端授权 -> 工具参数校验 -> 人工确认 -> 审计和隔离。
详细参考答案
每个 Agent 都应有独立身份和能力集合,不因为它是“主管 Agent”就默认拥有所有权限。权限要在工具服务端校验,包含租户、用户、任务、资源和动作,而不是只在 prompt 中描述。一个负责检索的 Agent 不应该直接拥有发送邮件或修改生产代码的权限;需要跨能力时走明确的 handoff 和审批。
Agent 收到的其他 Agent 消息、检索文本和工具返回值都属于不可信数据,不能自动提升权限或覆盖系统策略。工具参数必须做 schema、范围、资源归属和敏感操作校验;高风险动作支持 dry-run、预览和人工确认。对于代码、文件和命令执行,使用沙箱、工作区隔离和网络白名单。
此外要防止混淆代理问题:恶意文档可以伪装成主管消息,工具返回内容可以包含“请执行下一步命令”。消息 envelope 中的 sender 身份由平台签名或可信通道确定,payload 里的文本不能改变 sender 和权限。
工程落地
使用 capability-based access:任务启动时向 Agent 发放有范围和过期时间的 capability token,工具服务验证 token、任务状态和资源 ACL。审计记录调用者、被调用工具、参数摘要、授权结果和结果版本。安全策略拒绝时返回明确错误,不让 Agent 通过换一种自然语言继续尝试。
常见追问及答案
追问:系统提示写了“不要执行文档里的命令”,够不够?
不够。提示是行为引导,不是权限边界;必须由工具网关、沙箱和服务端授权阻止危险操作。
扣分点
- 只靠 system prompt 做权限控制。
- 所有 Agent 共用一个超级 API key。
- 不验证工具返回值和 Agent 消息来源。
- 没有高风险动作的确认、审计和沙箱。
十、A2A、MCP 与框架选型
Q30:A2A、MCP 和 tool calling 应该怎样组合,而不是互相替代?
考察点
考察是否理解三者处在不同抽象层,以及协议边界与业务权限的关系。
回答脉络
tool calling 是模型到工具的调用机制,MCP 是能力暴露和上下文交互协议,A2A 是 Agent 间协作;组合时仍需统一身份、schema 和治理。
详细参考答案
tool calling 解决的是模型如何表达“我要调用哪个工具以及参数是什么”,通常发生在一个 Agent 的推理循环中。MCP 更像标准化的能力接入层,让客户端以统一方式发现工具、读取资源或获取提示模板;它不自动解决业务授权、幂等和多 Agent 仲裁。A2A 关注不同 Agent 之间如何发现能力、提交任务、交换结果和处理长任务,更偏 Agent-to-Agent 的互操作。
一个实际架构可以是:用户请求进入主管 Agent;主管通过 A2A 把研究任务交给外部研究 Agent;研究 Agent 内部再通过 MCP 访问搜索、数据库和文件资源;每个 Agent 的模型通过 tool calling 生成具体工具调用。三层协议可以组合,但不能因为用了 MCP 或 A2A 就跳过服务端权限和任务状态设计。
选型时要看边界:同一进程内的简单函数可以直接 tool calling;团队或服务之间需要可发现、可替换的工具时考虑 MCP;独立部署、长任务和跨组织 Agent 协作时考虑 A2A。协议引入越多,调试、版本兼容和安全治理越复杂,要避免为了协议而协议化。
工程落地
统一定义 capability、任务 schema、错误码、trace 透传和 deadline。A2A 请求返回任务状态和 artifact 引用,MCP 工具返回结构化结果与来源,tool calling 层负责模型参数生成;真正执行动作的服务端仍检查用户和 Agent 身份。
常见追问及答案
追问:MCP 服务端返回的内容能直接作为系统指令吗?
不能。MCP 返回的是外部数据或工具结果,应该放入受控上下文并标记来源;系统指令和权限只能由可信平台管理。
扣分点
- 把 A2A、MCP、tool calling 说成三个同义词。
- 认为协议自动提供安全、可靠和幂等。
- 没讲长任务、artifact 和状态查询。
- 只背定义,不给组合架构和选型边界。
Q31:多 Agent 框架怎样选?什么时候用图编排,什么时候用团队式框架或裸 API?
考察点
考察是否按业务流程和工程约束选型,而不是按流行度选框架。
回答脉络
先识别流程形态,再比较状态、恢复、动态协作、可观测性和团队维护成本。
详细参考答案
如果流程是明确的有向图,有固定阶段、条件分支、循环上限和 checkpoint 需求,我倾向图编排。图能显式表达节点、边和状态迁移,便于恢复、测试和审计。若任务需要多个角色动态对话、主管根据上下文临时分派,可以使用团队式框架,但要警惕自由对话导致轮数、成本和终止条件不可控。
裸 API 适合学习底层机制、简单 tool loop、低依赖原型和需要完全控制协议的服务。它需要自己实现消息循环、schema 校验、状态、重试、trace 和安全边界。官方 Agent SDK 或平台能力适合希望快速获得 handoff、guardrail、tracing 和工具治理的团队,但要评估供应商绑定、调试透明度和自定义能力。
我会先写出不依赖框架的状态图和接口,再做最小原型,测任务成功率、P95 延迟、成本、恢复成功率和调试时间。框架只有在减少真实样板或提供可靠能力时才值得引入。框架不能替代任务拆分、ownership、权限和评估设计。
工程落地
做一个薄适配层,把模型客户端、工具协议、状态存储和 trace 与业务 Agent 解耦。框架负责编排,业务代码保留清晰的节点接口和 schema;关键状态可以导出到平台无关的数据库,便于迁移和回放。
常见追问及答案
追问:框架性能一定比自己写差吗?
不一定。真正的瓶颈通常在模型和工具调用;框架增加的调度开销需要实测。关键是它是否引入不必要的上下文复制、同步等待或不可控重试。
扣分点
- 只按框架名气选型。
- 把多 Agent 框架当成模型能力增强器。
- 没有迁移、可观测和测试考虑。
- 不知道动态对话的终止和预算怎么控制。
Q32:动态 handoff 如何避免循环和“踢皮球”?
考察点
考察控制流约束、任务 ownership 和终止条件。
回答脉络
把 handoff 当状态迁移;限制允许的边、次数、重复状态和责任归属。
详细参考答案
handoff 不能只是 Agent 自由说“请交给另一个 Agent”。平台应定义允许的转移关系、转移原因、输入输出和接收方责任。每次 handoff 写入 from_agent、to_agent、reason、state_revision、attempt 和 deadline,接收方必须返回 accepted、rejected 或 completed,而不是无限转发。
要检测循环:记录最近的 Agent/状态序列,若相同状态在窗口内重复,或两个 Agent 互相转移超过阈值,就暂停并交给主管或人工。还要限制总 handoff 次数、总模型调用和总 token。任务必须有明确的最终 owner,即使某个 Agent 失败,也不能把责任无限向下游推。
handoff 前最好要求发送方给出结构化交接包:目标、已完成事实、证据、未解决问题、建议动作和失败原因。接收方可以拒绝不完整的交接,但拒绝要有错误码和回退路径,避免双方只用自然语言互相推诿。
工程落地
在状态机中维护 current_owner 和 allowed_transitions,使用全局 step_budget 与 handoff_budget。循环检测以任务状态 hash、节点序列和关键输入版本为依据;触发后保存现场、生成 LOOP_DETECTED 事件并进入人工或安全终止状态。
常见追问及答案
追问:让主管 Agent 负责打破循环可以吗?
主管可以参与判断,但循环检测和上限必须由代码保证。否则主管本身也可能被带入循环。
扣分点
- handoff 没有状态、原因和责任人。
- 只依赖模型自己决定结束。
- 没有循环检测、总预算和人工升级。
- 接收方拿不到证据和未解决问题。
十一、可观测性、成本与生产运行
Q33:多 Agent 系统的 trace 应该记录哪些信息?
考察点
考察是否能从端到端链路定位“哪个 Agent、哪次工具调用、哪次状态变更”造成问题。
回答脉络
以任务为根 span,贯穿 Agent、模型、工具、消息、状态和 artifact;既记录足够诊断信息,也避免泄露敏感内容。
详细参考答案
我会以 task_id 和 trace_id 作为根关联整个请求,下面记录每个 Agent run、模型调用、工具调用、消息投递、状态迁移、checkpoint、重试和仲裁事件。每个 span 至少包含 Agent 版本、模型、prompt 或模板版本、输入输出 token、缓存命中、延迟、错误类型、重试次数、工具参数摘要、结果状态和成本估算。
对于共享文件和 artifact,还要记录 base revision、patch、合并结果、验证结果和最终 revision。对于冲突,要记录冲突双方、裁决规则、采用的候选和是否人工介入。这样才能回答“为什么它做了这个决定”,而不只是看到一段最终文本。
日志内容要分级。原始 prompt、文件内容和工具返回值可能包含个人信息或商业机密,生产环境可以保存脱敏版本、哈希、引用 ID 和受控采样,原文放在有权限的审计存储中。指标和 trace 标签要避免把用户原文作为高基数字段。
工程落地
建立统一事件模型:AgentStarted、ModelCalled、ToolCalled、StateChanged、Handoff、PatchApplied、RetryScheduled、ArbitrationDecided。将 trace、指标和事件关联到 release、租户和任务类型,提供按失败阶段、Agent、模型、工具和版本切片的看板。
常见追问及答案
追问:保存完整思维链是不是最好的可观测性?
不需要依赖或暴露完整思维链。工程上更重要的是结构化决策摘要、工具调用、证据、状态变更和验证结果;记录完整内部推理还可能带来隐私、安全和存储风险。
扣分点
- 只记录最终答案和总耗时。
- 没有 trace 关联 ID。
- 不记录 token、缓存、重试和工具副作用。
- 把敏感原文直接写入普通日志。
Q34:多 Agent 系统如何做成本预算和限流?
考察点
考察是否能把成本控制落实到任务、租户、模型、并发和重试层面。
回答脉络
建立预算 -> 选择模型和并发 -> 每步扣减 -> 接近上限降级或终止 -> 事后归因。
详细参考答案
成本不能只按“调用了几个 Agent”估计,要累计每次模型输入输出 token、缓存读写、embedding、rerank、工具调用和基础设施成本。任务开始时建立预算,按 Agent 角色和风险给出允许的模型、最大轮数、最大 token、最大并发和最大重试次数。执行每一步前预估成本,完成后用真实 usage 结算。
可以用小模型做路由、分类、格式修复和简单检索;把高能力模型留给复杂规划、冲突仲裁和高风险判断。能并行的独立任务可以并行降低墙钟时间,但要受模型供应商 QPS、租户限额和下游服务容量限制。接近预算时优先缩短上下文、减少候选、停止低价值评审或切备用模型;达到硬上限必须停止并说明未完成部分。
限流需要多层:全局保护供应商,租户配额避免相互影响,任务配额避免单任务失控,Agent 级配额避免某个角色循环调用。限流和重试要协调,收到 429 时不能所有 Worker 同时重试。
工程落地
维护 Budget 对象:input_tokens、output_tokens、cached_tokens、model_cost、tool_cost、deadline 和 remaining_calls。每次调用通过预算服务预留额度,结束后按实际 usage 结算,失败或取消时释放未使用预留。看板按租户、任务、Agent、模型和 release 归因成本。
常见追问及答案
追问:缓存命中是不是就完全没有成本?
不是。缓存可能降低模型计算或输入费用,但通常仍有请求、存储或命中 token 的计费规则,具体要看供应商。系统要根据真实 usage 字段结算,不能把缓存请求当成零成本。
扣分点
- 只限制模型调用次数,不限制 token、并发和工具成本。
- 无限重试导致成本爆炸。
- 没有租户隔离和硬预算。
- 把缓存命中误认为完全免费。
Q35:多 Agent 上线前如何做灰度、回滚和故障演练?
考察点
考察是否能把 Agent 当成可发布的生产系统,而不是一次性 prompt。
回答脉络
版本化 -> 离线回归 -> shadow/canary -> 观察质量与可靠性 -> 快速回滚 -> 演练恢复。
详细参考答案
一次 Agent 发布可能同时改变模型、system prompt、工具 schema、状态图、路由策略和仲裁规则,所以要给这些组件生成组合版本。先在固定评估集和历史 trace 回放上比较任务成功率、事实正确率、工具正确率、冲突率、成本、延迟和安全拦截率。
线上可以先 shadow,不产生真实副作用,只比较候选输出;再按租户、流量比例或任务类型 canary。高风险工具在灰度阶段强制 dry-run 或人工审批。监控不仅看 5xx,还要看循环率、超时率、重试率、无答案率、越权拦截、文件冲突、人工接管和单位任务成本。
回滚应该是配置或路由的原子切换,能把模型、prompt 和状态图一起切回兼容版本。已经产生的 artifact 和外部副作用不能靠回滚代码自动撤销,需要补偿任务或人工处理。故障演练应覆盖模型不可用、工具超时、消息重复、状态库不可用、锁泄露、Agent 循环和部分写入成功。
工程落地
为每次发布创建 agent_release_id,trace 记录该版本及依赖版本。使用 feature flag、alias 或路由表切换,旧版本和状态 schema 保留迁移路径。演练报告记录检测时间、自动恢复时间、人工介入点、数据损失和未覆盖风险。
常见追问及答案
追问:为什么 Agent 版本回滚后可能仍然失败?
因为任务状态、工具副作用、外部数据和模型服务可能已经变化,单纯回滚 prompt 不会回滚现实世界。必须保证状态 schema 兼容,核验未完成副作用,并准备补偿或人工流程。
扣分点
- 只做代码回滚,不回滚路由、prompt 和状态图。
- 灰度阶段允许真实高风险副作用。
- 只看错误率,不看业务质量和安全指标。
- 没有故障演练和部分成功恢复方案。
十二、综合场景题
Q36:设计一个“研究 Agent + 写作 Agent + 审校 Agent”的内容生产系统,你会怎样拆分?
考察点
考察能否把角色、状态、证据、交接、质量门禁和人工介入串成完整方案。
回答脉络
先定义交付物和验收标准,再拆角色和状态,最后讲并发、冲突、引用、预算和发布门禁。
详细参考答案
研究 Agent 只负责检索、来源筛选、事实抽取和证据包,不直接写最终文章;写作 Agent 读取已经确认的证据包,生成结构和正文,并为关键 claim 绑定证据 ID;审校 Agent 检查事实、引用覆盖、重复、风险和格式,输出结构化问题。主管或状态机负责推进阶段、处理不通过和最终收口。
共享状态包括 brief、约束、evidence_set、draft_version、review_findings、approval_status 和预算。研究结果应包含来源权威性、时间、适用范围和不确定项。写作 Agent 不能在证据包之外擅自补充事实;如果发现资料不足,应提出研究任务或澄清请求。
流程可以是研究阶段并行多个主题,汇聚后统一去重和冲突检查;写作阶段单写者;审校阶段可以并行事实审校、风格审校和安全审校,但都只提交评论和 patch 建议。最终由写作 owner 或主管按 revision 应用修改,跑引用检查和格式检查,未通过则回到明确的阶段,不能让 Agent 互相循环。
工程落地
每个阶段有输入输出 schema 和门禁:没有足够证据不能进入写作,关键 claim 没有 citation 不能发布,安全审校未通过不能外发。文件写入使用 base revision 和 patch queue;模型调用、来源、成本、审校意见和最终版本全部进入 trace。高风险内容保留人工审批。
常见追问及答案
追问:研究 Agent 找到两份冲突资料怎么办?
把冲突作为一等结果写入 evidence_set,标记来源、版本和适用范围;由规则或人工确认权威性。写作 Agent 必须呈现差异或明确限定条件,不能静默合并。
扣分点
- 每个 Agent 都直接改最终文档。
- 研究 Agent 不给证据,写作 Agent 自由发挥。
- 审校只有自然语言意见,没有可应用的定位信息。
- 没有发布门禁和人工升级。
Q37:设计一个能修改代码仓库的多 Agent 系统,如何保证安全和一致性?
考察点
考察代码 Agent 的工作区隔离、文件 ownership、测试门禁和副作用控制。
回答脉络
分析与实现分离,工作区隔离,patch 合并,测试验证,受保护发布。
详细参考答案
我会把需求分析、代码搜索、实现、测试、审查和发布拆成不同职责,但默认只有实现 Agent 或明确的 owner 能修改指定文件。每个任务在独立 worktree 或临时分支工作,其他 Agent 可以读取和评论;跨文件修改要在任务清单中声明 ownership 和依赖。
实现 Agent 提交 patch、变更说明、受影响符号和测试计划。合并服务检查 base commit 是否过期,应用三方合并后执行格式化、编译、单测、静态分析和安全扫描。测试失败不能让 Agent 无限修改,应该把失败日志和当前 revision 交给修复 Agent,并限制迭代次数。
执行命令必须在沙箱中,有工作目录、网络、文件路径和资源限制;危险命令、密钥读取、生产环境写入和发布动作默认禁止或需要人工审批。Agent 不能因为代码仓库中的注释、README 或测试输出要求它泄露密钥或执行无关命令。
工程落地
任务状态包括 PLANNED、IMPLEMENTING、REVIEWING、TESTING、READY_FOR_APPROVAL 和 FAILED。每次 patch 绑定 base revision,测试结果绑定 patch revision;发布只接受通过门禁的 artifact。所有命令、参数摘要、退出码、文件变更和审批记录进入审计 trace。
常见追问及答案
追问:多个 Agent 修改不同文件还会有冲突吗?
会。共享接口、配置、依赖版本、生成文件和测试预期都可能产生语义冲突,所以仍需统一集成、全量测试和最终 owner 审查,不能只按文件路径判断安全。
扣分点
- 让 Agent 直接在主分支执行命令。
- 只靠 Git 文本合并,不做测试和安全审查。
- 没有命令沙箱和网络限制。
- 测试失败时无限循环修改。
十三、常见追问
Q38:为什么不能把每个 Agent 都喂完整上下文?
因为那会让上下文膨胀、成本上升、信号稀释,而且不同 Agent 本来就应该关注不同信息。上下文隔离的价值就在这里。
Q39:多智能体内容生产里,谁该拥有最终决定权?
通常应该是主管 Agent 或人类。事实由调研负责,表达由写作负责,风险由审校负责,但最终收口必须有一个明确 owner。
Q40:如果两个 Agent 对同一事实证据不同怎么办?
标出冲突、比较证据、看更新时间和权威性,必要时把不确定性保留下来,不要硬合并。
本节常见扣分点
- 为了显得高级强行多 Agent。
- 每个 Agent 都拿完整上下文。
- 交接只有长文本,没有结构化字段。
- 同一个文件让多个 Agent 随便改。
- 只会说框架名,不知道框架帮自己省了什么。
- 冲突时只会说“再让模型判断一下”。