> ## 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.

# Multi-Agent

> 多 Agent 协作模式、通信方式、错误隔离、长任务设计，以及 Supervisor/Handoff/GroupChat 等编排面试要点。

> 多 Agent 我最怕的是把工作流节点当成 Agent：拆完没有状态归属、没有终止条件，系统一跑就互相甩锅。

***

## Q1: 什么是 Multi-Agent？和单 Agent 有什么区别？

**1. 2023年: 单 Agent 的能力边界**

早期的 AI Agent 是"一个 Agent 做所有事"——它既要理解用户意图，又要选择工具，还要处理错误。随着任务复杂度增加，单 Agent 的 prompt 越来越长，上下文窗口装不下，行为越来越不可控。

**2. 致命痛点: 上下文窗口溢出和角色混乱**

单 Agent 的上下文窗口有限（128K/200K tokens），复杂任务装不下。一个 Agent 扮演多个角色（写代码 + 审查 + 测试），prompt 太长容易混乱，输出质量下降。

**3. Multi-Agent 的引入: 专业化分工**

把复杂任务拆成子任务，每个子任务交给专门的 Agent。写代码的 Agent 只管写代码，审查的 Agent 只管审查，测试的 Agent 只管测试。每个 Agent 的 prompt 简短精准。

**4. 核心机制: 任务分解 + 通信协调 + 错误处理**

Multi-Agent 系统需要解决三个核心问题：怎么把大任务拆成子任务？Agent 之间怎么通信？一个 Agent 出错怎么办？

**5. 关键权衡: 并行加速 vs 通信开销**

Multi-Agent 可以并行执行多个任务，加速处理。但 Agent 之间的通信需要 tokens，多 Agent 系统的 token 消耗是单 Agent 的 N 倍。需要在速度和成本之间做权衡。

**Multi-Agent 解决的核心问题：**

```text theme={null}
问题：单 Agent 上下文窗口有限 + 角色混乱 + 无法并行

单 Agent：一个 Agent 处理所有任务，prompt 越来越长，行为不可控

解决：专业化分工 + 并行执行 + 错误隔离

Multi-Agent：Supervisor 分配任务 → 各 Agent 专注执行 → 结果汇总
```

> [!NOTE]
>
> Multi-Agent 把"一个全能选手"拆成"多个专业选手"，各司其职、并行协作。

> [card] 没有 Multi-Agent
>
> 你让一个 Agent 同时负责写代码、审查代码、写测试。它的 prompt 有 5000 字，上下文窗口快满了。写出来的代码有 bug，审查时又漏掉了，测试也没覆盖到边界情况。

> [card] 引入 Multi-Agent
>
> 你拆成三个 Agent：Coder Agent 专注写代码（prompt 500 字），Reviewer Agent 专注审查（prompt 300 字），Tester Agent 专注写测试（prompt 400 字）。三个 Agent 并行执行，各自的 prompt 简短精准，输出质量大幅提升。

> [!TIP]
>
> Multi-Agent 就像从全科诊所升级为专科医院。单 Agent 是全科诊所——一个医生看所有病（写代码 + 审查 + 测试），什么都懂一点但什么都不精，病人多了（上下文窗口溢出）就手忙脚乱。Multi-Agent 是专科医院——内科只看内科、外科只看外科、检验科只做化验（专业化分工），各科室可以同时接诊不同病人（并行执行），院长（Supervisor）负责分诊和协调。每个专科医生的诊疗手册（prompt）简短精准，诊断质量远高于全科医生。

***

## Q2: Multi-Agent 的常见协作模式有哪些？

Multi-Agent 的本质是**任务分解 + 通信协调**，核心模式有 5 种：

```text theme={null}
┌───────────────────────────────────────┐
│         Pipeline（流水线）              │  ← A → B → C 串行
└─────────────────┬─────────────────────┘
                  │ 适用：有先后依赖的任务
                  ▼
┌───────────────────────────────────────┐
│       Fan-out/Fan-in（扇出/扇入）       │  ← A → [B, C, D] → E 并行
└─────────────────┬─────────────────────┘
                  │ 适用：独立任务并行执行
                  ▼
┌───────────────────────────────────────┐
│         Supervisor（主管模式）          │  ← Router → [Agent A, B, C] 动态分配
└─────────────────┬─────────────────────┘
                  │ 适用：任务分配、智能路由
                  ▼
┌───────────────────────────────────────┐
│           Debate（辩论模式）            │  ← 多 Agent 对同一问题给出不同观点
└───────────────────────────────────────┘
                  │ 适用：代码审查、技术决策
```

```javascript theme={null}
// 1. Pipeline（流水线）：A → B → C 串行
const pipeline = new StateGraph()
  .addNode("parse", parseNode)
  .addNode("code", codeNode)
  .addNode("test", testNode)
  .addEdge(START, "parse")
  .addEdge("parse", "code")
  .addEdge("code", "test")
  .compile();

// 2. Fan-out/Fan-in：A → [B, C, D] → E 并行
const fanout = new StateGraph()
  .addNode("analyze", analyzeNode)
  .addNode("chunk1", chunk1Node)
  .addNode("chunk2", chunk2Node)
  .addNode("merge", mergeNode)
  .addConditionalEdges("analyze", (state) => [
    new Send("chunk1", state),
    new Send("chunk2", state),
  ])
  .compile();

// 3. Supervisor（主管模式）：Router → [Agent A, B, C]
const supervisor = new StateGraph()
  .addNode("router", routerNode)
  .addNode("coder", coderAgent)
  .addNode("reviewer", reviewerAgent)
  .addConditionalEdges("router", (state) => {
    if (state.task === "code") return "coder";
    if (state.task === "review") return "reviewer";
    return END;
  })
  .compile();

// 4. Debate（辩论模式）：多 Agent 对同一问题给出不同观点
const debate = new StateGraph()
  .addNode("agent1", agent1Node)
  .addNode("agent2", agent2Node)
  .addNode("judge", judgeNode)
  .addEdge("agent1", "judge")
  .addEdge("agent2", "judge")
  .compile();
```

> [!WARNING]
>
> Agent A 输出错误内容时，B 和 C 怎么办？有三种策略：
>
> * **容错继续（Fire and Forget）**：A 失败了，B 和 C 继续执行，最后由 Supervisor 决定怎么处理。用 `Promise.allSettled` 实现。
> * **快速失败（Fail Fast）**：A 失败了，立即终止整个流程。用 `Promise.all` 实现。
> * **条件传播（Conditional Propagation）**：A 的输出是 B 的输入，A 失败了 B 就不执行。
>
> 选择取决于业务场景：实时系统选容错优先，批处理选完整性优先。

> [!TIP]
>
> Multi-Agent 就像医院的多科会诊。Pipeline 是先看内科、再看外科、最后看康复科（有先后顺序）。Fan-out 是同时查血常规、CT、心电图（并行检查），然后汇总结果。Supervisor 是主治医师根据检查结果决定下一步（看哪个科室）。Debate 是多个专家对同一个病例给出不同诊断，最后由主任医师裁定。

### 编排模式的选择决策树

选择协作模式的决策树：

```text theme={null}
任务特征分析：
├── 有明确的先后依赖？ → Pipeline
├── 子任务可以并行？ → Fan-out/Fan-in
├── 需要动态分配？ → Supervisor
├── 需要多视角输入？ → Debate / Collaborative
├── 需要分层管理？ → Hierarchical
└── 混合场景？ → 组合使用（顶层 Supervisor + 中层 Collaborative + 底层 Pipeline）
```

### Multi-Agent 架构的五大模式详解

| 模式 | 拓扑结构 | 通信方式 | 适用场景 | 复杂度 |
| - | - | - | - | - |
| **Pipeline** | 线性链 | 上游输出 → 下游输入 | 数据处理流水线 | 低 |
| **Fan-out/Fan-in** | 扇出/扇入 | 并行执行 + Reducer 合并 | 独立子任务并行 | 中 |
| **Supervisor** | 星形 | 主管路由 + Agent 执行 | 动态任务分配 | 中 |
| **Hierarchical** | 树形 | 多层路由 | 大型复杂任务 | 高 |
| **Debate** | 全连接 | 并行输出 + 仲裁 | 技术决策、代码审查 | 中 |

***

## Q3: Multi-Agent 之间怎么通信？

### 基础梳理

| 通信方式 | 实现 | 适用场景 |
| - | - | - |
| **共享 State** | 所有 Agent 读写同一个 State 对象 | LangGraph（最常用） |
| **消息传递** | Agent 之间直接发消息 | 独立进程的 Agent |
| **黑板模式** | 共享的"黑板"，所有 Agent 都可以读写 | 传统 AI 系统 |
| **事件总线** | Agent 发布事件，其他 Agent 订阅 | 松耦合系统 |

### 专家视角深度剖析

