> ## Documentation Index
> Fetch the complete documentation index at: https://opc-43d279b8.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Lead Agent：任务拆解与子 Agent 分发

> Lead Agent 如何拆任务树、写交接契约、路由分派、汇总裁决冲突，以及超时重派与幂等的面试要点。

> Lead Agent 我踩过的坑都在交接上：信息丢了、超时重派导致重复执行、冲突没人拍板。拆任务容易，收尾难。

***

## Q1: Lead Agent、Supervisor、Orchestrator 是什么关系？

这三个词经常混用，但侧重点不同：

| 概念 | 核心职责 | 关键区别 |
| - | - | - |
| Supervisor | 监督子 Agent 执行，决定下一步交给谁 | 强调"调度与把关" |
| Orchestrator-Workers | 运行时动态拆解任务，分发给 Worker 并行执行 | 强调"拆解与并行" |
| Lead Agent | 对最终结果负责的"技术经理" | 强调"责任归属与结果收敛" |

一个完整的 Lead Agent 通常同时具备三者能力：

```text theme={null}
┌──────────────────────────────────────────────────────┐
│                     Lead Agent                       │
│                                                      │
│  ① 拆解：目标 → 任务树 / DAG                          │
│  ② 分派：按能力与负载路由到子 Agent                    │
│  ③ 监督：超时、失败、越级上报                          │
│  ④ 汇总：合并结果、裁决冲突、验收                      │
│  ⑤ 负责：对用户交付最终结果                            │
└──────────────────────────────────────────────────────┘
```

> [!WARNING]
>
> 有多个 Agent 并不等于多 Agent 编排。如果分派规则是代码写死的（账单问题给 A、技术问题给 B），那本质是 Workflow 的路由模式；只有 Lead 在运行时**动态决定怎么拆、拆多细、派给谁**，才属于编排者—工作者模式。

***

## Q2: Lead 怎么把一句话目标拆成可执行的任务树？

拆解的目标是一棵**可调度、可验收**的树，"分得越细越好"是常见误解。

```text theme={null}
目标：给现有后台增加"订单导出 PDF"功能
│
├── T1 调研（可并行）
│   ├── T1.1 找到现有订单列表与详情接口
│   └── T1.2 确认 PDF 生成库与字体方案
│
├── T2 设计（依赖 T1）
│   └── T2.1 输出接口契约与页面交互说明
│
├── T3 实现（依赖 T2，可并行）
│   ├── T3.1 后端导出接口
│   ├── T3.2 前端导出入口与进度态
│   └── T3.3 模板与排版
│
└── T4 验收（依赖 T3）
    ├── T4.1 单测与集成测试
    └── T4.2 人工验收清单
```

### 拆解的五个硬约束

| 约束 | 说明 | 反例 |
| - | - | - |
| 单一职责 | 一个叶子任务只由一个 Agent 完成 | "实现前后端并联调" |
| 输入契约 | 明确需要哪些文件、数据、上下文 | "你看着办" |
| 输出契约 | 明确产物格式与验收标准 | "写得好一点" |
| 依赖显式 | 用 DAG 表达先后关系 | 让 Worker 自己猜 |
| 粒度适中 | 一次工具调用链能完成 | 拆成十几个微任务 |

### 粒度怎么判断

```text theme={null}
太小：调度开销 > 执行成本，汇总成本爆炸
太大：Worker 上下文膨胀，失败重试代价高
合适：一个子任务 = 一个明确产物 + 一组相关工具调用
```

经验值：**子任务的工作量控制在 5-15 个工具调用以内**。超过就该继续拆，少于 2 个就该合并。

***

## Q3: 任务怎么分派？为什么"把完整对话历史丢给子 Agent"是错的？

分派是一次**结构化交接**，发一段任务描述远远不够。

### 交接契约

```typescript theme={null}
interface TaskHandoff {
  taskId: string;
  goal: string; // 一句话目标
  acceptance: string[]; // 验收标准，可逐条检查
  inputs: {
    files?: string[]; // 相关文件路径，不是全量仓库
    facts?: Record<string, string>; // 已确认的事实
    constraints?: string[]; // 技术栈、规范、禁用项
  };
  outputSchema: JSONSchema; // 产物结构
  deadlineMs: number;
  dependsOn: string[];
}
```

