Skip to main content

自定义防护栏

如果你想编写代码来运行自定义防护栏,请使用此功能。

快速开始

1. 编写一个 CustomGuardrail

一个自定义防护栏有三个方法来执行防护栏:

  • async_pre_call_hook - (可选)在调用LLM API之前修改输入或拒绝请求
  • async_moderation_hook - (可选)拒绝请求,在调用LLM API期间运行(有助于降低延迟)
  • async_post_call_success_hook - (可选)在调用LLM API之后对输入/输出应用防护栏

在此处查看方法的详细规范

示例 CustomGuardrail

创建一个名为 custom_guardrail.py 的新文件,并将以下代码添加到其中:

from typing import Any, Dict, List, Literal, Optional, Union

import litellm
from litellm._logging import verbose_proxy_logger
from litellm.caching.caching import DualCache
from litellm.integrations.custom_guardrail import CustomGuardrail
from litellm.proxy._types import UserAPIKeyAuth
from litellm.proxy.guardrails.guardrail_helpers import should_proceed_based_on_metadata
from litellm.types.guardrails import GuardrailEventHooks


class myCustomGuardrail(CustomGuardrail):
def __init__(
self,
**kwargs,
):
# 将 kwargs 存储为 optional_params
self.optional_params = kwargs

super().__init__(**kwargs)

async def async_pre_call_hook(
self,
user_api_key_dict: UserAPIKeyAuth,
cache: DualCache,
data: dict,
call_type: Literal[
"completion",
"text_completion",
"embeddings",
"image_generation",
"moderation",
"audio_transcription",
"pass_through_endpoint",
"rerank"
],
) -> Optional[Union[Exception, str, dict]]:
"""
在LLM API调用之前运行
仅在输入上运行
如果你想修改输入,请使用此方法
"""

# 在这个防护栏中,如果用户输入 `litellm`,我们将屏蔽它,然后发送给LLM
_messages = data.get("messages")
if _messages:
for message in _messages:
_content = message.get("content")
if isinstance(_content, str):
if "litellm" in _content.lower():
_content = _content.replace("litellm", "********")
message["content"] = _content

verbose_proxy_logger.debug(
"async_pre_call_hook: 屏蔽后的消息 %s", _messages
)

return data

async def async_moderation_hook(
self,
data: dict,
user_api_key_dict: UserAPIKeyAuth,
call_type: Literal["completion", "embeddings", "image_generation", "moderation", "audio_transcription"],
):
"""
与LLM API调用并行运行
仅在输入上运行

这不能修改输入,仅用于在调用LLM API之前拒绝或接受调用
"""

# 这与 async_pre_call_hook 的工作方式相同,但只是与LLM API调用并行运行
# 在这个防护栏中,如果用户输入 `litellm`,我们将屏蔽它。
_messages = data.get("messages")
if _messages:
for message in _messages:
_content = message.get("content")
if isinstance(_content, str):
if "litellm" in _content.lower():
raise ValueError("防护栏失败 - 检测到 `litellm`")

async def async_post_call_success_hook(
self,
data: dict,
user_api_key_dict: UserAPIKeyAuth,
response,
):
"""
在LLM API调用的响应上运行

可用于拒绝响应

如果响应包含单词 "coffee" -> 我们将引发异常
"""
verbose_proxy_logger.debug("async_pre_call_hook 响应: %s", response)
if isinstance(response, litellm.ModelResponse):
for choice in response.choices:
if isinstance(choice, litellm.Choices):
verbose_proxy_logger.debug("async_pre_call_hook choice: %s", choice)
if (
choice.message.content
and isinstance(choice.message.content, str)
and "coffee" in choice.message.content
):
raise ValueError("防护栏失败 - 检测到 Coffee")


2. 在你的 LiteLLM config.yaml 中传递你的自定义防护栏类

在下面的配置中,我们通过设置 guardrail: custom_guardrail.myCustomGuardrail 将防护栏指向我们的自定义防护栏。

  • Python 文件名: custom_guardrail.py
  • 防护栏类名 : myCustomGuardrail。这在步骤1中定义

guardrail: custom_guardrail.myCustomGuardrail

model_list:
- model_name: gpt-4
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY

guardrails:
- guardrail_name: "自定义前置防护"
litellm_params:
guardrail: custom_guardrail.myCustomGuardrail # 👈 关键更改
mode: "pre_call" # 运行async_pre_call_hook
- guardrail_name: "自定义调用中防护"
litellm_params:
guardrail: custom_guardrail.myCustomGuardrail
mode: "during_call" # 运行async_moderation_hook
- guardrail_name: "自定义后置防护"
litellm_params:
guardrail: custom_guardrail.myCustomGuardrail
mode: "post_call" # 运行async_post_call_success_hook

3. 启动 LiteLLM 网关

将您的 custom_guardrail.py 挂载到 LiteLLM Docker 容器中

这会将您的 custom_guardrail.py 文件从本地目录挂载到 Docker 容器中的 /app 目录,使其可被 LiteLLM 网关访问。

docker run -d \
-p 4000:4000 \
-e OPENAI_API_KEY=$OPENAI_API_KEY \
--name my-app \
-v $(pwd)/my_config.yaml:/app/config.yaml \
-v $(pwd)/custom_guardrail.py:/app/custom_guardrail.py \
my-app:latest \
--config /app/config.yaml \
--port 4000 \
--detailed_debug \

4. 测试它

测试 "custom-pre-guard"

Langchain, OpenAI SDK 使用示例

期望在将请求发送到 LLM API 之前屏蔽单词 litellm这会运行 async_pre_call_hook

curl -i  -X POST http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "say the word - `litellm`"
}
],
"guardrails": ["custom-pre-guard"]
}'

预期在预防护后的响应

{
"id": "chatcmpl-9zREDkBIG20RJB4pMlyutmi1hXQWc",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "It looks like you've chosen a string of asterisks. This could be a way to censor or hide certain text. However, without more context, I can't provide a specific word or phrase. If there's something specific you'd like me to say or if you need help with a topic, feel free to let me know!",
"role": "assistant",
"tool_calls": null,
"function_call": null
}
}
],
"created": 1724429701,
"model": "gpt-4o-2024-05-13",
"object": "chat.completion",
"system_fingerprint": "fp_3aa7262c27",
"usage": {
"completion_tokens": 65,
"prompt_tokens": 14,
"total_tokens": 79
},
"service_tier": null
}

测试 "custom-during-guard"

Langchain, OpenAI SDK 使用示例

期望此调用失败,因为消息内容中包含 litellm这会运行 async_moderation_hook

curl -i  -X POST http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "say the word - `litellm`"
}
],
"guardrails": ["custom-during-guard"]
}'

预期在运行期间防护后的响应

{
"error": {
"message": "Guardrail failed words - `litellm` detected",
"type": "None",
"param": "None",
"code": "500"
}
}

测试 "custom-post-guard"

Langchain, OpenAI SDK 使用示例

期望此调用失败,因为响应内容中将包含 coffee这会运行 async_post_call_success_hook

curl -i  -X POST http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "what is coffee"
}
],
"guardrails": ["custom-post-guard"]
}'

预期在运行期间防护后的响应

{
"error": {
"message": "Guardrail failed Coffee Detected",
"type": "None",
"param": "None",
"code": "500"
}
}

CustomGuardrail 方法

组件描述可选检查数据可修改输入可修改输出可失败调用
async_pre_call_hook在LLM API调用之前运行的钩子输入
async_moderation_hook在LLM API调用期间运行的钩子输入
async_post_call_success_hook在成功LLM API调用之后运行的钩子输入, 输出
优云智算