```javascript theme={null}
// 方式 1：共享 State（LangGraph 的方式，最常用）
const GraphState = Annotation.Root({
  input: Annotation,
  results: Annotation({
    reducer: (a, b) => a.concat(b),
    default: () => [],
  }),
});

// Agent A 写入 state
function agentA(state) {
  return { results: [resultA] };
}

// Agent B 读取 state 中 Agent A 的结果
function agentB(state) {
  const resultA = state.results[0];
  return { results: [processB(resultA)] };
}

// 方式 2：消息传递（独立进程的 Agent）
class Agent {
  constructor(name) {
    this.name = name;
    this.inbox = [];
  }
  send(target, message) {
    target.inbox.push({ from: this.name, content: message });
  }
  receive() {
    return this.inbox.shift();
  }
}

// 方式 3：事件总线（松耦合系统）
const eventBus = {
  listeners: {},
  on(event, callback) {
    if (!this.listeners[event]) this.listeners[event] = [];
    this.listeners[event].push(callback);
  },
  emit(event, data) {
    (this.listeners[event] || []).forEach((cb) => cb(data));
  },
};
```

> [!TIP]
>
> Agent 之间的通信就像办公室里的不同沟通方式。共享 State 是"白板"——所有人围着同一块白板工作，谁都能看、谁都能写（LangGraph 的方式，最常用但需要约定规则避免冲突）。消息传递是"发邮件"——你写好内容发给对方，对方有空再看（独立进程的 Agent）。事件总线是"广播喇叭"——你广播一条消息"会议室有咖啡"，感兴趣的人自己来拿（松耦合系统）。选择哪种取决于团队规模和协作紧密度——小团队用白板（共享 State），大团队用邮件（消息传递），跨部门用广播（事件总线）。

### 通信协议的选择标准

| 通信方式 | 延迟 | 解耦程度 | 实现复杂度 | 适用场景 |
| - | - | - | - | - |
| **共享 State** | 最低 | 低（紧耦合） | 低 | 同一进程内的 LangGraph |
| **消息传递** | 中 | 中 | 中 | 独立进程的 Agent |
| **事件总线** | 中 | 高（松耦合） | 高 | 分布式系统 |
| **REST API** | 高 | 高 | 中 | 跨机器的 Agent |
| **gRPC** | 低 | 高 | 高 | 高性能分布式系统 |

### Agent 间通信的 Token 开销

Agent 之间传递信息需要消耗 tokens。如果 Agent A 的输出有 1000 tokens，传给 Agent B 作为输入，这 1000 tokens 就是额外的成本。Multi-Agent 系统的 token 消耗通常是单 Agent 的 N 倍。

```javascript theme={null}
// Token 开销分析
// 单 Agent：1 次 LLM 调用 = 1000 tokens 输入 + 500 tokens 输出 = 1500 tokens
// Multi-Agent（3 个 Agent 串行）：
//   Agent A：1000 + 500 = 1500 tokens
//   Agent B：1000 + 500(A 的输出) + 500 = 2000 tokens
//   Agent C：1000 + 500(B 的输出) + 500 = 2000 tokens
//   总计：5500 tokens（是单 Agent 的 3.7 倍）

// 优化：用摘要替代全文传递
async function summarizeAndPass(output) {
  const summary = await smallLLM.invoke(`用 50 字总结：${output}`);
  return summary; // 从 500 tokens 压缩到 50 tokens
}
```

***

## Q4: Multi-Agent 的核心挑战是什么？

```javascript theme={null}
// 1. 通信开销
// Agent 之间传递信息需要 tokens，多 Agent 系统的 token 消耗是单 Agent 的 N 倍
// 解决：用摘要替代全文传递、只传递必要信息

// 2. 错误传播
// A 的错误输出传给 B，B 基于错误信息做出错误决策
// 解决：每个 Agent 加输出验证 + Reviewer Agent

// 3. 死循环
// Agent A 认为应该让 B 处理，B 认为应该让 A 处理
// 解决：设置最大循环次数、Supervisor 决策

// 4. 一致性
// 多个 Agent 并行修改同一份数据，产生冲突
// 解决：用不可变 State + Reducer 合并

// 5. 成本控制
// 10 个 Agent 各调一次 LLM，成本是单 Agent 的 10 倍
// 解决：用弱模型做简单任务、缓存结果、按需调用
```

> [!TIP]
>
> Multi-Agent 的核心挑战就像管理一个大团队。通信开销是"开会成本"——10 个人的团队，每次开会所有人的时间都算成本（token 消耗是单 Agent 的 N 倍）。错误传播是"传递错误信息"——A 给了 B 错误数据，B 基于错误数据做了错误决策，C 又基于 B 的错误继续错下去。死循环是"互相推诿"——A 说"这事该 B 做"，B 说"这事该 A 做"，无限循环。一致性是"多人同时改同一份文档"——需要锁定机制（Reducer 合并）避免冲突。

**成本控制的关键策略：**

```javascript theme={null}
// 限制每个 Agent 的 token 预算
const agent = createReactAgent({
  llm: openai,
  tools: [searchTool],
  maxTokens: 4000, // 限制单次调用的 token 数
});

// 用弱模型处理简单任务
const simpleAgent = createReactAgent({
  llm: new ChatOpenAI({ model: "gpt-4o-mini" }), // 便宜的模型
  tools: [basicTool],
});

// 缓存重复查询（Prompt Cache）
// Anthropic 的 Prompt Cache 可以节省 90% 的输入 token 费用
// 优化方法：把稳定的 System Prompt 放在前面，变化的用户输入放在后面
```

> [!TIP]
>
> Multi-Agent 的成本控制有三个关键：1) 用弱模型处理简单任务（gpt-4o-mini 做格式化，gpt-4o 做决策）；2) 限制每个 Agent 的 token 预算（maxTokens）；3) 缓存重复查询（Prompt Cache）。在实际项目中，80% 的任务可以用弱模型完成，只有 20% 的决策需要强模型。

***

## Q5: Hierarchical 和 Collaborative 模式是什么？

**1. Supervisor 的局限性**

Supervisor 模式中，所有决策都由一个主管 Agent 做。当任务复杂度增加，主管 Agent 的 prompt 越来越长，决策质量下降。而且主管是单点故障——它出错了，整个系统就瘫了。

**2. Hierarchical: 分层管理**

Hierarchical（层级模式）把 Supervisor 也拆成多层。顶层 Supervisor 只做宏观决策（分配到哪个团队），中层 Supervisor 做具体分配（分配给哪个 Agent），底层 Agent 执行具体任务。每层的 prompt 简短精准。

**3. Collaborative: 对等协作**

Collaborative（协作模式）没有主管，所有 Agent 地位平等，通过共享 State 或消息传递协作。适合需要多视角输入的场景（如代码审查、技术决策）。

**4. 模式选择的关键权衡**

层级模式适合大型复杂任务（有明确的组织结构），协作模式适合需要多视角的场景（没有明确的上下级关系）。实际项目中，两种模式经常混合使用。

**Hierarchical vs Collaborative 解决的核心问题：**

```text theme={null}
问题：单层 Supervisor 无法处理大规模复杂任务

单层 Supervisor：一个主管管所有 Agent，prompt 越来越长，决策质量下降

解决：Hierarchical 分层管理，Collaborative 对等协作

Hierarchical：顶层 Supervisor → 中层 Supervisor → 底层 Agent
Collaborative：Agent A ↔ Agent B ↔ Agent C（无主管，对等协作）
```

```javascript theme={null}
// Hierarchical（层级模式）：多层 Supervisor
const hierarchicalGraph = new StateGraph()
  // 顶层 Supervisor：宏观决策
  .addNode("topSupervisor", topSupervisorNode)
  // 中层 Supervisor：具体分配
  .addNode("devSupervisor", devSupervisorNode)
  .addNode("qaSupervisor", qaSupervisorNode)
  // 底层 Agent：执行任务
  .addNode("coder", coderAgent)
  .addNode("reviewer", reviewerAgent)
  .addNode("tester", testerAgent)
  // 顶层分配到中层
  .addConditionalEdges("topSupervisor", (state) => {
    if (state.domain === "dev") return "devSupervisor";
    if (state.domain === "qa") return "qaSupervisor";
  })
  // 中层分配到底层
  .addConditionalEdges("devSupervisor", (state) => {
    if (state.task === "code") return "coder";
    if (state.task === "review") return "reviewer";
  })
  .compile();

// Collaborative（协作模式）：无主管，对等协作
const collaborativeGraph = new StateGraph()
  .addNode("agent1", agent1Node)
  .addNode("agent2", agent2Node)
  .addNode("agent3", agent3Node)
  .addNode("consensus", consensusNode)
  // 所有 Agent 并行执行
  .addConditionalEdges(START, () => [
    new Send("agent1", state),
    new Send("agent2", state),
    new Send("agent3", state),
  ])
  // 汇总所有 Agent 的输出，达成共识
  .addEdge("agent1", "consensus")
  .addEdge("agent2", "consensus")
  .addEdge("agent3", "consensus")
  .compile();
```

