用“静态路由做边界、动态路由做调度、熔断/降级做兜底”,保障稳定性与成本。
🎯 文章目标
- 给出多模型/多供应商的可落地路由方案
- 提供熔断/降级的最小实现与参数建议
- 输出观测指标与调参方法
📚 背景/前置
- 典型维度:任务类型、上下文长度、风险等级、预算/配额、供应商健康度
- 输出目标:成功率↑、P95 延迟↓、成本在预算内
🔧 核心内容
1) 静态路由(先粗分)
- 文本抽取/分类/短问答 → 小模型(便宜快)
- 复杂写作/规划/多工具 → 大模型(质量稳)
- 高风险内容 → 更安全/合规模型(带审阅)
2) 动态路由(再细分)
- 指标感知:按模型/供应商的错误率、P95、拒配额率
- 预算感知:当月费用>阈值则偏向便宜模型
- 健康度:短窗内连续错误/超时则降低权重
- 路由方法:加权随机/上限负载(weighted random + max load per target)
3) 熔断与降级
- 触发:短窗 errorRate>5% 或 P95>2s 或超时>3 次
- 熔断:OPEN→HALF_OPEN→CLOSED 状态机,半开试探 1~N 个请求
- 降级:
- 模型降级:更小模型/低温度
- 上下文降级:摘要/检索精简、截断长上下文
- 接口降级:返回缓存/延迟生成
💡 实战示例:Node.js 路由 + 熔断
javascript
function chooseStatic(ctx){
if (ctx.type==='extract' && ctx.len<600) return 'small';
if (ctx.risk==='high') return 'secure';
return 'standard';
}
function pickByWeights(candidates){
const total = candidates.reduce((s,c)=>s+c.weight,0);
let r = Math.random()*total;
for(const c of candidates){ r-=c.weight; if (r<=0) return c; }
return candidates[candidates.length-1];
}
function breakerNext(state, event){
// state: {status:'CLOSED'|'OPEN'|'HALF_OPEN', fail:0, ts:0}
const now = Date.now();
if (state.status==='OPEN' && now-state.ts>30000) return {status:'HALF_OPEN', fail:0, ts:now};
if (event==='fail'){
const fail = state.fail+1;
if (fail>=3) return {status:'OPEN', fail, ts:now};
return {...state, fail};
}
if (event==='ok'){
if (state.status==='HALF_OPEN') return {status:'CLOSED', fail:0, ts:now};
return {...state, fail:0};
}
return state;
}
动态权重示意
javascript
function dynamicWeights(stats, budget){
// stats: {model:{errorRate,p95,load}, ...}; budget.usedPct
const base = { small:1, standard:1, secure:1 };
for (const m of Object.keys(base)){
if (stats[m].errorRate>0.05 || stats[m].p95>2000) base[m]*=0.2; // 降权
if (stats[m].load>0.8) base[m]*=0.7; // 限流
}
if (budget.usedPct>0.9){ base.standard*=0.6; base.secure*=0.5; base.small*=1.4; }
return base; // 交由 pickByWeights 使用
}
📊 指标看板(速查)
- 路由分布:各模型/供应商占比
- 质量:成功率、错误率(按可恢复/不可恢复)、P95/P99
- 成本:每请求成本、每类型成本、预算用量%
- 熔断:状态、触发次数、半开成功率
- 降级:触发次数、用户影响面、回滚时长
🧪 踩坑与经验
- 只做静态不做动态:无法应对波动与限流
- 熔断后不做降级:体验雪崩
- 忽略预算信号:月底“暴雷”被动降级
- 没有半开:熔断后恢复缓慢
📎 参考与延伸
- Hystrix/Resilience4j 思路、断路器模式
- 多目标路由与加权调度实践
💭 总结
- 用“静态+动态+熔断/降级”的组合,平衡质量/延迟/成本,提升系统韧性