

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 速率限制最佳实践
<a name="gateway-rate-limits-best-practices"></a>

本主题提供有关在网关上有效设计、部署和运行速率限制的指导。

## 设计模式
<a name="gateway-rate-limits-best-practices-design-patterns"></a>

 **分层访问 **   
使用相同的维度密钥（`$.context.jwt.sub`或`$.context.jwt.tier`），但每个层级的条目不同，创建多个速率限制。使用已知高级用户的精确条目并将`*`条目作为默认等级。

 **深度防御 **   
多个粒度的层速率限制。例如，将每个目标的 RPS 限制（保护后端容量）与每个调用者 RPM 限制（防止个人滥用）和每个工具的代币限制（控制成本）相结合。

 **基础架构即代码 BatchPut **   
用于`BatchPutGatewayRateLimits`以声明方式管理您的速率限制配置。Batch put 使用 upsert 语义，因此可以安全地从 CI/CD 管道或基础架构模板中重复运行。

 **逐步推出 **   
从宽松的速率限制开始，然后根据观察到的流量模式逐渐收紧限制。在降低限制之前，请监控 `aws.agentcore.gateway.throttle.customer.decision` OTEL 跨度属性和 429 个响应率。

 **紧急封锁 **   
在事件发生期间，使用`rate: 0`条目屏蔽特定的呼叫者、目标或工具。该区块在传播完成后生效（最长 30 秒）。

## 尺寸键选择指南
<a name="gateway-rate-limits-best-practices-dimension-keys"></a>

选择可生成有限、可预测数量的费率桶的维度键：


| 维度键 | 基数 | 建议 | 
| --- | --- | --- | 
|  `targetName`  | 低（已知设置） | 绝佳的选择。用于保护每个目标。 | 
|  `toolName`  | Low-medium | 对于具有已知工具集的 MCP 网关来说，是不错的选择。 | 
|  `qualifiedModelId`  | 低（已知设置） | 非常适合推理网关。 | 
|  `$.context.jwt.sub`  | Medium-high | 适用于每位用户的限制。基数受您的用户群限制。 | 
|  `$.context.jwt.team`  | 低 | 非常适合每队配额。 | 
|  `$.context.iam.principal`  | 中 | 适用于设置中的 IAM-authenticated 每个角色限制。 | 
|  `$.context.jwt.jti`  | 无界 | 不使用。为每个代币创建一个唯一的存储桶。 | 
|  `$.context.jwt.nonce`  | 无界 | 不使用。为每个请求创建一个唯一的存储桶。 | 

**警告**  
无限制的维度密钥（例如`$.context.jwt.jti`或请求范围内的索赔）会创建无限数量的费率区间。这会浪费内存，降低性能，并有效地禁用速率限制，因为每个请求都有自己的存储桶并且永远不会受到限制。

## 代币速率限制注意事项
<a name="gateway-rate-limits-best-practices-token-limits"></a>

由于其基于预算的执法模式，代币利率限制需要特别考虑：
+  **预算利用率：网关**在转发之前估算输入令牌，并记录响应后的实际使用情况。 Short-lived 突发可能会暂时超过配置的速率。
+  **直播选项：**对于直播聊天完成请求 (`/v1/chat/completions`)，当代币速率限制处于活动状态且该选项尚不存在时，网关会自动添加到`"stream_options": {"include_usage": true}`请求正文中。这样可以对 TPM 的执行进行准确的代币核算。
+  **支持的路径：**令牌速率限制仅适用于已知推理路径（`/v1/chat/completions`、`/v1/messages`、`/v1/responses`）上的请求。对其他路径的请求不受令牌限制的限制。
+  **Pass-through 目标：**如果您的目标在不使用已知推理路径的情况下代理到模型提供商，则令牌速率限制不适用。考虑使用请求速率限制或重组目标以使用支持的路径。

## 代币速率限制常见问题解答
<a name="gateway-rate-limits-best-practices-tpm-faq"></a>

本节回答了有关每分钟代币（TPM）执法在实践中如何运作的常见问题。

 **TPM 执法如何运作？**   
该网关使用基于预算的执法模型。当请求到达时，网关会估算输入代币数量，并从您配置的 TPM 预算中预留该金额。如果估算值超过剩余预算，则请求在到达模型之前以 HTTP 429 响应被拒绝。成功完成请求后，网关将初始估算值替换为模型提供者报告的实际代币使用量（输入\+输出代币），从而协调预算。

 **TPM 如何使用提示缓存？**   
