选型的核心矛盾
模型选型的本质是在多个维度之间找到最佳平衡点:
质量 ←→ 成本
速度 ←→ 准确性
隐私 ←→ 便利性
灵活性 ←→ 稳定性
没有”最好的模型”,只有”最适合的模型”。一个客服机器人和一个代码助手,对模型的需求完全不同。
选型框架:五个维度
维度 1:任务类型
不同任务对模型能力的要求差异很大:
| 任务类型 | 核心需求 | 推荐模型层级 |
|---|---|---|
| 文本分类 | 理解能力 | 小模型(1-7B)或 API mini |
| 信息提取 | 精确度 | 中等模型(7-14B)或 API 标准 |
| 代码生成 | 推理 + 知识 | 中大模型(14B+)或 API 标准/旗舰 |
| 创意写作 | 生成质量 | 大模型(70B+)或 API 旗舰 |
| 数学推理 | 逻辑推理 | 推理模型(o3)或专精模型 |
| 多轮对话 | 上下文理解 | 中大模型,长上下文 |
| 文档问答 | 长上下文 + 理解 | 长上下文模型 |
| 实时翻译 | 速度 + 质量 | 中等模型,低延迟 |
维度 2:质量要求
# 质量等级定义
quality_levels = {
"可接受": {
"描述": "基本完成任务,允许偶尔出错",
"场景": "内部工具、草稿生成、数据预处理",
"推荐": "小模型 / API mini 版本",
},
"良好": {
"描述": "大多数情况下输出质量高",
"场景": "客服、内容辅助、代码建议",
"推荐": "中等模型 / API 标准版本",
},
"优秀": {
"描述": "几乎所有情况下都表现出色",
"场景": "面向用户的产品、关键业务决策",
"推荐": "大模型 / API 旗舰版本",
},
"极致": {
"描述": "需要最高水平的推理和准确性",
"场景": "医疗、法律、科研",
"推荐": "旗舰模型 + 人工审核",
},
}
维度 3:延迟要求
| 场景 | 可接受延迟 | 推荐方案 |
|---|---|---|
| 实时对话 | < 500ms 首 token | 小模型本地 / API 快速模型 |
| 代码补全 | < 200ms | 本地小模型 |
| 内容生成 | < 3s 首 token | API 标准模型 |
| 批量处理 | 不限 | 任意模型,优化吞吐量 |
| 后台分析 | 分钟级 | 旗舰模型,追求质量 |
// 根据延迟要求选择模型
function selectByLatency(
maxFirstTokenMs: number,
isStreaming: boolean
): ModelRecommendation {
if (maxFirstTokenMs < 200) {
return {
deployment: "local",
model: "phi3:mini 或 qwen2.5:1.5b",
reason: "极低延迟需求,必须本地部署",
};
}
if (maxFirstTokenMs < 500) {
return {
deployment: "api",
model: "Claude Haiku / GPT-4o mini",
reason: "低延迟,使用快速 API 模型",
};
}
if (maxFirstTokenMs < 3000) {
return {
deployment: "api",
model: "Claude Sonnet / GPT-4o",
reason: "标准延迟,使用平衡模型",
};
}
return {
deployment: "api",
model: "Claude Opus / o3",
reason: "延迟不敏感,使用最强模型",
};
}
维度 4:成本预算
def estimate_monthly_cost(
calls_per_day: int,
avg_input_tokens: int,
avg_output_tokens: int,
model_pricing: dict
) -> dict:
"""估算月度成本"""
daily_input = calls_per_day * avg_input_tokens
daily_output = calls_per_day * avg_output_tokens
input_cost = (daily_input / 1_000_000) * model_pricing["input"]
output_cost = (daily_output / 1_000_000) * model_pricing["output"]
daily_cost = input_cost + output_cost
return {
"日成本": round(daily_cost, 2),
"月成本": round(daily_cost * 30, 2),
"年成本": round(daily_cost * 365, 2),
}
# 场景:每天 5000 次调用,平均 500 输入 + 300 输出 tokens
models = {
"Claude Haiku": {"input": 0.80, "output": 4.00},
"Claude Sonnet": {"input": 3.00, "output": 15.00},
"Claude Opus": {"input": 15.00, "output": 75.00},
"GPT-4o mini": {"input": 0.15, "output": 0.60},
"GPT-4o": {"input": 2.50, "output": 10.00},
}
for name, pricing in models.items():
cost = estimate_monthly_cost(5000, 500, 300, pricing)
print(f"{name}: 月成本 ${cost['月成本']}")
# Claude Haiku: 月成本 $240
# Claude Sonnet: 月成本 $900
# Claude Opus: 月成本 $4,500
# GPT-4o mini: 月成本 $38
# GPT-4o: 月成本 $825
维度 5:隐私与合规
| 需求 | 方案 | 模型选择 |
|---|---|---|
| 数据不能出境 | 国内云 / 本地部署 | Qwen、DeepSeek、本地开源 |
| 数据不能离开公司 | 私有部署 | 开源模型 + vLLM |
| 数据不能离开设备 | 边缘部署 | SLM(Phi、Gemma) |
| 无特殊要求 | 云端 API | 任意 |
| 需要审计追踪 | 自建服务 | 开源模型 |
决策树
第一步:明确任务类型
├── 简单任务(分类、提取、审核)
│ └── 预算紧张?
│ ├── 是 → 本地 SLM(Phi-3 mini / Qwen2.5 3B)
│ └── 否 → GPT-4o mini / Claude Haiku
│
├── 中等任务(问答、代码、写作)
│ └── 有隐私要求?
│ ├── 是 → 本地 7B-14B(Qwen2.5 14B / Llama 3.1 8B)
│ └── 否 → Claude Sonnet / GPT-4o
│
├── 复杂任务(推理、分析、研究)
│ └── 需要深度推理?
│ ├── 是 → o3 / Claude Opus (Extended Thinking)
│ └── 否 → Claude Sonnet / GPT-4o
│
└── 专业任务(代码、数学)
└── Qwen2.5-Coder / DeepSeek-Coder / o3-mini
实际选型案例
案例 1:电商客服机器人
需求分析:
- 任务:回答产品问题、处理退换货
- 质量:良好(不能出大错)
- 延迟:< 1s 首 token(实时对话)
- 调用量:每天 2 万次
- 预算:月预算 $500
- 隐私:无特殊要求
选型过程:
1. 排除旗舰模型(预算不够)
2. 排除本地部署(运维成本高)
3. GPT-4o mini:月成本约 $150 ✓
4. Claude Haiku:月成本约 $960 ✗(超预算)
最终选择:GPT-4o mini
备选方案:Claude Haiku(如果预算增加)
案例 2:代码审查工具
需求分析:
- 任务:审查 PR,发现 Bug 和代码质量问题
- 质量:优秀(不能漏掉重要问题)
- 延迟:< 30s(异步处理)
- 调用量:每天 200 次
- 预算:月预算 $2000
- 隐私:代码不能发送到第三方
选型过程:
1. 隐私要求 → 需要本地部署或可信 API
2. 代码理解需要较强能力 → 排除小模型
3. 本地部署 Qwen2.5-Coder 32B:需要 A100 GPU
4. Claude Sonnet(API 数据不用于训练):月成本约 $200
最终选择:Claude Sonnet(如果 API 政策可接受)
备选方案:本地部署 Qwen2.5-Coder 32B
案例 3:移动端离线助手
需求分析:
- 任务:简单问答、文本摘要、翻译
- 质量:可接受
- 延迟:< 500ms
- 隐私:数据不能离开设备
- 设备:手机(8GB RAM)
选型过程:
1. 必须本地运行 → 开源小模型
2. 手机 8GB RAM → 最大 3B 模型(量化后)
3. 需要中文能力 → Qwen2.5 优先
最终选择:Qwen2.5 1.5B(INT4 量化)
备选方案:Phi-3 mini(INT4 量化)
A/B 测试模型
选型不应该只靠理论分析,实际效果需要通过 A/B 测试验证。
interface ABTestConfig {
modelA: string;
modelB: string;
trafficSplit: number; // 0-1, modelA 的流量比例
metrics: string[];
duration: number; // 天数
}
class ModelABTest {
private results: {
model: string;
latency: number;
quality: number;
cost: number;
timestamp: number;
}[] = [];
constructor(private config: ABTestConfig) {}
async route(request: string): Promise<{
response: string;
model: string;
}> {
const useModelA = Math.random() < this.config.trafficSplit;
const model = useModelA ? this.config.modelA : this.config.modelB;
const start = Date.now();
const response = await callModel(model, request);
const latency = Date.now() - start;
this.results.push({
model,
latency,
quality: await evaluateQuality(response),
cost: calculateCost(request, response, model),
timestamp: Date.now(),
});
return { response, model };
}
getReport(): ABTestReport {
const modelAResults = this.results.filter(
r => r.model === this.config.modelA
);
const modelBResults = this.results.filter(
r => r.model === this.config.modelB
);
return {
modelA: {
name: this.config.modelA,
avgLatency: average(modelAResults.map(r => r.latency)),
avgQuality: average(modelAResults.map(r => r.quality)),
totalCost: sum(modelAResults.map(r => r.cost)),
sampleSize: modelAResults.length,
},
modelB: {
name: this.config.modelB,
avgLatency: average(modelBResults.map(r => r.latency)),
avgQuality: average(modelBResults.map(r => r.quality)),
totalCost: sum(modelBResults.map(r => r.cost)),
sampleSize: modelBResults.length,
},
};
}
}
Fallback 策略
生产环境中,单一模型不够可靠。我们需要 Fallback 策略来保证可用性。
interface FallbackConfig {
primary: ModelConfig;
fallbacks: ModelConfig[];
maxRetries: number;
timeoutMs: number;
}
async function callWithFallback(
prompt: string,
config: FallbackConfig
): Promise<{ response: string; model: string; attempt: number }> {
const models = [config.primary, ...config.fallbacks];
for (let i = 0; i < models.length; i++) {
const model = models[i];
try {
const response = await Promise.race([
callModel(model, prompt),
timeout(config.timeoutMs),
]);
return { response, model: model.name, attempt: i + 1 };
} catch (error) {
console.warn(
`模型 ${model.name} 调用失败 (尝试 ${i + 1}/${models.length}):`,
error
);
if (i === models.length - 1) {
throw new Error("所有模型都调用失败");
}
}
}
throw new Error("不应该到达这里");
}
// 使用示例
const result = await callWithFallback(userPrompt, {
primary: { name: "claude-sonnet-4-20250514", provider: "anthropic" },
fallbacks: [
{ name: "gpt-4o", provider: "openai" },
{ name: "qwen2.5:14b", provider: "ollama" }, // 本地兜底
],
maxRetries: 1,
timeoutMs: 10000,
});
Fallback 策略设计原则
| 原则 | 说明 |
|---|---|
| 降级而非失败 | 宁可用较弱的模型也不要返回错误 |
| 本地兜底 | 最后一层 Fallback 用本地模型 |
| 超时控制 | 每层都设置合理的超时时间 |
| 监控告警 | Fallback 触发时发送告警 |
| 成本感知 | Fallback 到更贵的模型时记录成本 |
选型清单
在做最终决策前,用这个清单检查一遍:
功能需求
- 明确了任务类型和复杂度
- 确定了输入输出的语言
- 评估了上下文长度需求
- 确认了是否需要多模态能力
非功能需求
- 确定了延迟要求
- 估算了调用量和成本
- 评估了隐私和合规要求
- 考虑了可用性和 SLA 需求
验证
- 用真实数据测试了候选模型
- 对比了至少 2-3 个候选方案
- 设计了 A/B 测试方案
- 准备了 Fallback 策略
运维
- 建立了成本监控
- 设置了质量监控
- 准备了模型切换方案
- 制定了定期评估计划
总结
模型选型是一个多维度的决策过程,核心是在质量、成本、速度、隐私之间找到平衡:
- 从任务需求出发,不要从模型出发
- 用数据说话,不要凭感觉选择
- 建立 Fallback 机制,不要依赖单一模型
- 持续评估和优化,不要一次选定就不管了
选对模型只是开始,持续优化才是关键。最好的选型策略不是找到完美的模型,而是建立一个能快速适应变化的系统。
相关文章
评论
加载中...
评论
加载中...