> [!WARNING]
>
> 选择协作模式的决策树：
>
> * 任务有明确的组织结构 → **Hierarchical**（层级模式）
> * 需要多视角输入、没有上下级关系 → **Collaborative**（协作模式）
> * 任务需要动态分配、主管可以根据结果调整策略 → **Supervisor**（主管模式）
> * 任务有明确的先后顺序 → **Pipeline**（流水线）
> * 任务可以并行执行 → **Fan-out/Fan-in**（扇出/扇入）
>
> 实际项目中，经常混合使用：顶层用 Supervisor 做路由，中层用 Collaborative 做多视角分析，底层用 Pipeline 做串行处理。

> [!TIP]
>
> Hierarchical 就像大公司的组织架构——CEO（顶层 Supervisor）决定大方向，VP（中层 Supervisor）分配具体任务，员工（底层 Agent）执行。Collaborative 就像创业小团队——没有严格的上下级，大家平等地讨论和协作，最后达成共识。大公司适合层级模式（任务复杂、需要分工），小团队适合协作模式（需要快速决策、多视角输入）。

### 模式混合使用的实际案例

实际项目中，单一模式很少能满足需求，通常需要混合使用：

```text theme={null}
案例：企业级代码审查系统

顶层：Supervisor 模式
├── 根据 PR 的类型分配到不同团队（前端/后端/基础设施）

中层：Collaborative 模式
├── 前端团队内部：安全专家、性能专家、可读性专家并行审查
├── 后端团队内部：安全专家、性能专家、可读性专家并行审查

底层：Pipeline 模式
├── 每个专家的审查流程：读代码 → 分析问题 → 生成建议 → 格式化输出

汇总：Debate 模式
├── 多个专家的意见可能冲突，由仲裁 Agent 综合判断
```

***

## Q6: Multi-Agent 的错误处理和容错机制有哪些？

**1. 单 Agent 失败的影响**

在 Multi-Agent 系统中，一个 Agent 失败可能影响整个工作流。如果 Agent A 的输出是 Agent B 的输入，A 失败了 B 就无法执行。

**2. 三种容错策略**

容错继续（Fire and Forget）：A 失败了，B 和 C 继续执行，最后由 Supervisor 决定怎么处理。快速失败（Fail Fast）：A 失败了，立即终止整个流程。条件传播（Conditional Propagation）：A 的输出是 B 的输入，A 失败了 B 就不执行。

**3. 重试和降级机制**

Agent 失败后，可以自动重试（配置重试次数和退避策略）。重试仍然失败，可以降级到更简单的处理方式（如用弱模型替代强模型，或返回默认结果）。

**4. Human-in-the-Loop**

对于高风险操作（如删除数据、发送邮件），在 Agent 执行前加 interrupt 节点，等待人类审批。人类可以修改 Agent 的输入、批准执行、或拒绝执行。

> [!TIP]
>
> Multi-Agent 的错误处理就像考试时的应急方案。容错继续是"一道题不会不影响做其他题"——A 题卡住了（Agent A 失败），先跳过做 B 和 C，最后再回来处理 A。快速失败是"发现作弊立即收卷"——任何一个环节出大错（致命错误），立即终止整个流程。重试降级是"写错了用修正带"——先尝试修正（重试 3 次），修正不了就换个方案（降级到弱模型）。Human-in-the-Loop 是"关键题请老师确认"——高风险操作（删除数据、发邮件）前暂停，等人类审批后才执行。

**错误处理和容错机制：**

```text theme={null}
问题：一个 Agent 失败可能影响整个工作流

没有容错：A 失败 → B 等待 → 整个流程卡住

解决：三种容错策略 + 重试降级 + Human-in-the-Loop

容错继续：A 失败 → B 和 C 继续 → Supervisor 汇总处理
快速失败：A 失败 → 立即终止 → 返回错误
条件传播：A 失败 → B 不执行 → 返回 A 的错误
```

```javascript theme={null}
// 策略 1：容错继续（Promise.allSettled）
async function faultTolerant(state) {
  const results = await Promise.allSettled([
    agentA(state),
    agentB(state),
    agentC(state),
  ]);
  // 区分成功和失败的结果
  const succeeded = results
    .filter((r) => r.status === "fulfilled")
    .map((r) => r.value);
  const failed = results
    .filter((r) => r.status === "rejected")
    .map((r) => r.reason.message);
  return { results: succeeded, errors: failed };
}

// 策略 2：快速失败（Promise.all）
async function failFast(state) {
  // 任何一个失败，立即抛出异常
  const results = await Promise.all([
    agentA(state),
    agentB(state),
    agentC(state),
  ]);
  return { results };
}

// 策略 3：重试 + 降级
import { RetryPolicy } from "@langchain/langgraph";

const retryPolicy = new RetryPolicy({
  maxAttempts: 3, // 最多重试 3 次
  backoffFactor: 2, // 退避倍数：1s → 2s → 4s
  retryOn: (error) => {
    // 只重试临时性错误（网络超时、API 限流）
    // 不重试永久性错误（参数错误、权限不足）
    return error.code === "TIMEOUT" || error.code === "RATE_LIMIT";
  },
});

// 策略 4：Human-in-the-Loop
async function humanApproval(state) {
  const decision = await interrupt({
    question: "Agent A 建议删除以下文件，是否批准？",
    files: state.filesToDelete,
  });
  if (decision === "approve") {
    return { approved: true };
  }
  return { approved: false, reason: "人类拒绝" };
}
```

> [!TIP]
>
> 错误处理的选择取决于业务场景：实时系统选容错优先（一个 Agent 失败不影响其他），批处理选完整性优先（一个失败全部重试）。对于高风险操作，必须加 Human-in-the-Loop——让人类做最终决策。重试时区分临时性错误（网络超时，可重试）和永久性错误（参数错误，不可重试）。

### 重试机制的退避策略

重试不是简单地"再来一次"，需要合理的退避策略防止雪崩：

```javascript theme={null}
// 指数退避（Exponential Backoff）
// 第 1 次重试：等 1 秒
// 第 2 次重试：等 2 秒
// 第 3 次重试：等 4 秒
// 加随机抖动（Jitter）防止多个 Agent 同时重试

function getRetryDelay(attempt) {
  const base = Math.pow(2, attempt) * 1000; // 指数退避
  const jitter = Math.random() * 1000; // 随机抖动
  return base + jitter;
}

// 重试的错误分类
const retryableErrors = [
  "TIMEOUT", // 网络超时
  "RATE_LIMIT", // API 限流
  "SERVER_ERROR", // 服务端 500 错误
];

const nonRetryableErrors = [
  "INVALID_PARAMS", // 参数错误（重试也不会成功）
  "AUTH_FAILED", // 认证失败
  "NOT_FOUND", // 资源不存在
];
```

### 幂等性设计

在 Multi-Agent 系统中，重试可能导致同一个操作被执行多次。幂等性设计确保"执行一次和执行多次的结果相同"。

```javascript theme={null}
// 幂等性设计：用唯一 ID 去重
const processedIds = new Set();

async function idempotentAgentCall(agentId, input) {
  const callId = `${agentId}-${hash(input)}`;

  // 检查是否已经处理过
  if (processedIds.has(callId)) {
    return getCachedResult(callId); // 返回缓存结果
  }

  const result = await agent.invoke(input);
  processedIds.add(callId);
  cacheResult(callId, result);
  return result;
}
```

***

## Q7: 长时间运行智能体（Long-running Agent）怎么设计？

**1. 长时间运行的困境**

当 Agent 需要连续工作 5 小时以上（如 AutoGPT、Devin 级别的自主智能体），会遇到四个核心问题：上下文窗口溢出（128K/200K tokens 装不下）、进程中断（网络断开、OOM、超时）、状态丢失（中断后无法恢复）、成本爆炸（长时间调用 LLM 费用飙升）。

**2. 异步执行（Asynchronous Execution）**

长时间任务不能阻塞用户界面。把 Agent 执行放到后台异步任务中，用户可以随时查看进度、暂停、恢复。LangGraph 用 `interrupt()` 实现暂停，用 `Command(resume=...)` 实现恢复。

**3. 状态快照与恢复（Checkpointing & Recovery）**

Agent 每执行完一个节点，自动保存状态快照到持久化存储（PostgreSQL）。中断后从最近的 checkpoint 恢复，而不是从头开始。这是长时间运行 Agent 的生命线。

**4. 长期记忆（Long-term Memory）**

用 4 层记忆模型（working → episodic → semantic → procedural）管理 Agent 的记忆。定期用小模型（Haiku）压缩历史对话，只保留关键决策和事实。100K tokens 的历史压缩为 5K tokens 的摘要，节省 95% 的 token。

**5. 进度追踪与断点续传**

把长任务拆成多个子任务（quest），每个子任务有明确的状态（pending → running → completed）。子任务完成后自动 cascade-unblock 依赖它的其他任务。用户可以看到整体进度百分比和当前执行的子任务。

**长时间运行 Agent 解决的核心问题：**

