LLM Gateway部署踩坑:解决多模型调用超时与Token溢出
简单理解,这玩意儿就是个“智能调度员”。它不是模型本身,而是一个拦截层,把你的请求先接过来,然后根据预设规则决定发给 GPT-4o 还是 Claude 3.5,或者在 A 挂了的时候瞬间切到 B。
在实际部署这个网关的过程中,我踩了几个比较典型的坑,分享给打算实操的朋友:
一、 解决响应超时与重试机制
最恶心的是模型供应商的随机延迟。我之前配置的超时时间是 30s,结果在高峰期,请求卡在 29s 左右才返回,导致前端页面转圈圈。
我的解决方案:
在 Gateway 层配置一个严格的 timeout 和 max_retries。不要依赖 SDK 的默认值,建议在配置文件中明确定义。
# gateway_config.yaml 示例配置
routing:
primary_model: "gpt-4o"
fallback_model: "claude-3-5-sonnet"
timeout_settings:
request_timeout: 15s # 超过15秒直接判定为慢请求
retry_attempts: 3 # 最多重试3次
retry_interval: 500ms # 重试间隔这样配置后,一旦主模型在 15s 内没响应,网关会立即尝试重试或直接路由到备用模型,实测将接口的 P99 延迟降低了约 40%。
二、 Token 计数与截断的实操问题
很多开发者在写 AI Agent 时,习惯在业务端计算 Token。但问题是,不同模型的 Tokenizer 算法不一样(比如 OpenAI 和 Anthropic 的计算结果有偏差),这会导致你发出的请求因为超过上下文窗口而被直接拒收(400 Error)。
避坑指南:
把 Token 计算下沉到 Gateway 层。在请求发出之前,利用网关拦截器进行预检。如果发现 prompt_tokens 接近临界值,直接在网关层执行截断策略,而不是等模型报错返回。
# 伪代码:网关层Token预检拦截逻辑
def pre_flight_check(request):
token_count = count_tokens(request.prompt, model=request.target_model)
limit = get_model_limit(request.target_model)
if token_count > limit:
# 执行硬截断,保留最近的对话上下文
request.prompt = truncate_prompt(request.prompt, limit - 100)
log.warn(f"Prompt truncated for {request.target_model}")
return request三、 成本监控与 Key 池管理
如果你的团队有多个开发者在共用几个 API Key,很容易出现某个同事写了个死循环脚本,瞬间把额度刷光的情况。
实操建议:
在 LLM Gateway 中引入 API-Key-ID 映射机制。不要在代码里硬编码 Key,而是通过网关分配虚拟 Key。
- 维度:配额限制 给每个虚拟 Key 设置每分钟请求数 (RPM) 和每分钟 Token 数 (TPM)。
- 维度:成本追踪 记录每个请求的
input_tokens和output_tokens,直接存入 Redis 计数器。 - 维度:动态切换 发现某个 Key 触发 429 错误时,网关自动从 Key 池中随机抽取下一个可用 Key。
通过这种方式,我把团队的 API 成本波动控制在了 $\pm 10\%$ 以内,再也不用担心半夜被额度耗尽的报警邮件吵醒。
总的来说,LLM Gateway 是从“跑通 Demo”到“上线产品”的必经之路。如果你还在手动管理多个 API Key,或者经常被模型响应速度搞崩溃,建议尽快把这层逻辑抽离出来。
