mm_agent_tutorial

第 6 章 Agent Handoff:任务移交与协作协议

1. 开篇段落

在构建复杂的智能体系统时,“单体全能”(One Model Fits All) 的幻想往往是项目失败的根源。尽管 GPT-4o 或 Gemini 1.5 Pro 等模型拥有巨大的上下文窗口,但试图让一个 Agent 连续完成“读取 500 页技术文档 -> 编写 Python 代码验证 -> 撰写商业报告”的全流程,通常会导致以下问题:

  1. 注意力稀释(Attention Dilution):随着上下文变长,模型对早期指令或中间约束的遵循能力显著下降(Lost-in-the-Middle 现象)。
  2. 角色混淆(Role Confusion):同一个 System Prompt 难以同时包含“严谨的审计员”和“富有创意的营销专家”两种立的人格约束。
  3. 成本失控:在长对话后期,为了修改一个标点符号而重新输入 100k tokens 是极大的浪费。

Agent Handoff(智能体移交) 是解决这些问题的核心架构模式。它不只是简单的函数调用,而是责任、上下文与状态的正式转移。本章将深入探讨如何设计一套“防弹”的移交协议,确保任务在不同专家 Agent(或人类)之间流转时,信息不丢失、目标不偏移、死循环被阻断。

本章学习目标:

  1. 架构视角:掌握线性、星型、分层等多种移交拓扑及其适用场景。
  2. 协议设计:构建标准化的 Handoff Packet(移交包),实现“无状态重启”与“有损压缩”。
  3. 多模态流转:解决图片、音频、长文档在 Agent 间传递时的引用与带宽问题。
  4. 防御性工程:设计握手、拒绝与回退机制,防止“击鼓传花”式的死循环。

2. 核心论述:移交的工程艺术

2.1 移交的本质:降低熵增

智能体系统的运行过程是一个熵增过程(噪声积累)。Handoff 的本质是一次熵减操作。 通过 Handoff,我们将前序 Agent 产生的冗长、混乱的思维链(Chain of Thought)和试错过程,压缩为清晰的“结论”“资产”,传递给下一个拥有全新、干净上下文窗口(Context Window)的 Agent。

2.2 移交拓扑结构 (Handoff Topologies)

不同的业务流需要不同的移交模式。不要被“多智能体”这个词迷惑,即使是两个 Agent,也存在复杂的拓扑。

A. 线性接力 (The Relay / Pipeline) 最简单、最稳健的模式。适用于标准化作业流程(SOP)。

[ Source ] -> (Agent A: Ingest) -> [Structured Data] -> (Agent B: Analyze) -> [Report] -> (Agent C: Publish)

B. 星型路由 (Hub-and-Spoke / Router) 通过一个中央大脑(Router)来分发任务。

                 +-----------+
                 |  Router   |
                 +-----+-----+
   (1) Intent?      /  |  \      (3) Aggregate
                   /   |   \
        +---------+ +--+--+ +---------+
        | Search  | | Code| | Draw    |
        +---------+ +-----+ +---------+
             (2) Execute & Return

C. 升级与回退 (Escalation & Fallback) 这是生产环境中最关键的模式。

D. 动态协作 (Dynamic Collaboration / Swarm) Agent 之间可以任意互相呼叫(类似于微服务网格)。

2.3 核心协议:Handoff Packet (移交包)

移交绝对不应该是把整个 Chat History 扔给下一个 Agent。这既昂贵又充满了上一轮的“思维垃圾”。 你需要定义一个标准化的 JSON Schema 作为移交包。

一个健壮的 Handoff Packet 必须包含以下四个象限:

字段类别 关键内容 说明
1. Meta (元数据) source_agent, target_agent, timestamp, handoff_id, priority 用于追踪、日志审计和防死循环(Traceability)。
2. Mission (任务) objective, definition_of_done (DOD), constraints 下一个 Agent 必须做什么?什么算做完?有什么禁?
3. Context (上下文) summary_so_far, user_original_intent, key_facts 对前序工作的有损压缩。只保留结论,丢弃推理过程。
4. Artifacts (资产) file_uris, image_ids, db_record_ids, extracted_data 引用指针。不要传文件内容,传 S3 链接或数据库 ID。

