独立产品 AI 多模型路由架构:根据请求特征分发到最优模型

📅 发布时间:2026/7/15 21:37:29 👁️ 浏览次数:
独立产品 AI 多模型路由架构:根据请求特征分发到最优模型
独立产品 AI 多模型路由架构根据请求特征分发到最优模型大家好我是蔓蔓。做独立产品最怕的一件事就是 AI API 账单失控。月初我统计了一笔账简单翻译任务用了 GPT-4o月花费 $120代码补全用了 Claude 3.5 Sonnet月花费 $80而这两类任务如果路由到更廉价的模型费用可以降低 70%。多模型路由不是省不省钱的问题是能不能活下去的问题。今天和大家分享我的多模型路由架构设计。一、单一模型的隐性成本为什么不能一个模型打天下许多独立产品在初期会选择一个最强大的模型处理所有 AI 任务这个决策在用户量增长后会暴露三个致命问题问题一成本失控不同复杂度任务的实际模型需求差异巨大任务类型最低可用模型月成本万次调用使用 GPT-4o 成本浪费比率文本摘要gpt-4o-mini$0.60$3050x关键词提取gpt-4o-mini$0.15$746x代码补全codestral$0.80$4050x翻译deepL API$25$1204.8x复杂推理gpt-4o$30$30合理问题二延迟不匹配实时交互场景如输入联想需要 200ms 内的响应而某些任务可以接受 5 秒延迟。使用同一个模型无法兼顾这两类场景。问题三供应商锁定OpenAI 宕机时所有 AI 功能不可用。多供应商路由可以天然实现故障切换。二、多模型路由器的核心架构路由器的核心能力是根据请求的多维特征实时决策最优模型。flowchart TB A[用户请求] -- B[请求特征提取器] B -- C1[任务类型br/分类/生成/翻译/代码] B -- C2[复杂度估算br/token数/上下文长度] B -- C3[延迟要求br/实时/批量/离线] B -- C4[质量要求br/高精度/可接受误差] C1 -- D[路由决策引擎] C2 -- D C3 -- D C4 -- D D -- E{决策逻辑} E --|低成本低延迟| F1[gpt-4o-mini] E --|代码生成| F2[codestral] E --|翻译专用| F3[DeepL API] E --|复杂推理| F4[gpt-4o] E --|长文本处理| F5[claude-3.5-sonnet] F1 -- G[统一响应适配器] F2 -- G F3 -- G F4 -- G F5 -- G G -- H[返回统一格式]请求特征提取// router/feature-extractor.ts interface RequestFeatures { taskType: TaskType; estimatedComplexity: number; // 0-1 inputTokens: number; expectedOutputTokens: number; latencyBudget: number; // ms qualityRequirement: high | medium | low; language: string; } type TaskType | classification | summarization | translation | code_generation | reasoning | creative_writing | chat; function extractFeatures(prompt: string, options?: { preferredLatency?: number; preferredQuality?: high | medium | low; }): RequestFeatures { // 基于 prompt 关键词推断任务类型 const taskType inferTaskType(prompt); return { taskType, estimatedComplexity: estimateComplexity(prompt), inputTokens: estimateTokens(prompt), expectedOutputTokens: estimateOutputTokens(taskType, prompt), latencyBudget: options?.preferredLatency ?? getDefaultLatency(taskType), qualityRequirement: options?.preferredQuality ?? getDefaultQuality(taskType), language: detectLanguage(prompt), }; }三、决策引擎多维加权评分模型路由决策不是一个简单的 if-else 映射而是对候选模型进行多维评分后选择最优。模型能力画像// router/model-profiles.ts interface ModelProfile { name: string; provider: string; costPer1KInput: number; costPer1KOutput: number; avgLatency: number; // ms maxContextLength: number; // 各任务类型的能力评分0-100 capabilities: RecordTaskType, number; // 语言支持评分0-100 languageSupport: Recordstring, number; // 当前健康状态 health: { available: boolean; errorRate: number; // 最近5分钟错误率 currentLatency: number; // 当前实测延迟ms }; } const modelProfiles: ModelProfile[] [ { name: gpt-4o-mini, provider: openai, costPer1KInput: 0.00015, costPer1KOutput: 0.0006, avgLatency: 400, maxContextLength: 128000, capabilities: { classification: 90, summarization: 85, translation: 80, code_generation: 70, reasoning: 65, creative_writing: 75, chat: 85, }, languageSupport: { zh: 90, en: 95, ja: 80, ko: 75 }, health: { available: true, errorRate: 0, currentLatency: 400 }, }, { name: gpt-4o, provider: openai, costPer1KInput: 0.005, costPer1KOutput: 0.015, avgLatency: 800, maxContextLength: 128000, capabilities: { classification: 95, summarization: 92, translation: 90, code_generation: 90, reasoning: 95, creative_writing: 90, chat: 95, }, languageSupport: { zh: 95, en: 98, ja: 85, ko: 80 }, health: { available: true, errorRate: 0, currentLatency: 800 }, }, // ... 更多模型 ];加权评分算法// router/scoring.ts interface RouteDecision { model: ModelProfile; score: number; reasoning: string[]; } function scoreModel( features: RequestFeatures, profile: ModelProfile, weights: RouteWeights ): RouteDecision { const reasoning: string[] []; // 健康检查不健康直接给 0 分 if (!profile.health.available || profile.health.errorRate 0.1) { return { model: profile, score: 0, reasoning: [模型不可用] }; } // 能力评分权重 0.40 const capabilityScore (profile.capabilities[features.taskType] || 50) / 100; // 成本评分权重 0.25 const estimatedCost (features.inputTokens / 1000) * profile.costPer1KInput (features.expectedOutputTokens / 1000) * profile.costPer1KOutput; // 成本越低分越高归一化到 0-1 const maxAcceptableCost 0.05; const costScore Math.max(0, 1 - estimatedCost / maxAcceptableCost); reasoning.push(预估成本 $${estimatedCost.toFixed(4)}); // 延迟评分权重 0.20 const latencyScore profile.health.currentLatency features.latencyBudget ? 1 : 0.2; // 语言支持评分权重 0.10 const languageScore (profile.languageSupport[features.language] || 60) / 100; // 上下文长度检查权重 0.05 const contextScore features.inputTokens profile.maxContextLength ? 1 : 0; const score capabilityScore * 0.40 costScore * 0.25 latencyScore * 0.20 languageScore * 0.10 contextScore * 0.05; return { model: profile, score: Math.round(score * 100) / 100, reasoning, }; }降级与回退策略// router/fallback.ts async function routeWithFallback( features: RequestFeatures ): PromiseModelProfile { // 主路由 const ranked rankModels(features); const primary ranked[0]; if (primary.score 0.3) { throw new Error(无可用模型满足请求要求); } try { // 尝试主模型 await testModelHealth(primary.model); return primary.model; } catch { // 回退到次选模型 for (const candidate of ranked.slice(1)) { if (candidate.score 0.3) break; try { await testModelHealth(candidate.model); return candidate.model; } catch { continue; } } throw new Error(所有模型均不可用); } }踩坑评分权重在不同产品阶段的失效问题加权评分模型中weights参数的选择直接影响路由质量。在实际运营中发现一个关键问题早期和成长期需要完全不同的权重配置。产品初期只有几十个用户时质量是唯一追求——任何任务都路由到最强的模型gpt-4o权重应该是capability: 0.70, cost: 0.10。但到了月活 500 的阶段账单从 $50 涨到 $300此时如果还维持高能力权重成本会失控。正确做法是随产品阶段动态调整// 动态权重配置 function getRouteWeights(productPhase: early | growth | mature): RouteWeights { switch (productPhase) { case early: return { capability: 0.70, cost: 0.10, latency: 0.10, language: 0.05, context: 0.05 }; case growth: return { capability: 0.40, cost: 0.25, latency: 0.20, language: 0.10, context: 0.05 }; case mature: return { capability: 0.30, cost: 0.30, latency: 0.25, language: 0.10, context: 0.05 }; } }另一个实际踩坑是latencyBudget的设定。最初将实时交互场景的latencyBudget设为 200ms但 gpt-4o-mini 的 P95 延迟约 400ms——所有模型都无法满足要求导致latencyScore全部为 0.2 分评分失真。修改为 500ms 后评分恢复正常同时前端通过 streaming 响应来补偿用户体验。四、实时健康监控与动态权重调整静态评分无法应对模型的实时状态变化。需要一个持续运行的健康监控// router/health-monitor.ts class ModelHealthMonitor { private metrics new Mapstring, { latencies: number[]; // 最近 100 次延迟数据 errors: number[]; // 错误时间戳 lastCheck: number; }(); async recordCall(modelName: string, latency: number, error?: Error) { let data this.metrics.get(modelName); if (!data) { data { latencies: [], errors: [], lastCheck: Date.now() }; this.metrics.set(modelName, data); } data.latencies.push(latency); if (data.latencies.length 100) data.latencies.shift(); if (error) { data.errors.push(Date.now()); // 只保留 5 分钟内的错误 data.errors data.errors.filter( (t) Date.now() - t 5 * 60 * 1000 ); } data.lastCheck Date.now(); // 更新模型画像 this.syncToProfile(modelName, data); } private syncToProfile( modelName: string, data: { latencies: number[]; errors: number[] } ) { const profile getProfile(modelName); if (!profile) return; if (data.latencies.length 0) { // 使用 P95 延迟而非平均值避免被少数异常值拉高 const sorted [...data.latencies].sort((a, b) a - b); const p95 sorted[Math.floor(sorted.length * 0.95)]; profile.health.currentLatency p95; } profile.health.errorRate data.errors.length / 100; // 最近 100 次调用的错误率 profile.health.available profile.health.errorRate 0.1; } }五、总结多模型路由是独立产品在成本和质量之间找到平衡点的关键架构决策。几个核心原则第一路由决策的本质是成本、延迟、能力的三维权衡。加权评分模型的核心价值在于将隐性决策显性化让路由过程可理解、可调优。权重参数应根据产品阶段动态调整早期注重质量高能力权重成长期注重成本高成本权重。第二模型健康绝不能依赖静态配置。实时监控 P95 延迟和错误率在模型降级时自动切换是生产环境的基本要求。健康监控数据也反向驱动评分的准确性。第三降级链路要完整。从主模型到备选模型再到兜底的廉价模型确保任何情况下用户都能获得响应——哪怕质量略有下降也远好于直接报错。推荐实施路径先接入 2-3 个模型建立基础的评分和路由机制再逐步完善健康监控和自动降级最后根据实际调用数据持续优化评分权重。你的产品目前是如何管理多模型调用的欢迎在评论区交流