通过请求分类+输出验证+自动降级的路由架构,在真实流量下实现成本与质量平衡,GPT-4o 账单曾暴涨 28 倍。
两个月前,我的代码库里只有一个 LLM 客户端,硬编码指向一个模型。最初我把所有请求都打到最便宜的模型上,因为账单看起来很漂亮。然后有用户给我看了一条自信满满的错误回复,我做了所有人都做的事:把所有请求切到 GPT-4o。账单涨了 28 倍,但简单请求占了流量的 90%,这些请求的质量并没有提升。问题不在于选错了模型——而是用了一个模型。
解决方案是一个路由器:几百行 Python 代码,对每个请求进行分类,发送到最便宜但足够用的模型,验证输出,验证失败时回退到更强的模型。这是详细步骤版,带有我真实流量下的成本数据。
每个 LLM API 请求并非同一个任务。在我的 pipeline 中,大致分为四类:
分类与提取 — 工单、意图、JSON 字段。高流量、低复杂度。
摘要 — 将长文档压缩成摘要。中等流量,需要连贯性。
翻译 — 双向中英文,面向双语团队。需要较强的语言质量。
复杂推理 — 需要真正推理的升级问题。低流量、高风险。
如果你把所有四种都发给便宜模型,5% 的难题返回结果平庸,你就交付了糟糕的输出。如果你把所有四种都发给高端模型,分类一个工单要花 $10.00 / 1M 输入 token。路由是中间路径:一个小型分类器决定任务类型,一个查询表决定用哪个模型。
每 1M token 的价格(截至发稿时):
我的路由表来自在四个模型上运行相同的 prompt(评估是另一篇文章的故事)。我的结论是:
这里没什么花哨的——就是一个路由字典加一个调用 OpenAI 兼容 SDK 的函数。四个模型都挂在一个端点后面,所以切换模型只是一行字符串的事:
import openai
client = openai.OpenAI(
api_key="sk-...",
base_url="https://api.tokencnn.com/v1", # one endpoint, every model
)
ROUTES = {
"classify": {"model": "deepseek-v4-flash", "max_tokens": 150},
"extract": {"model": "deepseek-v4-flash", "max_tokens": 300},
"summarize": {"model": "glm-5-130b", "max_tokens": 800},
"translate": {"model": "qwen3-235b-a22b", "max_tokens": 500},
"reason": {"model": "gpt-4o", "max_tokens": 1500},
}
def call_model(model, messages, max_tokens):
resp = client.chat.completions.create(
model=model,
messages=messages,
max_tokens=max_tokens,
)
return resp.choices[0].message.content
def route(task, messages):
spec = ROUTES[task]
return call_model(spec["model"], messages, spec["max_tokens"])
分类器就是另一个便宜调用,temperature=0,标签词汇紧凑。关键点:不确定时回退到贵价路由——被误分类的难题发到弱模型比把简单请求发给 GPT-4o 更糟糕:
CLASSIFIER_LABELS = "classify, extract, summarize, translate, reason"
def pick_task(text):
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content":
f"Label this request with exactly one of: {CLASSIFIER_LABELS}.\n\n{text}"}],
max_tokens=10,
temperature=0,
)
label = resp.choices[0].message.content.strip().lower()
return label if label in ROUTES else "reason" # fail safe, not fast
这是路由发挥作用的地方。便宜模型不是失败率更低,而是失败方式不同:GLM-5-130B 偶尔会在流式输出中途停顿,DeepSeek V4 Flash 有时在复杂 schema 上返回格式错误的 JSON,两者都可能 hallucinate 一个不符合 schema 的工具调用。所以我从不信任第一轮——我验证,失败时用上一级重试:
import json
def route_with_fallback(task, messages, validate):
spec = ROUTES[task]
for model in [spec["model"], "gpt-4o"]: # escalate to premium
text = call_model(model, messages, spec["max_tokens"])
try:
validate(text) # schema check, exact-match, hidden test
return model, text
except (json.JSONDecodeError, ValueError):
continue
raise RuntimeError(f"validation failed on both models for task={task}")
回退触发率约占请求的 2–4%,所以 GPT-4o 调用保持稀有——但这个选项才是让便宜模型能处理长尾的原因。重试一个不到一分钱调用比在所有请求上付 $30.00 / 1M 输出 token 要好。
以下是 10,000 请求/天、每个请求平均约 1,680 输入 token 和 190 输出 token 的真实数据。首先,如果你把所有请求都发给单一模型,要花多少钱:
STEPS = 10_000 # requests per day
IN_PER_STEP = 1_680 # avg input tokens per request
OUT_PER_STEP = 190 # avg output tokens per request
FINAL_OUT = 0
def daily_cost(p_in, p_out):
total_in = STEPS * IN_PER_STEP
total_out = STEPS * OUT_PER_STEP + FINAL_OUT
return (total_in * p_in + total_out * p_out) / 1_000_000
for name, p_in, p_out in [
("DeepSeek V4 Flash", 0.35, 1.10),
("Qwen3-235B-A22B", 1.60, 6.40),
("GLM-5-130B", 1.20, 4.80),
("GPT-4o", 10.00, 30.00),
]:
print(f"{name:18} ${daily_cost(p_in, p_out):.2f} / day")
DeepSeek V4 Flash $7.97 / day
Qwen3-235B-A22B $39.04 / day
GLM-5-130B $29.28 / day
GPT-4o $225.00 / day
现在同样的流量过路由器——token 量相同,只是付费的模型变了,所以下面的每个数字都可以从上面的常量复现:
所以路由后的账单比全切 GPT-4o 便宜 89%($225.00 → $25.13),同时在那 5% 需要它的请求上保持了 GPT-4o 的质量。两个实话:要承认的地方——路由比全用 DeepSeek 地板价贵 3.2 倍——路由不是为了最便宜,而是为了在满足质量底线的前提下账单最低——而且切到 GPT-4o 的那 5% 占了总账单的 45%。这才是你真正付的溢价,而它恰恰在你需要的地方。
均匀流量不需要路由器。如果每个调用形态相同(比如一个夜间批处理 job),一个模型一个价格更简单,分类器只会增加延迟。我不路由批处理 job。
分类器增加一次调用和约 0.7 秒。这是 DeepSeek V4 Flash 在每个请求上的 TTFT。对后台 pipeline 来说没问题;对盯着聊天光标看的用户来说能感知到。如果延迟比 70 美分更重要,就硬编码路由。
价格和模型会变动。中国厂商重新发布价格和静默升级模型的频率比你想象的更频繁。ROUTES 字典是配置,不是法律——我每月重新检查组合,当提供商在底层切换模型时,评估套件能 catch 回归。
验证才是真正的工作。路由器只是简单的 50 行代码。写出让回退可信的 schema 检查和测试花了我一周。如果你无法验证输出,路由只是一个更复杂的选模型方式——别费那劲。
烦人的不是代码——DeepSeek、Qwen 和 GLM 各有各的控制台、账单和速率限制,所以路由器意味着维护四个账号。我把所有请求都通过 tokencnn.com 路由:一个 OpenAI 兼容端点,deepseek-v4-flash、qwen3-235b-a22b 和 glm-5-130b 都挂在一个 API key 后面,所以上面的路由器无需改动就能工作,切换路由只是一行编辑的事。只需邮箱注册——无需中国手机号,无需微信——$1 免费额度大约够一周的路由流量:
curl https://api.tokencnn.com/v1/chat/completions \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash",
"messages": [
{"role": "system", "content": "Classify this ticket."},
{"role": "user", "content": "Label this request: ..."}
]
}'
最好的模型不是一个模型——而是一套策略。对每个请求分类,路由到最便宜但足够用的模型,验证输出,只有验证失败时才升级。在我的流量上,相比全用高端模型节省了 89%,同时在最需要的地方保留了 GPT-4o,代价是约 0.7 秒的分类器延迟,以及一个诚实的约束:你必须能够验证输出,否则回退只是表演。
你的路由表长什么样?我真的很想借鉴你的 task→model 映射——尤其是那个让你深刻认识到便宜模型不够用的任务场景。