Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 人工智能 / Artificial Intelligence

智能体工程 / Agent Engineering

1. Agent 工程体系全景 / Agent Engineering System Overview

2. Function Calling - 让 LLM 具备行动能力 / Function Calling for Giving LLMs the Ability to Act

3. Agent 框架演进 - 从裸 SDK 到 LangGraph / The Evolution of Agent Frameworks from Raw SDKs to LangGraph

4. RAG 基础 - 让 Agent 拥有"知识" / Retrieval-Augmented Generation Fundamentals for Agent Knowledge

5. 记忆管理 - Agent 的大脑 / Memory Management as the Brain of an Agent

6. Agent 工作流 - 从单步到复杂的执行编排 / Agent Workflows from Single Steps to Complex Orchestration

7. 多 Agent 系统 - 多个 Agent 协作 / Multi-Agent Systems and Agent Collaboration

8. RAG 进阶 - 企业级知识库实战 / Advanced RAG for Enterprise Knowledge Bases

9. 真实 Agent 应用场景 / Real-World AI Agent Applications

10. Structured Output - 让 LLM 输出可控的结构化数据 / Structured Output for Controllable, Machine-Readable LLM Responses

11. Tools Design Best Practices - AI Agent 工具设计最佳实践 / Tools Design Best Practices for AI Agents

12. Agent 架构模式 - 从单 Agent 到多 Agent 的工程范式 / Agent Architecture Patterns

13. Agent Modes — 编程 Agent 的交互模式设计 / Designing Interaction Modes for Coding Agents

14. Agent Workflow 编排:从循环到持久化执行的演进

15. Context Engineering - 从 Prompt 设计到上下文编排 / Context Engineering: From Prompt Design to Context Orchestration

16. Agent 缓存工程:从 KV Cache、Prompt Cache 到语义缓存 / Agent Caching Engineering

17. Harness Engineering, Skills, and Loop Engineering — 从信任模型到验证系统 / From Trusting Models to Verifying Systems

18. MCP 协议 - AI 工具的"USB 接口" / Model Context Protocol for AI Tool Integration

19. Agent 评估与测试 — 如何衡量一个"不可预测"的系统 / Agent Evaluation and Testing — How to Measure an "Unpredictable" System

20. 安全沙箱 - Agent 的安全边界 / Secure Sandboxes as Agent Safety Boundaries

21. 权限与门卫 - Agent 的安全控制中枢 / Permissions and Policy Gates for Agent Control

22. API Key 管理与安全 - Agent 的密钥生命周期的管理 / API Key Lifecycle Management and Security for Agents

23. 提示词注入防护 - Agent 的防御前沿 / Prompt Injection Defense for AI Agents

24. 可观测性与调试 - Agent 运行的透明度保障 / Observability and Debugging for Transparent Agent Operations

25. 模型路由 - 让正确的模型做正确的事 / Model Routing for Matching Models to Tasks

26. OpenClaw 设计深度分析 - 为什么它让人觉得"活"了 / OpenClaw Design Analysis and the Illusion of Liveliness

27. Claude Code 泄露源码深度分析 - 512,000 行代码揭示的生产级 Agent 架构 / Claude Code Source Analysis and Production Agent Architecture

28. LobeChat 设计深度分析 - 全栈 Agent Chat 应用工程实践 / LobeChat Design Analysis and Full-Stack Agent Chat Engineering

29. 编程 Agent 全面对比:从 Claude Code 到 Pi 的设计哲学 / Coding Agents Comparison: Design Philosophies from Claude Code to Pi

30. 领域 Agent 的确定性工具编译与延迟执行——从自然语言规格到单次 CAE 提交

31. Agent 工程学习指南 / An AI Agent Engineering Learning Guide

本页目录

模型路由 - 让正确的模型做正确的事 / Model Routing for Matching Models to Tasks ​

📅 创建时间:2026-05-08 🏷️ 标签:#ModelRouting #CostOptimization #Haiku #Sonnet #模型选择 📚 前置知识:[[13-可观测性与调试]]


📋 本章目标 ​

  • 理解为什么 Agent 需要模型路由
  • 掌握模型路由的决策策略
  • 理解 Claude Code 的模型分级策略
  • 能够为 Agent 设计合适的模型路由方案
  • 掌握成本与质量的平衡方法

