---
title: "AI Agent 模式解析：Routing 路由分流"
author: deletexiumu
pubDatetime: 2026-03-14T08:00:00+08:00
featured: false
draft: false
tags:
  - AI Agent
  - AI 编程
description: "Anthropic Building Effective Agents 系列第二篇：Routing 路由分流模式。通过 RouteLLM、claude-code-router 和客服路由三个案例，拆解如何用分类器将请求导向不同模型和处理流程，实现成本降低 85% 的路由优化。"
---
*Building Effective Agents 模式解析系列（2/6）*

---

## 真实场景引入

你用 Claude Opus 处理所有请求，月底看账单——吓一跳。细看调用记录，一大半是"你好"、"帮我格式化一下这段文字"、"今天周几"之类的活。用牛刀杀鸡，杀了整整一个月。

这不是个例。LLM 调用中真正需要强模型深度推理的请求，通常只占少数。但如果没有分流机制，每个请求都走同一条最贵的路。

有些团队的做法不一样：在请求到达模型之前加一层"分诊"，花几毫秒判断这个任务该交给谁。结果——成本大幅下降，质量几乎无损。

这层"分诊"，就是今天要讲的 **Routing（路由）**。

![Routing 基本架构](/blog/ai-agent-routing/01-routing-overview.png)

---

## 什么是 Routing