网关根据模型提供者在推理响应中返回的`input_tokens`和`output_tokens`值来计算令牌。网关无法独立跟踪或调整提示缓存。是否包含缓存令牌`input_tokens`取决于您的模型提供者报告使用情况的方式——这种行为因提供商而异。请查阅模型提供商的文档，了解提示缓存如何影响报告的令牌数量和有效的 TPM 消耗。

 **如果我的 TPM 限制为 50，而令牌生成器估计 51 个输入令牌，则请求是否受到限制？**   
是。在转发请求之前，网关会根据剩余的 TPM 预算评估代币生成器的估计值。如果估算值超过可用预算，则请求将被拒绝，并发出 HTTP 429 响应。响应中包含一个`retryAfter`字段，表示何时有足够的预算。

 **如果长时间运行的请求消耗的代币比最初估计的多，响应会受到限制吗？**   
没有。一旦网关接受并转发请求，响应将始终完整发送。网关会在请求时预留预估的代币，在请求进行期间，将继续根据剩余预算对其他请求进行评估。响应完成后，网关会将实际使用量与估计值进行核对。如果实际消耗量更高，则调整预算——这可能会导致后续请求受到限制，但最初的响应永远不会中断。

 **代币会计如何处理直播响应？**   
网关使用最终的响应区块作为代币对账的真实来源。并非所有模型提供商都会报告每个流媒体区块中的代币使用情况，有些提供商仅在最后一个区块中报告代币使用情况。网关会等待完整的响应，然后再调整 TPM 预算。对于 OpenAI Chat Completions 直播，当代币速率限制处于活动状态且此选项尚不存在时，网关会自动添加到`"stream_options": {"include_usage": true}`请求正文中，从而确保最后一个区块中提供准确的代币数量。

## 运营注意事项
<a name="gateway-rate-limits-best-practices-operational"></a>

 **传播时间 **   
速率限制更改最多需要 30 秒才能传播。为事件发生期间的延迟做好计划——区块入口（`rate: 0`）不是立即出现的。

 **行为评分为零 **   
速率为 0 会阻止所有匹配的流量。故意使用它来进行紧急封锁。 Double-check 在设置之前输入维度值`rate: 0`以避免意外阻塞合法流量。

 **不可变的维度键 **   
您无法更改`dimensionKeys`现有速率限制。如果您需要不同的维度，请删除现有的速率限制并创建新的速率限制。在创建生产率限制之前，请先规划您的维度密钥结构。

**重要**  
速率限制使用失效开放行为。如果限速服务暂时不可用，则允许流量通过。不要使用速率限制作为唯一的安全机制。将它们与身份验证、授权、网关规则和 WAF 相结合，进行深度防御。

## 监控
<a name="gateway-rate-limits-best-practices-monitoring"></a>

使用以下信号监控速率限制的有效性：

 **受限的响应信号：**
+ 监控来自您的网关的 HTTP 429 响应。
+ 解析受限响应中的`limitKey`字段，以确定触发的是哪个速率限制。
+ 使用该`retryAfter`值来了解执法窗口。

 **OpenTelemetry 跨度属性：**


| 属性 | What to monitor | 
| --- | --- | 
|  `aws.agentcore.gateway.throttle.customer.decision = throttled`  | 受限制的请求数。出现意外峰值时发出警报。 | 
|  `aws.agentcore.gateway.throttle.customer.limit_key`  | 确定哪些速率限制最为活跃。寻找不平衡的执法。 | 
|  `aws.agentcore.gateway.throttle.customer.metric`  | 确定请求、令牌或连接是否是瓶颈。 | 
|  `aws.agentcore.gateway.throttle.customer.matched_entry`  | 确定哪些呼叫者或目标最常达到极限。 | 
|  `aws.agentcore.gateway.throttle.customer.evaluated`  | 所有已检查存储桶的订购清单。有助于了解哪些限制适用于特定请求。 | 

 **监控查询示例：**

使用 CloudWatch 日志组上的亚马逊`aws/spans`日志见解来查询网关的 OTEL 跨度。以下示例有助于识别节流模式。

按速率限制计算受限制的请求：

```
filter attributes.`aws.agentcore.gateway.throttle.customer.decision` = "throttled"
| stats count(*) as throttle_count by attributes.`aws.agentcore.gateway.throttle.customer.limit_key`
| sort throttle_count desc
```

确定哪些来电者受到的限制最大：

```
filter attributes.`aws.agentcore.gateway.throttle.customer.decision` = "throttled"
| stats count(*) as throttle_count by attributes.`aws.agentcore.gateway.throttle.customer.matched_entry`
| sort throttle_count desc
| limit 20
```

