01
60 秒回答模板
多 Agent 协作里我会先把通信和共享状态拆开。Agent 之间不要直接共享一大块可变内存,而是通过编排器、消息队列或事件日志传递任务事件,例如谁接到子任务、工具调用开始、工具结果已生成。真正需要跨 Agent 复用的状态放在一个有 schema 的状态仓库里,按 session、task、agent、artifact 分 namespace,并给每次更新带 version、trace id 和幂等键。工具结果尽量作为不可变 artifact 存储,只在消息里传引用、摘要和校验信息,避免大 payload 在上下文里反复拷贝。并发冲突上,数据库行用事务、乐观锁或 compare-and-swap;文件写入用临时文件加原子 rename、目录级锁或单 writer 模型;长任务用 lease 防止多个 Agent 同时认领。冲突发生时不要静默覆盖,而是让编排器根据版本冲突重读、合并或重派。验证上要看事件可回放、幂等重试是否安全、并发压测下 lost update 为零,以及每个工具结果都能从最终回答追溯到原始调用。
考点 不要共享可变大上下文
难度 真实面经题
回答目标 回答要体现多 Agent 协作不是简单聊天,而是围绕消息、状态、artifact、锁、幂等和可观测性建立可靠的分布式工作流。
02
深入解析
01 通信和状态分离
多 Agent 通信首先要避免把聊天上下文当成唯一状态源。消息适合表达事件、意图和短摘要,状态仓库适合保存可恢复的任务进度、锁、产物引用和决策记录。这样单个 Agent 崩溃或上下文被截断时,系统仍能从持久状态恢复,而不是依赖某段自然语言记忆。
02 消息传递模型
常见做法是由编排器集中调度,或通过队列、事件总线、actor mailbox 让 Agent 订阅自己关心的事件。消息应包含 task id、sender、receiver、causal parent、幂等键、payload 摘要和状态版本。这样可以支持重试、超时、取消、回放和审计,也能避免广播式对话导致所有 Agent 都误读同一份上下文。
03 共享状态设计
共享状态要有明确 schema 和所有权边界,例如任务状态、计划、候选答案、工具调用记录、外部资源锁分别建模。不要让多个 Agent 随意写同一个 JSON blob,因为这种方式很难定位覆盖写。更稳妥的是把状态拆成细粒度记录,并对每类记录定义谁能创建、谁能更新、谁只能读取。
04 工具结果传递
工具结果一般不应完整塞进每条 Agent 消息,尤其是网页、文件、数据库查询或模型大输出。更好的方式是把原始结果作为不可变 artifact 保存,消息里只传 artifact id、摘要、schema 版本、哈希和必要片段。需要进一步处理时,Agent 根据引用读取受控内容,最终答案可以追溯到具体工具调用。
05 并发写控制
数据库写入可以用事务、唯一约束、行级锁、乐观锁版本号或 compare-and-swap;文件写入可以用单 writer、临时文件加原子替换、文件锁或按 Agent 分目录写入再合并。关键是不允许最后写入者无条件覆盖前一个结果,所有状态更新都要带预期版本,冲突时触发重读和合并。
06 任务认领和租约
当多个 Agent 从同一队列取任务时,需要任务认领机制。常用方式是 pending、running、completed 状态机,加 lease_until、owner_agent 和 heartbeat。Agent 超时未续租后任务才能被其他 Agent 接管。这样既能避免重复执行,也能处理 Agent 崩溃、网络断开和工具调用长时间挂起。
07 幂等和重试
分布式协作一定会遇到重复投递、超时重试和半成功状态,因此每个外部副作用都要设计幂等键。创建记录、写文件、调用外部 API、发送通知时都要能识别同一次逻辑操作。否则 Agent 看似只是重试一次,实际可能生成重复订单、重复写入或把旧工具结果覆盖新结果。
08 验证和观测
验证不能只靠人工看日志。应构造并发压测,让多个 Agent 同时更新同一任务、写同一类 artifact、模拟工具超时和重复消息,检查 lost update、重复执行和状态机非法迁移。生产侧要有 trace、事件回放、版本冲突计数、锁等待时间和最终答案到工具结果的 provenance。
03
易错点
- 把 Agent 间通信等同于把聊天记录互相转发,忽略持久状态和可恢复性。
- 让多个 Agent 读写同一个大 JSON 或同一个文件,没有版本号、锁或合并规则。
- 把工具返回的大 payload 反复塞进模型上下文,既浪费 token 又容易被转述污染。
- 依赖最后写入者胜出的数据库更新策略,把并发冲突当成正常成功。
- 没有为外部副作用设计幂等键,导致超时重试后重复创建数据或重复发送请求。
- 只记录最终结果,不记录消息、工具调用和状态版本,出错后无法还原因果链。
- 任务认领只放在内存里,Agent 崩溃后任务无法接管或被多个 Agent 同时执行。
- 把所有冲突都交给 LLM 自然语言判断,没有结构化验证、约束和回滚路径。
04
面试官追问
如果两个 Agent 同时修改同一个任务计划,应该怎么处理?
我会先避免两个 Agent 直接改同一字段,尽量拆成提案记录和编排器合并。如果确实要并发写同一计划,就用版本号或 compare-and-swap,更新时声明基于哪个版本。冲突后重读最新计划,按字段级规则合并,无法自动合并时让上层仲裁,而不是直接覆盖。
文件系统里的共享中间结果怎么避免覆盖?
把文件路径设计成按 task、agent、attempt 和 artifact id 分层,写入时先写临时文件,完成校验后原子 rename。公共索引文件由单 writer 或事务型元数据表维护。多个 Agent 不直接追加同一个文件,合并动作单独建模并记录输入 artifact 列表。
为什么不直接把所有 Agent 的消息放进同一个 LLM 上下文?
同一个上下文适合小规模协作演示,但不适合可靠工程系统。上下文会变长、被截断、缺少结构化版本,也无法表达锁和事务。生产系统应让 LLM 看到当前必要摘要,事实状态仍由可验证的结构化存储和 artifact 引用承载。
工具调用超时后应该重试还是等待?
先看工具是否具备幂等键和结果查询。如果请求可能已经成功,应先用幂等键查询或读取状态,再决定是否重试。对于不可幂等的外部副作用,要把调用设计成先创建意图、再确认提交,避免 Agent 因超时判断错误而重复执行。
怎么证明多 Agent 并发控制是有效的?
可以做三类验证:单元测试覆盖状态机非法迁移和版本冲突;并发压测让多个 Agent 抢同一任务、写同一资源;故障注入模拟超时、重复消息、Agent 崩溃。验收指标包括 lost update 为零、重复副作用为零、所有冲突可观测且可恢复。