第1部分:为什么需要模型路由? ​

1.1 模型能力与成本的不对称 ​

┌─────────────────────────────────────────────────────────────┐
│                    模型能力 vs 成本对比                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Claude 3.5 Sonnet(主力模型)                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 能力:★★★★★                                        │   │
│  │ 速度:★★★★☆                                        │   │
│  │ 价格:$$$($3/M 输入,$15/M 输出)                 │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Claude 3.5 Haiku(轻量模型)                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 能力:★★★☆☆                                        │   │
│  │ 速度:★★★★★                                        │   │
│  │ 价格:$($0.8/M 输入,$4/M 输出)                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  差距:Haiku 比 Sonnet 便宜约 20 倍                       │
│  但 Haiku 能完成 Sonnet 80% 的任务                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

1.2 Agent 中不同任务的难度差异 ​

┌─────────────────────────────────────────────────────────────┐
│                    Agent 任务难度分布                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  简单任务(80%的调用)← 应该用便宜模型                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 分类判断(是/否)                                 │   │
│  │ • 权限检查(是否危险操作)                         │   │
│  │ • 格式验证(JSON 是否有效)                        │   │
│  │ • 意图识别(用户想做什么)                         │   │
│  │ • 简单总结(100字以内)                           │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  复杂任务(20%的调用)← 必须用强模型                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 复杂代码生成                                      │   │
│  │ • 多步推理                                          │   │
│  │ • 架构设计                                          │   │
│  │ • Bug 诊断与修复                                   │   │
│  │ • 长文总结                                          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  如果所有任务都用 Sonnet → 80% 的钱花在了不需要的地方    │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

第2部分:模型路由策略 ​

2.1 Claude Code 的模型分级 ​

┌─────────────────────────────────────────────────────────────┐
│                    Claude Code 模型分级                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Haiku(最便宜)                                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用途:分类、路由、权限检查                            │   │
│  │ 特点:快速、低成本                                  │   │
│  │ 适用:yoloClassifier.ts 中的权限判断                 │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Sonnet(中档主力)                                         │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用途:标准会话执行                                  │   │
│  │ 特点:能力与成本的平衡                             │   │
│  │ 适用:大部分日常任务                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Opus(最强但最贵)                                        │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用途:ULTRAPLAN(深度规划)、复杂推理               │   │
│  │ 特点:极致能力,但成本高                           │   │
│  │ 适用:需要 30 分钟深度思考的复杂任务                 │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  核心原则:用最便宜的模型完成能完成的任务                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

2.2 路由决策框架 ​

python
from dataclasses import dataclass
from enum import Enum
from typing import Callable

class TaskComplexity(Enum):
    LOW = "low"      # 分类、路由、验证
    MEDIUM = "medium"  # 标准对话、代码修改
    HIGH = "high"    # 复杂推理、架构设计

@dataclass
class RouteDecision:
    model: str
    reasoning: str
    estimated_cost_input: float  # 每 1M tokens 的价格
    estimated_cost_output: float