### 上下文隔离：只给"需要知道的"

子 Agent 不应该继承 Lead 的完整对话历史。原因有三：

1. **成本。** 几千 token 的历史乘以 N 个子 Agent，成本线性放大。
2. **噪声。** 无关的讨论会干扰子 Agent 判断，甚至让它重复 Lead 已经排除的方案。
3. **一致性。** 每个子 Agent 看到的历史版本可能不同，导致产物互相矛盾。

正确做法是维护一份**任务简报（brief）**：目标、已确认事实、约束、验收标准。子 Agent 只读简报加自己的子任务。

### 路由策略

| 策略 | 怎么做 | 适合 |
| - | - | - |
| 能力路由 | 按标签匹配（coding/review/search） | 专家 Agent 分工明确 |
| 负载均衡 | 看当前队列长度与成功率 | Worker 同质、任务量大 |
| 点名分派 | Lead 直接指定 agentId | 关键任务、需要特定上下文 |
| 任务池抢单 | Worker 空闲后自己领取 | 弹性伸缩、异步执行 |

```text theme={null}
Lead
 │
 ├─ 能力匹配 ──→ 候选 Agent 列表
 │                   │
 ├─ 负载过滤 ──→ 当前队列最短的
 │                   │
 ├─ 历史成功率 ─→ 同类任务成功率最高的
 │                   │
 └──────────────→ 分派 + 记录 trace
```

> [!NOTE]
>
> 分派的质量取决于交接契约的质量。自然语言转述三层之后必然丢信息，结构化 Schema 才能保证子 Agent 拿到的是同一份事实。

***

## Q4: 子 Agent 的结果怎么汇总？冲突了谁说了算？

汇总包含三个动作——校验、合并、裁决，拼起 N 份结果不算完成。

### 第一步：逐份校验

每个子任务返回后，Lead 先做机器校验：

| 校验项 | 不通过怎么办 |
| - | - |
| JSON Schema 是否合法 | 打回重做，最多 2 次 |
| 验收标准是否逐条满足 | 标记缺失项，补做 |
| 是否引用了不存在的文件/接口 | 视为幻觉，要求重查 |
| 是否违反约束（技术栈、规范） | 直接拒绝 |

### 第二步：合并

| 合并类型 | 做法 |
| - | - |
| 拼接型 | 各子任务产物互不重叠，按模板组装 |
| 去重型 | 多份结果有重复，按置信度或来源去重 |
| 归并型 | 同一问题的多个方案，需要选一个或融合 |

### 第三步：冲突裁决

冲突在多 Agent 系统里是常态，不能靠"让模型再聊一轮"解决。

| 裁决策略 | 适用场景 | 风险 |
| - | - | - |
| 依赖关系优先 | 有明确上下游 | 依赖判断错就全错 |
| 置信度优先 | 各 Agent 输出带置信分 | 置信分可能虚高 |
| 历史正确率优先 | 同类任务有统计 | 新任务没有历史 |
| 评审 Agent 裁决 | 需要专业判断 | 多一层成本与偏差 |
| 人工裁决 | 高风险、不可逆 | 打断自动化 |

```text theme={null}
冲突 → 是否可机器判定？
         ├─ 是 → 按规则裁决（依赖/置信度/历史）
         └─ 否 → 评审 Agent 给出理由与建议
                    └─ 仍不确定 → 升级人工
```

**关键原则：Lead 对最终结果负责。** 不能把 N 份互相矛盾的结果直接丢给用户，让用户自己判断。

***

## Q5: 子任务失败、卡死、跑偏，Lead 怎么处理？

### 四类失败与处理

| 失败类型 | 表现 | 处理 |
| - | - | - |
| 瞬时失败 | 超时、限流、网络错误 | 指数退避重试，工具层自愈 |
| 参数/格式错误 | 输出不符合 Schema | 带错误信息打回，最多 2 次 |
| 方向错误 | 产物与目标不符 | 终止并重新拆解该子树 |
| 卡死 | 长时间无进展 | 心跳检测 + 超时重派 |