```text theme={null}
问题：Agent 连续工作 5 小时+，上下文溢出 + 进程中断 + 状态丢失 + 成本爆炸

没有设计：Agent 运行 3 小时后上下文溢出，忘记之前的决策
           进程 OOM 崩溃，所有进度丢失
           token 费用失控

解决：异步执行 + Checkpoint 恢复 + 长期记忆 + 进度追踪

异步执行：Agent 在后台运行，用户可查看/暂停/恢复
Checkpoint：每个节点执行后自动保存快照，中断后从最近快照恢复
长期记忆：4 层记忆模型定期压缩，100K→5K tokens
进度追踪：子任务拆分 + 状态机 + 依赖解锁
```

> [!NOTE]
>
> 长时间运行 Agent 的核心是"异步 + 快照 + 压缩"——后台异步执行，每个节点保存 checkpoint，定期压缩长期记忆。

> [card] 没有长时间运行设计
>
> 你让 Agent 连续工作 8 小时重写一个项目。3 小时后上下文溢出，Agent 忘记了之前的技术选型，开始重复劳动。6 小时后进程 OOM 崩溃，所有进度丢失，从头再来。token 费用已经花了 \$50。

> [card] 引入长时间运行设计
>
> 你把任务拆成 15 个子任务，异步执行。每完成一个节点自动保存 checkpoint。第 5 个子任务中断了，从 checkpoint 恢复继续。上下文用 Haiku 定期压缩，只保留关键决策。用户随时可以查看进度和暂停。

### 异步执行的实现模式

```javascript theme={null}
// 异步执行 + 进度追踪
import { Client } from "@langchain/langgraph-sdk";

const client = new Client({ apiUrl: "http://localhost:2024" });

// 1. 创建异步 run（不阻塞）
const run = await client.runs.create(threadId, "agent-graph", {
  input: { task: "重写用户认证模块" },
});

// 2. 轮询进度
const status = await client.runs.get(run.id);
console.log(`状态: ${status.status}`); // pending / running / completed / failed
console.log(`进度: ${status.metadata.progress}%`);

// 3. 中途暂停（Human-in-the-Loop）
await client.runs.interrupt(run.id);

// 4. 恢复执行
await client.runs.resume(run.id, { input: { approved: true } });
```

### 进度追踪与断点续传

```javascript theme={null}
// 子任务拆分 + 依赖管理 + 断点续传
const taskPlan = {
  quests: [
    { id: "Q1", name: "分析现有代码", status: "completed", dependsOn: [] },
    { id: "Q2", name: "设计新架构", status: "completed", dependsOn: ["Q1"] },
    { id: "Q3", name: "编写核心模块", status: "running", dependsOn: ["Q2"] },
    { id: "Q4", name: "编写测试", status: "pending", dependsOn: ["Q3"] },
    { id: "Q5", name: "集成测试", status: "pending", dependsOn: ["Q3", "Q4"] },
  ],
};

// Q3 完成后自动 cascade-unblock Q4
function onComplete(questId) {
  const quest = quests.find((q) => q.id === questId);
  quest.status = "completed";
  // 解锁依赖此任务的后续任务
  quests
    .filter((q) => q.dependsOn.includes(questId))
    .forEach((q) => {
      const allDepsCompleted = q.dependsOn.every(
        (depId) => quests.find((d) => d.id === depId).status === "completed",
      );
      if (allDepsCompleted) q.status = "unlocked";
    });
}
```

> [!TIP]
>
> 长时间运行 Agent 就像一个大型建筑工地的施工队。异步执行是施工队在后台干活，业主（用户）可以随时来看进度。进度追踪是把工程拆成"打地基→搭框架→砌墙→装修"等子任务，每个子任务有依赖关系（砌墙前必须搭好框架）。Checkpoint 是每完成一步就拍照存档，如果停电了（进程中断），来电后从上次存档的地方继续，不用推倒重来。长期记忆是施工日志——记录了所有关键决策（"承重墙用 C30 混凝土"），新工人（新 session）看了日志就能无缝接续。

***

## Q8: 企业级 Agent（Enterprise-grade Agent）怎么设计？

**1. 玩具级 vs 企业级的差距**

玩具级 Agent（demo 阶段）只关注"能不能跑通"。企业级 Agent 需要解决五个核心问题：权限控制（Agent 不能越权操作）、审计追踪（出了问题能溯源）、容错降级（部分失败不影响整体）、确定性边界（LLM 的输出必须可控）、成本控制（token 费用不能失控）。

**2. 权限收敛（最小权限原则）**

Agent 只拥有完成当前任务所需的最小权限。代码审查 Agent 只有读权限，没有写权限。部署 Agent 只能在 staging 环境操作，不能直接操作 production。通过 MCP Server 的 tool 级别权限控制实现。

**3. 审计日志（Audit Logging）**

Agent 的每一步操作（工具调用、LLM 输出、决策过程）都记录到审计日志。日志包含：时间戳、Agent ID、输入、输出、token 消耗、执行时间。出问题时可以完整溯源。LangSmith 自动做这件事。

**4. 容错降级（Fallback）与确定性边界**

Agent 的 LLM 输出是不确定的，但企业级系统需要确定性。方案：在关键节点加输出验证（JSON Schema 校验），验证失败时降级到规则引擎（确定性逻辑）。LLM 负责理解意图，规则引擎负责执行——把不确定性限制在理解层，执行层保持确定性。

**企业级 Agent 解决的核心问题：**

```text theme={null}
问题：玩具级 Agent 无法上生产环境

玩具级：Agent 有全部权限，没有审计日志，出错直接崩溃
        LLM 输出不可控，token 费用无上限

解决：权限收敛 + 审计日志 + 容错降级 + 确定性边界 + 成本控制

权限收敛：Agent 只有最小权限（MCP tool 级别控制）
审计日志：每步操作记录到 LangSmith，可完整溯源
容错降级：LLM 输出验证失败 → 降级到规则引擎
确定性边界：LLM 管理解意图，规则引擎管执行
成本控制：token 预算 + 模型分级 + Prompt Cache
```

> [!NOTE]
>
> 企业级 Agent 的核心是"可控"——权限可控、行为可审计、输出可验证、成本可预测。

```javascript theme={null}
// 企业级 Agent 的五层防护设计

// 1. 权限收敛：MCP tool 级别控制
const readOnlyAgent = createReactAgent({
  llm: openai,
  tools: [readFileTool, searchCodeTool], // 只有读权限，没有 writeFileTool
});

// 2. 审计日志：记录每步操作
const auditLogger = {
  log(agentId, action, input, output, tokenUsage) {
    const entry = {
      timestamp: new Date().toISOString(),
      agentId,
      action,
      input: truncate(input, 500),
      output: truncate(output, 500),
      tokens: tokenUsage,
    };
    // 写入 LangSmith 或自建审计系统
    langsmithClient.createRun(entry);
  },
};

// 3. 输出验证 + 降级
const validatedAgent = {
  async execute(task) {
    const result = await agent.invoke(task);
    const validation = schemaValidator.safeParse(result);
    if (!validation.success) {
      // 降级到规则引擎
      return ruleEngine.fallback(task);
    }
    return result;
  },
};

// 4. 确定性边界：LLM 理解 + 规则执行
async function boundedAgent(userInput) {
  // LLM 只负责理解意图（不确定性在这里）
  const intent = await llm.invoke(`提取用户意图：${userInput}`);
  // 规则引擎负责执行（确定性逻辑）
  return deterministicEngine.execute(intent);
}

// 5. 成本控制：token 预算管理
const budgetConfig = {
  perAgent: { maxTokens: 4000 },
  perWorkflow: { maxTokens: 50000 },
  totalDaily: { maxTokens: 1000000 },
  onExceed: "degrade", // 超预算时降级到弱模型
};
```

### 确定性边界的分层架构

```text theme={null}
企业级 Agent 的分层架构：

┌───────────────────────────────────────┐
│    理解层（LLM，不确定性）              │  ← 自然语言理解、意图提取、上下文推理
├───────────────────────────────────────┤
│    验证层（Schema，半确定性）            │  ← JSON Schema 校验、输出格式约束
├───────────────────────────────────────┤
│    执行层（规则引擎，确定性）            │  ← 工具调用、数据操作、业务逻辑
├───────────────────────────────────────┤
│    监控层（审计 + 告警）                │  ← 操作日志、成本追踪、异常告警
└───────────────────────────────────────┘

关键原则：不确定性只存在于理解层，执行层必须确定性
```

> [!TIP]
>
> 企业级 Agent 就像银行柜员。权限收敛是柜员只能操作自己权限内的业务（普通柜员不能做大额转账审批）。审计日志是每笔交易都有记录（时间、金额、操作人、审批人），出了问题可以完整追溯。确定性边界是柜员理解客户需求（LLM 理解意图），但具体操作必须按银行的规章制度来（规则引擎执行），不能随意发挥。容错降级是系统出问题时，柜员可以切换到手工记账模式（降级到规则引擎），不会因为系统故障停止服务。

***

## Q9: LangGraph 的编排模式有哪些？

LangGraph 提供了四种核心编排模式，适用于不同的 Multi-Agent 场景：

