模型网关实战:多模型路由、降级和成本对账的统一入口
结论先放这儿
| 问题 | 网关给什么 |
|---|---|
| 三五个应用各自直连各家 API | 一个统一入口,配置改一处 |
| 主模型挂了整条业务跟着挂 | 降级链自动回退备用模型 |
| 每月账单不知道花在哪 | usage 聚合,按应用和模型分账 |
| 换模型要改遍所有代码 | 路由层换配置,业务代码不动 |
选型实战讲过怎么挑模型,扛量实战讲过限流和熔断。这篇补中间的工程件。模型多了之后,谁来统一管它们?
一、网关解决什么问题
没有网关的状态通常长这样。三个应用各自写着不同厂商的 SDK,密钥散落在各处配置里,某家 API 抽风时三个应用一起挂,月底对账单只有总额没有明细。到处都痛。
网关就是加在业务和各家 API 之间的一层。业务代码只对网关说话。网关负责四件事,路由、降级、缓存、记账。LiteLLM 这类开源网关(或自建一个薄层)都能干这四件事,核心逻辑百来行。
二、路由:按任务挑模型
路由策略按维度排。代码任务走强模型,长文任务走长上下文模型,闲聊走便宜小模型。批量任务看成本,在线请求看延迟,超长的 Prompt 直接路由到支持长窗口的模型。路由函数就是一个映射表:
ROUTE = { 'code': 'claude-sonnet', 'long': 'gemini-flash', 'chat': 'gpt-4o-mini', } def route(task_type, prompt): model = ROUTE.get(task_type, 'gpt-4o-mini') if len(prompt) > 50000: # 超长走长上下文模型 model = 'gemini-flash' return model路由表是配置不是代码,改模型只改表。业务代码里只出现任务类型,不出现模型名。
三、降级链:主模型挂了不跟挂
每类任务配一条降级链,主模型失败自动回退。扛量篇的熔断器思路直接复用,连续失败就摘掉主模型一段时间。挂一个,跳一个,用下一个:
from collections import deque class Breaker: def __init__(self, threshold=3, cool=60): self.fails, self.threshold, self.cool = 0, threshold, cool self.opened_at = 0 def allow(self): if self.fails < self.threshold: return True return time.time() - self.opened_at > self.cool def record(self, ok): if ok: self.fails = 0 else: self.fails += 1 if self.fails >= self.threshold: self.opened_at = time.time() FALLBACK = ['claude-sonnet', 'gpt-4o', 'gemini-flash'] def call(prompt, task_type='code'): for model in FALLBACK: b = breakers[model] if not b.allow(): continue try: resp = llm_call(model, prompt) b.record(True) return resp except Exception: b.record(False) raise RuntimeError('全部模型不可用')降级链的顺序就是成本顺序,最划算的排前面。回退不是静默的,日志里记一笔降级事件,降级率涨了说明主模型不稳。
四、成本对账:usage 聚合
每次调用把 usage 记下来,按应用和模型分账:
import json, time def record_usage(app, model, usage): entry = { 'ts': int(time.time()), 'app': app, 'model': model, 'in': usage.prompt_tokens, 'out': usage.completion_tokens, } with open('usage.jsonl', 'a', encoding='utf-8') as f: f.write(json.dumps(entry, ensure_ascii=False) + '\n')月底按 jsonl 聚合,哪个应用烧钱、哪个模型性价比低,一目了然。账目清楚了才好做选型决策。Tokenizer 篇说过 token 是计费单位,对账就以 usage 字段为准,聚合脚本只做分账不做估算。
写在最后
网关的四件事,路由让换模型变成改配置,降级让单点故障不传染,缓存和记账让账单可查。核心逻辑百来行。开源网关能白嫖就先用开源的。自己写也只是一个薄层。模型多了之后再上网关,一上就别让业务代码直连厂商 API。
本文的方法与代码按自己的项目实践整理,网关选型可参考 LiteLLM 等开源实现的配置模型。