### 越级上报

子 Agent 遇到以下情况不应擅自行动，而应带着上下文上报 Lead：

* 需要更高权限（删除、发布、改生产配置）。
* 发现任务前提不成立（接口不存在、需求矛盾）。
* 多个方案代价接近，无法自主决策。
* 连续失败达到阈值。

```text theme={null}
Worker 执行
   │
   ├─ 正常完成 ──────────────→ 返回结果
   ├─ 可自愈错误 ──→ 重试 ──→ 仍失败 ─┐
   ├─ 需要决策 ───────────────────────┤
   └─ 卡死/超时 ──────────────────────┤
                                       ▼
                              Lead 重新规划
                                 ├─ 重派给其他 Worker
                                 ├─ 拆成更小任务
                                 ├─ 降级方案
                                 └─ 升级人工
```

### 幂等性：重派的前提

所有写操作必须幂等，否则"超时后重派"会变成"重复下单"。常用做法：

1. 每个任务带唯一 `taskId`，下游按 ID 去重。
2. 写操作使用幂等键（`idempotency-key`）。
3. 重派前先查询任务状态，不要盲目重试。

***

## Q6: 怎么保证 Lead Agent 可观测、可评测？

多 Agent 最难的排障问题是："到底是哪一步错了？"没有 trace，调试就是玄学。

### 必须记录的事件

| 事件 | 关键字段 |
| - | - |
| 任务拆解 | 任务树、拆分理由、依赖关系 |
| 任务分派 | taskId、agentId、交接契约、时间 |
| 工具调用 | 工具名、参数、结果、耗时、错误码 |
| 子 Agent 返回 | 产物、校验结果、重试次数 |
| 冲突裁决 | 冲突双方、裁决依据、最终选择 |
| 人工介入 | 审批人、操作、时间 |

### 核心指标

```text theme={null}
任务层：成功率、平均完成时间、重派率、越级上报率
Agent 层：单任务步数、工具误调用率、上下文峰值、token 成本
系统层：队列长度、并发数、超时率、人工接管率
质量层：一次验收通过率、返工率、用户满意度
```

### 评测怎么做

1. **固定任务集。** 选 20-50 个真实任务，覆盖简单/中等/困难。
2. **固定模型与 Harness。** 只改编排策略，做 A/B。
3. **自动校验产物。** 能用 Schema 和测试校验的，不要用模型打分。
4. **LLM-as-a-Judge 只做补充。** 用于主观质量，且要人工抽检校准。
5. **回归门禁。** 成功率下降超过阈值就阻断发布。

***

## Q7: 成本与并发怎么控制？

多 Agent 的成本是**乘法增长**：子 Agent 数量 × 每轮上下文 × 轮次，按线性估算会严重低估。

| 手段 | 做法 | 效果 |
| - | - | - |
| 模型分级 | Lead 用强模型，Worker 用便宜模型 | 大幅降本 |
| 上下文预算 | 每个子任务设 token 上限 | 防止单点爆炸 |
| 结果截断 | 工具返回只保留头尾 | 降低回灌成本 |
| 并行限流 | 控制同时运行的 Worker 数 | 防止限流与雪崩 |
| 缓存 | 稳定前缀 + Prompt Cache | 长任务显著降本 |
| 早停 | 达到验收标准立即结束 | 避免过度执行 |

```text theme={null}
成本 ≈ Σ(子任务数 × 平均上下文 × 轮次 × 单价) + Lead 开销 + 汇总开销
```

> [!WARNING]
>
> 每多一个 Agent，就多一次上下文组装、一次模型调用、一次结果校验和一层失败可能性。先用单 Agent 跑通基线，确认瓶颈确实是上下文或工具过载，再拆多 Agent。过早拆分只会增加调度复杂度。

***

## Q8: 一个最小可用的 Lead Agent 实现长什么样？