```text theme={null}
┌───────────────────────────────────────┐
│    Supervisor 模式                     │  ← 一个主管路由 + N 个 Agent 执行
└─────────────────┬─────────────────────┘
                  │ 适用：动态任务分配、智能路由
                  ▼
┌───────────────────────────────────────┐
│    Hierarchical 模式                   │  ← 多层 Supervisor 逐级分配
└─────────────────┬─────────────────────┘
                  │ 适用：大型复杂任务、有组织结构
                  ▼
┌───────────────────────────────────────┐
│    Network 模式                        │  ← Agent 之间直接通信，无主管
└─────────────────┬─────────────────────┘
                  │ 适用：需要多轮协商的场景
                  ▼
┌───────────────────────────────────────┐
│    自定义拓扑                           │  ← 任意图结构，按需组合
└───────────────────────────────────────┘
                  │ 适用：复杂业务流程
```

### Supervisor 模式详解

Supervisor 模式是最常用的编排模式。一个 Supervisor Agent 根据当前状态决定下一步调用哪个 Worker Agent。Worker 完成后返回 Supervisor，Supervisor 决定是继续调用其他 Worker 还是结束。

```javascript theme={null}
// Supervisor 模式：动态路由 + Agent 执行
import { StateGraph, END } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({ model: "gpt-4o" });

// Supervisor 节点：用 LLM 决定下一步
async function supervisorNode(state) {
  const response = await llm.invoke([
    SystemMessage(
      (content = `你是主管，决定下一步调用哪个 Agent。
可用 Agent：coder（写代码）、reviewer（审查代码）、tester（写测试）。
输出 JSON：{"next": "coder"} 或 {"next": "reviewer"} 或 {"next": "FINISH"}`),
    ),
    ...state.messages,
  ]);
  const decision = JSON.parse(response.content);
  return { next: decision.next };
}

// Worker 节点：执行具体任务
async function coderNode(state) {
  const result = await coderAgent.invoke(state);
  return { messages: [result] };
}

// 组装图
const graph = new StateGraph(State)
  .addNode("supervisor", supervisorNode)
  .addNode("coder", coderNode)
  .addNode("reviewer", reviewerNode)
  .addNode("tester", testerNode)
  .addConditionalEdges("supervisor", (state) => state.next, {
    coder: "coder",
    reviewer: "reviewer",
    tester: "tester",
    FINISH: END,
  })
  .addEdge("coder", "supervisor")
  .addEdge("reviewer", "supervisor")
  .addEdge("tester", "supervisor")
  .compile();
```

### Hierarchical 模式详解

Hierarchical 模式把 Supervisor 拆成多层。顶层 Supervisor 做宏观决策（分配到哪个领域），中层 Supervisor 做具体分配（分配给哪个 Agent），底层 Agent 执行具体任务。每层的 prompt 简短精准，避免单层 Supervisor 的 prompt 过长问题。

```javascript theme={null}
// Hierarchical 模式：多层 Supervisor
const hierarchicalGraph = new StateGraph(State)
  // 顶层：宏观决策
  .addNode("topSupervisor", topSupervisorNode)
  // 中层：领域分配
  .addNode("devSupervisor", devSupervisorNode)
  .addNode("qaSupervisor", qaSupervisorNode)
  // 底层：执行
  .addNode("coder", coderAgent)
  .addNode("reviewer", reviewerAgent)
  .addNode("tester", testerAgent)
  // 顶层 → 中层
  .addConditionalEdges("topSupervisor", (state) => state.domain, {
    dev: "devSupervisor",
    qa: "qaSupervisor",
  })
  // 中层 → 底层
  .addConditionalEdges("devSupervisor", (state) => state.task, {
    code: "coder",
    review: "reviewer",
  })
  // 底层 → 回到中层
  .addEdge("coder", "devSupervisor")
  .addEdge("reviewer", "devSupervisor")
  .compile();
```

### Network 模式详解

Network 模式没有固定的主管，所有 Agent 地位平等，可以直接互相调用。适合需要多轮协商的场景（如技术方案评审、辩论式决策）。缺点是控制流不明确，容易出现死循环。

```javascript theme={null}
// Network 模式：Agent 之间直接通信
const networkGraph = new StateGraph(State)
  .addNode("architect", architectAgent)
  .addNode("securityExpert", securityAgent)
  .addNode("perfExpert", perfAgent)
  // 每个 Agent 可以决定调用其他 Agent 或结束
  .addConditionalEdges("architect", (state) => state.next, {
    securityExpert: "securityExpert",
    perfExpert: "perfExpert",
    FINISH: END,
  })
  .addConditionalEdges("securityExpert", (state) => state.next, {
    architect: "architect",
    perfExpert: "perfExpert",
    FINISH: END,
  })
  .addConditionalEdges("perfExpert", (state) => state.next, {
    architect: "architect",
    securityExpert: "securityExpert",
    FINISH: END,
  })
  .compile();
```

### 自定义拓扑

对于复杂业务流程，可以组合多种模式，构建自定义拓扑。例如：顶层用 Supervisor 做路由，中层用 Collaborative 做多视角分析，底层用 Pipeline 做串行处理。

```javascript theme={null}
// 自定义拓扑：Supervisor + Collaborative + Pipeline
const customGraph = new StateGraph(State)
  // 顶层 Supervisor 路由
  .addNode("router", routerNode)
  // 并行分析（Collaborative）
  .addNode("securityCheck", securityAgent)
  .addNode("perfCheck", perfAgent)
  .addNode("readabilityCheck", readabilityAgent)
  // 汇总 + Pipeline 后处理
  .addNode("consensus", consensusNode)
  .addNode("formatter", formatterNode)
  // Supervisor → 并行分析
  .addConditionalEdges("router", () => [
    new Send("securityCheck", state),
    new Send("perfCheck", state),
    new Send("readabilityCheck", state),
  ])
  // 并行分析 → 汇总
  .addEdge("securityCheck", "consensus")
  .addEdge("perfCheck", "consensus")
  .addEdge("readabilityCheck", "consensus")
  // 汇总 → Pipeline
  .addEdge("consensus", "formatter")
  .compile();
```

> [!TIP]
>
> LangGraph 的编排模式就像不同的交通调度方式。Supervisor 模式是"出租车调度中心"——乘客打电话（用户请求），调度员（Supervisor）根据目的地分配给合适的司机（Worker Agent），司机完成后回来等下一单。Hierarchical 模式是"公交公司层级管理"——总经理管分公司（顶层 Supervisor），分公司管车队（中层），车队管具体线路（底层 Agent）。Network 模式是"拼车群"——没有调度员，乘客和司机在群里直接沟通，灵活但容易乱。自定义拓扑是"综合交通枢纽"——地铁、公交、出租车、共享单车组合使用，按需选择最合适的交通方式。

### 编排模式的选择标准

| 模式 | 控制流 | 适用场景 | 复杂度 | 死循环风险 |
| - | - | - | - | - |
| **Supervisor** | 中心化路由 | 动态任务分配 | 中 | 低 |
| **Hierarchical** | 多层路由 | 大型复杂任务 | 高 | 低 |
| **Network** | 去中心化 | 多轮协商 | 高 | 高 |
| **自定义拓扑** | 按需组合 | 复杂业务流程 | 最高 | 取决于设计 |

> [!TIP]
>
> 选择编排模式的决策树：简单任务用 Supervisor（一个路由 + N 个 Worker），大型任务用 Hierarchical（多层路由），需要多视角协商用 Network（但要加最大轮次限制防止死循环），复杂业务用自定义拓扑（组合多种模式）。实际项目中，90% 的场景用 Supervisor 就够了。

***

## Q10: Supervisor、Orchestrator-Workers、Handoff、GroupChat、Evaluator-Optimizer 到底差在哪？

> 背定义没有意义。这五种模式的真正差别只有三个问题：**谁决定下一步、状态放在哪、失败怎么传播。** 答不出这三点，就等于只会背名词。

### 一张表看穿五种模式

| 模式 | 谁决定下一步 | 状态归属 | 代表实现 | 主要失败模式 |
| - | - | - | - | - |
| Supervisor | 中心 Router（通常是 LLM） | 共享图状态 | LangGraph supervisor | 路由震荡、Router prompt 膨胀、单点瓶颈 |
| Orchestrator-Workers | Orchestrator 运行时拆解 | Orchestrator + 结果表 | Anthropic orchestrator-workers | 过度拆解、成本乘法、汇总冲突 |
| Handoff | 当前 Agent 主动移交 | 随会话一起移交 | OpenAI Agents SDK handoffs | 击鼓传花、责任丢失、无全局预算 |
| GroupChat | 发言选择器（轮询或 LLM） | 共享消息记录 | AutoGen GroupChat | 无限闲聊、上下文爆炸、共识偏差 |
| Evaluator-Optimizer | 固定循环：生成 → 评估 | 草稿 + 反馈 | Anthropic evaluator-optimizer | 不收敛、评估器放水、来回震荡 |

### 状态归属决定"能不能恢复"

这是最容易被忽略、但工程上最关键的一点：