比较一段时间内允许的请求和限制的请求：

```
filter ispresent(attributes.`aws.agentcore.gateway.throttle.customer.decision`)
| stats count(*) as total,
        sum(attributes.`aws.agentcore.gateway.throttle.customer.decision` = "throttled") as throttled
  by bin(5m)
```

如果单一速率限制导致了大多数油门事件，请考虑配置的速率是否过于严格，或者流量模式是否表明存在滥用情况。

## 根据速率限制跨度创建警报
<a name="gateway-rate-limits-best-practices-alarms"></a>

您可以将速率限制 OTEL 跨度属性转换为 CloudWatch 指标和警报，以主动监控节流行为。这需要启用网关可观察性（请参阅[启用 AgentCore 网关资源](observability-configure.md#observability-configure-cloudwatch)的可观察性）。

### 步骤 1：启用网关跨度
<a name="_step_1_enable_gateway_spans"></a>

确保您的网关启用了可观察性。网关跨度导出到 CloudWatch 交易搜索 CloudWatch 和生成式 AI 可观测性页面并可在其中查看。

### 第 2 步：创建 CloudWatch 指标筛选条件
<a name="_step_2_create_a_cloudwatch_metric_filter"></a>

在`aws/spans`日志组上创建指标筛选器，将油门事件提取为自定义指标。以下示例创建了一个指标，该指标按速率限制对受限制的请求进行计数：

```
{
  "filterPattern": "{ $.attributes.aws\\.agentcore\\.gateway\\.throttle\\.customer\\.decision = \"throttled\" }",
  "metricTransformations": [
    {
      "metricName": "GatewayRateLimitThrottleCount",
      "metricNamespace": "AgentCore/Gateway/RateLimits",
      "metricValue": "1",
      "defaultValue": 0,
      "dimensions": {
        "LimitKey": "$.attributes.aws\\.agentcore\\.gateway\\.throttle\\.customer\\.limit_key"
      }
    }
  ]
}
```

### 第 3 步：创建 CloudWatch 警报
<a name="_step_3_create_a_cloudwatch_alarm"></a>

指标过滤器到位后，创建警报，当油门速率超过阈值时触发。

**Example**  

1. 运行以下命令：

   ```
   aws cloudwatch put-metric-alarm \
       --alarm-name "GatewayRateLimitThrottleSpike" \
       --namespace "AgentCore/Gateway/RateLimits" \
       --metric-name "GatewayRateLimitThrottleCount" \
       --statistic Sum \
       --period 300 \
       --evaluation-periods 1 \
       --threshold 100 \
       --comparison-operator GreaterThanThreshold \
       --alarm-description "Alert when rate limit throttles exceed 100 in 5 minutes" \
       --alarm-actions "arn:aws:sns:us-west-2:123456789012:my-alarm-topic"
   ```

1. 

   ```
   import boto3
   
   cloudwatch = boto3.client("cloudwatch", region_name="us-west-2")
   
   cloudwatch.put_metric_alarm(
       AlarmName="GatewayRateLimitThrottleSpike",
       Namespace="AgentCore/Gateway/RateLimits",
       MetricName="GatewayRateLimitThrottleCount",
       Statistic="Sum",
       Period=300,
       EvaluationPeriods=1,
       Threshold=100,
       ComparisonOperator="GreaterThanThreshold",
       AlarmDescription="Alert when rate limit throttles exceed 100 in 5 minutes",
       AlarmActions=["arn:aws:sns:us-west-2:123456789012:my-alarm-topic"],
   )
   
   print("Alarm created successfully")
   ```

### 第 4 步：构建仪表板
<a name="_step_4_build_a_dashboard"></a>

创建 CloudWatch 仪表板以可视化一段时间内的油门率。以下控件配置显示按速率限制分组的油门次数：

```
{
  "metrics": [
    [
      "AgentCore/Gateway/RateLimits",
      "GatewayRateLimitThrottleCount",
      "LimitKey", "per-target-rps"
    ],
    [
      "AgentCore/Gateway/RateLimits",
      "GatewayRateLimitThrottleCount",
      "LimitKey", "per-caller-rpm"
    ]
  ],
  "period": 60,
  "stat": "Sum",
  "title": "Rate Limit Throttles by Limit"
}
```

**提示**  
您还可以使用内置`Throttles`指标（默认情况下在网关调用指标下可用）来计算总节流次数，而不考虑每个限制的粒度。当您需要每个限制或每个呼叫者可见性时，对跨度属性使用自定义指标过滤器。