```typescript theme={null}
// 极简 Lead Agent：拆解 → 拓扑调度 → 校验 → 汇总
type Task = {
  id: string;
  goal: string;
  deps: string[];
  status: "pending" | "running" | "done" | "failed";
  result?: unknown;
  retries: number;
};

async function runLead(goal: string) {
  const tree = await planner.decompose(goal); // 输出 Task[]

  while (tree.some((t) => t.status === "pending" || t.status === "running")) {
    // 1. 找出依赖已完成的 ready 任务
    const ready = tree.filter(
      (t) =>
        t.status === "pending" &&
        t.deps.every((d) => tree.find((x) => x.id === d)?.status === "done"),
    );

    // 2. 并行执行，控制在并发上限内
    await runWithConcurrency(ready, 3, async (task) => {
      task.status = "running";
      const agent = router.pick(task); // 能力 + 负载 + 历史成功率
      try {
        const output = await agent.run(buildHandoff(task, tree));
        const check = validator.check(task, output);
        if (!check.ok) throw new Error(check.reason);
        task.result = output;
        task.status = "done";
      } catch (err) {
        task.retries += 1;
        if (task.retries >= 3) {
          task.status = "failed";
          await escalator.escalate(task, err); // 重派 / 拆小 / 降级 / 人工
        } else {
          task.status = "pending";
        }
      }
    });
  }

  const failed = tree.filter((t) => t.status === "failed");
  if (failed.length) return synth.partial(tree, failed);

  return synth.merge(tree); // 合并 + 冲突裁决
}
```

### 这段代码对应的工程决策

| 代码 | 决策 |
| - | - |
| `planner.decompose` | 拆解由模型完成，但输出必须是结构化任务树 |
| `deps.every(...)` | 用 DAG 显式表达依赖，不靠自然语言约定 |
| `runWithConcurrency` | 并发有上限，防止限流和资源抢占 |
| `router.pick` | 分派不是随机，按能力、负载、历史成功率 |
| `validator.check` | 结果先机器校验，不把脏数据往下传 |
| `escalator.escalate` | 失败有明确出口，不无限重试 |

***

## Q9: 任务树和 DAG 到底有什么区别？为什么 Lead 应该产出 DAG？

### 机制差异

| 维度 | 任务树（Tree） | DAG（有向无环图） |
| - | - | - |
| 父节点 | 每个节点只有一个父节点 | 一个节点可以有多个前置依赖 |
| 表达力 | 只能表达"属于谁" | 能表达"依赖谁" |
| 共享依赖 | 无法表达 | 天然支持 |
| 调度 | 按层级遍历 | 按入度为 0 的节点就绪 |
| 失败影响 | 只能向上回溯一个分支 | 能精确定位哪些节点被阻塞 |

树适合"责任归属"，DAG 适合"执行调度"。Lead 真正需要的是后者：`T3.1 后端接口` 和 `T3.2 前端入口` 都依赖 `T2.1 接口契约`，如果用树表达，这条共享依赖会丢失，导致前端在契约未定时就开始实现。

```text theme={null}
         T1 调研
        /       \
   T1.1 接口   T1.2 PDF 方案
        \       /
         T2 设计（依赖 T1.1 与 T1.2）
              │
      ┌───────┴───────┐
   T3.1 后端       T3.2 前端
      └───────┬───────┘
           T4 验收
```

### 粒度怎么量化

不要只说"适中"，给可执行的判断：

```text theme={null}
一个叶子任务应满足：
1. 产物唯一：能写成一个文件 / 一份报告 / 一个补丁
2. 工具可控：5-15 次工具调用可完成
3. 可验收：验收标准能逐条机器或人工检查
4. 可回滚：失败时不影响已完成的其他节点
5. 依赖显式：前置节点全部写在 dependsOn 里
```

### 预算与早停

拆解必须有上限，否则 Lead 会"越拆越贵"：

| 限制 | 建议 | 超限动作 |
| - | - | - |
| 最大树深 | 4 层 | 拒绝继续拆解，强制收敛 |
| 最大叶子数 | 20 个 | 合并低价值任务 |
| 单任务 token 预算 | 8K-16K | 截断上下文或降级模型 |
| 全局预算 | 按任务定价 | 达到 80% 预警，100% 停止 |
| 早停条件 | 验收标准全部满足 | 立即结束，不再优化 |

