本页面适用于 Apigee,但不适用于 Apigee Hybrid。
查看 Apigee Edge 文档。
概览
PromptTokenLimit 政策通过限制用户提示中的 token 数量来保护大语言模型 (LLM) 后端 免受流量激增的影响。
PromptTokenLimit 政策与 SpikeArrest 政策类似; 不过,SpikeArrest 政策限制的是请求数量,而 PromptTokenLimit 政策限制的是这些请求中的 token 数量。 此政策专门针对 LLM 应用量身定制,因为在 LLM 应用中,费用和 性能与处理的 token 数量直接相关。
此政策是一项 可扩展政策,使用此政策可能会影响费用或 使用情况,具体取决于您的 Apigee 许可。如需了解政策类型 和使用情况影响,请参阅 政策类型。
PromptTokenLimit 和 LLMTokenQuota 之间的区别
PromptTokenLimit 政策用于运营流量管理,以 防止 token 使用量突然激增。相比之下, LLMTokenQuota 政策用于在较长时间段(例如数小时、数天或数月)内对 客户端应用强制执行消耗量限制,以管理 费用和执行业务协议。
PromptTokenLimit 元素
定义 PromptTokenLimit 政策。
| 默认值 | 请参阅下面的默认政策标签页 |
| 是否必需? | 可选 |
| 类型 | 复杂对象 |
| 父元素 | 不适用 |
| 子元素 |
<Identifier><Rate>(必需)<UseEffectiveCount><UserPromptSource><IgnoreUnresolvedVariables> |
语法
PromptTokenLimit 元素使用以下语法:
<PromptTokenLimit continueOnError="false" enabled="true" name="POLICY_NAME">
<DisplayName></DisplayName>
<Properties/>
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
<Identifier ref=""/>
<Rate ref="">[pm|ps]</Rate>
<UseEffectiveCount>[false|true]</UseEffectiveCount>
<IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</PromptTokenLimit>
默认政策
以下示例显示了在界面中将 PromptTokenLimit 政策添加至您的 流时的默认设置:
<PromptTokenLimit continueOnError="false" enabled="true" name="PTL-limitTokens-1">
<DisplayName></DisplayName>
<Properties/>
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
<Identifier ref=""/>
<Rate ref="">[pm|ps]</Rate>
<UseEffectiveCount>[false|true]</UseEffectiveCount>
<IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</PromptTokenLimit>
此元素具有所有政策中常见的以下属性:
| 属性 | 默认 | 是否必需? | 说明 |
|---|---|---|---|
name |
不适用 | 必需 |
政策的内部名称。 (可选)使用 |
continueOnError |
false | 可选 | 设置为 false 可在政策失败时返回错误。这是大多数政策的预期行为。设置为 true,即使在政策失败后,仍可以继续执行流。另请参阅:
|
enabled |
true | 可选 | 设置为 true 可实施政策。 设为 false 可关闭政策。即使政策仍附加到某个流,也不会强制执行该政策。 |
async |
false | 已弃用 | 此属性已弃用。 |
示例
以下示例展示您可以使用 PromptTokenLimit 政策的一些方法:
示例 1
在单个副本中限制提示 token。
在此示例中, 提示 token 限制发生在单个副本中,不会 分布在区域中的多个消息处理器中。
<PromptTokenLimit continueOnError="false" enabled="true" name="PTL-limitTokens-1">
<DisplayName></DisplayName>
<Properties/>
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
<Identifier ref="request.url"/>
<Rate>1pm</Rate>
<UseEffectiveCount>false</UseEffectiveCount>
</PromptTokenLimit>示例 2
分布式 token 限制。
在此示例中,提示 token 限制分布在区域中的多个 副本中,并且采用了“滑动窗口”速率限制算法。
<PromptTokenLimit continueOnError="false" enabled="true" name="PTL-limitTokens-1">
<DisplayName></DisplayName>
<Properties/>
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
<Identifier ref="request.url"/>
<Rate>1pm</Rate>
<UseEffectiveCount>true</UseEffectiveCount>
</PromptTokenLimit>示例 3
每个请求的上下文窗口大小 token 限制。
在此示例中,提示 token 限制发生在单个 副本中,不会分布在区域中的多个消息处理器中。此特定配置用于每个请求的上下文窗口大小 token 限制。
<PromptTokenLimit continueOnError="false" enabled="true" name="PTL-limitTokens-1">
<DisplayName></DisplayName>
<Properties/>
<UserPromptSource>{jsonPath('$.messages',request.content,true)}</UserPromptSource>
<Identifier ref="messageid"/>
<Rate>1pm</Rate>
<UseEffectiveCount>false</UseEffectiveCount>
</PromptTokenLimit>示例 4
具有默认值的分布式 token 限制。
在此示例中,提示 token 限制发生在单个
副本中,不会分布在区域中的多个消息处理器中。系统使用了用户提示来源默认值:
{jsonPath('$.messages',request.content,true)}
<PromptTokenLimit continueOnError="false" enabled="true" name="PTL-limitTokens-1"> <DisplayName></DisplayName> <Properties/> <Identifier ref="messageid"/> <Rate>1pm</Rate> <UseEffectiveCount>false</UseEffectiveCount> </PromptTokenLimit>
子元素参考
本部分介绍 <PromptTokenLimit> 的子元素。
<DisplayName>
除了用于 name 属性之外,还可用于在管理界面代理编辑器中使用其他更加自然的名称标记政策。
<DisplayName> 元素适用于所有政策。
| 默认值 | 不适用 |
| 是否必需? | 可选。如果省略 <DisplayName>,则会使用政策的 name 属性的值 |
| 类型 | 字符串 |
| 父元素 | <PolicyElement> |
| 子元素 | 无 |
<DisplayName> 元素使用以下语法:
语法
<PolicyElement> <DisplayName>POLICY_DISPLAY_NAME</DisplayName> ... </PolicyElement>
示例
<PolicyElement> <DisplayName>My Validation Policy</DisplayName> </PolicyElement>
<DisplayName> 元素没有属性或子元素。
<Identifier>
您可以选择对请求进行分组的方式,从而根据客户端应用 PromptTokenLimit 政策。例如,您可以按开发者 ID 对请求进行分组,这种情况下,每个开发者的请求将计入他们自己的 PromptTokenLimit 速率,而不是向代理进行的所有请求。
如果您将 <Identifier> 元素留空,系统会对发送到该 API 代理的所有请求
强制执行一个速率限制。
| 默认值 | 不适用 |
| 是否必需? | 可选 |
| 类型 | 字符串 |
| 父元素 |
<PromptTokenLimit>
|
| 子元素 | 无 |
语法
<PromptTokenLimit continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <Identifier ref="FLOW_VARIABLE"/> </PromptTokenLimit>
示例 1
以下示例按开发者 ID 实施 PromptTokenLimit 政策:
<PromptTokenLimit name="PTL-limitTokens-1">
<Identifier ref="developer.id"/>
<Rate>42pm</Rate/>
<UseEffectiveCount>true</UseEffectiveCount>
</PromptTokenLimit>
下表介绍 <Identifier> 的特性:
| 属性 | 说明 | 默认值 | 状态 |
|---|---|---|---|
ref |
确定 PromptTokenLimit 组传入请求的变量。 您可以使用任何流程变量来表示唯一客户端,例如使用 VerifyAPIKey 政策的客户端。此外,您还可以使用 JavaScript 政策或 AssignMessage 政策设置自定义变量。 | 不适用 | 必需 |
<Rate>
通过设置每分钟或每秒允许的 token 数来指定采用哪个速率限制 token 峰值(或爆发)。
您可以将该元素与 <Identifier> 结合使用,通过接受客户端的值来在运行时平滑节流流量。使用 <UseEffectiveCount> 元素设置政策使用的速率限制
算法。
<UseEffectiveCount>.
| 默认值 | 不适用 |
| 是否必需? | 必需 |
| 类型 | 整数 |
| 父元素 |
<PromptTokenLimit>
|
| 子元素 | 无 |
语法
您可以通过以下某种方式指定速率:
- 指定为
<Rate>元素的正文的静态速率 - 变量值,可由客户端传递;使用
ref属性标识流变量的名称
<PromptTokenLimit
continueOnError="[false|true]"
enabled="[true|false]"
name="POLICY_NAME"
>
<Rate ref="FLOW_VARIABLE">RATE[pm|ps]</Rate>
</PromptTokenLimit>有效的速率值(定义为变量值或在元素的正文中)必须 遵循以下格式:
intps(每秒 token 数,以毫秒为单位进行平滑处理)intpm(每分钟 token 数,以秒为单位进行平滑处理)
int 的值必须是非零正整数。
示例 1
以下示例将速率设置为每秒 5 个 token:
<PromptTokenLimit name="PTL-Static-5ps">
<Rate>5ps</Rate>
<UseEffectiveCount>false</UseEffectiveCount>
</PromptTokenLimit>
此政策将速率平滑处理为每 200 毫秒 (1000/5) 允许一个 token。
示例 2
以下示例将速率设置为每分钟 12 个 token:
<PromptTokenLimit name="PTL-Static-12pm"> <Rate>12pm</Rate> <UseEffectiveCount>false</UseEffectiveCount> </PromptTokenLimit>
此示例政策将速率平滑处理为每五 秒 (60/12) 允许一个 token。
下表介绍 <Rate> 的特性:
| 属性 | 说明 | 状态 | 默认值 |
|---|---|---|---|
ref |
标识用于指定速率的流变量。这可以是任何流程变量(例如 HTTP 查询参数、标头或消息正文内容),也可以是 KVM 等值。如需了解详情,请参阅流变量参考文档。 您还可以通过 JavaScript 政策或 AssignMessage 政策使用自定义变量。 如果您同时定义 例如: <Rate ref="request.header.custom_rate">1pm</Rate> 在此示例中,如果客户端没有传递 标头,则 您可以使用 如果您为 |
可选 | 不适用 |
Rate 的属性,这些属性用于定义流量限制行为:
| 属性 | 说明 |
|---|---|
messagesPerPeriod |
指定在定义的时间段内允许的 token 数量。例如,如果某项政策配置为“10ps”(每秒 10 个 token),则 messagesPerPeriod 值为 10。 |
periodInMicroseconds |
定义计算
messagesPerPeriod 的时间段(以微秒为单位)。对于“10ps”配置,此值为 1,000,000,相当于 1 秒。 |
maxBurstMessageCount |
表示在新的时间间隔开始时可以立即或在短时间内允许的 token 数上限。 |
<UseEffectiveCount>
借助该元素,您可以将值设为 true 或 false,从而在不同的 PromptTokenLimit 算法之间进行选择,如下所述:
true
如果设置为 true,则 PromptTokenLimit 分布在一个区域中。这意味着
请求计数在该区域内的消息处理器 (MP) 之间同步。此外,系统还将采用“滑动窗口”速率限制算法。此算法提供一致的速率限制行为,并且无法“平滑”发送到后端的传入请求数。如果在很短的时间间隔内发送突发的大量请求,只要这些请求不超过 <Rate> 元素中配置的速率限制,系统就会允许这些请求通过。例如:
<PromptTokenLimit name="Prompt-Token-Limit-1"> <Rate>12pm</Rate> <Identifier ref="client_id" /> <UseEffectiveCount>true</UseEffectiveCount> </PromptTokenLimit>
false(默认)
如果设置为 false(默认),PromptTokenLimit 政策
使用
“令牌桶”
算法,通过将指定的速率限制划分为更小的时间间隔来平滑 token 峰值。这种方法的缺点是,
短时间内传入的多个合法 token 可能会被拒绝。
举例来说,假设您输入了一个 30pm 的速率(每分钟 30 个 token)。在 测试时,您可能认为您可以在 1 秒内发送 30 个 token,只要 在 1 分钟内即可。但该政策并非这样执行这种 设置的。如果您思考一下就会明白,某些环境中 1 秒钟内 30 个 token 会被视为是一个小型高峰。
-
每分钟 速率可以以 秒 为时间间隔,平滑发送允许的全部请求。
例如,30pm 会按以下所示实现平滑发送:
60 秒(1 分钟)/ 30pm = 间隔时间为 2 秒,或每 2 秒允许 1 个 token。2 秒内发出的第二个 token 将会失败。同时,一分钟内发出的第 31 个 token 将会失败。 -
每秒 速率可以以 毫秒 为时间间隔,平滑发送允许的全部请求。
例如,10ps 会按以下所示实现平滑发送:
1000 毫秒(1 秒钟)/10ps = 间隔时间为 100 毫秒,或每 100 毫秒允许 1 个 token。100 毫秒内发出的第二个 token 将会失败。同时,一秒钟内发出的第 11 个 token 将会失败。
| 默认值 | False |
| 是否必需? | 可选 |
| 类型 | 布尔值 |
| 父元素 |
<PromptTokenLimit>
|
| 子元素 | 无 |
下表说明了 <UseEffectiveCount> 元素的属性:
| 属性 | 说明 | 默认值 | 状态 |
|---|---|---|---|
ref |
标识包含 <UseEffectiveCount> 值的变量。这可以是任何流变量,例如 HTTP 查询参数、标头或消息正文内容。如需了解详情,请参阅流变量参考文档。此外,您还可以使用 JavaScript 政策 或 AssignMessage 政策 设置自定义变量
。 |
不适用 | 可选 |
<UserPromptSource>
提供用于检索用户提示文本的来源。使用 消息模板。
消息模板应提供用户提示文本的单个值。
例如,{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}。
| 默认值 | 不适用 |
| 是否必需? | 可选 |
| 类型 | 字符串 |
| 父元素 |
<PromptTokenLimit>
|
| 子元素 | 无 |
语法
<PromptTokenLimit
continueOnError="[false|true]"
enabled="[true|false]"
name="POLICY_NAME">
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
</PromptTokenLimit>示例 1
<PromptTokenLimit name="Prompt-Token-Limit-1">
<UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource>
</PromptTokenLimit><IgnoreUnresolvedVariables>
确定在遇到无法解析的变量时处理是否停止。
设置为 true 可忽略无法解析的变量并继续处理;否则
false。默认值为 false。
| 默认值 | False |
| 是否必需? | 可选 |
| 类型 | 布尔值 |
| 父元素 |
<PromptTokenLimit>
|
| 子元素 | 无 |
语法
<PromptTokenLimit
continueOnError="[false|true]"
enabled="[true|false]"
name="POLICY_NAME">
<IgnoreUnresolvedVariables>[true|false]</IgnoreUnresolvedVariables>
</PromptTokenLimit>示例
<PromptTokenLimit name="Prompt-Token-Limit-1"> <Rate>10ps</Rate> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </PromptTokenLimit>
流变量
PromptTokenLimit 政策执行时,系统会填充以下流变量:
| 变量 | 类型 | 权限 | 说明 |
|---|---|---|---|
ratelimit.POLICY_NAME.failed |
布尔值 | 只读 | 如果政策遇到内部执行
失败,则此变量为 true。不应 使用此变量来检查是否超出速率限制。
由于政策的
"故障开放"设计,在高负载下可能会将其设置为 true。 |
ratelimit.POLICY_NAME.resolvedUserPrompt |
字符串 | 只读 | 返回提取的用户提示。 |
ratelimit.POLICY_NAME.userPromptSource |
字符串 | 只读 | 返回政策中指定的用户提示的消息模板。 |
ratelimit.POLICY_NAME.userPromptTokenCount |
字符串 | 只读 | 返回提取的用户提示的 token 计数。 |
如需了解详情,请参阅流变量参考文档。
错误参考信息
本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。您可能还会看到 SpikeArrest 政策错误。 在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅 有关政策错误的注意事项和 处理故障。
运行时错误
政策执行时可能会发生这些错误。
| 故障代码 | HTTP 状态 | Apigee 故障 | 原因 | 修复 |
|---|---|---|---|---|
policies.prompttokenlimit.FailedToExtractUserPrompt |
400 |
FALSE | 无法从 API 请求中提取用户提示。 | |
policies.prompttokenlimit.PromptTokenLimitViolation |
429 |
FALSE | PromptTokenLimit 违规。 | |
policies.prompttokenlimit.FailedToCalculateUserPromptTokens |
500 |
TRUE | 无法为用户提示计算令牌。 |
部署错误
在您部署包含此政策的代理时,可能会发生这些错误。
| 故障代码 | HTTP 状态 | Apigee 故障 | 原因 | 修复 |
|---|---|---|---|---|
policies.prompttokenlimit.MessageWeightNotSupported |
500 | FALSE | PromptTokenLimit 政策不支持 MessageWeight。 |
故障变量
发生运行时错误时,系统会设置这些变量。如需了解详情,请参阅 您需要了解的有关政策错误的信息。
| 变量 | 其中 | 示例 |
|---|---|---|
ratelimit.policy_name.fault.name |
fault_name 是故障名称,如上面的运行时错误表中所列。故障名称是故障代码的最后一部分。 | fault.name Matches "PromptTokenLimitViolation" |
ratelimit.policy_name.failed |
policy_name 是抛出故障的政策的用户指定名称。 | ratelimit.PTL-PromptTokenLimitPolicy.failed = true |
错误响应示例
错误响应的示例如下所示:
{ "fault":{ "detail":{ "errorcode":"policies.prompttokenlimit.PromptTokenLimitViolation" }, "faultstring":"Prompt Token Limit Violation. Allowed rate : MessageRate{capacity=10, period=Minutes}" } }
故障规则示例
下面显示了用于处理 PromptTokenLimitViolation 故障的故障规则示例:
<FaultRules>
<FaultRule name="Prompt Token Limit Errors">
<Step>
<Name>Assign-Message-1</Name>
</Step>
<Condition>(fault.name Matches "PromptTokenLimitViolation")</Condition>
</FaultRule>
</FaultRules>超出 LLMTokenQuota 或 PromptTokenLimit 政策设置的速率限制的当前 HTTP 状态代码为 429(请求过多)。
架构
每种政策类型均由 XML 架构 (.xsd) 定义。GitHub 提供了政策架构作为参考。
相关主题
- LLMTokenQuota 政策:LLMTokenQuota 政策,用于限制响应 token 配额使用量。
- 速率限制,让您大致了解速率限制
- 比较速率限制政策