多模态特别说明 (Rule of Thumb)

2.4 上下文压缩策略:如何“断章取义”?

移交时的最大痛点是信息丢失。如何保证 Agent B 能接得住?

  1. 摘要链 (Summary Chain):Agent A 在移交前,必须执行一个内部思考步骤:“总结我目前已知的信息,并为下一个接手者写一份简报”。这份简报是 Packet 的核心。
  2. 不可变事实 (Immutable Facts):维护一个全局的 KV 存储或清单。例如用户的姓名、订单号、已确认的需求。这些信息不随 Handoff 压缩,而是作为附件始终跟随。
  3. 回溯指针 (Back-links):如果 Agent B 对简报有疑问,Packet 中应包含指向 Agent A 完整日志的链接(Trace ID),允许 B 在极少数情况下“查阅原档”(虽然我们尽量避免)。

2.5 拒绝与握手协议 (Rejection & Handshake)

Agent Handoff 不总是成功的。Agent B 可能认为任务描述不清,或者自己无法处理。


3. 本章小结

  1. 分而治之:Handoff 是解决 Context 限制和能力专业化的唯一路径。
  2. 协议至上:定义清晰的 Handoff Packet 结构(Meta, Mission, Context, Artifacts)比优化 Prompt 更重要。
  3. 引用代替拷贝:在多模态系统中,始终传递资产的 URI 和 ID,而非 Base64 或原始文本。
  4. 防卫性设计:必须设计死循环检测(TTL)、拒绝机制(NACK)和人工接管通道(Escalation)。
  5. 有损压缩:移交必然丢失信息,关键在于保留“结论”和“事实”,丢弃“过程”和“噪音”。

4. 练习题

基础题 (50%) —— 熟悉协议与流程

Q1: 为什么在移交时,不建议直接把上轮的 Chat History 完整拼接到下一个 Agent 的 Prompt 中?请列举三个原因。 (点击展开) 1. **成本与配额**:历史记录可能非常长,导致 Token 消耗指数级增长,且容易超出上下文窗口限制。 2. **注意力干扰(噪音)**:上一个 Agent 的试错过程、失败尝试和纠结的思维链,对下一个 Agent 来说是干扰信息,可能导致它重蹈覆辙或产生幻觉。 3. **角色污染**:上一个 Agent 的 System Prompt 或对话风格可能会“泄漏”到下一个 Agent,导致角色扮演失败(例如严谨的审核员开始像推销员一样说话)。 **提示**:想象一下,你接手同事的工作时,是希望他给你一份 500 页的聊天记录,还是一份 1 页的交接文档?
Q2: 设计一个简单的 JSON Handoff Packet,用于将一个“PDF 总结任务”从“阅读者 Agent”移交给“翻译 Agent”。 (点击展开) ```json { "meta": { "from": "reader_agent_v1", "to": "translator_agent_v1", "trace_id": "trace_88219" }, "task": { "action": "translate_summary", "target_language": "Spanish", "tone": "professional" }, "context": { "summary_content": "The Q3 financial report shows a 20% increase in revenue...", "key_terms": ["EBITDA", "YoY"] }, "artifacts": { "source_doc_id": "s3://docs/q3_report.pdf", "source_page_refs": [3, 4] } } ``` **提示**:包含元数据、具体要做什么、原始内容是什么、以及原始文件的引用。
Q3: 什么是“死循环移交”(Infinite Handoff Loop)?如何通过协议字段防止它? (点击展开) **现象**:Agent A 觉得这事该 B 做,移交给 B;B 看了觉得缺信息,又移回给 A。两者反复踢皮球。 **防止手段**: 1. **TTL / Hop Count**:在 Packet 的 `meta` 中增加 `hop_count` 字段,每次移交 +1。如果超过阈值(如 5),强制终止或转人工。 2. **Chain History**:记录已经经手过的 Agent 列表 `["A", "B"]`。B 看到 A 已经在列表里,且任务状态未变,应触发报错而非回传。 **提示**:网络数据包中的 TTL 字段是做什么的?