class ModelRouter:
    """模型路由器"""

    MODEL_CATALOG = {
        "haiku": {
            "name": "claude-3-5-haiku",
            "strengths": ["快速分类", "意图识别", "简单验证"],
            "cost_input": 0.8,
            "cost_output": 4.0,
            "max_tokens": 4096,
        },
        "sonnet": {
            "name": "claude-3-5-sonnet",
            "strengths": ["代码生成", "日常对话", "分析总结"],
            "cost_input": 3.0,
            "cost_output": 15.0,
            "max_tokens": 8192,
        },
        "opus": {
            "name": "claude-3-7-sonnet",
            "strengths": ["复杂推理", "深度规划", "架构设计"],
            "cost_input": 15.0,
            "cost_output": 75.0,
            "max_tokens": 8192,
        },
    }

    def route(self, task: str, context: dict = None) -> RouteDecision:
        """根据任务特征决定使用哪个模型"""

        # 策略1:基于任务类型路由
        task_type = self._classify_task(task, context)
        if task_type == TaskComplexity.LOW:
            return RouteDecision(
                model="haiku",
                reasoning=f"任务类型 '{task_type.value}' 适合轻量模型",
                estimated_cost_input=self.MODEL_CATALOG["haiku"]["cost_input"],
                estimated_cost_output=self.MODEL_CATALOG["haiku"]["cost_output"],
            )

        # 策略2:基于复杂度评估
        complexity = self._estimate_complexity(task, context)
        if complexity < 0.3:
            return RouteDecision(
                model="haiku",
                reasoning="复杂度评分 0.3,使用轻量模型",
                estimated_cost_input=self.MODEL_CATALOG["haiku"]["cost_input"],
                estimated_cost_output=self.MODEL_CATALOG["haiku"]["cost_output"],
            )
        elif complexity < 0.7:
            return RouteDecision(
                model="sonnet",
                reasoning="复杂度评分 0.7,使用主力模型",
                estimated_cost_input=self.MODEL_CATALOG["sonnet"]["cost_input"],
                estimated_cost_output=self.MODEL_CATALOG["sonnet"]["cost_output"],
            )
        else:
            return RouteDecision(
                model="opus",
                reasoning="复杂度评分 > 0.7,使用最强模型",
                estimated_cost_input=self.MODEL_CATALOG["opus"]["cost_input"],
                estimated_cost_output=self.MODEL_CATALOG["opus"]["cost_output"],
            )

    def _classify_task(self, task: str, context: dict) -> TaskComplexity:
        """分类任务类型"""
        # 基于关键词的简单分类
        low_keywords = ["分类", "判断", "检查", "验证", "识别", "是否"]
        high_keywords = ["设计", "架构", "优化性能", "深度分析", "复杂", "多个"]

        if any(kw in task for kw in low_keywords):
            return TaskComplexity.LOW
        if any(kw in task for kw in high_keywords):
            return TaskComplexity.HIGH
        return TaskComplexity.MEDIUM

    def _estimate_complexity(self, task: str, context: dict) -> float:
        """评估任务复杂度,返回 0-1 的分数"""
        score = 0.0

        # 长度因素
        if len(task) > 500:
            score += 0.2

        # 代码量因素(如果有)
        if context and "code_length" in context:
            if context["code_length"] > 500:
                score += 0.2
            if context["code_length"] > 2000:
                score += 0.3

        # 多步骤因素
        if context and "expected_steps" in context:
            if context["expected_steps"] > 3:
                score += 0.2
            if context["expected_steps"] > 5:
                score += 0.2

        # 模糊度因素
        ambiguous_words = ["大概", "可能", "也许", "似乎", "怎样"]
        if any(w in task for w in ambiguous_words):
            score += 0.1

        return min(score, 1.0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

第3部分:实战路由策略 ​

3.1 工具级别的路由 ​

python
class ToolRouter:
    """工具级别的模型路由"""

    # 每个工具最适合的模型
    TOOL_MODEL_MAP = {
        # 简单验证类:用 Haiku
        "classify_intent": "haiku",
        "check_permission": "haiku",
        "validate_format": "haiku",
        "detect_injection": "haiku",
        "detect_secrets": "haiku",
        "parse_json": "haiku",

        # 标准工具:用 Sonnet
        "read": "sonnet",
        "write": "sonnet",
        "edit": "sonnet",
        "grep": "sonnet",
        "bash": "sonnet",
        "search": "sonnet",
        "explain_code": "sonnet",
        "debug": "sonnet",

        # 复杂工具:用 Opus
        "architect_design": "opus",
        "complex_refactor": "opus",
        "multi_file_analysis": "opus",
        "security_review": "opus",
    }

    def get_model_for_tool(self, tool_name: str) -> str:
        """获取工具对应的模型"""
        return self.TOOL_MODEL_MAP.get(tool_name, "sonnet")  # 默认 Sonnet

    def execute_with_routing(self, tool_name: str, task: str, context: dict):
        """根据路由执行工具"""
        model = self.get_model_for_tool(tool_name)
        return self.call_model(model, task, context)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

3.2 成本感知的批量路由 ​

python
class CostAwareRouter:
    """成本感知的路由器"""

    def __init__(self, monthly_budget: float):
        self.monthly_budget = monthly_budget
        self.spent = 0.0
        self.daily_quota = monthly_budget / 30

    def can_afford(self, estimated_cost: float, model: str) -> bool:
        """检查是否能负担这次调用"""
        daily_spent = self.get_daily_spent()

        if model == "opus" and estimated_cost > 0.50:
            # Opus 昂贵,严格控制
            return daily_spent < self.daily_quota * 0.3  # Opus 不超过日预算的 30%

        if model == "sonnet" and estimated_cost > 0.10:
            return daily_spent < self.daily_quota * 0.7

        return True  # Haiku 便宜,不限制

    def route_with_budget(self, task: str) -> RouteDecision:
        """结合预算的路由"""
        base_decision = ModelRouter().route(task)

        # 如果超出预算,降级模型
        if not self.can_afford(
            base_decision.estimated_cost_input,
            base_decision.model
        ):
            if base_decision.model == "opus":
                return RouteDecision(
                    model="sonnet",
                    reasoning=f" Opus 超出预算,降级为 Sonnet",
                    estimated_cost_input=self.MODEL_CATALOG["sonnet"]["cost_input"],
                    estimated_cost_output=self.MODEL_CATALOG["sonnet"]["cost_output"],
                )
            elif base_decision.model == "sonnet":
                return RouteDecision(
                    model="haiku",
                    reasoning=f"Sonnet 今日配额用尽,降级为 Haiku",
                    estimated_cost_input=self.MODEL_CATALOG["haiku"]["cost_input"],
                    estimated_cost_output=self.MODEL_CATALOG["haiku"]["cost_output"],
                )

        return base_decision
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

第4部分:动态路由与学习 ​

4.1 基于历史的路由优化 ​

python
class AdaptiveRouter:
    """自适应路由器——根据历史成功率调整路由"""

    def __init__(self):
        self.task_results = {}  # task_pattern -> success_rate

    def record_result(self, task_pattern: str, model: str, success: bool):
        """记录任务执行结果"""
        key = f"{model}:{task_pattern}"
        if key not in self.task_results:
            self.task_results[key] = {"success": 0, "total": 0}

        self.task_results[key]["total"] += 1
        if success:
            self.task_results[key]["success"] += 1

    def get_success_rate(self, task_pattern: str, model: str) -> float:
        """获取特定任务在特定模型上的成功率"""
        key = f"{model}:{task_pattern}"
        if key not in self.task_results:
            return None
        data = self.task_results[key]
        return data["success"] / data["total"] if data["total"] > 0 else None

    def route_adaptive(self, task: str) -> str:
        """自适应路由——选择历史上成功率最高的模型"""
        task_pattern = self._extract_pattern(task)

        best_model = "sonnet"  # 默认
        best_rate = 0.0

        for model in ["haiku", "sonnet", "opus"]:
            rate = self.get_success_rate(task_pattern, model)
            if rate is not None and rate > best_rate:
                best_rate = rate
                best_model = model

        return best_model
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

第5部分:路由的工程实践 ​

5.1 模型降级策略 ​

┌─────────────────────────────────────────────────────────────┐
│                    模型降级策略                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  主模型不可用时:                                          │
│  Sonnet 限流 → 降级到 Haiku + 重试(简单任务)            │
│  Sonnet 失败 → 降级到 Opus(复杂任务)                     │
│                                                             │
│  降级触发条件:                                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • API 返回 429 Rate Limit                          │   │
│  │ • API 返回 500/503 服务器错误                       │   │
│  │ • 响应超时(> 60s)                               │   │
│  │ • 输出为空或格式错误                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  降级重试次数:                                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Haiku → Sonnet:重试 1 次                           │   │
│  │ Sonnet → Opus:重试 2 次(复杂任务重试更重要)      │   │
│  │ Opus → Sonnet:重试 3 次(终极手段)                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

5.2 A/B 测试框架 ​

python
class ABTestRouter:
    """A/B 测试路由——用于实验不同路由策略"""

    def __init__(self, experiment_name: str):
        self.experiment_name = experiment_name
        self.variants = {
            "control": lambda task: "sonnet",  # 对照组
            "cheap": self._route_cheap,        # 实验组:尽量用便宜的
            "fast": self._route_by_speed,       # 实验组:按速度选择
        }
        self.results = {v: {"success": 0, "cost": 0.0, "count": 0}
                         for v in self.variants}

    def route(self, task: str, user_id: str) -> str:
        """根据用户 ID 分配实验组"""
        variant = "control" if hash(user_id) % 2 == 0 else "cheap"
        model = self.variants[variant](task)
        self.current_variant = variant
        return model

    def record(self, task: str, model: str, success: bool, cost: float):
        """记录实验结果"""
        variant = getattr(self, "current_variant", "control")
        self.results[variant]["count"] += 1
        if success:
            self.results[variant]["success"] += 1
        self.results[variant]["cost"] += cost

    def get_experiment_report(self) -> dict:
        """输出实验报告"""
        report = {}
        for variant, data in self.results.items():
            count = data["count"]
            if count > 0:
                report[variant] = {
                    "samples": count,
                    "success_rate": data["success"] / count,
                    "avg_cost": data["cost"] / count,
                    "cost_efficiency": data["success"] / data["cost"] if data["cost"] > 0 else 0,
                }
        return report
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

核心总结 ​

总结1:路由的核心思想 ​

用 Haiku 做分类和路由
用 Sonnet 做标准任务
用 Opus 做深度推理
总原则:最便宜完成任务的模型就是最好的模型
1
2
3
4

总结2:路由策略 ​

基于规则:关键词、任务类型、复杂度评分
基于成本:月度预算、日配额、成本阈值
基于历史:成功率统计、自适应学习
基于实验:A/B 测试验证假设
1
2
3
4

总结3:降级策略 ​

Rate Limit → 降级到便宜模型重试
Server Error → 降级到更可靠模型
超时 → 降级 + 增加超时时间
1
2
3

章节测试 ​

测试1:路由原则 ​

模型路由的核心原则是什么?

测试2:Haiku 适用场景 ​

以下哪个任务最适合用 Haiku? A. 写一个完整的 REST API B. 判断用户输入是否包含敏感词 C. 分析一个复杂的并发 bug D. 设计微服务架构

测试3:成本节省 ​

如果 80% 的简单任务用 Haiku($0.8/M),20% 的复杂任务用 Sonnet($3/M),相比全部用 Sonnet 能节省多少成本?

测试4:降级策略 ​

什么时候应该触发模型降级?

测试5:自适应路由 ​

自适应路由根据什么来优化模型选择?


参考答案 ​

测试1答案 ​

答案:用最便宜的模型完成能完成的任务。不同任务难度不同,应该匹配最适合的模型——简单任务用 Haiku,标准任务用 Sonnet,深度推理用 Opus。


测试2答案 ​

答案:B(判断用户输入是否包含敏感词)

解析:敏感词判断是简单的分类任务,不需要复杂推理,Haiku 完全能胜任且成本最低。其他选项都需要深度推理或代码生成,需要 Sonnet 或 Opus。


测试3答案 ​

答案:约节省 70% 的成本

解析:简单计算——假设 100 个任务,Haiku 处理 80 个,Sonnet 处理 20 个:

  • 混合方案:80 × $0.8 + 20 × $3 = $64 + $60 = $124
  • 全部 Sonnet:100 × $3 = $300
  • 节省:(300 - 124) / 300 ≈ 59%

实际场景中简单任务 Token 量通常更少,节省比例可达 70-80%。


测试4答案 ​

答案:以下情况应触发降级:

  1. API 返回 429 Rate Limit
  2. API 返回 500/503 错误
  3. 响应超时(超过设定阈值)
  4. 输出为空或格式错误

测试5答案 ​

答案:基于历史成功率统计

解析:自适应路由器记录每个任务类型在每个模型上的历史成功率,然后选择历史上成功率最高的模型。随着数据积累,路由越来越精准。


相关笔记 ​

  • [[13-可观测性与调试]] - 成本监控是路由优化基础
  • [[08-real-world-applications]] - 不同场景的模型选择
  • [[03-rag-basics]] - RAG 中的检索可以用轻量模型

下一步学习 ​

  • [ ] 阅读 24 - OpenClaw 设计分析
  • [ ] 阅读 25 - Claude Code 泄露源码分析

学习状态:🟡 开始学习

最后更新于:

Pager
上一篇24. 可观测性与调试 - Agent 运行的透明度保障 / Observability and Debugging for Transparent Agent Operations
下一篇26. OpenClaw 设计深度分析 - 为什么它让人觉得"活"了 / OpenClaw Design Analysis and the Illusion of Liveliness

持续记录,持续成长

Copyright © Tidenflow