* **共享图状态**（Supervisor）：状态集中，checkpoint 好做，但所有 Worker 争用同一份状态，必须用 reducer 定义合并规则。
* **会话移交**（Handoff）：状态跟着对话走，实现简单，但没有全局视图，超时和预算难以统一收口。
* **消息记录**（GroupChat）：状态就是聊天记录，可回放，但 token 随轮次增长很快。
* **草稿 + 反馈**（Evaluator-Optimizer）：状态最小，适合可自动判分的任务，不适合开放式任务。

> [!WARNING]
>
> 更想听的是失败模式：Supervisor 会**路由震荡**（A 说交给 B，B 又交回 A）；Handoff 会**击鼓传花**（没人对最终结果负责）；GroupChat 会**无限闲聊**；Evaluator-Optimizer 会因为**评估标准模糊而不收敛**。能说出这些，说明你真跑过。

### 每个模式都要能回答"机制 / 替代 / 代价 / 失败 / 验证"

| 模式 | 机制 | 替代方案 | 代价 | 怎么验证 |
| - | - | - | - | - |
| Supervisor | 每轮由 Router 选下一个 Worker | 固定路由表 | 每轮多一次 LLM 调用 | 回放 trace，看路由决策是否稳定 |
| Orchestrator-Workers | 先拆解再并发执行 | 人工预先拆好 | 拆解质量决定系统上限 | 固定任务集对比拆解前后成功率 |
| Handoff | 把控制权和上下文交给下一个 Agent | 中心调度 | 容易丢责任 | 检查每个任务是否有唯一 owner |
| GroupChat | 共享会话 + 选发言人 | Supervisor | token 随轮次增长 | 统计平均轮次与无效发言占比 |
| Evaluator-Optimizer | 生成与评估循环直到达标 | 一次生成 + 人工审 | 评估器偏差会被放大 | 对比评估分与人工分的一致性 |

***

## Q11: 动态拆解 vs 固定工作流路由，什么时候该让模型决定？

这是多 Agent 设计里最常被问、也最容易答错的判断题。

### 机制差异

| 维度 | 固定工作流路由 | 动态拆解 |
| - | - | - |
| 谁决定路径 | 代码里的 if/switch 或路由表 | LLM 在运行时决定 |
| 可预测性 | 高，可穷举所有分支 | 低，同输入可能走不同路径 |
| 适用前提 | 分支稳定、可枚举 | 任务形态未知、步骤随输入变化 |
| 测试方式 | 分支覆盖 + 单测 | 回放数据集 + 统计稳定性 |
| 主要风险 | 覆盖不到新情况 | 拆解发散、不可复现、成本失控 |

### 判断标准：能否"预先枚举"

```text theme={null}
问自己三个问题：
1. 这类请求的分支能不能列全？        能 → 固定路由
2. 每个分支的处理步骤是否长期稳定？    是 → 固定路由
3. 任务规模是否随输入剧烈变化？        是 → 动态拆解
```

多数生产系统不是二选一，而是**固定骨架 + 动态内核**：外层用确定性工作流保证可观测、可回滚，只在"需要拆几个子任务"这类不确定的地方交给模型。

```ts theme={null}
type Route =
  | { kind: "fixed"; handler: "export-pdf" | "export-csv" }
  | { kind: "dynamic"; goal: string };

// 能枚举的走固定分支，枚举不了的才进动态编排
function route(intent: Intent): Route {
  if (intent.type === "export") {
    return {
      kind: "fixed",
      handler: intent.format === "pdf" ? "export-pdf" : "export-csv",
    };
  }
  return { kind: "dynamic", goal: intent.raw };
}
```

> [!WARNING]
>
> 动态拆解不是"更高级"，而是把不确定性从业务层搬到了编排层。一旦编排由模型决定，你就失去了对步数、成本和路径的静态保证，必须额外投入 trace、预算和回归评测。没有这三样，动态拆解上线就是事故。

***

## Q12: 多 Agent 为什么会放大错误？三层防线怎么建？

### 错误会被结构放大

```text theme={null}
串行链路：整体成功率 ≈ (1 - p)^N      （p 为单步成功率）
并行扇出：任一失败概率 ≈ 1 - (1 - p)^N
```

单 Agent 成功率 95% 听起来不错，但 10 步串联后只剩约 60%。多 Agent 不仅步数更多，还叠加了三种特有的放大机制：

| 放大机制 | 表现 | 后果 |
| - | - | - |
| 上下文污染 | 一个 Agent 的错误结论写进共享记忆 | 后续所有 Agent 都基于错误前提工作 |
| 共识偏差 | 多个 Agent 共享同一份错误上下文还互相"确认" | 投票无法纠错，反而放大 |
| 重试风暴 | 上游失败触发下游重派，重派又触发重试 | 限流、雪崩、成本飙升 |

### 三层防线

| 防线 | 目标 | 具体手段 |
| - | - | - |
| 契约层 | 不让脏数据往下传 | 输出 Schema 校验、验收标准逐条检查、幻觉检测 |
| 隔离层 | 不让错误横向扩散 | 上下文隔离、独立评估器、只读共享事实表 |
| 收口层 | 不让错误无限放大 | 预算上限、熔断、最大轮次、死信队列、升级人工 |

> [!NOTE]
>
> 多 Agent 的可靠性不来自"更多 Agent"，而来自"每一步都能校验、每个错误都有边界、每次失败都有出口"。

***

## Q13: 底层源码——LangGraph 的 Multi-Agent 实现

LangGraph 的 Supervisor 模式是怎么实现的？