> [!WARNING]
>
> 每多一个叶子节点，就多一次上下文组装、模型调用、结果校验和失败可能。拆解前先问：这个拆分带来的成功率提升，能不能覆盖多出来的成本？答不上来就不拆。

***

## Q10: 交接契约里哪些字段最容易被省略，后果分别是什么？

交接契约要让子 Agent 拿到**同一份事实**，发一段任务描述做不到这一点。字段缺失的后果可以逐条对应：

| 字段 | 省略后的后果 | 典型事故 |
| - | - | - |
| `taskId` | 无法去重、无法关联 trace | 重派导致重复下单 |
| `goal` | 子 Agent 自由发挥 | 产物与目标不符 |
| `acceptance` | 无法机器验收 | "看起来还行"就通过 |
| `inputs.files` | 子 Agent 猜文件或读全仓库 | 上下文爆炸、改错文件 |
| `inputs.facts` | 重复调研、结论矛盾 | 两个 Agent 给出冲突事实 |
| `inputs.constraints` | 违反技术栈或规范 | 引入禁用依赖 |
| `outputSchema` | 汇总时无法解析 | 合并阶段大面积返工 |
| `deadlineMs` | 卡死无人处理 | 一个节点拖垮整条链路 |
| `dependsOn` | 依赖靠自然语言约定 | 上游未完成就开跑 |

### 扩展后的契约

```ts theme={null}
interface TaskHandoff {
  taskId: string;
  goal: string;
  acceptance: string[];
  inputs: {
    files?: string[];
    facts?: Record<string, string>;
    constraints?: string[];
    artifactRefs?: string[]; // 上游产物在对象存储中的引用
  };
  outputSchema: JSONSchema;
  deadlineMs: number;
  dependsOn: string[];
  owner: string; // 唯一责任人，移交不换 owner
  idempotencyKey: string; // 写操作去重
  budget: { maxTokens: number; maxToolCalls: number };
}
```

### 上下文隔离的边界

只给"需要知道的"，不是"Lead 知道的都给它"：

* **给**：目标、已确认事实、约束、验收标准、上游产物引用。
* **不给**：完整对话历史、已被排除的方案、其他子 Agent 的私有推理。
* **原因**：成本线性放大、无关讨论造成噪声、不同步的历史导致产物互相矛盾。

> [!NOTE]
>
> 契约的质量决定分派的质量。自然语言转述三层之后必然丢信息，结构化 Schema 才能保证所有子 Agent 基于同一份事实工作。

***

## Q11: 路由、超时重派、补偿与越级上报怎么串成一条可靠链路？

### 路由不是随机，是加权

```text theme={null}
候选 Agent
   │
   ├─ 能力过滤：标签必须覆盖任务所需技能
   ├─ 负载过滤：当前队列长度 / 并发上限
   ├─ 历史成功率：同类任务最近 N 次成功率
   └─ 熔断状态：连续失败超阈值的 Agent 暂时摘除
        │
        ▼
   打分 = w1·能力匹配 + w2·(1-负载) + w3·历史成功率
```

冷启动没有历史数据时，用能力匹配 + 负载均衡兜底，并保留一定探索比例，避免某个 Agent 永远接不到任务。

### 超时重派必须幂等

超时不等于没执行。写操作超时后直接重派，会变成重复下单、重复发消息。

```ts theme={null}
async function dispatchWithRetry(task: Task, agent: Agent) {
  // 1. 重派前先查状态，不要盲目重试
  const existing = await store.getByKey(task.idempotencyKey);
  if (existing?.status === "done") return existing.result;

  // 2. 写操作带幂等键，下游按 key 去重
  const result = await agent.run(buildHandoff(task), {
    idempotencyKey: task.idempotencyKey,
    deadlineMs: task.deadlineMs,
  });

  // 3. 校验通过的产物才落库
  const check = validator.check(task, result);
  if (!check.ok) throw new Error(check.reason);
  await store.save(task.idempotencyKey, { status: "done", result });
  return result;
}
```

### 补偿事务

已经产生副作用的步骤失败时，不能"假装没发生"，要显式补偿：

