---
title: "限流"
description: "pirouter 按上游部署的分钟配额限流，不按 API key。本页说明限流的规则、两种 429 怎么区分、和模型回退的关系，以及该怎么重试。"
canonical: "https://pirouter.ai/zh/docs/rate-limits"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/(start)/rate-limits.mdx"
---

# 限流

pirouter 按上游部署的分钟配额限流，不按 API key。本页说明限流的规则、两种 429 怎么区分、和模型回退的关系，以及该怎么重试。

pirouter 的限流按上游部署计，不按 key，也不按工作区。每个上游部署有每分钟请求数（RPM）和每分钟 token 数（TPM）两种配额，请求被选中的那个部署用满了配额，就返回 `429`。

## 两种 429

你可能收到两种 `429`，处理办法不同：

|                 | pirouter 限流               | provider 限流                    |
| --------------- | ------------------------- | ------------------------------ |
| 谁返回的            | pirouter 网关               | provider，经 pirouter 原样转交       |
| `error.code`    | `rate_limited`            | provider 自己的错误体，没有这个码          |
| `X-Pi-Provider` | 不带                        | 带                              |
| `Retry-After`   | 一定带，1 到 60 秒              | provider 给了才有                  |
| pirouter 已经做了什么 | 没有转发，不计费                  | 已经换过同一模型的其它 provider，都失败了      |
| 你该做什么           | 等 `Retry-After` 秒，或者换一个模型 | 按 `Retry-After`（有的话）或逐步加长的间隔重试 |

看 `error.code` 是不是 `rate_limited`，或者看有没有 `X-Pi-Provider` 响应头，就能分清是哪一种。

## 规则

- **按上游部署计**。同一个模型可能有几个上游部署，每个部署各有自己的配额。换 key 不会绕开限流。
- **只有 RPM 和 TPM 两项**。两项都是按部署设定的分钟配额。

* **按自然分钟计**。计数按 UTC 的整分钟清零，不是滑动窗口。

- **RPM 在放行时计数，TPM 在请求结束后计数**。被拒绝的请求也计入当分钟的请求数。token 数在请求结束后按实际的输入加输出累加；当分钟的累计已经达到上限时，下一个请求被拒绝。所以一个大请求可以让当分钟的用量超过上限。

* **只检查被选中的那个部署**。pirouter 先按[路由规则](https://pirouter.ai/zh/docs/routing.md)选出一个部署，再检查它的配额。它用满了就直接返回 `429`，不会改去同一模型的其它部署。

## `rate_limited` 的响应

pirouter 限流时返回 `429`，`error.type` 是 `rate_limit_error`，`error.code` 是 `rate_limited`。代码里按 `error.code` 判断，不要匹配 `error.message` 的文本。

响应带 `Retry-After` 响应头，值是到下一个整分钟的秒数，在 1 到 60 之间。浏览器里的代码也能读到它。

这个响应是网关自己给出的，只带 `X-Pi-Trace-Id` 和 CORS 头，不带 `X-Pi-Provider`。请求没有转发给任何 provider，也不扣钱：配额检查在预扣余额之前。

控制台 **日志** 里，这类请求的结果显示为「触发限流」，提示是「该模型的上游容量已满。请稍后重试，或换一个模型。」

## provider 返回的 429

provider 自己限流时，pirouter 自动换下一家：先换同一模型的其它 provider，再换[备用模型](https://pirouter.ai/zh/docs/fallbacks.md)。这些你看不到。只有所有候选都失败、而且最后一次仍是 provider 的 `429` 时，你才会收到它：状态码和响应体是 provider 的，带 `X-Pi-Provider`，provider 给的 `Retry-After` 原样转交。

## 和模型回退的关系

- **pirouter 的限流不会触发模型回退**。请求一开始就被配额拒绝时，pirouter 不会改用 `models` 里的下一个模型，直接返回 `429`。想立刻得到回答，自己换一个模型发。
- **回退途中被限流，整条回退链结束**。前一次尝试失败、下一个候选又被配额拒绝时，返回的是 `429` `rate_limited` 和 `Retry-After`，不是前一次尝试的错误。

一个请求在所有模型上加起来最多尝试 5 次。

## 重试建议

| 你收到的                                                  | 怎么做                                                     |
| ----------------------------------------------------- | ------------------------------------------------------- |
| `429` `rate_limited`                                  | 等 `Retry-After` 秒再发，减少同时在途的请求。换 key 没有用                 |
| provider 的 `429`（带 `X-Pi-Provider`）                   | pirouter 已经换过 provider。有 `Retry-After` 就按它等，没有就逐步加长间隔重试 |
| `402`                                                 | 不要重试，先[充值](https://pirouter.ai/zh/docs/billing.md#充值)   |
| `500`、`502`、`503`、`504`，或 `200` 里的 `upstream_timeout` | 逐步加长间隔重试，间隔以秒计                                          |

OpenAI 和 Anthropic 的官方 SDK 默认会自动重试 `429`，并读取 `Retry-After`。这是 SDK 自己的行为，重试次数在 SDK 里设置。

更多错误见[哪些错误可以重试](https://pirouter.ai/zh/docs/errors.md#哪些错误可以重试)。

## 目前没有的能力

- **按 key 或按工作区的限流**。
- **剩余额度的响应头**。响应里没有 `x-ratelimit-*` 一类的头，看不到当分钟还剩多少配额。
- **并发数上限**。配额只按每分钟的请求数和 token 数计。

## 下一步

- [模型回退](https://pirouter.ai/zh/docs/fallbacks.md): 请求的模型不可用时自动换一个模型。
- [请求与响应头](https://pirouter.ai/zh/docs/headers.md): 每个响应头的含义和出现条件。
