限流策略
限流策略是与调用方 API Key 和模型分开管理的配额规则。它可以按团队、成员、API Key、模型、模型名称或模型服务提供方选择流量,再把匹配请求划分到独立配额桶中。策略还可以在周期性时间窗口内暂停自身执行。
条件策略使用请求条件和可选的配额桶维度,是新配置的推荐形式。对于以单个 API Key、模型、团队或成员为目标的现有配置,仍可使用经典策略。
策略不会取代单个 API Key 或模型上配置的限制。AISIX 会同时评估所有匹配策略和这些资源上的限制;只有所有匹配配额桶都有容量,请求才会继续。
本指南介绍如何通过 AISIX Cloud 或开源 AISIX 网关配置并验证条 件策略、维护经典策略,以及安排策略暂停时间。
准备工作
开始前,请准备以下内容:
- 了解 API Key 与模型限流中介绍的限制字段、计数器行为、存储选项和资源专属限制。
- 可以发送代理请求的模型别名和调用方 API Key。
- 对于按成员划分的示例:已绑定到所选团队和某个成员的调用方 API Key。
- 以下配置路径之一:
- AISIX Cloud,其中包含环境、已接入的网关和具有写权限范围的 Admin Token。
- 开源 AISIX 网关,以及可验证并重新加载的声明式资源文件。
导出用于验证示例的网关请求参数:
# AISIX_PROXY 末尾不包含斜杠或端点路径。
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_MODEL="gpt-4o-prod"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
对于 AISIX Cloud,还需导出示例使用的控制平面参数和资源 ID。请从团队页面复制 TEAM_ID。
# AISIX_CP 包含 /api,末尾不包含斜杠。
# 本地 On-Premises 快速入门使用 http://localhost:8080/api。
export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_BASE_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
export TEAM_ID="YOUR_TEAM_ID"
选择策略形式
策略有两种形式。在 AISIX Cloud 中,形式在创建后固定不变。对于开源 AISIX 网关,声明式资源文件中的条目必须只使用一种形式;混用两种形式的字段会导致加载错误。
- 条件策略(推荐):使用条件树匹配请求,按
group_by中的维度拆分计数器,并使用与调用方 API Key 和模型相同的七字段limits结构限制流量。控制台的 New policy 流程只会创建这种形式。 - 经典策略(旧版):通过
scope和scope_ref指定单个对象,并使用window搭配max_requests或max_tokens。Admin API 和资源文件仍支持现有经典策略。
新配置请使用条件策略。它可以复现每种经典作用域,并支持同一请求匹配多个策略。
配置条件策略
条件策略需要作出三个决定:哪些请求匹配、如何拆分计数器,以及每个配额桶可以使用多少流量。
{
"name": "algo-team-premium-models",
"conditions": [
{ "dimension": "team", "operator": "in", "value": ["<team-id>"] },
{
"logic": "or",
"children": [
{ "dimension": "model_name", "operator": "~~", "value": "^gpt-4" },
{ "dimension": "provider", "operator": "==", "value": "anthropic" }
]
}
],
"group_by": ["member"],
"limits": { "rpm": 20 }
}
使用条件匹配请求
conditions 中的顶层 节点全部生效,形成 AND 关系。节点可以是单个条件,也可以是通过 logic: and 或 logic: or 组合嵌套 children 的分组。空列表或省略列表会匹配环境中的所有请求。
| 维度 | 值 | 说明 |
|---|---|---|
team | 团队 ID | 与调用方 API Key 的团队绑定匹配 |
member | 成员或用户 ID | 与调用方 API Key 的成员绑定匹配 |
api_key | 调用方 API Key ID | |
model | 模型 ID | 匹配实际分发的模型;当请求经模型组、语义路由器或 ensemble 路由时,还匹配调用方所寻址的组/路由器。因此组自身的 ID 会选中经它路由的每个请求,而某成员的 ID 无论直接调用还是经组到达都会匹配。negate 将两者一并排除。 |
model_name | 模型别名 | 与 model 相同的配对匹配,作用于显示名;支持跨别名的正则表达式匹配。 |
provider | 模型服务提供方目录 ID,例如 openai 或 anthropic | 与实际分发模型的模型服务提供方匹配 |
在 AISIX Cloud 中,身份维度使用资源 ID,model_name 和 provider 使用字符串。对于开源 AISIX 网关,api_key 和 model 的值使用声明式资源文件中对应条目的 display_name。team 和 member 的值分别按原值匹配调用方 API Key 的 team_id 和 user_id。
操作符遵循 lua-resty-expr,与 APISIX 路由 vars 使用相同的表达式词汇:
| 操作符 | 含义 | 适用范围 |
|---|---|---|
== / ~= | 等于/不等于 | 所有维度 |
in | 值位于包含 1–64 个条目的列表中 | 所有维度 |
~~ / ~* | 区分/不区分大小写的正则表达式,最多 256 个字符 | model_name 和 provider |
negate: true | 反转条件或分组 | 任意节点 |
team、member、api_key 和 model 维度包含 ID,因此使用相等或列表操作符。不携带某个维度的请求既不匹配该维度上的条件,也不匹配其取反条件,但 or 分组中的其他分支仍可能匹配。一个策略最多包含 16 个条件,嵌套层级最多为 3 层。
把计数器拆分为配额桶
group_by 接受 team、member、api_key、model 和 provider。所选维度值的每种不同组合都会获得具有相同限制的独立配额桶。group_by 为空或省略时只创建一个共享配额桶。匹配但缺少所选配额桶维度的请求不受该策略约束。
常见模式包括:
- 团队共享池:匹配一个团队并将
group_by留空,使整个团队共享配额。 - 每成员默认配额:匹配一个团队并设置
group_by: [member],使每个成员获得独立配额。可与团队共享池策略叠加,同时执行团队总量和成员上限。 - 公平共享模型:匹配一个模型并设置
group_by: [team],使每个团队获得独立配额。
设置限制
limits 接受 rps、rpm、rph、rpd、tpm、tpd 和 concurrency,至少需要一个字段。Token 限制会在响应或流报告用量后结算,详见限流字段与计数器行为。
请求窗口如何计数取决于策略引用的维度:
- 如果策略的条件和
group_by均不使用model、model_name或provider,AISIX 会在请求闸门处只预留一次。因此,仅匹配api_key、team或member的策略,即使请求发生重试或故障转移,也只消耗一个请求槽位。 - 如果策略的条件或
group_by使用模型属性,AISIX 会在明确实际分发模型的位置预留。直接模型请求在请求闸门处预留一次。对于路由或语义父模型,AISIX 会对每次目标尝试评估策略,包括同一目标的重试与故障转移。对于 ensemble 父模型,则会对每次 panel 或 judge 调用评估策略。每次预留都会消耗一个请求槽位,即使上游调用失败也不会退还。使用group_by: [model]时,每个实际分发的直接模型使用各自的配额桶。
action 为未来行为预留。目前唯一支持且默认的值是 reject,它会返回 HTTP 429。
完整的策略 Schema 和字段验证规则参见资源文件参考。
AISIX Cloud
在控制台中创建条件策略:
- 打开环境并选择 Rate limits。
- 选择 New policy,输入 Name。
- 在 Match conditions 下添加条件行。当策略需要任一条件满足或嵌套组合时添加条件分组。不设置条件表示匹配所有请求。
- 在 Quota buckets 下保留 Shared quota,或选择 Split by dimension 并选择维度。
- 在 Limits 网格中填写至少一个字段,然后选择 Create policy。
策略列表会把条件显示为标签,并使用括号和明确的 AND/OR 关系表示分组。编辑策略可以更改条件、配额桶和限制。更改配额桶维度集合会改变计数器 Key;仅编辑条件或限制不会重置现有计数器。
对于自动化,请通过 Admin API 创建策略。以下示例为一个团队中的每个成员提供独立的每分钟一次请求配额桶:
curl -sS -X POST "${AISIX_CP}/environments/${ENV_ID}/rate_limits" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"name": "team-member-default",
"conditions": [
{ "dimension": "team", "operator": "in", "value": ["${TEAM_ID}"] }
],
"group_by": ["member"],
"limits": { "rpm": 1 }
}
EOF
成功请求返回 201 Created,策略会投射到已接入的网关。条件策略没有“每个对象只能一个”的限制,因此可以按场景需要叠加任意数量。列出、获取、更新和删除操作参见 AISIX Cloud Admin API 参考。
开源 AISIX 网关
在 rate_limit_policies 集合中声明条件策略。api_key 和 model 条件值使用目标条目的 display_name。AISIX 在加载资源文件时解析这些名称,未知名称会导致 加载错误。
api_keys:
- display_name: chat-app
key_env: CALLER_API_KEY
allowed_models:
- gpt-4o-prod
team_id: team-blue
user_id: user-alice
rate_limit_policies:
- name: team-member-default
conditions:
- dimension: team
operator: in
value: [team-blue]
group_by: [member]
limits:
rpm: 1
❶ team_id 和 user_id 把调用方 API Key 绑定到团队和成员。team 条件匹配 Key 的 team_id;member 配额桶以其 user_id 为 Key。
❷ team 和 member 条件按原值匹配这些绑定。
❸ group_by: [member] 为每个已绑定成员提供独立的每分钟一次请求配额桶。
让验证命令可以访问调用方凭证:
export CALLER_API_KEY="${AISIX_API_KEY}"
验证完整资源文件并重新加载网关。
验证策略
一次只配置并测试一个策略。可运行的策略示例使用每分钟一次请求,因此可以使用验证限流中的请求序列,并使用与策略匹配的调用方和模型。
当条件策略在兼容 OpenAI 的端点上拒绝请求时,429 正文会标识该策略:
{
"error": {
"message": "request limit exceeded (requests) (policy 'team-member-default')",
"type": "rate_limit_exceeded",
"policy": {
"id": "<policy-id>",
"name": "team-member-default"
}
}
}
如果请求匹配多个策略或直接限制,每个匹配层都必须有容量。兼容 OpenAI 的响应中命名的策略,就是拒绝该请求的那一层。兼容 Anthropic 的错误保留严格的 Anthropic 封装,不包含 policy 对象。
管理经典单作用域策略
经典策略以单个对象为目标。每个经典作用域都有直接对应的条件形式:
| 经典作用域 | 匹配流量 | 条件形式 |
|---|---|---|
| API Key | 使用所选调用方 API Key 认证的请求 | conditions: api_key in {K} |
| 模型 | 解析到所选模型的请求 | conditions: model in {M} |
| 团队 | 调用方 API Key 携带所选团队绑定的请求 | conditions: team in {T} |
| 成员 | 调用方 API Key 携带所选成员绑定的请求 | conditions: member in {U} |
| 团队中的每个成员 | 同时携带所选团队和成员绑定的请求 | conditions: team in {T} 搭配 group_by: [member] |
匹配等价并不一定意味着计数等价。以路由、语义或 ensemble 父模型为对象的经典模型策略会在请求闸门处只预留一次;条件式 model in {M} 则会对每次目标尝试评估,因此一个经过该父模型的客户端请求可能消耗多个槽位。
经典策略使用 scope 和 scope_ref,并把 window 设置为 second、minute、hour 或 day。它们要求提供 max_requests、max_tokens 或两者。Token 上限适用于分钟和天窗口——天窗口正是为团队设置每日 Token 配额的方式,对应条件式策略里按条件组生效的 tpd 限额。AISIX Cloud 会拒绝秒或小时窗口上的 Token 上限。对于开源 AISIX 网关,资源 Schema 虽 接受该配置,但运行时不会执行相应上限。
在 AISIX Cloud 中,每个环境对于每种作用域和目标只能包含一个经典策略。作用域和目标在创建后不能更改。
导出经典策略要限制的调用方 API Key ID:
export API_KEY_ID="YOUR_CALLER_API_KEY_ID"
然后为该调用方 API Key 创建每分钟一次请求的策略:
curl -sS -X POST "${AISIX_CP}/environments/${ENV_ID}/rate_limits" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"name": "rate-limited-app-policy",
"scope": "api_key",
"scope_ref": "${API_KEY_ID}",
"window": "minute",
"max_requests": 1
}
EOF
控制台使用 Legacy 标记经典策略,并显示对应的条件形式。一键 convert 操作会以条件形式重新创建经典策略。转换会重新开始计数,且无法撤销。对于模型作用域的路由、语义或 ensemble 父模型,转换还可能按上文所述改变配额消耗。如果不转换,仍可编辑经典策略的名称、窗口、上限和暂停计划。
按计划暂停策略
两种形式的策略都可以在 schedules 中包含周期性暂停窗口。任一窗口匹配时,AISIX 会跳过该策略;窗口结束后恢复执行。
计划行为如下:
- 窗口使用
days_of_week每周重复,或使用dates指定日历日期;两者互斥。 start_time和end_time在窗口的 IANAtimezone中使用HH:MM。24:00仅可用于end_time,表示当天结束。end_time早于start_time时,窗口会跨越午夜, 并归属于开始日。例如,周五22:00到09:00覆盖周五夜间至周六上午。- 多个窗口取并集;任一窗口匹配时策略都会暂停。
- 暂停不会重置计数器。窗口开启和关闭时,配额桶会保留计数。
- 预算、身份认证和安全护栏仍然生效,因为暂停的只有该限流策略。
以下计划会在周末、节假日以及每晚 22:00 至次日 09:00 暂停策略。夜间窗口包含周日,因此可以覆盖周一 09:00 之前:
{
"schedules": [
{
"timezone": "Asia/Shanghai",
"days_of_week": ["mon", "tue", "wed", "thu", "fri", "sun"],
"start_time": "22:00",
"end_time": "09:00"
},
{
"timezone": "Asia/Shanghai",
"days_of_week": ["sat", "sun"],
"start_time": "00:00",
"end_time": "24:00"
},
{
"timezone": "Asia/Shanghai",
"dates": ["2026-10-01", "2026-10-02", "2026-10-03"],
"start_time": "00:00",
"end_time": "24:00"
}
]
}
AISIX Cloud
在控制台中打开策略的创建或编辑表单。在 Suspension windows 下选择时区,选择每周日期或明确日期,然后设置时间范 围或 All day。策略列表会汇总窗口,并在某个窗口生效时显示 Suspended now 标记。
对于自动化,请导出待更新策略的 ID:
export POLICY_ID="YOUR_RATE_LIMIT_POLICY_ID"
然后使用完整替换列表 PATCH 策略。发送 null 或空列表可移除所有窗口:
curl -sS -X PATCH "${AISIX_CP}/environments/${ENV_ID}/rate_limits/${POLICY_ID}" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"schedules": [
{
"timezone": "Asia/Shanghai",
"days_of_week": ["sat", "sun"],
"start_time": "00:00",
"end_time": "24:00"
}
]
}
EOF
在 schedules 出现之前发布的网关版本会拒绝携带该字段的策略行,并停止执行该策略。添加计划前,请升级所有已接入的网关。不含计划的策略不受影响 。
开源 AISIX 网关
在 resources.yaml 的策略中添加相同窗口。以下示例把周末窗口添加到前面配置的条件策略:
rate_limit_policies:
- name: team-member-default
conditions:
- dimension: team
operator: in
value: [team-blue]
group_by: [member]
limits:
rpm: 1
schedules:
- timezone: Asia/Shanghai
days_of_week: [sat, sun]
start_time: "00:00"
end_time: "24:00"
验证完整资源文件并重新加载网关。所有计划字段和验证规则参见资源文件参考。
故障排除
策略行为不符合预期时,请先确认它可以评估哪些请求属性,以及还有哪些其他限制层会生效。
| 现象 | 检查项 |
|---|---|
| 团队或成员策略未生效。 | 确认调用方 API Key 携带匹配的团队或成员绑定。按 member 分组的策略会跳过未绑定成员的调用方 API Key 请求。 |
| API Key 或模型条件不匹配。 | 在 AISIX Cloud 中使用资源 ID;在开源资源文件中使用条目的 display_name,然后验证并重新加载完整文件。 |
策略暂停期间请求仍返回 429。 | 检查调用方或模型上的直接限制,以及其他匹配策略。计划只会暂停携带它的策略。 |
| 通过 AISIX Cloud 添加的计划未生效。 | 确认策略更改已到达网关,并且所有已接入网关都支持计划。 |
后续步骤
有关资源专属限制、计数器存储和共享执行行为,请查看 API Key 与模型限流。使用指标监控限流拒绝。