Supervisor 模式的核心是一个 Router 节点，根据当前状态决定下一步调用哪个 Agent（详见 [LangGraph 源码：libs/langgraph/langgraph/prebuilt/chat\_agent\_executor.py](https://github.com/langchain-ai/langgraph/blob/main/libs/langgraph/langgraph/prebuilt/chat_agent_executor.py)）：

```python theme={null}
# Supervisor 模式的实现（简化）
from langgraph.prebuilt import create_react_agent

# Router 节点：根据 LLM 输出决定下一步
def supervisor_router(state):
    response = llm.invoke([
        SystemMessage(content="你是主管，决定下一步调用哪个 Agent"),
        *state["messages"],
    ])
    # LLM 输出：{"next": "coder"} 或 {"next": "reviewer"} 或 {"next": "FINISH"}
    return json.loads(response.content)["next"]

# 组装图
graph = StateGraph(State)
graph.add_node("supervisor", supervisor_node)
graph.add_node("coder", coder_agent)
graph.add_node("reviewer", reviewer_agent)
graph.add_conditional_edges("supervisor", supervisor_router, {
    "coder": "coder",
    "reviewer": "reviewer",
    FINISH: END,
})
graph.add_edge("coder", "supervisor")
graph.add_edge("reviewer", "supervisor")
```

***

## Q14: 及格回答 vs 满分回答

### 问题："说说 Multi-Agent 的架构模式"

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

> "有 Pipeline、Fan-out/Fan-in、Supervisor、Debate 等模式。Pipeline 是串行，Fan-out 是并行，Supervisor 有主管调度。"

问题出在：**知道模式但不理解挑战**。

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

> "Multi-Agent 的核心问题是**任务分解、通信协调、错误处理**。任务分解：Pipeline 适合有依赖关系的任务（A 的输出是 B 的输入），Fan-out 适合独立任务（并行执行后汇总），Supervisor 适合动态任务（主管根据中间结果决定下一步）。<sup>\[1]</sup>"

> "通信协调有四种方式：共享 State（LangGraph 的方式，所有节点读写同一个状态对象，通过 Annotation + Reducer 定义合并规则）、消息传递（Agent 之间直接发消息）、黑板模式（所有 Agent 读写同一个'黑板'）、事件总线（发布/订阅模式）。LangGraph 的 Reducer 是关键——它解决了并行节点的状态冲突问题。<sup>\[2]</sup>"

> "错误处理有三种策略：容错继续（A 失败不影响 B 和 C，用 `Promise.allSettled`）、快速失败（A 失败立即终止，用 `Promise.all`）、条件传播（A 失败则 B 不执行）。选择取决于业务场景——实时系统选容错优先，批处理选完整性优先。成本控制是另一个核心挑战：用弱模型处理简单任务、限制 token 预算、缓存重复查询。<sup>\[3]</sup>"

### 常见追问

> [accordion] Multi-Agent 的成本怎么控制?
>
> **答题要点：**
> 说出三个关键策略：弱模型、token 预算、缓存。
>
> **高分回答：**
> "成本控制有三个关键策略：
>
> 1. **弱模型分级**：80% 的简单任务用 gpt-4o-mini（便宜 10 倍），20% 的决策用 gpt-4o。在 LangGraph 中，不同节点可以用不同的模型。
> 2. **token 预算**：限制每个 Agent 的单次调用 token 数（maxTokens），限制整个工作流的总 token 消耗（budget.total）。超出预算时降级到更简单的处理方式。
> 3. **Prompt Cache**：Anthropic 的 Prompt Cache 可以节省 90% 的输入 token 费用。优化方法：把稳定的 System Prompt 放在前面，变化的用户输入放在后面。相同前缀的请求直接复用缓存的 KV Cache。"

> [accordion] 怎么防止 Agent 之间的死循环?
>
> **答题要点：**
> 说出三种防止死循环的机制。
>
> **高分回答：**
> "死循环是 Multi-Agent 系统最常见的问题之一。防止方法：
>
> 1. **最大循环次数**：设置 Supervisor 的最大轮转次数（如 `maxIterations: 10`）。超过次数强制终止，返回当前最佳结果。
> 2. **状态变化检测**：如果连续两轮的状态没有变化（Agent 的输出和上一轮相同），说明陷入了死循环，强制终止。
> 3. **Supervisor 决策**：Supervisor 的 prompt 中明确写'如果 Agent A 和 Agent B 互相推诿，直接交给人工处理'。LLM 会理解这个指令，避免无限循环。"

> [accordion] 怎么调试 Multi-Agent 系统?
>
> **答题要点：**
> 说出调试 Multi-Agent 系统的四个关键手段。
>
> **高分回答：**
> "调试 Multi-Agent 系统有四个关键手段：
>
> 1. **日志聚合**：每个 Agent 的输入输出记录到同一个日志流，用 `run_id` 关联同一轮执行的所有 Agent 调用。LangSmith 自动做这件事。
> 2. **可视化执行流**：LangGraph Studio 可以看到图的执行过程——哪个节点执行了、状态怎么变化的、走了哪条边。这是最直观的调试方式。
> 3. **断点调试**：在某个节点加 `interrupt`，暂停执行等待人类检查。发现问题可以修改 State 后重试。
> 4. **成本追踪**：记录每个 Agent 的 token 消耗和执行时间，找出性能瓶颈。LangSmith 的 Dashboard 可以看到每个节点的耗时和 token 消耗。"

> [accordion] Hierarchical 和 Collaborative 模式该怎么选?
>
> **答题要点：**
> 从任务结构、决策复杂度、容错需求三个维度对比。
>
> **高分回答：**
> "选择取决于任务的组织结构：
>
> 1. **Hierarchical（层级模式）**：适合有明确组织结构的大型任务。例如企业级代码审查——顶层 Supervisor 分配到'前端团队'和'后端团队'，中层 Supervisor 分配到具体的审查 Agent。优点是职责清晰、易于扩展；缺点是层级越深，通信开销越大。
>
> 2. **Collaborative（协作模式）**：适合需要多视角输入的场景。例如技术方案评审——多个 Agent（安全专家、性能专家、可维护性专家）各自给出意见，最后汇总达成共识。优点是没有单点故障、多视角覆盖；缺点是需要共识机制（投票、加权平均）。
>
> 实际项目中，两种模式经常混合使用：顶层用 Supervisor 做路由，中层用 Collaborative 做多视角分析，底层用 Pipeline 做串行处理。"

> [accordion] Multi-Agent 的错误处理怎么设计?
>
> **答题要点：**
> 说出三种容错策略的适用场景和实现方式。
>
> **高分回答：**
> "错误处理有三种策略，选择取决于业务场景：
>
> 1. **容错继续**（Fire and Forget）：用 `Promise.allSettled` 实现。Agent A 失败了，B 和 C 继续执行，最后由 Supervisor 汇总成功和失败的结果。适合实时系统——不能因为一个 Agent 失败就阻塞整个流程。
>
> 2. **快速失败**（Fail Fast）：用 `Promise.all` 实现。任何一个 Agent 失败，立即终止整个流程。适合批处理——数据完整性比速度更重要。
>
> 3. **条件传播**（Conditional Propagation）：在 LangGraph 中用 `addConditionalEdges` 实现。Agent A 失败时，根据错误状态决定下一步——重试、降级、或跳过后续节点。
>
> 另外，对于高风险操作必须加 Human-in-the-Loop——用 `interrupt` 节点暂停执行，等待人类审批。重试时区分临时性错误（网络超时，可重试）和永久性错误（参数错误，不可重试）。"

> [accordion] Multi-Agent 和单 Agent + 工具链的区别?
>
> **答题要点：**
> 从并行能力、专业化分工、容错能力三个维度对比。
>
> **高分回答：**
> "单 Agent + 工具链是线性的（一个 Agent 调用多个工具，串行执行），Multi-Agent 是并行的（多个 Agent 同时执行）。
>
> Multi-Agent 的优势：
>
> 1. **并行加速**：Fan-out 模式可以把一个大任务拆成 N 个子任务并行执行，时间从 O(N) 降到 O(1)。
> 2. **专业化分工**：每个 Agent 专注一个领域，prompt 简短精准，输出质量更高。
> 3. **容错隔离**：一个 Agent 失败不影响其他 Agent，系统整体更健壮。
>
> 代价：
>
> 1. **通信开销**：Agent 之间传递信息需要 tokens，成本是单 Agent 的 N 倍。
> 2. **状态同步复杂度**：需要 Reducer 处理并行节点的状态冲突。
> 3. **调试难度**：多 Agent 系统的行为难以预测和复现。
>
> 选择标准：简单任务用单 Agent + 工具链，复杂任务（需要并行、需要专业化分工、需要容错）用 Multi-Agent。"

> [accordion] Multi-Agent 的幂等性怎么设计?
>
> **答题要点：**
> 从请求去重、结果缓存、状态机三个维度回答。
>
> **高分回答：**
> "幂等性确保'执行一次和执行多次的结果相同'，在重试场景下至关重要：
>
> 1. **请求去重**：用唯一 ID 标识每次调用。`callId = agentId + hash(input)`，已处理的 callId 直接返回缓存结果。LangGraph 的 Checkpoint 天然支持——从 checkpoint 恢复时不会重复执行已完成的节点。
>
> 2. **结果缓存**：相同输入的结果缓存起来，后续调用直接返回缓存。适合确定性任务（如代码格式化、文档生成）。不适合非确定性任务（如创意写作）。
>
> 3. **状态机**：用状态机管理任务的状态流转（pending → running → completed → failed）。重试时检查当前状态，避免重复执行已完成的步骤。
>
> 实际项目中，LangGraph 的 Checkpoint 是最简单的幂等性方案——每个节点执行后自动保存状态，重试时从 checkpoint 恢复。"

> [accordion] 长时间运行的 Agent 怎么保证不丢状态?
>
> **答题要点：**
> 说出 Checkpoint、Session 分段、长期记忆三种机制。
>
> **高分回答：**
> "长时间运行 Agent 的状态保证有三个关键机制：
>
> 1. **Checkpoint（状态快照）**：LangGraph 每个节点执行完后自动保存状态快照到 PostgreSQL。中断后从最近的 checkpoint 恢复，不需要从头开始。这是最基本的状态保证。
>
> 2. **Session 分段 + 交接笔记**：把长任务拆成多个 session，每个 session 结束时保存交接笔记（Brief），包含已完成的任务、关键决策、当前约束。下一个 session 开始时自动加载 Brief，实现无缝接续。
>
> 3. **长期记忆（Long-term Memory）**：用 4 层记忆模型（working → episodic → semantic → procedural）管理记忆。定期用小模型压缩历史对话，100K tokens 压缩为 5K tokens。频繁访问的记忆强化，陈旧记忆自动淘汰（遗忘曲线）。"

> [accordion] 企业级 Agent 的权限怎么设计?
>
> **答题要点：**
> 说出最小权限原则和 MCP tool 级别控制。
>
> **高分回答：**
> "企业级 Agent 的权限设计遵循最小权限原则——Agent 只拥有完成当前任务所需的最小权限。
>
> 具体实现是 MCP tool 级别控制：不同的 Agent 配置不同的工具集。代码审查 Agent 只有 readFileTool 和 searchCodeTool（读权限），没有 writeFileTool（写权限）。部署 Agent 只能操作 staging 环境的工具，不能操作 production 环境的工具。
>
> 另外，高风险操作（删除数据、发送邮件、部署生产环境）必须加 Human-in-the-Loop——用 interrupt 节点暂停执行，等待人类审批。Agent 可以建议，但最终决策权在人类。"

> [accordion] Agent 的 LLM 输出不可控怎么办?
>
> **答题要点：**
> 说出确定性边界的分层架构。
>
> **高分回答：**
> "LLM 的输出天然是不确定的，但企业级系统需要确定性。解决方案是分层架构：
>
> 1. **理解层（LLM，不确定性）**：LLM 只负责理解用户意图、提取结构化信息。这是不确定性的来源，但影响范围被限制在理解层。
>
> 2. **验证层（Schema，半确定性）**：LLM 的输出经过 JSON Schema 校验。如果输出不符合预期格式，触发降级策略（重试或用规则引擎）。
>
> 3. **执行层（规则引擎，确定性）**：具体的工具调用、数据操作、业务逻辑由规则引擎执行，不依赖 LLM 的输出。
>
> 关键原则：不确定性只存在于理解层，执行层必须确定性。这和 Anthropic 的 'Building Effective Agents' 理念一致——LLM 做路由和理解，规则引擎做执行。"

> [accordion] LangGraph 的四种编排模式怎么选?
>
> **答题要点：**
> 从控制流、复杂度、死循环风险三个维度对比。
>
> **高分回答：**
> "LangGraph 有四种编排模式，选择取决于任务特征：
>
> 1. **Supervisor 模式**：一个主管路由 + N 个 Worker 执行。控制流清晰，死循环风险低。90% 的场景用这个就够了。
>
> 2. **Hierarchical 模式**：多层 Supervisor 逐级分配。适合大型复杂任务（有明确的组织结构），但层级越深，通信开销越大。
>
> 3. **Network 模式**：所有 Agent 地位平等，直接互相调用。适合需要多轮协商的场景（如技术方案评审），但死循环风险高，必须加最大轮次限制。
>
> 4. **自定义拓扑**：组合多种模式，构建任意图结构。适合复杂业务流程（顶层 Supervisor + 中层 Collaborative + 底层 Pipeline）。
>
> 选择标准：简单任务用 Supervisor，大型任务用 Hierarchical，多视角协商用 Network，复杂业务用自定义拓扑。"

> [accordion] Multi-Agent 在生产环境的可观测性怎么设计?
>
> **答题要点：**
> 从日志、追踪、指标三个维度回答可观测性设计。
>
> **高分回答：**
> "生产环境的 Multi-Agent 系统需要完整的可观测性：
>
> 1. **日志聚合**：每个 Agent 的输入输出记录到同一个日志流，用 `run_id` 关联同一轮执行的所有 Agent 调用。LangSmith 自动做这件事——可以看到每个节点的输入、输出、耗时、token 消耗。
>
> 2. **分布式追踪**：用 OpenTelemetry 做分布式追踪，记录每个 Agent 调用的 span（开始时间、结束时间、状态）。在 Jaeger 或 Zipkin 中可以看到完整的调用链路和瓶颈。
>
> 3. **关键指标**：监控三个核心指标——成功率（Agent 调用的成功/失败比例）、延迟分布（P50/P95/P99 延迟）、token 消耗（每个 Agent 的 token 成本）。设置告警阈值，成功率低于 95% 或 P99 延迟超过 30 秒时触发告警。
>
> 4. **成本追踪**：记录每个 Agent 的 token 消耗和执行时间，找出成本最高的 Agent。LangSmith 的 Dashboard 可以看到每个节点的耗时和 token 消耗，方便优化。"

***

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

> 以下八题覆盖"机制差异、状态归属、失败模式、动态 vs 固定、错误放大"，每题给出及格与满分对照。面试时按"结论 → 机制 → 代价 → 验证"的顺序讲。

### 追问 1：五种编排模式的状态分别放在哪？

**及格回答：** 都放在共享的 State 里，节点读写同一个状态对象。

**满分回答：** 不同模式的状态归属不同，直接决定能不能做断点恢复。Supervisor 是共享图状态，集中但需要 reducer 合并；Handoff 是会话移交，状态跟着对话走，简单但没有全局视图；GroupChat 状态就是消息记录，可回放但 token 增长快；Evaluator-Optimizer 状态只有草稿和反馈，最小但只适合可判分任务。选型时我会先问"这个状态需不需要跨 Agent 共享、需不需要恢复"，再决定模式。

### 追问 2：什么时候必须用动态拆解，什么时候固定路由更好？

**及格回答：** 任务复杂就用动态拆解，简单就用固定路由。

**满分回答：** 判断标准是"分支能否预先枚举"。分支可穷举、步骤稳定，就用固定工作流，因为可测试、可观测、可回滚；只有任务规模随输入剧烈变化、无法预先拆好时，才交给模型动态拆解。生产里我优先选"固定骨架 + 动态内核"：外层确定性工作流保证收口，只在拆几个子任务这种不确定点上用模型。动态拆解的真实代价是把不确定性搬到编排层，必须配套 trace、预算和回归评测。

### 追问 3：Supervisor 路由震荡怎么治？

**及格回答：** 加最大轮次限制，超过就停。

**满分回答：** 先定位震荡原因：通常是 Router 的 prompt 缺少"当前已完成什么"的摘要，导致它反复改判。治法分三层：一是在 Router 输入里加入已完成任务和剩余目标的结构化摘要，减少信息缺失；二是给每个任务记 owner，禁止把同一任务交回上一个 Agent；三是设最大轮次和重复决策检测，连续两轮路由相同就强制收敛或升级人工。单纯加轮次上限只是兜底，不解决根因。

### 追问 4：Handoff 模式怎么避免"击鼓传花、无人负责"？

**及格回答：** 让最后一个 Agent 负责汇总。

**满分回答：** Handoff 的根本风险是责任随控制权一起被移交出去。工程上要做三件事：第一，任务始终有唯一 owner 字段，移交只是换执行者，不换责任人；第二，全局预算和超时挂在任务上而不是某个 Agent 上，避免每换一次手就重置；第三，设终止条件——谁收到"最终交付"指令谁负责收口，禁止无 owner 的悬空移交。没有这三条，Handoff 在复杂任务里几乎必然失控。

### 追问 5：Orchestrator-Workers 的拆解粒度怎么定？

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

**满分回答：** 粒度由"产物边界"决定，不由"步骤多少"决定。一个子任务应该对应一个明确产物和一组相关工具调用，经验上控制在 5 到 15 次工具调用；太小则调度和汇总开销超过执行成本，太大则单点失败重试代价高、上下文膨胀。还要设最大树深和最大叶子数，防止 Orchestrator 无限拆解。验证方式是固定任务集对比不同粒度下的成功率与总成本，而不是凭感觉。

### 追问 6：GroupChat 怎么防无限闲聊和上下文爆炸？

**及格回答：** 限制最大轮数，到点就结束。

**满分回答：** GroupChat 要同时管住"发言"和"上下文"两件事。发言侧：用明确的发言选择策略（轮询或 LLM 选择），设最大轮次和"连续无新增信息"检测，检测到重复观点就终止。上下文侧：不是把全部历史塞给每个 Agent，而是维护一份共享摘要加各自私有上下文，避免 token 随轮次平方增长。另外要有裁决者，否则多人 Agent 容易形成共识偏差——大家共享同一份错误上下文还互相确认。

### 追问 7：Evaluator-Optimizer 怎么保证收敛，评估器放水怎么办？

**及格回答：** 设个最大迭代次数就行。

**满分回答：** 收敛要靠"明确的验收标准 + 分数阈值 + 最大轮次"三者共同约束。评估标准必须是可逐条检查的，而不是"写得好不好"；每轮要输出差在哪里，让生成器有明确改进方向，否则会来回震荡。评估器放水是常见问题：同源模型容易给自己人打高分，所以评估器要么换模型、要么用规则校验兜底、要么定期用人工标注校准。上线前我会对比评估分和人工分的一致性，一致性低就说明评估器不可信。

### 追问 8：多 Agent 的错误放大怎么量化、怎么防？

**及格回答：** 多加校验，出错就重试。

**满分回答：** 先量化：串行链路整体成功率约等于单步成功率的 N 次方，所以单步 95% 在 10 步后只剩六成左右；并行扇出则是任一失败概率随分支数上升。放大机制有三类：上下文污染、共识偏差、重试风暴。防线也分三层：契约层用 Schema 和验收标准挡住脏数据；隔离层用上下文隔离和独立评估器阻断横向扩散；收口层用预算、熔断、死信队列和升级人工兜住底线。关键认知是——多 Agent 的可靠性来自边界和出口，不来自 Agent 数量。

***

## 延伸阅读与引用参考

* [LangGraph Multi-Agent 文档](https://langchain-ai.github.io/langgraphjs/concepts/multi_agent)：LangGraph 官方对 Multi-Agent 模式的详细说明。<sup>\[1]</sup>
* [LangGraph 源码](https://github.com/langchain-ai/langgraph)：LangGraph 的完整源码，理解 Supervisor、Send、Reducer 的底层实现。<sup>\[2]</sup>
* [Anthropic: Building Effective Agents](https://www.anthropic.com/research/building-effective-agents)：Orchestrator-Workers、Evaluator-Optimizer 等模式的原始出处，并明确区分"工作流"与"Agent"。<sup>\[3]</sup>
* [LangGraph Persistence 文档](https://langchain-ai.github.io/langgraphjs/concepts/persistence)：LangGraph 的 Checkpoint 机制详解，长时间运行 Agent 的状态保存基础。
* [Andrew Ng: Agentic Design Patterns](https://www.deeplearning.ai/the-batch/how-agents-can-improve-llm-performance/)：Andrew Ng 对 Agentic Workflow 和多 Agent 协作模式的总结。
* [OpenAI Agents SDK: Handoffs](https://openai.github.io/openai-agents-python/handoffs/)：Handoff 模式把控制权与上下文交给另一个 Agent 的官方实现与语义。
* [AutoGen: Group Chat](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/design-patterns/group-chat.html)：GroupChat 的发言选择与共享消息模型。
* [LangGraph Streaming & Human-in-the-Loop](https://langchain-ai.github.io/langgraphjs/concepts/streaming)：异步执行、进度追踪、Human-in-the-Loop 的官方实现指南。


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