| 步骤 | 正向操作 | 补偿操作 |
| - | - | - |
| 创建草稿 | 写入 draft 记录 | 删除草稿或标记作废 |
| 上传产物 | 写入对象存储 | 删除该版本对象 |
| 对外通知 | 发送消息 | 发送更正/撤回（若支持） |

补偿操作本身也必须幂等，且要记录在 trace 里，否则回滚会变成二次事故。

### 越级上报的触发条件

```text theme={null}
Worker 执行
   ├─ 正常完成 ───────────────→ 返回结果
   ├─ 可自愈错误 ─→ 重试 ─→ 仍失败 ─┐
   ├─ 需要更高权限 ──────────────────┤
   ├─ 任务前提不成立 ────────────────┤
   ├─ 多方案代价接近，无法自主决策 ──┤
   └─ 连续失败达阈值 ────────────────┤
                                     ▼
                            Lead 重新规划
                               ├─ 重派给其他 Worker
                               ├─ 拆成更小任务
                               ├─ 降级方案
                               └─ 升级人工
```

关键原则：**决策权集中，执行权下放。** Worker 可以上报异常，但不应该擅自改变任务目标；Lead 负责拆解与裁决，并对最终结果负责。

***

## 及格回答 vs 满分回答

### 问题："Lead Agent 怎么把任务拆给子 Agent，怎么保证最后能交付？"

**及格回答（60-70分）：**

> "主 Agent 把任务拆成几个子任务，分给不同的子 Agent 并行做，最后把结果合起来。需要给子 Agent 设超时，失败了就重试。"

问题出在：**知道流程，但没讲清契约、依赖和裁决**。

**满分回答（90-100分）：**

> "拆解产出的是任务树或 DAG，不是一段自然语言清单。每个节点必须有输入契约、输出 Schema、验收标准和显式依赖，子 Agent 只拿任务简报，不继承完整对话历史。"

> "分派按能力、负载和历史成功率路由；执行时并行有上限，失败分瞬时、格式、方向和卡死四类处理。汇总先做机器校验，再按拼接、去重、归并合并，冲突按依赖、置信度或评审裁决，Lead 对最终结果负责。"

> "最后靠 trace 和固定任务集做评测，看成功率、重派率和人工接管率。没有这些，多 Agent 只是把单 Agent 的问题放大 N 倍。"

### 常见追问

> [accordion] 怎么判断一个任务该拆成多 Agent?
>
> **答题要点：**
> 先找瓶颈，再拆分。
>
> **高分回答：**
> "单 Agent 遇到三类瓶颈才拆：上下文膨胀导致遗忘、工具超过十几个导致选错、角色冲突导致提示互相打架。拆分前先跑单 Agent 基线，如果瓶颈是模型能力而不是结构，拆了也没用。"

> [accordion] 子 Agent 之间需要共享记忆吗?
>
> **答题要点：**
> 共享事实，不共享全部历史。
>
> **高分回答：**
> "共享的是任务简报和已确认事实，不是完整对话。共享记忆要有版本和权限，否则一个子 Agent 的错误结论会污染所有人。推荐做法是 Lead 维护一份只读的共享事实表，子 Agent 的私有推理留在各自会话里。"

> [accordion] 为什么不能让子 Agent 自己决定下一步做什么?
>
> **答题要点：**
> 决策权集中，执行权下放。
>
> **高分回答：**
> "子 Agent 自主决策会导致任务边界模糊、重复工作和无法收敛。正确分工是 Lead 负责拆解和裁决，Worker 负责在明确契约内执行。Worker 可以上报异常，但不应该擅自改变任务目标。"

> [accordion] 冲突裁决为什么不能只靠投票?
>
> **答题要点：**
> 投票需要独立且同权，Agent 不满足。
>
> **高分回答：**
> "多个 Agent 可能共享同一份错误上下文，投票会放大共识偏差；不同 Agent 的专业度也不一样，同权投票不合理。更可靠的是按依赖关系、置信度、历史正确率裁决，高风险场景引入评审 Agent 或人工。"

