告别429:Portkey 网关重试配置指南
【免费下载链接】gatewayA blazing fast AI Gateway with integrated guardrails. Route to 1,600+ LLMs, 50+ AI Guardrails with 1 fast & friendly API.项目地址: https://gitcode.com/GitHub_Trending/ga/gateway
凌晨两点,生产环境被 429 刷屏。你上周手写的那个重试循环卡在嵌套 if 里,配置改了三遍不生效,最后只能硬加 sleep。手动应付 LLM 的不稳定真的很痛苦:重试、降级、限流,样样都要自己写代码。Portkey 网关就是为这件事设计的——把一个 JSON 配置从请求头递过去,自动重试和多模型 fallback 立刻生效。
读完这篇,你能做到:一条命令在本机跑起 Portkey 网关,用一条 curl 验证 429 自动重试确实生效,不用改业务代码。
它到底在干什么
Portkey 网关就像站在你的应用和 1,600+ 个 LLM 之间的调度台:请求不再直连 OpenAI 或 Anthropic,而是先经过它这一关。
它具体解决三件事:429/5xx 时自动重试,模型临时过载不再算你的锅;主模型挂掉时自动 fallback 到备胎;用负载均衡把流量摊到多个模型上,顺带还有内容审核这类 guardrails。
整个方案的核心是配置驱动:所有行为靠一份 JSON 声明,代码里几乎不用动。官方把这套思路讲得很清楚,可以先翻仓库里的教程 writing-your-first-gateway-config.md 建立整体印象。
3 分钟跑通第一条重试请求
把网关在本地跑起来
网关本体就是一个 HTTP 服务,重试逻辑全靠后续的配置驱动,所以不需要克隆源码或构建,一条命令就能启动。
npx @portkey-ai/gateway跑完后控制台会打印Your AI Gateway is running at: http://localhost:8787,同端口下的/public/页面是它的 Web 控制台,后面看日志会用到。
把重试配置写对
网关不知道你想在哪些错误码上重试、重试几次,不给配置它就只会把请求原样转发。我们要写的第一份配置就是"重试规则":
{ "provider": "openai", "api_key": "sk-xxxx", "retry": { "attempts": 3, "on_status_codes": [429, 500, 502, 503, 504] } }这就是全文的主角 config(网关配置):一份告诉网关"怎么对待这次请求"的 JSON。provider和api_key声明请求转发给谁,retry声明命中所列状态码时最多再试 3 次——上限是 5 次,源码里写死的,多写也不生效。写完这份 JSON,手里就有了一个可以直接塞进请求头的配置。
发一条真实请求验证效果
配置要放进请求头x-portkey-config才生效,所以最直接的验证方式就是发一条真实请求。把上一步的 JSON 压成单行,用 curl 打向本地网关:
retry_config='{"provider":"openai","api_key":"sk-xxxx","retry":{"attempts":3,"on_status_codes":[429,500,502,503,504]}}' curl http://localhost:8787/v1/chat/completions \ -H "Content-Type: application/json" \ -H "x-portkey-config: $retry_config" \ -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'如果你更习惯 SDK,Portkey 客户端的config参数能直接接这份 JSON,OpenAI SDK 也能通过改 baseURL 接进来,这里不展开。
执行后应看到:响应 200 且正常返回内容;一旦发生了重试,响应头里会多出一个x-portkey-retry-attempt-count。所有请求还会出现在控制台日志页里,逐条列出耗时、token 和花费:
换个场景试试:负载均衡与 fallback
把上面的 JSON 换个写法,网关就能做更复杂的事,业务代码一行不动。
场景一,按比例分流:把strategy设为loadbalance,在targets里用weight控制比例:
{ "strategy": { "mode": "loadbalance" }, "targets": [ { "provider": "openai", "weight": 0.7 }, { "provider": "anthropic", "weight": 0.3 } ] }每个 target 还能加override_params单独覆盖模型等参数。
场景二,主模型挂了自动换备胎:把mode改成fallback,targets 按优先级排,谁先成功用谁:
{ "strategy": { "mode": "fallback" }, "targets": [ { "provider": "openai" }, { "provider": "anthropic" } ] }这两种模式还能嵌套——外层负载均衡、每个 target 内部再挂一层 fallback,拼出完整的容错链路:
容易踩的坑
- 配置写了却一次都没重试:原因——
on_status_codes只写了 429,默认集合被整个覆盖,5xx 不再触发。正确做法——显式写全[429, 500, 502, 503, 504]。 - 没报错但模型也不回话:原因——配置里漏了
provider和api_key,网关不知道该转发给谁。正确做法——这两个字段和retry放在同一份 JSON 里。 - attempts 写了 10,实际只重试 5 次:原因——网关把重试次数封顶在 5。正确做法——
attempts保持不超过 5,别指望更大值。
一段 JSON、一个请求头,就能把手写 sleep 和重试循环的工作整段省掉——重试、降级、分流,都是声明式配置的事。
下一步建议去 cookbook/getting-started/ 目录翻翻其他模板,缓存、多模型协作都有现成样例;要部署到自己的服务器上,再看 docs/installation-deployments.md 的部署章节。
有空的话,把 loadbalance 的 weight 改成 0.9/0.1,盯着日志页看看流量真的按这个比例分走。
【免费下载链接】gatewayA blazing fast AI Gateway with integrated guardrails. Route to 1,600+ LLMs, 50+ AI Guardrails with 1 fast & friendly API.项目地址: https://gitcode.com/GitHub_Trending/ga/gateway
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考