生成式 AI 的成本问题,往往不是“某个模型太贵”,而是所有请求都被送进了同一个高价模型。Cloudflare AI Gateway 新增的 Auto Router 尝试改变这一点:它在边缘侧使用分类器判断请求复杂度,再综合预期输出质量与 Token 成本,为每个请求选择更合适的模型。
这类路由的价值不只是降低平均单价。更重要的是,它让团队不必在“全部使用便宜模型”和“全部使用高性能模型”之间二选一。
自动路由改变了什么
固定模型调用通常长这样:摘要、分类、代码生成、复杂推理全部进入同一个模型。这样容易维护,却会出现明显浪费:
- 简单抽取任务不需要昂贵的推理能力;
- 极短请求也可能触发高价模型;
- 少量困难请求决定了整个应用的模型档位;
- 团队为了控制成本,只能统一降低模型规格,从而影响复杂任务质量。
Auto Router 的思路是在真正调用生成模型前,先判断请求的难度。根据来源摘要,这个分类器部署在边缘,并以预期质量和 Token 成本之间的平衡作为选型依据。
可以把它抽象成一个约束优化问题:
在预期质量 >= 业务要求的候选模型中,选择预计成本最低的模型
这比单纯按 Prompt 长度路由更合理。一个只有十几个字的数学证明请求可能很难,而一段很长的文本分类请求仍可能适合小模型。
节省来自请求分布,而不是最低价格
自动路由能省多少钱,取决于真实流量里各类请求的占比。可以用下面的简化公式估算路由后的平均成本:
平均成本 = Σ(某模型被选中的比例 × 该模型的单次平均成本)
假设 70% 的请求是摘要、改写和字段抽取,25% 是一般问答,只有 5% 需要复杂推理,那么让全部请求都进入最强模型通常并不经济。路由器可以把高性能模型保留给真正需要它的那部分流量。
不过,成本不能脱离质量单独观察。上线时至少要同时跟踪:
- 每个模型承接的请求比例;
- 输入与输出 Token 数;
- 单次请求及每日总成本;
- 人工评分、任务成功率或自动评测分数;
- 路由错误导致的重试和升级调用;
- 各模型的延迟、错误率与限流情况。
如果便宜模型导致大量重试,表面上的 Token 单价下降未必能转化为总账单下降。
用一个本地脚本模拟质量—成本路由
下面的示例不是 Cloudflare 官方 API 或配置,而是一个可以直接运行的最小模型,用来验证路由策略和成本计算。模型名称、价格与质量分数均为演示数据;接入生产环境前,应替换为自己的供应商价格和离线评测结果。
将以下内容保存为 auto_router_demo.py:
from dataclasses import dataclass
import sys
@dataclass(frozen=True)
class Model:
name: str
input_usd_per_million: float
output_usd_per_million: float
quality_score: float
MODELS = [
Model("mini", 0.20, 0.80, 0.78),
Model("standard", 1.00, 4.00, 0.90),
Model("reasoning", 4.00, 16.00, 0.97),
]
COMPLEX_TERMS = {
"证明", "推导", "架构", "调试", "优化", "多步骤",
"prove", "derive", "architecture", "debug", "optimize",
}
def classify_complexity(prompt: str) -> int:
text = prompt.lower()
score = min(len(prompt) // 400, 2)
score += sum(1 for term in COMPLEX_TERMS if term in text)
return min(score, 4)
def required_quality(complexity: int) -> float:
return 0.74 + complexity * 0.055
def estimate_tokens(prompt: str, complexity: int) -> tuple[int, int]:
input_tokens = max(1, len(prompt) // 4)
output_tokens = max(64, int(input_tokens * (0.5 + complexity * 0.25)))
return input_tokens, output_tokens
def estimate_cost(model: Model, input_tokens: int, output_tokens: int) -> float:
return (
input_tokens * model.input_usd_per_million
+ output_tokens * model.output_usd_per_million
) / 1_000_000
def route(prompt: str) -> tuple[Model, int, int, int, float]:
complexity = classify_complexity(prompt)
quality_floor = required_quality(complexity)
candidates = [m for m in MODELS if m.quality_score >= quality_floor]
selected = min(
candidates or [MODELS[-1]],
key=lambda m: estimate_cost(m, *estimate_tokens(prompt, complexity)),
)
input_tokens, output_tokens = estimate_tokens(prompt, complexity)
cost = estimate_cost(selected, input_tokens, output_tokens)
return selected, complexity, input_tokens, output_tokens, cost
prompt = " ".join(sys.argv[1:]) or "把下面的客服邮件归类为退款、咨询或投诉"
model, complexity, input_tokens, output_tokens, cost = route(prompt)
print(f"prompt: {prompt}")
print(f"complexity: {complexity}/4")
print(f"selected_model: {model.name}")
print(f"estimated_tokens: input={input_tokens}, output={output_tokens}")
print(f"estimated_cost_usd: {cost:.8f}")
运行两个不同难度的请求:
python auto_router_demo.py "把这封邮件分类为退款、咨询或投诉"
python auto_router_demo.py "调试一个分布式任务系统的重复消费问题,并推导至少三种修复方案的权衡"
这个示例刻意把“复杂度判断”和“模型选择”分开。实际接入 AI Gateway Auto Router 时,可以继续在应用侧记录业务标签和最终结果,用于检查自动路由是否符合自己的质量要求;具体端点、模型支持范围与配置方式则应以当前账户和产品文档为准。
上线时不要只看总账单
更稳妥的上线方式是先做影子评测或小流量灰度:保留当前固定模型作为基线,让同一批测试集分别经过固定策略和自动路由策略,然后比较质量、成本和延迟。
建议按以下顺序实施:
- 建立基线:记录当前模型的每任务成本、成功率和延迟分位数。
- 准备代表性评测集:覆盖短问答、长文本、代码、结构化输出和高风险请求。
- 设置质量下限:不要只规定预算,也要规定任务成功率或人工评分下限。
- 小流量启用路由:先观察模型选择分布,再逐步扩大比例。
- 保留升级与回退机制:解析失败、置信度不足或关键任务可以回退到指定模型。
- 定期重测:模型版本、价格和业务流量结构变化后,原来的最优路由可能不再最优。
自动路由也不是所有场景的默认答案。受监管流程、需要固定模型行为的审计任务、依赖特定模型工具调用能力的工作流,以及对输出一致性要求极高的批处理任务,可能更适合显式锁定模型。
Auto Router 最适合请求复杂度差异明显、流量规模足够大、同时具备质量评测体系的应用。它解决的不是“永远选择最便宜的模型”,而是把昂贵能力留给真正需要它的请求。