> [accordion] 超时后直接重派有什么风险?
>
> **答题要点：**
> 重复副作用。
>
> **高分回答：**
> "如果子任务包含写操作，超时可能只是响应慢，实际已经执行。直接重派会重复下单、重复发消息。必须先做幂等键和状态查询，确认未完成再重派，或者把写操作拆成独立可补偿的步骤。"

> [accordion] Lead 用强模型、Worker 用弱模型，怎么保证质量?
>
> **答题要点：**
> 契约 + 校验 + 分级。
>
> **高分回答：**
> "Lead 负责拆解和验收，必须强；Worker 做边界清晰、可校验的任务，可以用便宜模型。前提是任务契约足够结构化、结果能机器校验。对于主观质量高的任务，仍然要给 Worker 配强模型或增加评审环节。"

> [accordion] 多 Agent 系统上线后成功率反而下降，怎么排查?
>
> **答题要点：**
> 从单 Agent 基线、交接、校验、并发四条线查。
>
> **高分回答：**
> "先对比单 Agent 基线，确认是不是拆分本身带来的损耗；再看交接契约是否丢信息，子 Agent 是否拿到错误上下文；然后看校验是否形同虚设，脏数据是否被继续传递；最后看并发是否触发限流或资源竞争。按 trace 逐步定位，不要先怪模型。"

> [accordion] 如何防止 Lead 无限拆解、越拆越贵?
>
> **答题要点：**
> 深度、数量、预算三重限制。
>
> **高分回答：**
> "设置最大树深、最大叶子数和总 token 预算，任一超限就强制收敛。拆解节点必须给出拆分理由和预期产物，无法说明收益的拆解直接拒绝。再用历史数据评估拆解带来的成功率提升是否覆盖成本。"

***

## 八道深度追问：及格 vs 满分

> 八题覆盖"任务树 / 粒度 / 契约 / 隔离 / 路由 / 重派 / 裁决 / 预算"。回答顺序建议：结论 → 机制 → 代价 → 怎么验证。

### 追问 1：任务树和 DAG 有什么区别，为什么 Lead 要产出 DAG？

**及格回答：** 差不多，都是把任务拆开，DAG 就是有依赖的树。

**满分回答：** 树只能表达"隶属于谁"，每个节点只有一个父节点；DAG 能表达"依赖谁"，一个节点可以有多个前置。真实任务里共享依赖很常见，比如前后端都依赖同一份接口契约。如果只用树，这条共享依赖会丢失，导致前端在契约未定时就开工。Lead 产出 DAG 是为了能做拓扑调度：按入度为 0 就绪、按依赖被阻塞、失败时能精确知道哪些节点受影响。责任归属仍可用 owner 字段表达，但调度必须靠 DAG。

### 追问 2：拆分粒度如何量化，而不是凭感觉？

**及格回答：** 拆到每个子任务能独立完成就行。

**满分回答：** 我用五条可执行标准量化：产物唯一（能写成一个文件或一份报告）、工具可控（5 到 15 次调用）、可验收（标准能逐条检查）、可回滚（失败不影响已完成节点）、依赖显式（全部写进 dependsOn）。此外设最大树深 4 层、最大叶子数 20 个，防止无限拆解。验证方式是固定任务集对比不同粒度下的成功率和总成本，如果拆细后成功率提升覆盖不了多出来的调度与汇总成本，就说明拆过头了。

### 追问 3：交接契约里最容易被省略的字段是什么，后果是什么？

**及格回答：** 目标和验收标准吧，不写清楚子 Agent 会乱做。

**满分回答：** 最容易被省略、后果最严重的是 `idempotencyKey` 和 `dependsOn`。少了幂等键，超时重派会重复产生副作用；少了依赖声明，上游没完成下游就开跑。其次是 `outputSchema`，缺了它汇总阶段无法解析，会大面积返工；还有 `owner`，没有唯一责任人，Handoff 或重派之后就没人对最终结果负责。我的做法是把这些字段设成必填，缺一个就拒绝分派，而不是靠子 Agent 猜。

### 追问 4：为什么不能把完整对话历史给子 Agent？

**及格回答：** 因为 token 太多，成本高。

