PromptTokenLimit 政策

本页面适用于 Apigee,但不适用于 Apigee Hybrid

查看 Apigee Edge 文档。

概览

PromptTokenLimit 政策通过限制用户提示中的 token 数量来保护大语言模型 (LLM) 后端免受流量激增的影响。

PromptTokenLimit 政策与 SpikeArrest 政策类似;不过,SpikeArrest 政策限制的是请求数量,而 PromptTokenLimit 政策限制的是这些请求中的令牌数量。 此政策专门针对 LLM 应用量身定制,其中费用和性能直接与处理的 token 数量相关。

此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型

PromptTokenLimit 和 LLMTokenQuota 之间的区别

PromptTokenLimit 政策用于运营流量管理,以防止令牌使用量突然激增。相比之下,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 不适用 必需

政策的内部名称。name 属性的值可以包含字母、数字、空格、连字符、下划线和英文句点。此值不能超过 255 个字符。

(可选)使用 <DisplayName> 元素在管理界面代理编辑器中给政策添加不同的自然语言名称标签。

continueOnError false 可选 设置为 false 可在政策失败时返回错误。这是大多数政策的预期行为。设置为 true,即使在政策失败后,仍可以继续执行流。另请参阅:
enabled true 可选 设置为 true 可实施政策。 设为 false 可关闭政策。即使政策仍附加到某个流,也不会强制执行该政策。
async   false 已弃用 此属性已弃用。

示例

以下示例展示了使用 PromptTokenLimit 政策的一些方法:

示例 1

单个副本中的提示 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 限制。

在此示例中,提示令牌限制分布在一个区域中的多个副本中,并采用“滑动窗口”速率限制算法。

<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 限制。

在此示例中,提示令牌限制发生在单个副本内,不会分布在区域中的多个消息处理器之间。此特定配置用于限制每个请求的上下文窗口大小令牌。

<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

使用默认值进行分布式令牌限制。

在此示例中,提示令牌限制发生在单个副本内,不会分布在区域中的多个消息处理器之间。使用用户提示来源默认值: {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>

通过设置每分钟或每秒允许的令牌数来指定采用哪个速率限制令牌高峰(或爆发)。 您可以将该元素与 <Identifier> 结合使用,通过接受客户端的值来在运行时平滑限制流量。 使用 <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 个令牌:

<PromptTokenLimit name="PTL-Static-5ps">
  <Rate>5ps</Rate>
  <UseEffectiveCount>false</UseEffectiveCount>
</PromptTokenLimit>
        

此政策将速率平滑处理为每 200 毫秒 (1000/5) 允许一个令牌。

示例 2

以下示例将速率设置为每分钟 12 个令牌:

<PromptTokenLimit name="PTL-Static-12pm">
  <Rate>12pm</Rate>
  <UseEffectiveCount>false</UseEffectiveCount>
</PromptTokenLimit>

此示例政策将速率平滑处理为每五秒 (60/12) 允许一个令牌。

下表介绍 <Rate> 的特性:

属性 说明 状态 默认值
ref 标识用于指定速率的流变量。这可以是任何流程变量(例如 HTTP 查询参数、标头或消息正文内容),也可以是 KVM 等值。如需了解详情,请参阅流变量参考文档

您还可以通过 JavaScript 政策AssignMessage 政策使用自定义变量。

如果您同时定义 ref此元素的正文,则在请求中设置流变量时,系统会应用 ref 的值。(如果在请求中未设置 ref 中标识的变量,则正好相反)。

例如:

<Rate ref="request.header.custom_rate">1pm</Rate>

在此示例中,如果客户端未传递 custom_rate 标头,则 API 代理的速率是所有客户端每分钟 1 个令牌。如果客户端传递 custom_rate 标头(其值为 10ps),则速率限制是代理上所有客户端每秒 10 个请求,直到发送不带 custom_rate 标头的请求。

您可以使用 <Identifier> 对请求类型进行分组,以便对不同类型的客户端强制执行自定义速率。

如果您为 ref 指定了值,但没有在 <Rate> 元素的正文中设置速率,而客户端没有传递值,则 PromptTokenLimit 政策会抛出一个错误。

可选 不适用
下表介绍了 Rate 的属性,这些属性用于定义流量限制行为:
属性 说明
messagesPerPeriod 指定在定义的时间段内允许的令牌数量。例如,如果某项政策配置为“10ps”(每秒 10 个令牌),则 messagesPerPeriod 值为 10。
periodInMicroseconds 定义计算 messagesPerPeriod 的时间段(以微秒为单位)。对于“10ps”配置,此值为 1,000,000,相当于 1 秒。
maxBurstMessageCount 表示在新的时间间隔开始时可以立即或在短时间内允许的令牌数上限。

<UseEffectiveCount>

借助该元素,您可以将值设为 truefalse,从而在不同的 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 政策将使用“令牌桶”算法,通过将指定的速率限制划分为更小的时间间隔来平滑令牌高峰。这种方法的缺点是,短时间内传入的多个合法令牌可能会被拒绝。

举例来说,假设您输入了一个 30pm 的速率(每分钟 30 个令牌)。在测试时,您可能认为您可以在 1 秒内发送 30 个令牌,只要在 1 分钟内即可。但该政策并非这样执行这种设置的。如果您思考一下就会明白,某些环境中 1 秒钟内 30 个令牌会被视为是一个小型高峰。

  • 每分钟速率可以以为时间间隔,平滑发送允许的全部请求。

    例如,30pm 会按以下所示实现平滑发送:
    60 秒(1 分钟)/ 30pm = 间隔时间为 2 秒,或每 2 秒允许 1 个令牌。2 秒内发出的第二个令牌将会失败。同时,一分钟内发出的第 31 个令牌将会失败。

  • 每秒速率会以毫秒为时间间隔,平滑发送允许的全部请求。

    例如,10ps 会按以下所示实现平滑发送:
    1000 毫秒(1 秒钟)/10ps = 间隔时间为 100 毫秒,或每 100 毫秒允许 1 个令牌。100 毫秒内发出的第二个令牌将会失败。同时,一秒钟内发出的第 11 个令牌将会失败。

默认值 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 布尔值 只读 指示政策是否失败(truefalse)。
ratelimit.POLICY_NAME.resolvedUserPrompt 字符串 只读 返回提取的用户提示。
ratelimit.POLICY_NAME.userPromptSource 字符串 只读 返回政策中指定的用户提示的消息模板。
ratelimit.POLICY_NAME.userPromptTokenCount 字符串 只读 返回提取的用户提示的令牌数量。

如需了解详情,请参阅流变量参考文档

错误参考信息

本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 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>JavaScript-1</Name>
            <Condition>(fault.name Matches "PromptTokenLimitViolation") </Condition>
        </Step>
        <Condition>ratelimit.PTL-1.failed=true</Condition>
    </FaultRule>
</FaultRules>

超出 LLMTokenQuota 或 PromptTokenLimit 政策设置的速率限制的当前 HTTP 状态代码为 429(请求过多)。

架构

每种政策类型均由 XML 架构 (.xsd) 定义。GitHub 提供了政策架构作为参考。

相关主题