HappyHorse 1.0 正式上线立即体验
修复 OpenRouter 429 "Provider Returned Error":速率限制、上游提供商与回退方案
guide

修复 OpenRouter 429 "Provider Returned Error":速率限制、上游提供商与回退方案

EvoLink Team
EvoLink Team
Product Team
2026年5月13日
14 分钟阅读
如果你的 OpenRouter 请求返回 429"provider returned error",修复方法取决于错误实际发生的位置。

这两种错误在日志中看起来类似,但根本原因不同:

  • 429 Too Many Requests:你的请求因触发速率限制而被拒绝
  • Provider returned error:OpenRouter 接受了你的请求,但上游模型提供商(OpenAI、Anthropic、Google 等)返回了错误

混淆这两者会导致错误的修复方向。本指南帮助你隔离原因并选择正确的应对策略。

要点速览

  • OpenRouter 自身的 429 意味着你触发了 OpenRouter 的速率限制或配额。
  • "Provider returned error" 意味着上游提供商拒绝了请求——而非 OpenRouter。
  • 检查响应头和错误体来区分这两种情况。
  • 修复方法不同:OpenRouter 429 需要调整密钥/套餐;提供商错误需要上游诊断或路由切换。
  • 对于生产工作负载,应在错误发生前就设计好回退方案。

第 1 步:仔细阅读错误响应

收到错误时,查看以下三个信号:

信号在哪里找它告诉你什么
HTTP 状态码响应状态429 = 速率限制;502/503 = 上游故障
错误消息体JSON 响应中的 error.message通常显示 "provider returned error" 或具体的速率限制消息
响应头x-ratelimit-remaining, retry-afterOpenRouter 自身是否在限流你

典型的 OpenRouter 429 看起来像这样:

{
  "error": {
    "code": 429,
    "message": "Rate limit exceeded. Please slow down."
  }
}

典型的 provider returned error 看起来不同:

{
  "error": {
    "code": 502,
    "message": "Provider returned error: [上游错误详情]"
  }
}

区分这两者很重要,因为它们需要不同的修复方法。

第 2 步:确认错误来源

使用这个决策树:

请求失败
├── HTTP 429 + OpenRouter 速率限制消息
│   → 原因:OpenRouter 层级的速率限制
│   → 修复:降低请求速率、升级套餐或增加延迟
│
├── HTTP 429 + 消息中包含 "provider returned error"
│   → 原因:上游提供商的速率限制透传
│   → 修复:检查提供商配额、切换模型或添加回退路由
│
├── HTTP 502/503 + "provider returned error"
│   → 原因:上游提供商宕机或暂时性故障
│   → 修复:带退避重试、切换提供商或使用回退
│
└── HTTP 400/401 + 错误消息
    → 原因:请求格式错误、密钥无效或模型未找到
    → 修复:检查 API 密钥、模型 ID 和请求格式

第 3 步:修复 OpenRouter 层级的 429

如果 429 来自 OpenRouter 自身(非上游透传),按以下顺序检查:

3.1 检查当前速率限制套餐

OpenRouter 根据账户套餐应用速率限制。免费套餐用户的限制远低于付费用户。

操作:在 OpenRouter 控制台检查当前限制和用量。

3.2 降低请求速率

如果你的发送速度超过套餐允许的范围:

import asyncio
import random

async def call_with_backoff(make_request, max_retries=5):
    for attempt in range(max_retries):
        try:
            return await make_request()
        except Exception as e:
            if "429" in str(e) and attempt < max_retries - 1:
                # 如果有 retry-after 则遵守,否则使用带抖动的退避
                delay = min(30, (2 ** attempt) + random.random())
                await asyncio.sleep(delay)
            else:
                raise

3.3 分散流量

Agent 工作负载往往会产生突发模式。与其同时发送 50 个请求:

  • 使用信号量限制并发
  • 在批次之间添加小延迟
  • 分离前台和后台队列

第 4 步:修复上游提供商错误

如果错误消息包含 "provider returned error",问题出在上游。OpenRouter 转发了你的请求,但模型提供商拒绝了它。

4.1 常见上游原因

上游原因你看到的现象如何验证
提供商速率限制429 透传检查是否降低请求速率后同一模型正常工作
提供商宕机502/503 透传查看提供商状态页面(如 status.openai.com)
模型已弃用或不可用404 或 model not found在 OpenRouter 模型列表中验证模型 ID 是否仍有效
区域限制403 或 access denied部分提供商按地理位置限制访问
输入过大400 并带有上下文/token 消息检查输入是否超过模型的上下文窗口

4.2 切换到不同的提供商路由

OpenRouter 将请求路由到上游提供商。如果某个提供商正在限流你,同一个模型可能通过不同的提供商路径可用。

检查:

  • 该模型在 OpenRouter 上是否有多个提供商选项
  • 是否可以在请求中配置提供商偏好
  • 是否有能力类似的回退模型可用

4.3 添加区分错误类型的重试逻辑

不要对所有错误使用相同的重试方式:

async def smart_retry(make_request, max_retries=3):
    for attempt in range(max_retries):
        try:
            return await make_request()
        except Exception as e:
            error_msg = str(e)

            # 不重试:请求错误、认证错误、模型未找到
            if any(code in error_msg for code in ["400", "401", "404"]):
                raise

            # 带退避重试:速率限制或提供商错误
            if any(code in error_msg for code in ["429", "502", "503"]):
                delay = min(30, (2 ** attempt) + random.uniform(0, 1))
                await asyncio.sleep(delay)
            else:
                raise

第 5 步:提前设计回退方案

在生产环境中,问题不是上游错误是否会发生——它们一定会发生。问题是你的系统是优雅降级还是直接崩溃。

回退清单

回退层需要实现什么为什么
带退避重试遵守 retry-after 的抖动指数退避处理暂时性故障而不放大负载
模型回退主模型失败时,路由到能力相当的替代模型当某条模型路径故障时保持工作流运行
提供商回退某个提供商返回错误时,尝试不同路由减少对单一提供商的依赖
队列 + 熔断器连续 N 次失败后停止向故障路径发送请求防止重试风暴使问题恶化
优雅降级更小的上下文、更便宜的模型或缓存的响应对终端用户来说优于硬性失败

什么时候应该考虑统一 API 网关

如果你正在 OpenRouter 之上构建回退逻辑来处理上游故障,你实际上是在路由层之上构建另一个路由层。

在这种情况下,使用一个将提供商路由、回退和模型选择作为内置功能的网关,可能比在应用层编写这些逻辑更简单。

EvoLink 的 Smart Router 在网关层处理这些问题:
  • 自动跨提供商路由
  • 在响应中返回实际使用的模型
  • OpenAI 兼容的请求格式——不需要重写代码
  • 无额外路由费用
curl https://api.evolink.ai/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "evolink/auto",
    "messages": [
      {"role": "user", "content": "你的提示词"}
    ]
  }'

这不能消除客户端重试逻辑的需要,但它将提供商选择和回退从你的应用代码中移出。

错误原因树(参考)

OpenRouter 请求失败
│
├── 来自 OpenRouter 的 429
│   ├── 免费套餐限制 → 升级账户
│   ├── 突发流量 → 添加并发控制
│   └── 持续高流量 → 检查套餐限制
│
├── "Provider returned error"
│   ├── 上游 429
│   │   ├── 提供商速率限制 → 降低速率或切换提供商
│   │   └── 共享配额耗尽 → 检查组织级限制
│   ├── 上游 502/503
│   │   ├── 提供商宕机 → 查看状态页面,等待或切换
│   │   └── 暂时性故障 → 带退避重试
│   └── 上游 400
│       ├── 上下文过长 → 截断或切换模型
│       ├── 参数无效 → 查看 API 文档
│       └── 模型已弃用 → 验证模型 ID
│
└── 其他错误
    ├── 401 → API 密钥无效
    ├── 404 → 模型未找到
    └── 网络错误 → 检查连接

下一步行动

  1. 检查你的当前错误:使用第 2 步来确认是 OpenRouter 429 还是提供商错误。
  2. 应用针对性修复:不要将速率限制修复方案应用于提供商错误,反之亦然。
  3. 添加结构化重试逻辑:在代码中区分可重试和不可重试的错误。
  4. 提前设计回退方案:生产系统不应只依赖单一上游路径。

相关文章

探索 EvoLink Smart Router

常见问题

OpenRouter 上的 "provider returned error" 是什么意思?

它表示 OpenRouter 收到了你的请求并将其转发给上游模型提供商,但提供商返回了错误。这个错误不是来自 OpenRouter 本身——而是来自 OpenAI、Anthropic、Google 或为该模型提供服务的提供商。

OpenRouter 的 429 和上游提供商的 429 相同吗?

不同。OpenRouter 层级的 429 意味着你触发了 OpenRouter 自身的速率限制。以 "provider returned error" 形式透传的提供商 429 意味着上游提供商拒绝了请求。修复方法不同。

遇到 "provider returned error" 应该重试吗?

取决于错误类型。如果上游返回 502/503(暂时性故障),带退避重试是合理的。如果返回 400(请求错误)或 404(模型未找到),重试无济于事——应该修复请求本身。

如何判断问题出在我的 API 密钥、配额还是提供商?

按以下顺序检查:(1) API 密钥是否有效?尝试一个简单的测试请求。(2) 在 OpenRouter 控制台检查配额和速率限制用量。(3) 如果密钥和配额都没问题,错误很可能来自上游提供商——查看错误消息获取详情。

统一 API 网关能消除提供商错误吗?

没有任何网关能阻止上游提供商故障。但具备内置路由和回退功能的网关,可以在一条路径失败时自动切换到替代提供商或模型,减少对你的应用的影响。

什么时候应该从 OpenRouter 切换到其他路由方案?

以下情况时值得考虑:(1) 提供商错误是反复出现的生产问题,(2) 你需要 OpenRouter 不提供的回退逻辑,(3) 你的工作负载跨多种模态(文本 + 图像 + 视频),或 (4) 你希望路由决策在网关层管理而非写在应用代码中。

准备好把 AI 成本降低 89% 吗?

现在就开始使用 EvoLink,体验智能 API 路由的强大能力。