**满分回答：** 成本只是第一层，更严重的是噪声和一致性。完整历史里有大量与子任务无关的讨论，会干扰子 Agent 判断，甚至让它重复 Lead 已经排除的方案；更麻烦的是，不同子 Agent 看到的历史版本可能不同，产物就会互相矛盾。正确做法是维护一份任务简报：目标、已确认事实、约束、验收标准、上游产物引用。子 Agent 只读简报加自己的子任务，私有推理留在各自会话里。

### 追问 5：路由时能力、负载、历史成功率怎么加权，冷启动怎么办？

**及格回答：** 优先给能力匹配的，忙的就少派一点。

**满分回答：** 先做硬过滤再做打分：能力标签不覆盖的直接排除，熔断中的排除，然后按能力匹配、剩余容量、同类任务最近 N 次成功率加权打分。冷启动没有历史数据时，退化为能力匹配加负载均衡，并保留小比例探索，避免某个 Agent 永远接不到任务、永远没有数据。关键是权重不能写死，要能用线上数据回归校准，并记录每次路由决策，否则出了问题无法复盘。

### 追问 6：超时重派怎么避免重复副作用？

**及格回答：** 重试前先检查一下是不是已经完成了。

**满分回答：** 核心是幂等。每个写操作带唯一 idempotencyKey，下游按 key 去重；重派前先查任务状态，状态是 done 就直接返回已有结果，不要盲目重试。对于已经产生副作用但后续失败的步骤，要显式补偿，比如删除已上传的对象或作废草稿，补偿本身也必须幂等并写入 trace。最忌讳的是"超时了就当没发生，直接重跑"，那会把一次超时变成重复下单。

### 追问 7：冲突裁决为什么不能只靠投票？

**及格回答：** 投票比较公平，少数服从多数。

**满分回答：** 投票成立的前提是投票者相互独立且同权，而多 Agent 往往不满足：它们可能共享同一份错误上下文，投票只会放大共识偏差；不同 Agent 的专业度也不同，同权不合理。更可靠的是按依赖关系、置信度、历史正确率裁决，高风险场景引入独立评审 Agent 或人工。而且 Lead 必须对最终结果负责，不能把几份互相矛盾的结果直接丢给用户。

### 追问 8：预算和早停怎么设，怎么证明没有牺牲质量？

**及格回答：** 设个 token 上限，到上限就停。

**满分回答：** 预算要分层：单任务 token 和工具调用上限、全局任务预算、并发上限。早停以"验收标准已全部满足"为触发条件，预算是兜底红线，达到任一条件就立即结束，不再过度优化。为了证明没有牺牲质量，我会用固定任务集做对照：一组开早停、一组不设上限，比较成功率、返工率和单位任务成本。如果早停组成功率下降明显，说明阈值设得太激进；如果成本下降而质量持平，才是有效的早停。

***

## 延伸阅读与引用参考

* [Multi-Agent 协作系统设计实战：三种编排模式与避坑指南](https://bbs.huaweicloud.com/blogs/512211)：流水线、主管-工作者、移交三种模式与工程要点。
* [Agent 开发中的多智能体编排有哪些主流模式？](https://cloud.tencent.cn/developer/techpedia/2738/22396)：Supervisor、Orchestrator-Workers、GroupChat、Evaluator-Optimizer 的定义与子 Agent 历史隔离。
* [Agent Swarm 的 Lead-Worker 编排](https://blog.gitcode.com/a76cdaa6e406ae632973135783bb4409.html)：Lead 只分派、Worker 隔离执行、任务池与依赖链的工程实现。
* [DeepAgents 异步任务编排与子 Agent 开发](https://blog.csdn.net/weixin_29094539/article/details/170392748)：任务模型、依赖管理、超时重试与状态持久化。
* [Anthropic: Building Effective Agents](https://www.anthropic.com/research/building-effective-agents)：Orchestrator-Workers 模式的原始出处，强调"能枚举就用工作流"。
* [LangGraph Multi-Agent 文档](https://langchain-ai.github.io/langgraphjs/concepts/multi_agent)：Supervisor 与 Handoff 的图结构实现。
* [OpenAI Agents SDK: Handoffs](https://openai.github.io/openai-agents-python/handoffs/)：移交时控制权与上下文的传递语义。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.