ai-prompt-guard
ai-prompt-guard 插件通过检查和验证传入的提示词消息来保护你的 LLM 端点。它根据用户定义的允许和拒绝模式检查请求内容,确保只有批准的输入被转发到上游 LLM。根据配置,该插件可以仅检查最新消息或整个对话历史记录,并且可以设置为检查所有角色的提示词或仅检查最终用户的提示词。
当同时配置了 allow_patterns 和 deny_patterns 时,插件首先确保至少匹配一个 allow_patterns。如果没有匹配,请求将被拒绝。如果匹配了允许模式,它会接着检查是否出现了拒绝模式。
演示
以下演示展示了如何在 API7 企业版控制台中完成配置允许和拒绝模式示例:你可以同时定义允许模式和拒绝模式来验证用户提示词,并了解允许模式如何优先生效。
示例
以下示例将使用 OpenAI 作为上游模型服务提供方。在开始之前,请创建一个 OpenAI 账号 并获取 API Key。你可以选择将密钥保存到环境变量中,如下所示:
export OPENAI_API_KEY=YOUR_OPENAI_API_KEY # 替换为你的 API Key
如果你使用其他模型服务提供方,请参考该提供方的文档获取 API Key。
实现允许和拒绝模式
以下示例演示了如何使用 ai-prompt-guard 插件通过定义允许和拒绝模式来验证用户提示词,并理解允许模式的优先级。
定义允许和拒绝模式。你可以选择将它们保存到环境变量中以便更容易转义:
# 允许美元金额
export ALLOW_PATTERN_1='\\$?\\(?\\d{1,3}(,\\d{3})*(\\.\\d{1,2})?\\)?'
# 拒绝美国号码格式的电话号码
export DENY_PATTERN_1='(\\([0-9]{3}\\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- Admin API
- ADC
- Ingress Controller
创建一个使用 ai-proxy 代理到 OpenAI 并使用 ai-prompt-guard 检查输入提示词的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "ai-prompt-guard-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer '"$OPENAI_API_KEY"'"
}
},
"options":{
"model": "gpt-4"
}
},
"ai-prompt-guard": {
"allow_patterns": [
"'"$ALLOW_PATTERN_1"'"
],
"deny_patterns": [
"'"$DENY_PATTERN_1"'"
]
}
}
}'
❶ 指定提供商为 openai。
❷ 在 Authorization 请求头中以 Bearer Token 形式附带 OpenAI API Key。
❸ 指定模型名称。
❹ 允许匹配任何美元金额的消息模式。
❺ 拒绝包含任何美国电话号码格式的消息模式。
创建一个配置了 ai-prompt-guard 和 ai-proxy 插 件的路由,如下所示:
services:
- name: prompt-guard-service
routes:
- name: prompt-guard-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: "Bearer ${OPENAI_API_KEY}"
options:
model: gpt-4
ai-prompt-guard:
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
将配置同步到网关:
adc sync -f adc.yaml
❶ 指定提供商为 openai。
❷ 在 Authorization 请求头中以 Bearer Token 形式附带 OpenAI API Key。
❸ 指定模 型名称。
❹ 允许匹配任何美元金额的消息模式。
❺ 拒绝包含任何美国电话号码格式的消息模式。
- Gateway API
- APISIX CRD
创建一个配置了 ai-prompt-guard 和 ai-proxy 插件的路由,如下所示:
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-prompt-guard-plugin-config
spec:
plugins:
- name: ai-prompt-guard
config:
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- name: ai-proxy
config:
provider: openai
auth:
header:
Authorization: "Bearer YOUR_OPENAI_API_KEY"
options:
model: gpt-4
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: prompt-guard-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-prompt-guard-plugin-config
将配置应用到集群:
kubectl apply -f ai-prompt-guard-ic.yaml
❶ 配置允许模式,以匹配任意美元金额。
❷ 配置拒绝模式,以匹配任意美国电话号码格式。
❸ 在 Authorization 请求头中附带 OpenAI API Key。
❹ 指定模型名称。
创建一个配置了 ai-prompt-guard 和 ai-proxy 插件的路由,如下所示:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: prompt-guard-route
spec:
ingressClassName: apisix
http:
- name: prompt-guard-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-prompt-guard
enable: true
config:
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- name: ai-proxy
enable: true
config:
provider: openai
auth:
header:
Authorization: "Bearer YOUR_OPENAI_API_KEY"
options:
model: gpt-4
将配置应用到集群:
kubectl apply -f ai-prompt-guard-ic.yaml
❶ 配置允许模式,以匹配任意美元金额。
❷ 配置拒绝模式,以匹配任意美国电话号码格式。
❸ 在 Authorization 请求头中附带 OpenAI API Key。
❹ 指定模型名称。
向该路由发送请求以评价一次购买的公允性:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
...
"model": "gpt-4-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The purchase is not at a decent price. Typically, a hot brewed coffee costs anywhere from $1 to $3 in most places in the US, so $12.5 is quite expensive.",
"refusal": null
},
"logprobs": null,
"finish_reason": "stop"
}
],
...
}
向该路由发送另一个请求,消息中不包含任何价格:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "user", "content": "John paid a bit for a hot brewed coffee in El Paso." }
]
}'
你应该收到 HTTP/1.1 400 Bad Request 响应,并看到以下消息:
{"message":"Request doesn't match allow patterns"}
向该路由发送第三个请求,消息中包含电话号码:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "user", "content": "John (647-200-9393) paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你应该收到 HTTP/1.1 400 Bad Request 响应,并看到以下消息:
{"message":"Request contains prohibited content"}
默认情况下,该插件仅检查 user 角色的输入和最后一条消息。例如,如果你发送的请求在 system 提示词中包含禁止内容:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase from 647-200-9393 is at a decent price in USD." },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你将收到 HTTP/1.1 200 OK 响应。
如果你发送的请求中,倒数第二条消息包含禁止内容:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "user", "content": "Customer John contact: 647-200-9393" },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你也将收到 HTTP/1.1 200 OK 响应。
查看 下一个示例,了解如何检查所有角色的消息和所有消息。
验证所有角色的消息和对话历史
以下示例演示了如何使用 ai-prompt-guard 插件验证所有角色的提示词(例如 system 和 user),并验证整个对话历史记录而不仅仅是最后一条消息。
定义允许和拒绝模式。你可以选择将它们保存到环境变量中以便更容易转义:
export ALLOW_PATTERN_1='\\$?\\(?\\d{1,3}(,\\d{3})*(\\.\\d{1,2})?\\)?'
export DENY_PATTERN_1='(\\([0-9]{3}\\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- Admin API
- ADC
- Ingress Controller
创建一个使用 ai-proxy 代理到 OpenAI 并使用 ai-prompt-guard 检查输入提示词的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "ai-prompt-guard-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer '"$OPENAI_API_KEY"'"
}
},
"options":{
"model": "gpt-4"
}
},
"ai-prompt-guard": {
"match_all_roles": true,
"match_all_conversation_history": true,
"allow_patterns": [
"'"$ALLOW_PATTERN_1"'"
],
"deny_patterns": [
"'"$DENY_PATTERN_1"'"
]
}
}
}'
❶ 验证所有角色的消息。
❷ 验证整个对话的消息。
创建一个配置了 ai-prompt-guard 和 ai-proxy 插件的路由,如下所示:
services:
- name: prompt-guard-service
routes:
- name: prompt-guard-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: "Bearer ${OPENAI_API_KEY}"
options:
model: gpt-4
ai-prompt-guard:
match_all_roles: true
match_all_conversation_history: true
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
将配置同步到网关:
adc sync -f adc.yaml
❶ 验证所有角色的消息。
❷ 验证整个对话的消息。
- Gateway API
- APISIX CRD
创建一个配置了 ai-prompt-guard 和 ai-proxy 插件的路由,如下所示:
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-prompt-guard-plugin-config
spec:
plugins:
- name: ai-prompt-guard
config:
match_all_roles: true
match_all_conversation_history: true
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- name: ai-proxy
config:
provider: openai
auth:
header:
Authorization: "Bearer YOUR_OPENAI_API_KEY"
options:
model: gpt-4
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: prompt-guard-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-prompt-guard-plugin-config
将配置应用到集群:
kubectl apply -f ai-prompt-guard-history-ic.yaml
❶ 验证所有角色的消息。
❷ 验证整个对话的消息。
创建一个配置了 ai-prompt-guard 和 ai-proxy 插件的路由,如下所示:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: prompt-guard-route
spec:
ingressClassName: apisix
http:
- name: prompt-guard-route
match:
paths:
- /anything
methods:
- POST
plugins:
- name: ai-prompt-guard
enable: true
config:
match_all_roles: true
match_all_conversation_history: true
allow_patterns:
- '\$?\(?\d{1,3}(,\d{3})*(\.\d{1,2})?\)?'
deny_patterns:
- '(\([0-9]{3}\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}'
- name: ai-proxy
enable: true
config:
provider: openai
auth:
header:
Authorization: "Bearer YOUR_OPENAI_API_KEY"
options:
model: gpt-4
将配置应用到集群:
kubectl apply -f ai-prompt-guard-history-ic.yaml
❶ 验证所有角色的消息。
❷ 验证整个对话的消息。
发送一个请求,其中 system 提示词包含禁止内容:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase from 647-200-9393 is at a decent price in USD." },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你应该收到 HTTP/1.1 400 Bad Request 响应,并看到以下消息:
{"message":"Request contains prohibited content"}
发送一个请求,其中同一角色的多条消息包含禁止内容:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "user", "content": "Customer John contact: 647-200-9393" },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee in El Paso." }
]
}'
你应该收到 HTTP/1.1 400 Bad Request 响应,并看到以下消息:
{"message":"Request contains prohibited content"}
发送一个符合模式的请求:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "Rate if the purchase is at a decent price in USD." },
{ "role": "system", "content": "The purchase is made in El Paso." },
{ "role": "user", "content": "Customer John contact: xxx-xxx-xxxx" },
{ "role": "user", "content": "John paid $12.5 for a hot brewed coffee." }
]
}'
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
...,
"model": "gpt-4-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "$12.5 is generally considered quite expensive for a cup of brew coffee.",
"refusal": null
},
"logprobs": null,
"finish_reason": "stop"
}
],
...
}