挑战题 (50%) —— 系统设计与工程思维

Q4: 场景:DeepResearch Agent 正在撰写报告,需要一张图表。它移交给 Code Agent 画图,但 Code Agent 报错说“数据列缺失”。请设计一个带有“自我修复”能力的移交流程。 (点击展开) 这是一个典型的 **Request-Reply-Repair** 模式: 1. **Attempt 1**: Research Agent -> Handoff Packet (含数据) -> Code Agent。 2. **Failure**: Code Agent 运行 Python 失败,捕获 `KeyError: 'revenue'`。 3. **Return (NACK)**: Code Agent 不只是报错停止,而是发起一个 **Reverse Handoff** 回给 Research Agent。 * Content: "Execution Failed." * Reason: "Missing column 'revenue' in provided dataset." * Suggestion: "Please check extraction or provide correct CSV." 4. **Repair**: Research Agent 收到退回包,读取 Reason。它的 Policy 决定重新读取文档提取 'revenue' 列。 5. **Attempt 2**: Research Agent 发送新的 Packet (含修复后的数据) -> Code Agent。 6. **Success**: Code Agent 绘图成功,返回 Image URI。 **关键点**:Code Agent 的报错必须结构化返回给 Research Agent,而不是抛给用户。
Q5: 在“人机移交”(Human Handoff)场景中,如何处理“人类操作员下班了”导致的长延迟问题?这对系统架构有什么影响? (点击展开) **核心挑战**:**状态持久化与唤醒(State Hydration)**。 1. **异步架构**:系统不能让 Python 线程或 API 连接一直 `sleep()` 等待人类。 2. **序列化存储**:当决定移交给人时,必须将当前 Handoff Packet 序列化存入数据库(PostgreSQL/Redis),标记状态为 `WAITING_FOR_HUMAN`,并释放计算资源。 3. **回调钩子 (Webhook)**:当人类在 UI 上完成操作并点击“提交”时,前端触发 Webhook。 4. **状态恢复**:系统根据 ID 从数据库拉取 Packet,将人类的输入注入到 `context` 中,然后**重新实例化**一个新的 Agent 继续运行。 **结论**:人机移交强制要求系统架构必须是**无状态(Stateless)**且**事件驱动(Event-driven)**的。
Q6 (开放题): 假设你有一个包含 5 个不同专家 Agent 的系统。请设计一个评分机制,让 Router 自动决定把任务派给谁,而不是写死规则。 (点击展开) **思路:基于描述符的语义匹配(Semantic Routing)。** 1. **注册机制**:每个 Agent 在启动时,向 Router 注册自己的 `Manifest`(清单)。 * `Agent A (Coder)`: "擅长 Python, 数据处理, 绘图。输入需要 CSV。" * `Agent B (Writer)`: "擅长 本润色, 创意写作, 总结。输入需要文本。" 2. **任务向量化**:Router 接收到任务 "帮我分析这个 Excel 并画个图" 时,将其 Embedding 为向量。 3. **相似度匹配**:计算 任务向量 与 Agent 描述向量 的相似度(Cosine Similarity)。 4. **动态选择**:选择得分最高的 Agent。 5. **反馈闭环 (RLHF)**:如果 Router 派给 A,但 A 失败了(返回 NACK),Router 应降低该类任务对 A 的权重,并尝试得分第二高的 Agent。 **提示**:这类似于 RAG 中的检索过程,只不过检索的是“工具人”而不是“文档”。

5. 常见陷阱与错误 (Gotchas)

5.1 传声筒效应 (The Telephone Game)

5.2 格式承诺崩溃 (Schema Promise Break)

5.3 幻觉引用 (Hallucinated References)

5.4 幽灵权限 (Phantom Privileges)