AI 智能体开发 · Day 4 详细学习手册
AI 智能体开发 · Day 4 详细学习手册
主题:主流大模型对比与选择——从"知道有哪些模型"到"能选对模型"
总时长:2.5-3 小时(可分两到三次完成)
难度:低偏实践(概念为主 + 大量对比实验)
产出:模型选择决策表 + 1 个自动化对比脚本 + 1 个模型路由器 + 结构化笔记
前置条件:完成 Day 1(API 调用)、Day 2(Transformer 理解)、Day 3(Token/Embedding/Context Window)
今天最重要:选对模型 = 省钱 + 提效。这篇手册的价值是让你以后面对任何需求,5 秒内做出模型选择决策
目录
- 学习目标与知识地图
- Part A:LLM 市场全景(30 分钟)
- Part B:主流模型逐一详解(30 分钟)
- Part C:模型选择决策框架(25 分钟)
- Part D:自动化对比实验(30 分钟)
- Part E:成本分析与优化(20 分钟)
- Part F:综合实验——模型路由器(20 分钟)
- 今日笔记模板
- 验收清单
- 常见问题 FAQ
- 扩展资源
- 核心概念速查卡
- 明日预告
1. 学习目标与知识地图
你今天要达成的目标
概念层面(能用自己话讲清楚):
- 2026 年大模型市场的主要玩家和阵营划分
- OpenAI / Anthropic / Google / DeepSeek / 阿里 / 智谱 各自的旗舰模型和特点
- 闭源 vs 开源模型的核心 tradeoff
- 模型命名规则(gpt-4o / claude-3-5-sonnet / deepseek-reasoner 分别什么意思)
- 评估模型的六个维度(推理/代码/中文/多模态/长文本/成本)
- API 定价模型(输入/输出分别计费,为什么输出更贵)
操作层面(亲手做过):
- 用同一组 Prompt 对比多个模型的输出质量
- 测量不同模型的响应速度和 Token 消耗
- 建立自己的模型选择决策表
- 实现一个根据任务类型自动选择模型的模型路由器
- 计算不同场景下的月成本估算
知识地图
Part A: 市场全景
├── 三大阵营(海外/国内/开源)
├── 闭源 vs 开源的 tradeoff
├── 模型能力的六个维度
└── 2026 年市场格局
Part B: 模型详解
├── OpenAI:GPT-4o / GPT-4o-mini / o1 / o3
├── Anthropic:Claude 3.5 Sonnet / Haiku / Opus
├── Google:Gemini 1.5 Pro / Flash
├── DeepSeek:chat / reasoner (R1)
├── 阿里:Qwen-Max / Plus / Turbo
├── 智谱:GLM-4 / GLM-4-Flash
└── 开源:Llama 3 / Qwen 开源 / DeepSeek 开源
Part C: 选择框架
├── 六维度评估法
├── 场景→模型 决策树
├── 模型命名规则解读
└── API 兼容性(OpenAI 兼容格式)
Part D: 对比实验
├── 多维度测试 Prompt 设计
├── model_comparison.py 自动化对比
└── 结果分析与评分
Part E: 成本分析
├── 定价模型详解
├── 月成本估算公式
├── 不同场景的成本对比
└── 五个省钱策略
Part F: 模型路由器
└── model_router.py(根据任务类型自动选模型)
今天和前三天的关系
Day 1: 你学会了调用 LLM API,拿到了回复
→ 但你只用了 DeepSeek,不知道还有哪些模型可选
Day 2: 你理解了 Transformer 架构
→ 知道了模型"内部"怎么工作,但不同模型的"外部"差异呢?
Day 3: 你理解了 Token(计费单位)和 Context Window(使用限制)
→ 知道了怎么算成本,但不同模型的价格差异有多大?
Day 4: 今天把"选模型"这件事彻底搞清楚
→ 市场有哪些模型 → 各自什么特点 → 怎么选 → 怎么比 → 怎么省钱
→ 这是后续所有开发的基础:选对模型,事半功倍
实际开发中的典型决策:
→ "这个 Agent 需要写代码" → Claude 3.5 Sonnet
→ "这个客服每天 10 万次调用" → DeepSeek / Qwen-Turbo
→ "需要处理 50 万字文档" → Gemini 1.5 Pro
→ "预算为零" → 本地开源模型
2. Part A:LLM 市场全景(30 分钟)
这部分帮你建立"地图感"。不需要记住每个细节,但要知道市场格局,知道遇到需求时该往哪个方向看。
2.1 三大阵营(10 分钟)
2026 年的大模型市场,可以划分为三大阵营:
┌─────────────────────────────────────────────────────────────────┐
│ 海外闭源阵营 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ OpenAI │ │ Anthropic │ │ Google │ │
│ │ GPT-4o │ │ Claude 3.5 │ │ Gemini 1.5 │ │
│ │ GPT-4o-mini │ │ Sonnet/Haiku│ │ Pro/Flash │ │
│ │ o1 / o3 │ │ Opus │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ 特点:综合能力强,生态成熟,但价格高,国内访问需代理 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 国内闭源阵营 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ DeepSeek │ │ 阿里通义 │ │ 智谱 │ │
│ │ deepseek- │ │ Qwen-Max │ │ GLM-4 │ │
│ │ chat │ │ Qwen-Plus │ │ GLM-4-Flash │ │
│ │ deepseek- │ │ Qwen-Turbo │ │ │ │
│ │ reasoner │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ 特点:性价比极高,中文好,国内直连,API 兼容 OpenAI 格式 │
│ + Moonshot Kimi(长文本优势)、百度文心、字节豆包等 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 开源阵营 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Meta Llama │ │ Qwen 开源 │ │ DeepSeek 开源│ │
│ │ Llama 3 │ │ Qwen2.5 │ │ DeepSeek- │ │
│ │ 8B/70B/405B │ │ 7B/14B/72B │ │ V3 / R1 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ 特点:可本地部署,数据不出门,零 API 成本,但需要 GPU 硬件 │
└─────────────────────────────────────────────────────────────────┘
关键认知:
海外模型 vs 国内模型:
不是"谁强谁弱"的问题,而是"适合不适合"的问题
海外旗舰(GPT-4o / Claude 3.5):
→ 综合能力确实领先,尤其在复杂推理和英文场景
→ 但价格高 10-30 倍,国内访问不方便
国内旗舰(DeepSeek / Qwen):
→ 性价比极高,中文场景表现优秀
→ DeepSeek-V3 在很多基准测试上接近 GPT-4o,但价格只有 1/15
→ API 兼容 OpenAI 格式,迁移成本几乎为零
开源模型:
→ 适合数据敏感场景(医疗/金融/政务)
→ 适合零预算的个人项目
→ 但需要 GPU 硬件,部署有门槛
2.2 闭源 vs 开源的核心 tradeoff(10 分钟)
闭源 API 开源本地部署
──────── ────────────
使用门槛 低(注册 Key 即用) 高(需要 GPU + 部署)
初始成本 零(按用付费) 高(硬件 + 电费)
边际成本 每次调用都付费 接近零(电费)
数据安全 数据发送到第三方 数据不出门
模型质量 旗舰模型最强 稍逊于旗舰,但差距在缩小
更新频率 厂商自动更新 需要自己拉新模型
可控性 低(厂商可能改接口/涨价) 高(完全自己掌控)
定制化 低(只能调参数) 高(可以微调/改架构)
决策建议:
什么时候用闭源 API:
→ 个人学习/副业项目 → 闭源(省心)
→ 快速验证想法 → 闭源(速度快)
→ 需要顶级模型质量 → 闭源旗舰
→ 调用量不大(日均 < 10 万次)→ 闭源
什么时候用开源本地:
→ 数据敏感(医疗/金融/政务)→ 开源
→ 日均调用量极大(> 100 万次)→ 开源(边际成本低)
→ 需要离线运行 → 开源
→ 有 GPU 硬件 → 开源
→ 需要深度定制/微调 → 开源
个人开发者建议:
→ 先用闭源 API(DeepSeek/Qwen)入门
→ 项目稳定后再评估是否转开源
→ 不要一上来就折腾部署,浪费时间在基础设施上
2.3 评估模型的六个维度(10 分钟)
这六个维度是你以后选模型的"尺子"。不需要跑 benchmark,但心里要有这把尺子。
维度 1: 推理能力
→ 复杂逻辑推理、数学题、多步分析
→ 强:o1/o3 > Claude 3.5 > GPT-4o > DeepSeek-R1
→ 测试方法:给它一道多步推理题
维度 2: 代码能力
→ 写代码、Debug、代码解释、重构
→ 强:Claude 3.5 Sonnet > GPT-4o > DeepSeek-V3
→ 测试方法:让它写一个有边界条件的函数
维度 3: 中文理解
→ 中文语境、成语、文化背景、古文
→ 强:DeepSeek > Qwen > GLM-4 > GPT-4o
→ 测试方法:让它解释一个中文成语或写中文文案
维度 4: 多模态
→ 图片理解、OCR、图表分析
→ 强:GPT-4o > Claude 3.5 > Gemini > Qwen-VL
→ 测试方法:给它一张图片让它描述
维度 5: 长文本
→ Context Window 大小、长文本中信息检索能力
→ 强:Gemini 1.5 (1M) > Claude 3.5 (200K) > GPT-4o (128K)
→ 测试方法:放一篇长文让它找特定信息
维度 6: 成本
→ 输入/输出单价、速度(影响用户体验)
→ 强:DeepSeek > Qwen-Turbo > GPT-4o-mini > Claude 3.5
→ 评估方法:算月成本(Part E 会详细讲)
六维度雷达图直觉:
推理
★
/ \
/ \
代码 ★ ★ 中文
\ /
\ /
多模态 ★ ★ 成本
|
★
长文本
没有模型在六个维度都满分
→ 选模型 = 在你的场景最重要的维度上做最优选择
例:
"我要做代码 Agent" → 代码维度权重最高 → Claude 3.5
"我要做中文客服" → 中文+成本维度权重最高 → DeepSeek / Qwen
"我要做文档分析" → 长文本维度权重最高 → Gemini / Claude
"我要做图片识别" → 多模态维度权重最高 → GPT-4o
自测题(写在笔记里):
1. 如果你要做一个"帮用户写简历"的 Agent,哪个维度最重要?
提示:中文理解 + 成本(因为调用量可能大)
2. 如果你要做一个"分析财报数据"的 Agent,哪个维度最重要?
提示:推理 + 长文本(财报很长)
3. 为什么不能无脑选最贵的模型?
提示:成本、延迟、有些任务便宜的模型就够了
3. Part B:主流模型逐一详解(30 分钟)
这部分是"菜单"——每个模型家族的特点、适用场景、价格。不需要全记,但以后翻回来能快速查阅。
3.1 OpenAI 系列(7 分钟)
GPT-4o(旗舰)
├── o = Omni,原生多模态(文/图/音/视频)
├── 上下文: 128K
├── 价格: 输入 ~$2.5/百万tok, 输出 ~$10/百万tok
├── 特点: 综合最强,多模态支持最好
├── 适合: 复杂任务、多模态、英文场景
└── 缺点: 贵,国内访问需代理
GPT-4o-mini(轻量)
├── 上下文: 128K
├── 价格: 输入 ~$0.15/百万tok, 输出 ~$0.6/百万tok
├── 特点: 便宜 30 倍,速度快
├── 适合: 简单任务、大量调用、快速原型
└── 缺点: 复杂推理不如旗舰
o1 / o3(推理模型)
├── 特点: "思考"后再回答,推理能力极强
├── 适合: 数学、竞赛编程、科学推理
├── 缺点: 慢(几十秒到几分钟)、贵、不支持 Function Calling(早期版本)
└── 注意: 日常开发用不到,研究/竞赛才需要
命名规则:
gpt-4o → 4代 + Omni(多模态)
gpt-4o-mini→ 4代 + Omni + 轻量版
o1 → 新系列,专攻推理(不叫 gpt)
o1-mini → 推理 + 轻量
o3 → o 系列第三代
3.2 Anthropic Claude 系列(5 分钟)
Claude 3.5 Sonnet(主力)
├── 上下文: 200K
├── 价格: 输入 ~$3/百万tok, 输出 ~$15/百万tok
├── 特点: 代码能力公认最强,长文本优秀,安全性好
├── 适合: 代码生成、长文档分析、需要高质量输出
└── 缺点: 贵,国内访问需代理
Claude 3.5 Haiku(轻量)
├── 上下文: 200K
├── 价格: 输入 ~$0.8/百万tok, 输出 ~$4/百万tok
├── 特点: 快速、便宜、保持质量
└── 适合: 大量调用场景
Claude 3 Opus(上一代旗舰)
├── 上下文: 200K
├── 特点: 已被 3.5 Sonnet 超越,新项目不建议用
└── 注意: 模型迭代快,不要迷信"旗舰"
命名规则:
claude-3-5-sonnet → 3.5代 + Sonnet(中档)
claude-3-5-haiku → 3.5代 + Haiku(轻量)
claude-3-opus → 3代 + Opus(旗舰)
Sonnet = 中档,平衡质量和速度(最常用)
Haiku = 轻量,快速便宜
Opus = 旗舰,最强最贵
注意: Claude 3.5 Sonnet 比 Claude 3 Opus 更强
→ 模型不是越新越好,要看具体版本和你的任务
3.3 Google Gemini 系列(4 分钟)
Gemini 1.5 Pro(旗舰)
├── 上下文: 1M tokens(最大!)
├── 价格: 输入 ~$1.25/百万tok, 输出 ~$5/百万tok
├── 特点: 超长上下文、多模态、性价比不错
├── 适合: 超长文档分析、视频理解、大量文本处理
└── 缺点: 长文本中"中间遗忘"较明显
Gemini 1.5 Flash(轻量)
├── 上下文: 1M tokens
├── 价格: 极低
├── 特点: 快速、便宜、也支持 1M 上下文
└── 适合: 大规模处理、实时场景
Gemini 的独特价值:
1M token 上下文意味着什么:
→ 一本《三体》全集 ≈ 80 万字 ≈ 120 万 token
→ 可以一次性放进 Gemini 的上下文窗口
→ GPT-4o 的 128K 只能放 ~6 万字
→ 这不是"好一点",是"能做 vs 不能做"的区别
实际场景:
→ 分析一整本书 → Gemini
→ 分析一整份财报(200 页)→ Gemini
→ 分析一个中型代码库 → Gemini
→ 但注意: 能放进去 ≠ 能处理好(中间遗忘问题)
3.4 DeepSeek 系列(5 分钟)
deepseek-chat(对话主力)
├── 模型: DeepSeek-V3
├── 上下文: 64K
├── 价格: 输入 ~¥1/百万tok, 输出 ~¥2/百万tok
├── 特点: 性价比之王!接近 GPT-4o 的质量,1/15 的价格
├── 适合: 日常开发、中文场景、大量调用
└── 缺点: 上下文 64K 偏小,不支持 Embedding
deepseek-reasoner(推理模型 R1)
├── 特点: 推理能力极强,类似 o1
├── 适合: 数学、逻辑推理、复杂分析
├── 价格: 略高于 deepseek-chat
└── 缺点: 慢,输出包含"思考过程"(需要过滤)
DeepSeek 为什么重要:
价格对比(输出/百万 token):
GPT-4o: ~¥72
Claude 3.5: ~¥108
GPT-4o-mini: ~¥4
DeepSeek-V3: ~¥2 ← 便宜到离谱
质量对比(MMLU 基准测试,近似值):
GPT-4o: ~88%
Claude 3.5: ~88%
DeepSeek-V3: ~85% ← 差距很小
结论:
→ DeepSeek 用 1/36 的价格,达到 96% 的质量
→ 对于个人开发者和中小项目,DeepSeek 是最优选
→ 这也是为什么本课程前几周默认用 DeepSeek
3.5 阿里通义 Qwen 系列(4 分钟)
Qwen-Max(旗舰)
├── 上下文: 32K-128K(版本不同)
├── 价格: 输入 ~¥20/百万tok, 输出 ~¥60/百万tok
├── 特点: 国内模型质量天花板,中文最强之一
└── 适合: 对质量要求最高的中文场景
Qwen-Plus(主力)
├── 上下文: 128K
├── 价格: 输入 ~¥0.8/百万tok, 输出 ~¥2/百万tok
├── 特点: 性价比高,和 DeepSeek 同级别
└── 适合: 日常开发,中文场景
Qwen-Turbo(轻量)
├── 上下文: 128K
├── 价格: 极低
├── 特点: 快速、便宜
└── 适合: 大量调用、简单任务
Qwen vs DeepSeek 怎么选:
两者价格接近,质量接近,选哪个?
选 DeepSeek 的理由:
→ 社区生态更活跃(开源了 V3 和 R1)
→ reasoning 模型(R1)表现更好
→ API 文档更简洁
选 Qwen 的理由:
→ 支持 Embedding(DeepSeek 不支持)
→ 多模态支持更好(Qwen-VL)
→ 阿里云生态更完善(如果你用阿里云)
→ 有更多尺寸的开源版本可本地部署(7B/14B/72B)
个人建议:
→ 聊天/生成: 用 DeepSeek(更便宜)
→ 需要 Embedding: 用 Qwen 或百炼
→ 需要多模态: 用 Qwen-VL
→ 两个都注册,互相备份
3.6 其他值得关注的模型(5 分钟)
智谱 GLM-4
├── 上下文: 128K
├── 价格: ~¥5/百万tok(输入和输出同价)
├── 特点: 中文理解强,有免费的 GLM-4-Flash
├── 适合: 学习练手(Flash 免费)、中文场景
└── 独特优势: GLM-4-Flash 完全免费,适合开发调试
Moonshot Kimi
├── 上下文: 128K-256K
├── 特点: 长文本处理优秀,国内用户友好
├── 适合: 长文档分析、中文摘要
└── 注意: API 兼容 OpenAI 格式
百度文心一言
├── 特点: 百度生态整合,中文搜索增强
└── 适合: 百度生态内项目
字节豆包
├── 特点: 价格极低,抖音/飞书生态
└── 适合: 字节生态内项目
开源模型
├── Llama 3(Meta): 英文最强开源,8B 可消费级 GPU 跑
├── Qwen2.5 开源: 中文最强开源,多尺寸可选
├── DeepSeek-V3 开源: 质量最高的开源之一,但 671B 参数太大
└── 部署工具: Ollama / vLLM / LM Studio
3.7 API 兼容性(重要!)
OpenAI 兼容格式是"事实标准":
→ 几乎所有国内模型都兼容 OpenAI 的 API 格式
→ 意味着: 换模型只需改 api_key 和 base_url,代码不用改
兼容 OpenAI 格式的模型:
✓ DeepSeek
✓ 阿里百炼(Qwen)
✓ 智谱 GLM
✓ Moonshot Kimi
✓ 字节豆包
✓ 零一万物
代码示例(同一套代码,切换模型只改配置):
# DeepSeek
client = OpenAI(api_key=DEEPSEEK_KEY, base_url="https://api.deepseek.com")
client.chat.completions.create(model="deepseek-chat", messages=[...])
# Qwen
client = OpenAI(api_key=DASHSCOPE_KEY, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")
client.chat.completions.create(model="qwen-plus", messages=[...])
→ 只有 api_key、base_url、model 名不同,其余完全一样
→ 这是为什么本课程推荐用 openai SDK 调国内模型
4. Part C:模型选择决策框架(25 分钟)
这部分给你一套"5 秒决策"的方法论。以后遇到任何需求,照着决策树走就能选对。
4.1 场景→模型决策树(10 分钟)
你的需求是什么?
│
├─ 需要顶级推理能力(数学/竞赛/科研)
│ ├─ 预算充足 → o1 / o3(OpenAI 推理模型)
│ └─ 预算有限 → DeepSeek-R1(deepseek-reasoner)
│
├─ 需要写代码/重构/Debug
│ ├─ 预算充足 → Claude 3.5 Sonnet(公认代码最强)
│ └─ 预算有限 → DeepSeek-V3 / Qwen-Plus
│
├─ 需要处理超长文档(> 10 万字)
│ ├─ → Gemini 1.5 Pro(1M 上下文)
│ └─ 备选 → Claude 3.5(200K)
│
├─ 需要图片理解/多模态
│ ├─ 预算充足 → GPT-4o
│ └─ 预算有限 → Qwen-VL
│
├─ 中文场景(客服/写作/摘要)
│ ├─ 质量优先 → Qwen-Max / DeepSeek-V3
│ └─ 成本优先 → DeepSeek-V3 / Qwen-Turbo
│
├─ 大量调用(日均 > 1 万次)
│ ├─ → DeepSeek-V3(最便宜的优质模型)
│ └─ 备选 → GPT-4o-mini / Qwen-Turbo
│
├─ 数据敏感/需要本地部署
│ ├─ 有 GPU → Qwen2.5 开源 / Llama 3
│ └─ 无 GPU → 暂时用 API,数据脱敏后调用
│
├─ 快速原型/开发调试
│ ├─ → GLM-4-Flash(免费)或 DeepSeek(极便宜)
│ └─ 上线后再换更好的模型
│
└─ 不确定选什么
├─ 个人项目 → DeepSeek-V3(默认首选)
├─ 公司项目 → GPT-4o 或 Claude 3.5(稳妥)
└─ 先用便宜的测试,质量不够再升级
4.2 模型选择决策表(5 分钟)
把这张表存到手机里,以后随时查阅。
| 场景 | 首选模型 | 备选模型 | 月成本估算* |
|---|---|---|---|
| 代码生成/Debug | Claude 3.5 Sonnet | DeepSeek-V3 | ¥50-500 |
| 中文客服/问答 | DeepSeek-V3 | Qwen-Plus | ¥10-200 |
| 长文档分析 | Gemini 1.5 Pro | Claude 3.5 | ¥30-300 |
| 图片理解 | GPT-4o | Qwen-VL | ¥50-500 |
| 数学/逻辑推理 | DeepSeek-R1 | o1 | ¥20-200 |
| 数据提取/分类 | GPT-4o-mini | Qwen-Turbo | ¥5-50 |
| 创意写作 | GPT-4o | DeepSeek-V3 | ¥10-100 |
| 快速原型 | GLM-4-Flash(免费) | DeepSeek-V3 | ¥0-10 |
| 大规模调用 | DeepSeek-V3 | Qwen-Turbo | ¥100-2000 |
| 本地部署 | Qwen2.5-7B | Llama3-8B | ¥0(API) |
*月成本估算基于日均 100-1000 次调用,仅供参考
4.3 模型命名规则速查(5 分钟)
OpenAI 命名:
gpt-4o → GPT 第4代 + Omni(多模态)
gpt-4o-mini → 轻量版
gpt-4-turbo → 旧版加速版
o1 → 推理系列第1代
o3-mini → 推理系列第3代 + 轻量
text-embedding-3-small → Embedding 模型第3代 + 小尺寸
Anthropic 命名:
claude-3-5-sonnet-20241022 → 3.5代 + Sonnet档 + 日期版本
claude-3-haiku → 3代 + Haiku档(轻量)
claude-3-opus → 3代 + Opus档(旗舰)
档位: Opus(旗舰)> Sonnet(中档)> Haiku(轻量)
注意: 3.5 Sonnet > 3 Opus(新一代中档 > 旧一代旗舰)
DeepSeek 命名:
deepseek-chat → 对话模型(V3)
deepseek-reasoner → 推理模型(R1)
deepseek-coder → 代码模型(已合并到 V3)
阿里 Qwen 命名:
qwen-max → 旗舰
qwen-plus → 主力
qwen-turbo → 轻量
qwen-long → 长文本专用
qwen-vl-plus → 视觉语言模型
智谱 GLM 命名:
glm-4 → 旗舰
glm-4-flash → 轻量(免费!)
glm-4v → 视觉版
Google Gemini 命名:
gemini-1.5-pro → 旗舰
gemini-1.5-flash → 轻量
gemini-1.5-pro-002 → 第2个版本迭代
4.4 "够用就好"原则(5 分钟)
新手常见误区:
❌ "反正用最好的 GPT-4o,质量有保障"
→ 结果: 月账单 $500+,大部分任务 GPT-4o-mini 就够了
❌ "我用 o1 推理模型,更聪明"
→ 结果: 每次等 30 秒,用户跑了,而且 o1 不支持 Function Calling
❌ "我要用最新的模型"
→ 结果: 新模型可能有不兼容改动,线上项目炸了
正确心态:
✓ "这个任务最便宜的模型能不能做?"
→ 能做就用便宜的,做不了再升级
✓ "先跑起来再优化"
→ 开发阶段用便宜/免费的,上线后看数据再调
✓ "不同任务用不同模型"
→ 简单分类用 mini,复杂推理用旗舰
→ 这就是 Part F 模型路由器的思路
成本直觉:
同一个 Prompt,GPT-4o 的成本 ≈ 30-50 倍 DeepSeek
如果一个任务 DeepSeek 能做到 90 分
→ 用 GPT-4o 做到 95 分,多花 30-50 倍的钱值不值?
→ 大多数情况下,不值
5. Part D:自动化对比实验(30 分钟)
手动去各平台 Playground 对比太慢。我们写一个脚本,一次跑多个模型、多个 Prompt,自动出对比报告。
5.1 测试 Prompt 设计(5 分钟)
好的测试 Prompt 应该能"区分"模型水平——太简单的所有模型都能做,区分不出差异。
# code/model_comparison.py
"""
Day 4 实验: 多模型自动化对比
用同一组 Prompt 测试不同模型,对比质量/速度/成本
"""
import os
import time
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
# ============ 模型配置 ============
# 取消注释你有的模型
models_config = {
"DeepSeek-V3": {
"client": OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
),
"model": "deepseek-chat",
"input_price": 1, # ¥/百万token
"output_price": 2, # ¥/百万token
},
# "Qwen-Plus": {
# "client": OpenAI(
# api_key=os.getenv("DASHSCOPE_API_KEY"),
# base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
# ),
# "model": "qwen-plus",
# "input_price": 0.8,
# "output_price": 2,
# },
# "GLM-4-Flash": {
# "client": OpenAI(
# api_key=os.getenv("ZHIPU_API_KEY"),
# base_url="https://open.bigmodel.cn/api/paas/v4"
# ),
# "model": "glm-4-flash",
# "input_price": 0, # 免费
# "output_price": 0,
# },
# "GPT-4o-mini": {
# "client": OpenAI(api_key=os.getenv("OPENAI_API_KEY")),
# "model": "gpt-4o-mini",
# "input_price": 1, # ~¥1
# "output_price": 4, # ~¥4
# },
}
5.2 多维度测试 Prompt(5 分钟)
# ============ 测试 Prompt 设计 ============
# 每个 Prompt 测试不同维度
test_prompts = {
"代码生成": {
"prompt": """请用 Python 实现一个 LRU Cache(最近最少使用缓存),要求:
1. 支持 get(key) 和 put(key, value) 操作
2. 容量满时淘汰最久未使用的元素
3. get 和 put 都是 O(1) 时间复杂度
4. 添加类型注解和文档字符串
5. 写 3 个测试用例
只输出代码,不要解释。""",
"eval_criteria": ["能运行", "O(1)复杂度", "有类型注解", "有测试用例"],
},
"中文理解": {
"prompt": """请解释以下成语的含义,并各造一个句子:
1. 亡羊补牢
2. 刻舟求剑
3. 画蛇添足
格式:
【成语】含义:... 造句:...""",
"eval_criteria": ["含义准确", "造句通顺", "格式正确"],
},
"逻辑推理": {
"prompt": """一个房间里有3个开关,控制隔壁房间的3盏灯。
你只能在隔壁房间看一次灯。如何确定每个开关对应哪盏灯?
请一步一步推理,给出答案。""",
"eval_criteria": ["推理清晰", "答案正确", "步骤完整"],
},
"摘要总结": {
"prompt": """请将以下文本摘要为3个要点:
人工智能(AI)是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的"容器"。人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。
3个要点:""",
"eval_criteria": ["要点准确", "无遗漏", "简洁"],
},
}
5.3 自动化对比引擎(10 分钟)
# ============ 对比引擎 ============
def call_model(client, model_name, prompt, temperature=0):
"""调用模型并记录数据"""
start_time = time.time()
try:
response = client.chat.completions.create(
model=model_name,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=2000,
)
elapsed = time.time() - start_time
content = response.choices[0].message.content
usage = response.usage
finish_reason = response.choices[0].finish_reason
return {
"content": content,
"time": elapsed,
"prompt_tokens": usage.prompt_tokens,
"completion_tokens": usage.completion_tokens,
"total_tokens": usage.total_tokens,
"finish_reason": finish_reason,
"error": None,
}
except Exception as e:
elapsed = time.time() - start_time
return {
"content": "",
"time": elapsed,
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"finish_reason": "error",
"error": str(e),
}
def calculate_cost(config, result):
"""计算单次调用成本(¥)"""
if result["error"]:
return 0
input_cost = result["prompt_tokens"] / 1_000_000 * config["input_price"]
output_cost = result["completion_tokens"] / 1_000_000 * config["output_price"]
return round(input_cost + output_cost, 6)
def run_comparison():
"""运行完整对比"""
all_results = {}
for prompt_name, prompt_data in test_prompts.items():
print(f"\n{'=' * 65}")
print(f"测试: {prompt_name}")
print(f"评估标准: {', '.join(prompt_data['eval_criteria'])}")
print(f"{'=' * 65}")
all_results[prompt_name] = {}
for model_name, config in models_config.items():
print(f"\n--- {model_name} ---")
result = call_model(
config["client"],
config["model"],
prompt_data["prompt"]
)
cost = calculate_cost(config, result)
result["cost"] = cost
if result["error"]:
print(f" ❌ 错误: {result['error']}")
else:
print(f" 耗时: {result['time']:.2f}s")
print(f" Token: {result['prompt_tokens']} + {result['completion_tokens']} = {result['total_tokens']}")
print(f" 成本: ¥{cost:.6f}")
print(f" 完成原因: {result['finish_reason']}")
print(f" 输出预览:")
preview = result["content"][:300]
print(f" {preview}")
if len(result["content"]) > 300:
print(f" ...(共 {len(result['content'])} 字符)")
all_results[prompt_name][model_name] = result
return all_results
def print_summary(results):
"""打印汇总对比表"""
print(f"\n\n{'=' * 65}")
print("汇总对比")
print(f"{'=' * 65}")
for prompt_name, model_results in results.items():
print(f"\n【{prompt_name}】")
print(f"{'模型':<15} {'耗时':>8} {'总Token':>10} {'成本(¥)':>12} {'状态':>6}")
print("-" * 55)
for model_name, r in model_results.items():
if r["error"]:
print(f"{model_name:<15} {'ERROR':>8} {'-':>10} {'-':>12} {'✗':>6}")
else:
print(f"{model_name:<15} {r['time']:>7.2f}s {r['total_tokens']:>10} ¥{r['cost']:>10.6f} {'✓':>6}")
# 保存完整结果到文件
save_results(results)
def save_results(results):
"""保存结果到 JSON 文件,方便后续分析"""
output = {}
for prompt_name, model_results in results.items():
output[prompt_name] = {}
for model_name, r in model_results.items():
output[prompt_name][model_name] = {
"time": round(r["time"], 2),
"tokens": r["total_tokens"],
"cost": r["cost"],
"content_length": len(r["content"]),
"error": r["error"],
}
with open("code/day4_results.json", "w", encoding="utf-8") as f:
json.dump(output, f, ensure_ascii=False, indent=2)
print(f"\n详细结果已保存到 code/day4_results.json")
# ============ 运行 ============
if __name__ == "__main__":
results = run_comparison()
print_summary(results)
print(f"\n{'=' * 65}")
print("手动评估指南")
print(f"{'=' * 65}")
print("现在请手动检查每个模型的输出:")
print("1. 代码能否运行?(复制到本地执行)")
print("2. 是否满足评估标准?")
print("3. 输出质量主观评分(1-10)")
print("4. 记录到 notes/day4.md")
print("\n评估标准:")
for name, data in test_prompts.items():
print(f" {name}: {', '.join(data['eval_criteria'])}")
运行:
python code/model_comparison.py
预期输出:
=================================================================
测试: 代码生成
评估标准: 能运行, O(1)复杂度, 有类型注解, 有测试用例
=================================================================
--- DeepSeek-V3 ---
耗时: 3.42s
Token: 156 + 890 = 1046
成本: ¥0.001936
完成原因: stop
输出预览:
```python
from typing import Optional, Dict, Any
from collections import OrderedDict
class LRUCache:
...
...(共 2840 字符)
=================================================================
测试: 中文理解
...
=================================================================
汇总对比
=================================================================
【代码生成】
模型 耗时 总Token 成本(¥) 状态
-------------------------------------------------------
DeepSeek-V3 3.42s 1046 ¥0.001936 ✓
【中文理解】
...
详细结果已保存到 code/day4_results.json
5.4 结果分析(10 分钟)
运行完后,按以下步骤分析:
步骤 1: 代码生成对比
→ 把每个模型的代码复制出来
→ 在本地运行:python -c "粘贴代码"
→ 检查:
□ 能运行吗?
□ get/put 是 O(1) 吗?(用了 OrderedDict 或双向链表+哈希表?)
□ 有类型注解吗?
□ 有测试用例吗?测试能通过吗?
→ 评分 1-10
步骤 2: 中文理解对比
→ 检查:
□ 成语含义准确吗?(网上查一下对照)
□ 造句通顺吗?
□ 格式对吗?
→ 评分 1-10
步骤 3: 逻辑推理对比
→ 标准答案:利用灯泡发热
- 开开关1,等5分钟
- 关开关1,开开关2
- 进房间看:
亮的 → 开关2
不亮但热的 → 开关1
不亮也不热的 → 开关3
→ 检查模型是否推理出"温度"这个关键信息
→ 评分 1-10
步骤 4: 摘要总结对比
→ 检查:
□ 3个要点都涵盖了核心信息?
□ 没有编造信息?
□ 简洁吗?
→ 评分 1-10
步骤 5: 填写对比表
| 维度 | DeepSeek-V3 | Qwen-Plus | GLM-4-Flash | 评分理由 |
|------|-------------|-----------|-------------|---------|
| 代码生成 | __/10 | __/10 | __/10 | ... |
| 中文理解 | __/10 | __/10 | __/10 | ... |
| 逻辑推理 | __/10 | __/10 | __/10 | ... |
| 摘要总结 | __/10 | __/10 | __/10 | ... |
| 速度 | __s | __s | __s | ... |
| 成本 | ¥__ | ¥__ | ¥__ | ... |
| 综合 | __/10 | __/10 | __/10 | ... |
关键发现(运行后验证):
1. 便宜模型 ≠ 质量差
→ DeepSeek 在大部分任务上和 GPT-4o 差距很小
→ 但价格只有 1/30
2. 温度=0 不代表完全一样
→ 不同模型即使 temperature=0,输出也不同
→ 因为模型权重、训练数据不同
3. Token 消耗差异大
→ 同一个 Prompt,不同模型的 Token 数可能差 2-3 倍
→ 这直接影响成本(Day 3 学的 Token 知识在这里用上了)
4. 速度差异明显
→ GLM-4-Flash 最快(轻量模型)
→ DeepSeek 稍慢但可接受
→ 如果做实时聊天,速度很重要
5. 完成原因要检查
→ finish_reason="stop" 表示正常完成
→ finish_reason="length" 表示被 max_tokens 截断
→ 截断意味着输出不完整,需要加大 max_tokens
6. Part E:成本分析与优化(20 分钟)
这部分帮你建立"成本直觉"。学会算账,才知道该用哪个模型。
6.1 定价模型详解(5 分钟)
API 定价的基本规则:
1. 输入和输出分别计费
→ 输入(Prompt Token): 你发给模型的内容
→ 输出(Completion Token): 模型生成的内容
→ 输出通常比输入贵 2-5 倍(因为生成比理解更耗算力)
2. 按百万 Token 计价
→ 价格单位: ¥/百万 token 或 $/百万 token
→ 1 百万 token ≈ 50-75 万字中文
3. 有些模型有缓存折扣
→ 如果 Prompt 前缀和上次一样,缓存命中,输入价格打折
→ DeepSeek 缓存命中: 输入价格降到 ¥0.1/百万token
→ 适合: System Prompt 固定 + 变化用户输入的场景
4. 有些模型有免费额度
→ GLM-4-Flash: 完全免费
→ 阿里百炼: 新用户有免费 token
→ DeepSeek: 新用户有赠送额度
各模型定价对比(2026 年,可能变化):
模型 输入(¥/百万tok) 输出(¥/百万tok) 备注
─────────────────────────────────────────────────────
DeepSeek-V3 1 2 缓存命中输入¥0.1
Qwen-Plus 0.8 2
Qwen-Turbo 0.3 0.6 最便宜的之一
Qwen-Max 20 60 贵但质量高
GLM-4 5 5 输入输出同价
GLM-4-Flash 0 0 免费!
Kimi 12 12
─────────────────────────────────────────────────────
GPT-4o ~18 ~72 ($2.5/$10)
GPT-4o-mini ~1 ~4 ($0.15/$0.6)
Claude 3.5 Sonnet ~22 ~108 ($3/$15)
Claude 3.5 Haiku ~6 ~30 ($0.8/$4)
Gemini 1.5 Pro ~9 ~36 ($1.25/$5)
Gemini 1.5 Flash ~0.5 ~1.5 极便宜
直观对比(输出价格/百万token):
GLM-4-Flash ¥0 ▏
Qwen-Turbo ¥0.6 ▏
DeepSeek-V3 ¥2 █
GPT-4o-mini ¥4 ██
GLM-4 ¥5 ██▌
Gemini Flash ¥1.5 █
GPT-4o ¥72 ████████████████████████████████
Claude 3.5 ¥108 ████████████████████████████████████████████████
→ Claude 3.5 比 DeepSeek 贵 54 倍!
→ 这就是为什么"选对模型"直接决定你的项目能不能活下去
6.2 月成本估算公式(5 分钟)
月成本 = 日均调用次数 × (平均输入token × 输入单价 + 平均输出token × 输出单价) × 30
────────────────────────────────────────────────────────────
1,000,000
实例计算:
场景 1: 个人学习项目
日均: 50 次调用
平均输入: 500 token
平均输出: 800 token
DeepSeek: 50 × (500×1 + 800×2) / 1M × 30 = 50 × 0.0021 × 30 = ¥3.15/月
GPT-4o: 50 × (500×18 + 800×72) / 1M × 30 = 50 × 0.0666 × 30 = ¥99.9/月
Claude: 50 × (500×22 + 800×108) / 1M × 30 = 50 × 0.0974 × 30 = ¥146.1/月
→ 个人项目用 DeepSeek 每月 ¥3,完全无压力
场景 2: 小型客服 Agent
日均: 5,000 次调用
平均输入: 1000 token(含 System Prompt)
平均输出: 500 token
DeepSeek: 5000 × (1000×1 + 500×2) / 1M × 30 = 5000 × 0.002 × 30 = ¥300/月
GPT-4o: 5000 × (1000×18 + 500×72) / 1M × 30 = 5000 × 0.054 × 30 = ¥8,100/月
Qwen-Turbo: 5000 × (1000×0.3 + 500×0.6) / 1M × 30 = 5000 × 0.0006 × 30 = ¥90/月
→ 客服场景用 GPT-4o 每月 ¥8,100,用 Qwen-Turbo 只要 ¥90
→ 差 90 倍!这就是为什么大调用量场景必须选便宜模型
场景 3: 文档分析 Agent
日均: 100 次调用
平均输入: 50,000 token(长文档)
平均输出: 2,000 token(分析报告)
DeepSeek: 100 × (50000×1 + 2000×2) / 1M × 30 = 100 × 0.054 × 30 = ¥162/月
Claude: 100 × (50000×22 + 2000×108) / 1M × 30 = 100 × 1.316 × 30 = ¥3,948/月
Gemini: 100 × (50000×9 + 2000×36) / 1M × 30 = 100 × 0.522 × 30 = ¥1,566/月
→ 长文档场景成本暴增(因为输入 token 多)
→ 如果需要 50 万字上下文,只有 Gemini 1M 能做
6.3 五个省钱策略(10 分钟)
策略 1: 分层路由——简单任务用便宜模型(最重要!)
用户输入 → 判断复杂度
├─ 简单(分类/提取/闲聊)→ DeepSeek / Qwen-Turbo
└─ 复杂(推理/代码/分析)→ Claude / GPT-4o
效果: 假设 80% 的请求是简单的
→ 80% 用 DeepSeek(¥2/百万输出)
→ 20% 用 Claude(¥108/百万输出)
→ 混合成本: ¥2×0.8 + ¥108×0.2 = ¥23.2/百万输出
→ 比纯 Claude 省 78%
→ 这就是 Part F 模型路由器的原理!
策略 2: 缓存——相同请求不重复调用
场景: 用户问"什么是 RAG",100 个人问了一模一样的问题
→ 不缓存: 调用 100 次 API
→ 缓存: 调用 1 次,其余 99 次返回缓存
实现方式:
→ 简单: 用字典/Redis 缓存 (hash(prompt) → response)
→ 高级: 利用 DeepSeek 的 Prefix Caching(System Prompt 部分缓存打折)
策略 3: Prompt 压缩——减少输入 Token
方法:
→ 去掉不必要的客套话("请你帮我..." → 直接说做什么)
→ 用简洁的指令格式("步骤:1. 2. 3." 而不是大段描述)
→ Day 3 学过: 中文 Prompt 压缩能省 72-82% 的 token
→ System Prompt 只放必要的规则
效果: 输入从 2000 token 压到 500 token → 成本降 75%
策略 4: 限制输出长度——减少输出 Token
方法:
→ 设 max_tokens 限制最大输出
→ 在 Prompt 中要求简洁回答("用 100 字以内回答")
→ 要求结构化输出(JSON 比自然语言短)
效果: 输出从 1000 token 降到 300 token → 成本降 70%
→ 注意: 输出比输入贵,所以减少输出更省钱
策略 5: 批处理——合并多个请求
场景: 要对 100 条评论做情感分析
→ 逐条: 100 次 API 调用
→ 批量: 1 次调用处理 20 条 → 5 次调用
实现:
prompt = "请对以下评论做情感分析(正面/负面/中性),输出 JSON:
1. 评论内容1
2. 评论内容2
...
20. 评论内容20"
效果: 调用次数减少 80%,System Prompt 只发 5 次而不是 100 次
成本优化效果汇总:
策略 节省幅度 实现难度 推荐优先级
──────────────────────────────────────────────────
分层路由 60-80% 中 ★★★★★
缓存 30-90% 低 ★★★★★
Prompt 压缩 40-75% 低 ★★★★☆
限制输出长度 50-70% 极低 ★★★★☆
批处理 50-80% 中 ★★★☆☆
→ 先做最简单的(限制输出 + Prompt 压缩)
→ 再做最有效的(分层路由 + 缓存)
→ 最后做批处理(需要改代码架构)
7. Part F:综合实验——模型路由器(20 分钟)
这是今天最重要的实验。模型路由器是 Agent 系统的核心组件——根据任务类型自动选择最合适的模型,在质量和成本之间做最优平衡。
7.1 设计思路(5 分钟)
模型路由器的工作流程:
用户输入
│
▼
┌──────────────┐
│ 任务分类器 │ ← 用最便宜的模型判断任务类型
│ (GLM-4-Flash│ (免费模型做分类,成本几乎为零)
│ / Qwen-Tur)│
└──────┬───────┘
│
┌────┴────┐
│ 任务类型 │
├─────────┤
│ 代码生成 │ → Claude 3.5 Sonnet / DeepSeek-V3
│ 逻辑推理 │ → DeepSeek-R1 / o1
│ 简单问答 │ → DeepSeek-V3 / Qwen-Turbo
│ 文本摘要 │ → Qwen-Turbo / GPT-4o-mini
│ 数据提取 │ → GPT-4o-mini / Qwen-Turbo
└─────────┘
│
▼
┌──────────────┐
│ 执行模型 │ ← 用选定的模型处理任务
│ (按路由结果) │
└──────┬───────┘
│
▼
返回结果 + 记录成本
7.2 完整实现(15 分钟)
创建 code/model_router.py:
"""
Day 4 综合实验: 模型路由器
根据任务类型自动选择最合适的模型,平衡质量和成本
"""
import os
import time
import json
from enum import Enum
from dataclasses import dataclass, field
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
# ============ 模型配置 ============
class ModelTier(Enum):
"""模型档位"""
FREE = "free" # 免费/极便宜
CHEAP = "cheap" # 便宜
MID = "mid" # 中档
PREMIUM = "premium" # 旗舰
@dataclass
class ModelConfig:
"""单个模型的配置"""
name: str # 显示名称
model_id: str # API 模型名
client: OpenAI # API 客户端
tier: ModelTier # 档位
input_price: float # 输入价格 ¥/百万token
output_price: float # 输出价格 ¥/百万token
max_tokens: int = 2000 # 默认最大输出
# 根据你有的 API Key 配置模型
def get_available_models():
models = {}
if os.getenv("DEEPSEEK_API_KEY"):
models["deepseek"] = ModelConfig(
name="DeepSeek-V3",
model_id="deepseek-chat",
client=OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
),
tier=ModelTier.CHEAP,
input_price=1,
output_price=2,
)
if os.getenv("DASHSCOPE_API_KEY"):
models["qwen_turbo"] = ModelConfig(
name="Qwen-Turbo",
model_id="qwen-turbo",
client=OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
),
tier=ModelTier.CHEAP,
input_price=0.3,
output_price=0.6,
)
if os.getenv("ZHIPU_API_KEY"):
models["glm_flash"] = ModelConfig(
name="GLM-4-Flash",
model_id="glm-4-flash",
client=OpenAI(
api_key=os.getenv("ZHIPU_API_KEY"),
base_url="https://open.bigmodel.cn/api/paas/v4"
),
tier=ModelTier.FREE,
input_price=0,
output_price=0,
)
return models
# ============ 任务类型定义 ============
class TaskType(Enum):
"""任务类型"""
CODE = "代码生成/Debug"
REASONING = "逻辑推理/数学"
CHAT = "日常对话/问答"
SUMMARY = "文本摘要/总结"
EXTRACTION = "信息提取/分类"
CREATIVE = "创意写作"
UNKNOWN = "未分类"
# 任务→模型档位 路由表
TASK_MODEL_ROUTING = {
TaskType.CODE: ModelTier.MID, # 代码需要质量
TaskType.REASONING: ModelTier.MID, # 推理需要质量
TaskType.CHAT: ModelTier.CHEAP, # 日常对话用便宜的
TaskType.SUMMARY: ModelTier.CHEAP, # 摘要便宜的就够
TaskType.EXTRACTION: ModelTier.CHEAP,# 提取便宜的就够
TaskType.CREATIVE: ModelTier.MID, # 创意需要质量
TaskType.UNKNOWN: ModelTier.CHEAP, # 默认用便宜的
}
# ============ 模型路由器 ============
@dataclass
class CallRecord:
"""单次调用记录"""
user_input: str
task_type: TaskType
model_used: str
response: str
time: float
tokens_in: int
tokens_out: int
cost: float
class ModelRouter:
"""模型路由器:根据任务类型选择最合适的模型"""
def __init__(self):
self.models = get_available_models()
self.call_history: list[CallRecord] = []
if not self.models:
raise RuntimeError("没有可用的模型!请检查 .env 中的 API Key")
print(f"模型路由器已初始化,可用模型:")
for key, m in self.models.items():
print(f" - {m.name} ({m.tier.value}) ¥{m.input_price}/{m.output_price} per Mtok")
print()
def _classify_task(self, user_input: str) -> TaskType:
"""用最便宜的模型做任务分类"""
# 找一个免费/便宜的模型做分类
classifier = None
for tier_priority in [ModelTier.FREE, ModelTier.CHEAP, ModelTier.MID]:
for m in self.models.values():
if m.tier == tier_priority:
classifier = m
break
if classifier:
break
if not classifier:
return TaskType.UNKNOWN
classify_prompt = f"""请判断以下用户输入属于哪个任务类型,只输出类型名称,不要解释:
- 代码生成/Debug(写代码、改代码、编程问题)
- 逻辑推理/数学(数学题、逻辑谜题、多步推理)
- 日常对话/问答(闲聊、知识问答、咨询)
- 文本摘要/总结(总结、缩写、提炼要点)
- 信息提取/分类(从文本中提取信息、分类、打标签)
- 创意写作(写故事、写文案、写诗)
用户输入: {user_input[:200]}
任务类型:"""
try:
response = classifier.client.chat.completions.create(
model=classifier.model_id,
messages=[{"role": "user", "content": classify_prompt}],
temperature=0,
max_tokens=20,
)
result = response.choices[0].message.content.strip()
# 匹配任务类型
for task_type in TaskType:
if task_type.value in result or result in task_type.value:
return task_type
return TaskType.UNKNOWN
except Exception:
return TaskType.UNKNOWN
def _select_model(self, task_type: TaskType) -> ModelConfig:
"""根据任务类型选择模型"""
target_tier = TASK_MODEL_ROUTING.get(task_type, ModelTier.CHEAP)
# 按优先级找对应档位的模型
# 优先精确匹配档位,没有就降级
tier_fallback = {
ModelTier.PREMIUM: [ModelTier.PREMIUM, ModelTier.MID, ModelTier.CHEAP, ModelTier.FREE],
ModelTier.MID: [ModelTier.MID, ModelTier.CHEAP, ModelTier.FREE],
ModelTier.CHEAP: [ModelTier.CHEAP, ModelTier.FREE, ModelTier.MID],
ModelTier.FREE: [ModelTier.FREE, ModelTier.CHEAP, ModelTier.MID],
}
for tier in tier_fallback.get(target_tier, [ModelTier.CHEAP]):
for m in self.models.values():
if m.tier == tier:
return m
# 兜底:返回第一个可用模型
return list(self.models.values())[0]
def chat(self, user_input: str, force_model: str = None) -> str:
"""
路由器主入口
force_model: 强制使用某个模型(跳过路由)
"""
print(f"用户: {user_input}")
# 步骤 1: 任务分类
task_type = self._classify_task(user_input)
print(f"任务分类: {task_type.value}")
# 步骤 2: 模型选择
if force_model and force_model in self.models:
model = self.models[force_model]
print(f"模型选择: {model.name} (强制指定)")
else:
model = self._select_model(task_type)
print(f"模型选择: {model.name} ({model.tier.value}档)")
# 步骤 3: 调用模型
start_time = time.time()
try:
response = model.client.chat.completions.create(
model=model.model_id,
messages=[{"role": "user", "content": user_input}],
temperature=0,
max_tokens=model.max_tokens,
)
elapsed = time.time() - start_time
content = response.choices[0].message.content
usage = response.usage
# 计算成本
cost = (
usage.prompt_tokens / 1_000_000 * model.input_price +
usage.completion_tokens / 1_000_000 * model.output_price
)
# 记录
record = CallRecord(
user_input=user_input,
task_type=task_type,
model_used=model.name,
response=content,
time=elapsed,
tokens_in=usage.prompt_tokens,
tokens_out=usage.completion_tokens,
cost=cost,
)
self.call_history.append(record)
print(f"耗时: {elapsed:.2f}s | Token: {usage.total_tokens} | 成本: ¥{cost:.6f}")
print(f"回复: {content[:200]}...")
print()
return content
except Exception as e:
print(f"错误: {e}")
return f"错误: {e}"
def stats(self):
"""显示使用统计"""
print(f"\n{'=' * 60}")
print(f"路由器使用统计")
print(f"{'=' * 60}")
if not self.call_history:
print(" 暂无调用记录")
return
total_calls = len(self.call_history)
total_cost = sum(r.cost for r in self.call_history)
total_tokens = sum(r.tokens_in + r.tokens_out for r in self.call_history)
avg_time = sum(r.time for r in self.call_history) / total_calls
print(f" 总调用次数: {total_calls}")
print(f" 总成本: ¥{total_cost:.4f}")
print(f" 总 Token: {total_tokens}")
print(f" 平均耗时: {avg_time:.2f}s")
# 按任务类型统计
print(f"\n 按任务类型:")
task_stats = {}
for r in self.call_history:
if r.task_type.value not in task_stats:
task_stats[r.task_type.value] = {"count": 0, "cost": 0}
task_stats[r.task_type.value]["count"] += 1
task_stats[r.task_type.value]["cost"] += r.cost
for task, stats in task_stats.items():
print(f" {task}: {stats['count']}次, ¥{stats['cost']:.4f}")
# 按模型统计
print(f"\n 按模型:")
model_stats = {}
for r in self.call_history:
if r.model_used not in model_stats:
model_stats[r.model_used] = {"count": 0, "cost": 0}
model_stats[r.model_used]["count"] += 1
model_stats[r.model_used]["cost"] += r.cost
for model, stats in model_stats.items():
print(f" {model}: {stats['count']}次, ¥{stats['cost']:.4f}")
# ============ 运行测试 ============
if __name__ == "__main__":
router = ModelRouter()
# 模拟不同类型的用户输入
test_inputs = [
"用 Python 写一个快速排序函数,带注释", # 代码生成
"一个水池有两个管子,一个进水一个出水。进水管每小时注 3 吨,出水管每小时排 2 吨。水池容量 10 吨,空池开始,几小时注满?", # 逻辑推理
"今天天气怎么样?", # 日常对话
"请把这段话总结为3个要点:人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。", # 摘要
"从以下文本中提取人名和地点:张三昨天去了北京出差,李四留在上海。", # 信息提取
"写一首关于编程的短诗", # 创意写作
]
for user_input in test_inputs:
router.chat(user_input)
# 显示统计
router.stats()
print(f"\n{'=' * 60}")
print("实验总结")
print(f"{'=' * 60}")
print("1. 路由器自动识别了不同任务类型")
print("2. 简单任务(问答/摘要/提取)用了便宜模型")
print("3. 复杂任务(代码/推理)用了更强的模型")
print("4. 整体成本远低于'全部用旗舰模型'")
print("5. 这就是 Agent 系统中'模型路由'的核心原理")
print("\n下一步: 你可以加入更多模型、更精细的路由规则")
print("→ 比如根据输入长度路由(短文本用便宜模型,长文本用大上下文模型)")
print("→ 比如根据用户等级路由(免费用户用便宜模型,付费用户用旗舰)")
运行:
python code/model_router.py
预期输出:
模型路由器已初始化,可用模型:
- DeepSeek-V3 (cheap) ¥1/2 per Mtok
- GLM-4-Flash (free) ¥0/0 per Mtok
用户: 用 Python 写一个快速排序函数,带注释
任务分类: 代码生成/Debug
模型选择: DeepSeek-V3 (cheap档)
耗时: 3.21s | Token: 45 + 320 = 365 | 成本: ¥0.000685
回复: ```python
def quicksort(arr):
...
用户: 一个水池有两个管子...
任务分类: 逻辑推理/数学
模型选择: DeepSeek-V3 (cheap档)
耗时: 4.15s | Token: 80 + 450 = 530 | 成本: ¥0.000980
回复: 让我们一步一步来计算...
用户: 今天天气怎么样?
任务分类: 日常对话/问答
模型选择: GLM-4-Flash (free档)
耗时: 1.12s | Token: 20 + 50 = 70 | 成本: ¥0.000000
回复: 作为一个AI,我无法获取实时天气信息...
...
============================================================
路由器使用统计
============================================================
总调用次数: 6
总成本: ¥0.002xxx
总 Token: xxxx
平均耗时: 2.xx s
按任务类型:
代码生成/Debug: 1次, ¥0.000685
逻辑推理/数学: 1次, ¥0.000980
日常对话/问答: 1次, ¥0.000000
文本摘要/总结: 1次, ¥0.000000
信息提取/分类: 1次, ¥0.000xxx
创意写作: 1次, ¥0.000xxx
按模型:
GLM-4-Flash: 3次, ¥0.000000
DeepSeek-V3: 3次, ¥0.002xxx
实验总结
1. 路由器自动识别了不同任务类型
2. 简单任务(问答/摘要/提取)用了免费模型
3. 复杂任务(代码/推理)用了更强的模型
4. 整体成本远低于'全部用旗舰模型'
5. 这就是 Agent 系统中'模型路由'的核心原理
实验后思考:
1. 如果你有 Claude 3.5 和 DeepSeek 两个模型
路由器应该怎么配?哪些任务给 Claude,哪些给 DeepSeek?
2. 分类器本身也会消耗 token
→ 如果用户请求很简单(如"你好"),分类器的成本可能比执行还高
→ 怎么优化?(提示:先做规则匹配,匹配不到再调分类器)
3. 路由器的分类不一定准确
→ 如果分类错了(把代码任务分给了便宜模型)怎么办?
→ 提示:可以加一个"质量检测"环节,如果输出太短或质量低,自动升级模型重试
4. 实际生产中的路由策略:
→ 基于规则: 输入包含"代码/code/python" → 代码模型
→ 基于长度: 输入 > 10000 token → 长文本模型
→ 基于用户: VIP 用户 → 旗舰模型,免费用户 → 便宜模型
→ 基于时间: 高峰期 → 便宜模型(降本),低峰期 → 旗舰模型(提质)
8. 今日笔记模板
创建 notes/day4.md:
# Day 4 笔记:主流大模型对比与选择
日期:____
学习时长:____
## 市场全景
- 三大阵营:
- 闭源 vs 开源的核心 tradeoff:
- 我的选择倾向:
## 模型对比表(填入你的实测数据)
| 模型 | 代码生成 | 中文理解 | 逻辑推理 | 摘要 | 速度 | 成本 |
|------|---------|---------|---------|------|------|------|
| | /10 | /10 | /10 | /10 | __s | ¥__ |
| | /10 | /10 | /10 | /10 | __s | ¥__ |
## 我的模型选择决策
1. 日常开发默认用:
2. 写代码用:
3. 处理长文档用:
4. 大量调用时用:
5. 免费调试用:
## 成本估算
我的项目场景:____
日均调用次数:____
月成本估算:
- 用 DeepSeek:¥__
- 用 GPT-4o:¥__
- 用混合路由:¥__
## 模型路由器实验记录
| 用户输入 | 分类结果 | 选用模型 | 耗时 | 成本 | 备注 |
|---------|---------|---------|------|------|------|
| | | | | | |
| | | | | | |
## 五个省钱策略
1.
2.
3.
4.
5.
## 还不清楚的点
-
-
## 明天的问题
-
9. 验收清单
概念验收
- 能说出三大阵营和各自代表模型
- 理解闭源 vs 开源的核心 tradeoff
- 知道评估模型的六个维度
- 能解释为什么输出比输入贵
- 能读懂模型命名规则(gpt-4o / claude-3-5-sonnet / deepseek-reasoner)
- 理解 API 兼容格式(OpenAI 兼容)的意义
- 能说出至少 3 个省钱策略
代码验收
-
model_comparison.py运行成功,记录了多模型对比数据 -
model_router.py运行成功,路由器能自动分类任务并选模型 - 手动评估了各模型的输出质量(1-10 评分)
-
day4_results.json保存了对比结果
产出验收
-
notes/day4.md写完,包含对比表和决策 - 2 个脚本推送到 GitHub(model_comparison / model_router)
- 有自己的"模型选择决策表"
- 能回答"这个场景该用什么模型"(5 秒内决策)
10. 常见问题 FAQ
Q1: 我只有 DeepSeek 的 Key,怎么做多模型对比?
A: 注册智谱(GLM-4-Flash 免费)和阿里百炼(有免费额度),这样就有 3 个模型可以对比。注册很快,不需要付费。如果你有 OpenAI 的 Key 更好,可以加入 GPT-4o 对比。
Q2: 为什么同一个 Prompt 不同模型的 Token 数不一样?
A: 因为不同模型用不同的分词器(Day 3 学过)。同一段文本,DeepSeek 的分词器和 Qwen 的分词器切出来的 Token 数不同。这直接影响成本——Token 少的模型更省钱。
Q3: DeepSeek 和 GPT-4o 的质量差距到底有多大?
A: 在日常开发任务(代码生成、问答、摘要)上,差距很小(5-10%)。在复杂推理、多语言混合、创意写作上,GPT-4o 略好。但对于 95% 的个人项目和中小项目,DeepSeek 完全够用。关键是用 1/30 的价格拿到 90%+ 的质量,性价比极高。
Q4: 模型会不定期更新,怎么跟得上?
A: 三个策略:
- 关注各平台的公告/公众号(DeepSeek、阿里、智谱都有公众号)
- 关注 HuggingFace 排行榜(看开源模型排名变化)
- 实际项目中用
model_comparison.py定期跑一遍,用数据说话 - 不需要追最新模型——如果当前模型够用,就不要换。线上项目换模型要充分测试。
Q5: 模型路由器的分类准确率不高怎么办?
A: 三层优化:
- 先做规则匹配(输入含"代码/python/function" → 代码任务,零成本零延迟)
- 规则匹配不到再调分类器模型
- 加质量检测:如果输出太短或 finish_reason=length,自动升级模型重试
实际生产中,规则匹配能处理 50-70% 的请求,剩下的才需要分类器。
Q6: 缓存怎么实现?用户问法不同但意思一样怎么办?
A: 简单缓存用 hash(prompt) → response 字典,完全匹配才命中。语义缓存需要用 Embedding(Day 3 学的)——把用户输入做 Embedding,和缓存的 Embedding 比相似度,超过阈值就返回缓存。语义缓存更复杂但效果更好,后续项目阶段会实现。
Q7: 开源模型什么时候该考虑?
A: 三个信号:
- 月 API 费用 > ¥2000(自己部署可能更便宜)
- 数据合规要求不能发第三方(医疗/金融)
- 需要离线运行(网络不稳定的环境)
如果月费用 < ¥500,别折腾部署,API 更划算。部署一个 7B 模型需要至少 8GB 显存的 GPU,电费+硬件折旧不低。
Q8: 国内模型和海外模型的差距会缩小吗?
A: 趋势上看在缩小。DeepSeek-V3 在很多 benchmark 上已经接近 GPT-4o,某些中文任务甚至更好。开源的 Qwen2.5 和 DeepSeek 在国际排行榜上表现优秀。但 OpenAI 和 Anthropic 仍在快速迭代(o 系列、多模态等),差距是否完全消除取决于多方面因素。对开发者来说,关注实际任务表现比关注排名更重要。
11. 扩展资源
必看
| 资源 | 类型 | 时长 | 价值 |
|---|---|---|---|
| DeepSeek 定价页 | 文档 | 5 min | 确认最新价格 |
| 阿里百炼模型列表 | 文档 | 5 min | 了解 Qwen 全系列 |
| OpenAI 模型文档 | 文档 | 10 min | 了解 GPT 系列 |
| LMSYS Chatbot Arena | 在线工具 | 10 min | 看模型实时排名(众包评测) |
推荐
| 资源 | 类型 | 时长 | 价值 |
|---|---|---|---|
| 智谱 GLM 定价 | 文档 | 5 min | 免费模型详情 |
| Anthropic 定价页 | 文档 | 5 min | Claude 系列价格 |
| Google Gemini 定价 | 文档 | 5 min | Gemini 系列价格 |
| DeepSeek API 文档 | 文档 | 15 min | Prefix Caching 等高级特性 |
可选
| 资源 | 类型 | 时长 | 价值 |
|---|---|---|---|
| HuggingFace Open LLM Leaderboard | 排行榜 | 15 min | 开源模型排名 |
| Ollama 官网 | 工具 | 10 min | 本地跑开源模型最简单的工具 |
| OpenAI Cookbook | 代码 | 30 min | 官方最佳实践 |
在线工具
- LMSYS Arena: https://chat.lmsys.org — 模型盲测对战平台,看真实排名
- DeepSeek 定价: https://api-docs.deepseek.com/zh-cn/quick_start/pricing
- 阿里百炼: https://help.aliyun.com/zh/model-studio/getting-started
- OpenAI Tokenizer: https://platform.openai.com/tokenizer
12. 核心概念速查卡
┌─────────────────────────────────────────────────────────────┐
│ Day 4 核心概念速查卡 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 三大阵营 │
│ ├─ 海外闭源: OpenAI(GPT) / Anthropic(Claude) / Google(Gemini)│
│ ├─ 国内闭源: DeepSeek / 阿里(Qwen) / 智谱(GLM) / Kimi │
│ └─ 开源: Llama / Qwen开源 / DeepSeek开源 │
│ │
│ 六维度评估 │
│ ├─ 推理: o1 > Claude > GPT-4o > DeepSeek-R1 │
│ ├─ 代码: Claude 3.5 > GPT-4o > DeepSeek-V3 │
│ ├─ 中文: DeepSeek > Qwen > GLM > GPT-4o │
│ ├─ 多模态: GPT-4o > Claude > Gemini > Qwen-VL │
│ ├─ 长文本: Gemini(1M) > Claude(200K) > GPT-4o(128K) │
│ └─ 成本: GLM-Flash(免费) > DeepSeek > Qwen-Turbo > GPT-4o │
│ │
│ 默认选择 │
│ ├─ 个人项目: DeepSeek-V3(性价比之王) │
│ ├─ 代码任务: Claude 3.5 Sonnet(代码最强) │
│ ├─ 长文档: Gemini 1.5 Pro(1M 上下文) │
│ ├─ 免费调试: GLM-4-Flash(完全免费) │
│ └─ 不确定: 先用便宜的,质量不够再升级 │
│ │
│ 成本公式 │
│ ├─ 月成本 = 日调用 × (输入tok×输入价 + 输出tok×输出价) × 30 │
│ ├─ 输出比输入贵 2-5 倍 │
│ ├─ DeepSeek 比 GPT-4o 便宜 ~30 倍 │
│ └─ 80% 请求用便宜模型 → 省 60-80% 成本 │
│ │
│ 五个省钱策略 │
│ ├─ 分层路由: 简单→便宜,复杂→旗舰(省 60-80%) │
│ ├─ 缓存: 相同请求不重复调用(省 30-90%) │
│ ├─ Prompt 压缩: 去废话,简洁指令(省 40-75%) │
│ ├─ 限制输出: max_tokens + 要求简洁(省 50-70%) │
│ └─ 批处理: 合并多个请求(省 50-80%) │
│ │
│ API 兼容 │
│ ├─ OpenAI 格式 = 事实标准 │
│ ├─ 换模型只改 api_key + base_url + model 名 │
│ └─ 代码几乎不用改 │
│ │
│ 速记口诀 │
│ ├─ 选模型: "够用就好,不是越贵越好" │
│ ├─ 省钱: "简单任务用便宜的,复杂任务才上旗舰" │
│ ├─ 路由: "先分类,再选模型,最后执行" │
│ └─ 成本: "输入省着给,输出限制长,请求做缓存" │
│ │
└─────────────────────────────────────────────────────────────┘
13. 明日预告
Day 5:温度、Top-P 与采样策略
明天你将:
- 深入理解 Temperature 的数学原理(不只是"调创意度")
- 理解 Top-P(核采样)和 Top-K 采样
- 知道为什么 Temperature 和 Top-P 通常只调一个
- 用代码做参数对比实验:同一 Prompt,不同参数组合
- 建立不同场景的参数选择决策表
今天和明天的关系:
- 今天你学会了选"用哪个模型"
- 明天你学会调"模型的参数"
- 选对模型 + 调对参数 = 在质量和可控性之间做最优平衡
- Day 5 的参数实验会用到今天的 model_comparison.py 框架
预习建议:
- 回顾 Day 2 讲的 Softmax(Temperature 本质上是在调 Softmax 的"锐度")
- 在 DeepSeek Playground 里试试不同 Temperature 的效果
- 想想:为什么代码生成要用 Temperature=0?创意写作要用高 Temperature?
时间安排建议
| 模式 | 安排 | 适合 |
|---|---|---|
| 一次性学完 | 约 2.5-3 小时 | 周末/有大块时间 |
| 分两次 | Day 4a: Part A-D(2h)+ Day 4b: Part E-F(1h) | 工作日晚上 |
| 分三次 | Part A-B / Part C-D / Part E-F | 每次 50-60 分钟 |
| 纯概念 | 只看 Part A-C,跳过代码 | 先建立框架,代码周末补 |
| 速览模式 | 只看速查卡 + 决策树,代码有需要再跑 | 已有基础,快速回顾 |
更多推荐



所有评论(0)