Anthropic 在 [Building Effective Agents](https://www.anthropic.com/engineering/building-effective-agents) 中将 Routing 定义为五种 Agentic 工作流模式之一：

> "Routing classifies an input and directs it to a specialized followup task."

**核心定义**：将输入进行分类，导向最合适的专业化处理路径。每条路径可以有独立的 prompt、工具集，甚至不同的模型。

为什么需要路由？Anthropic 原文给出了直接的理由：没有路由时，为一种输入优化 prompt 会降低其他类型的表现。路由实现的是 **关注点分离（separation of concerns）**——不用一个万能 prompt 处理所有情况。

### 路由器的三种实现方式

从简单到复杂，路由器有三种主流实现（以下速度为经验区间，取决于具体实现和部署环境）：

| 方式 | 原理 | 速度 | 语义理解 | 成本 | 适用场景 |
|------|------|------|---------|------|---------|
| **关键字/规则路由** | 正则匹配、IF-ELSE | 微秒级 | 无 | 极低 | 边界清晰的简单分类 |
| **嵌入相似度路由** | 查询转向量，匹配最近的路由示例 | 毫秒级 | 良好 | 中低 | 粗粒度语义分类 |
| **LLM 分类路由** | 用一次 LLM 调用判断类别 | 秒级 | 最佳 | 高 | 复杂意图、边缘情况 |

三者的取舍很直观：**规则路由快但笨，LLM 路由聪明但慢，嵌入路由在中间找平衡**。

### 路由延迟悖论（Router Latency Paradox）

路由器是为了省时间、省钱而存在的，但它自身也消耗时间和成本。如果路由器做了一次完整的 LLM 推理，那每个请求都多了一次调用开销。

核心判断标准很简单：**只有下游节省 > 路由开销时，路由才值得做。** 这也是为什么实践中大多数路由器选择轻量实现——用 BERT 级别的分类器或嵌入相似度，而不是用 GPT-4 来做分诊。

### 与 Prompt Chaining 的关系

上一篇讲的 Prompt Chaining 是"步骤固定，顺序执行"；Routing 是"先分类，再走不同路径"。Chain 关注步骤之间的顺序，Routing 关注输入的分类。

一个容易混淆的点：Routing 决定走哪条路径，并不天然意味着并行——并行是 Parallelization 模式的领域（系列第三篇会讲）。

---

## 核心案例：RouteLLM——在 MT Bench 上省 85% 成本

### 问题背景

每个请求都用 GPT-4 太贵，但全用弱模型质量又不行。能不能自动判断"这个问题值不值得上强模型"？

UC Berkeley 的 LMSYS 团队给出了答案：[RouteLLM](https://github.com/lm-sys/RouteLLM)，一个发表在 ICLR 2025 的开源路由框架。

### 架构拆解

RouteLLM 的核心思路极其简洁：

```
用户请求 → 路由器（轻量分类器）→ 强模型路径 / 弱模型路径 → 输出
```

路由器本身是轻量模型（论文最佳结果来自矩阵分解路由器 MF，也提供 BERT 和因果 LLM 方案），推理开销可忽略。它做的只有一件事：判断这个查询的"难度"——强模型在这个问题上的胜率是否足够高，值得为它花更多的钱。

**路由决策公式**：

```
R(q) = M_weak   if P(wins|q) < α
     = M_strong if P(wins|q) ≥ α
```

其中 α 是成本阈值——调高 α 意味着更多请求走弱模型（省钱但可能损失质量），调低 α 意味着更多请求走强模型（保质量但花更多钱）。

### 四种路由策略

RouteLLM 提供了四种路由器实现，覆盖从免训练到重量级的不同需求：

| 策略 | 原理 | 特点 |
|------|------|------|
| **矩阵分解（MF）** | 将"模型-查询"评分建模为矩阵补全问题 | 推荐使用，性能最强、轻量 |
| **相似度加权排序（SW Ranking）** | 用历史问答对的相似度加权计算 | 免训练，仅需 CPU |
| **BERT 分类器** | 直接训练二分类器判断难度 | 中等复杂度 |
| **因果 LLM 分类器** | 基于 Llama 3 8B 做 few-shot 分类 | 最重量级 |

### 核心数据

以下数据来自 RouteLLM ICLR 2025 论文（arXiv:2406.18665v4），模型对为 GPT-4（gpt-4-1106-preview）vs Mixtral 8x7B：

| Benchmark | 最佳路由器调用比例（GPT-4 调用占比） | 说明 |
|-----------|--------------------------------------|------|
| **MT Bench** | **约 13%**（省约 85% 成本） | 与训练数据分布最接近，效果最好 |
| MMLU | 约 35% | 选择题格式，与 Arena 数据分布差异大 |
| GSM8K | 约 33% | 数学推理，路由增益相对有限 |

MT Bench 上的结果最亮眼——MF 路由器 + 数据增强后，仅需约 13% 的 GPT-4 调用即可维持 95% 的 GPT-4 水平（"省约 85%"这个数字也被 RouteLLM 官方 README 作为宣传数据使用）。但不同 benchmark 差异较大：MMLU 和 GSM8K 上虽然也有成本节省，但幅度远不如 MT Bench。

这种差异的根源在于训练数据的分布：RouteLLM 基于 Chatbot Arena 的大规模对战数据（D_arena，约 65K 对比样本）训练，而 MT Bench 的查询分布与 Arena 数据最为接近（嵌入相似度约 0.608），所以路由效果最好。对于分布外（OOD）的场景（如 MMLU 的选择题），额外加入约 1,500 条 gold-label 标注（不到训练数据的 2%）可显著改善路由准确率。

### 可迁移性：学到的是"难度"，不是"模型"

RouteLLM 最有意思的发现：在 GPT-4 / Mixtral 上训练的路由器，**直接迁移**到 Claude 3 Opus / Claude 3 Sonnet、Llama 3.1 70B / 8B 等从未见过的模型对上，仍然表现优异。

这说明路由器学到的是**查询难度特征**——哪些问题天然更难、需要更强的推理能力——而不是某个特定模型的特征。这种泛化能力让路由器的实用价值大幅提升：你不需要每换一对模型就重新训练。

### 为什么是 Routing 的好案例

1. 完全符合 Anthropic 的定义：分类输入 → 导向专业化处理（强模型/弱模型）
2. 有严格的学术 benchmark 支撑，数据可追溯
3. 路由器本身的设计体现了"路由延迟悖论"的解法——用极轻量分类器（MF 路由器处理速度约 155 请求/秒），让路由开销可忽略

![RouteLLM 架构](/blog/ai-agent-routing/02-routellm-architecture.png)

---

## 辅助案例：claude-code-router + 客服路由

### claude-code-router：规则路由的工程实践

[claude-code-router](https://github.com/musistudio/claude-code-router) 是一个模型网关/代理层——它不是学术研究，而是工程化的路由变体。

**架构**：Claude Code → 本地代理（127.0.0.1:3456）→ 路由判断 → 不同提供商/模型

它的路由逻辑分三层：

**任务类型路由**：不同类型的请求走不同模型。

| 路由键 | 用途 | 典型模型选择 |
|--------|------|-------------|
| `think` | 推理密集型（Plan Mode） | 强推理模型 |
| `background` | 轻量任务 | 便宜模型 |
| `webSearch` | 搜索功能 | 搜索增强模型 |
| `image` | 视觉任务 | 多模态模型 |

**阈值路由**：超过 `longContextThreshold`（如 60k tokens）自动切到长上下文模型。

**Fallback**：`default` 路由兜底一切未匹配的请求。

每个提供商还有独立的格式转换器（Transformer），将 Anthropic 格式转为目标 API 格式——这不是路由本身，而是路由后的处理差异。

**与 RouteLLM 的区别**：claude-code-router 用规则/阈值路由（快但不理解语义），RouteLLM 用训练的分类器（准但需要训练数据）。两者代表了路由实现光谱的两端。

### 客服路由：Anthropic 原文的核心示例

Anthropic 在原文中给出的第一个 Routing 示例就是客服场景：将用户查询分为一般问题、退款请求、技术支持，分别导入不同流程、不同 prompt、不同工具集。

这不是假想场景。几个公开案例：

- **Verizon**（Reuters 2024-06-18 报道）：AI 在客户接通客服前预测来电原因，准确率 80%，覆盖每年 1.7 亿次来电
- **Motel Rocks**（Zendesk 官方案例）：43% 的工单被 AI 代理自动分流拦截，无需人工介入

客服路由的本质和 RouteLLM 一样——先分类，再分配。区别在于分类维度：RouteLLM 按难度分（简单/复杂），客服按意图分（咨询/退款/技术支持），claude-code-router 按任务类型分（推理/搜索/视觉）。

### 三个案例的互补

| 案例 | 路由维度 | 路由方式 | 核心目标 |
|------|---------|---------|---------|
| RouteLLM | 查询难度 | 训练分类器 | 成本优化 |
| claude-code-router | 任务类型 | 规则+阈值 | 多模型聚合 |
| 客服路由 | 用户意图 | LLM/ML 分类 | 流程分流 |

---

## 怎么设计一个好的路由

### 分类器设计要点

**分类边界要清晰**。模糊的类别 = 模糊的路由 = 差的效果。"技术问题"和"产品咨询"之间如果大量重叠，路由器会频繁犯错，错误还会沿下游传播。

**类别数量控制**。3-8 个是经验甜区。太少，分流没意义；太多，路由器自己先犯迷糊了。

**置信度阈值**。不要硬分类——当路由器不确定时，走 fallback 路径。强行猜测比承认不确定更危险。

### 生产级混合路由方案

实践中，单一路由策略往往不够用。以下是一种常见的混合路由架构（经验做法，实际效果取决于场景和实现）：

```
层 1：快速启发式（关键字/长度/格式检查）    → 微秒级
层 2：轻量分类器（BERT / 嵌入相似度）      → 毫秒级
层 3：安全检查（PII 检测 / 内容过滤）       → 毫秒级
层 4：低置信度升级到 LLM 分类              → 较慢但最准确
```

核心思路：**快的先过滤，贵的只在必要时触发**。这本身就是 Routing 的嵌套应用——用路由来决定是否需要更精细的路由。

### Fallback 设计

路由器不确定时怎么办？三种策略：

1. **默认走强模型**（保质量）——宁可多花钱，不出错
2. **默认走弱模型**（省成本）——多数情况够用
3. **请求人工分类**（最安全）——适合高风险场景

最安全的做法：**不确定时走强模型**。claude-code-router 的实现更务实：`default` 路由兜底一切未匹配的请求，保证没有请求会"掉到地上"。

### 评估路由效果

不能只看分类准确率——还要看端到端的**质量-成本比**。一个路由器分类准确率 99% 但把所有请求都分到强模型，和一个不存在的路由器没区别。

RouteLLM 的评估思路值得借鉴：**固定性能为标准**（如 95% GPT-4 水平），看最多能省多少成本。这比"固定成本看性能"更符合业务场景——你通常有一个不可妥协的质量底线。

### 最小路由模板

下面是一个 3 路由的完整示例，展示路由的核心结构。`call_llm` 需要根据你实际使用的 API 来实现。

**路由表：**

| 路由 | 触发条件 | 处理方式 |
|------|---------|---------|
| `simple` | 短查询 + 低复杂度关键词 | 弱模型，简洁 prompt |
| `complex` | 长查询或包含推理关键词 | 强模型，详细 prompt |
| `fallback` | 以上都不匹配 | 强模型（保质量） |

**Python 代码：**

```python
import re
from typing import Any

# ---------- 工具函数 ----------
def call_llm(prompt: str, model: str = "YOUR_MODEL_ID") -> str:
    """调用 LLM，返回文本响应（省略具体 API 调用细节）"""
    ...

# ---------- 路由分类器 ----------
SIMPLE_PATTERNS = [
    r"^(你好|hello|hi)\b",
    r"格式化",
    r"翻译.{0,10}$",
    r"今天.*(周几|日期|天气)",
]

COMPLEX_PATTERNS = [
    r"分析|比较|设计|架构|方案",
    r"为什么.{10,}",
    r"怎么(实现|解决|优化)",
]

def classify(query: str) -> str:
    """基于规则的路由分类器"""
    query_lower = query.strip().lower()

    # 规则 1：短查询 + 简单模式 → simple
    if len(query) < 50:
        for pattern in SIMPLE_PATTERNS:
            if re.search(pattern, query_lower):
                return "simple"

    # 规则 2：包含复杂模式 → complex
    for pattern in COMPLEX_PATTERNS:
        if re.search(pattern, query_lower):
            return "complex"

    # 规则 3：长查询默认走 complex
    if len(query) > 200:
        return "complex"

    # Fallback
    return "fallback"

# ---------- 路由表 ----------
ROUTE_CONFIG = {
    "simple": {
        "model": "YOUR_WEAK_MODEL_ID",
        "system_prompt": "简洁回答用户问题，不需要详细解释。",
    },
    "complex": {
        "model": "YOUR_STRONG_MODEL_ID",
        "system_prompt": "详细分析用户问题，给出完整的推理过程。",
    },
    "fallback": {
        "model": "YOUR_STRONG_MODEL_ID",
        "system_prompt": "回答用户问题。",
    },
}

# ---------- 路由执行 ----------
def route_and_respond(query: str) -> dict[str, Any]:
    """分类 → 路由 → 调用对应模型"""
    route = classify(query)
    config = ROUTE_CONFIG[route]

    prompt = f"{config['system_prompt']}\n\n用户问题：{query}"
    response = call_llm(prompt, model=config["model"])

    return {
        "route": route,
        "model": config["model"],
        "response": response,
    }

# ---------- 使用示例 ----------
result = route_and_respond("你好，今天天气怎么样？")
# → route: "simple", model: YOUR_WEAK_MODEL_ID

result = route_and_respond("帮我分析一下微服务架构和单体架构在团队规模小于10人时的优劣")
# → route: "complex", model: YOUR_STRONG_MODEL_ID
```

**几个设计要点：**

- `classify` 是纯规则路由——速度极快、零成本，但不理解语义。生产环境中可以在此基础上叠加嵌入相似度或 LLM 分类作为第二层。
- `ROUTE_CONFIG` 是路由表，每条路由定义了模型和 prompt。扩展新路由只需加一条配置。
- `fallback` 走强模型——这是"不确定时保质量"策略的体现。
- 返回值包含 `route` 字段，方便后续分析路由分布和效果。

---

## 适用场景与模式组合

### 适合用路由的场景

- **请求类型差异大，需要专业化处理**：客服分类、代码审查多语言路由、内容审核分级
- **成本敏感，不同复杂度用不同模型**：RouteLLM 场景——简单问题不必上强模型
- **分类边界清晰，准确率高**：路由的价值建立在准确分类的基础上

### 不适合用路由的场景

- **类别之间边界模糊**：分不清属于哪类时，路由器自己先犯错，错误沿下游传播
- **所有请求都需要同样的处理**：没有分流的必要
- **分类本身就很复杂，路由开销 > 节省**：路由延迟悖论的另一面

### 与其他模式的组合

- **Chain + Routing**：在 Chain 的某步嵌套路由。上一篇提到的客服场景——先用 Chain 做主流程（接收 → 分类 → 处理 → 回复），在"分类"节点用 Routing 将不同类型的查询导向不同的处理链
- **Routing + Chain**：每条路由内部是一条独立的 Chain。客服场景最典型——退款路由走"验证身份 → 查订单 → 发起退款"链，技术支持路由走"诊断问题 → 查知识库 → 给出方案"链
- **混合路由本身就是 Routing 的嵌套**：规则路由 → 嵌入路由 → LLM 路由，层层递进

核心判断标准：**输入是否有明确的分类？分类后的处理是否有显著差异？** 两个都是 → 用 Routing。

---

## 结尾

这是 Building Effective Agents 模式解析系列的第二篇。上一篇 Prompt Chaining 解决的是"怎么按顺序干"，这一篇 Routing 解决的是"谁来干"。

核心观点只有一句：**Routing 的本质是"让专业的人干专业的事"——先分类，再分配。** 分类的方式可以是一行正则，也可以是一个训练好的分类器，关键是让路由开销远小于它带来的节省。

**下一步**：拿文中的最小路由模板试一下。找一个你正在做的多模型调用场景，定义好分类规则和路由表，跑一遍看效果。模板在"怎么设计一个好的路由"章节。

---

*原文参考：[Anthropic - Building Effective Agents](https://www.anthropic.com/engineering/building-effective-agents)*

*核心案例：[RouteLLM - Learning to Route LLMs with Preference Data（ICLR 2025）](https://arxiv.org/abs/2406.18665)*

*案例来源：[claude-code-router](https://github.com/musistudio/claude-code-router)*

*数据来源：[Verizon AI Customer Service（Reuters, 2024-06-18）](https://www.reuters.com/)*

*数据来源：[Motel Rocks - Zendesk Customer Story](https://www.zendesk.com/)*

---

## 相关阅读

- [AI Agent 模式解析：Prompt Chaining 提示链](/posts/prompt-chaining-agent-pattern/) — 系列第一篇，讲解如何用固定顺序的流水线模式编排 AI 任务
