🔑 虚拟密钥
通过代理的虚拟密钥追踪支出并控制模型访问
设置
要求:
- 需要一个postgres数据库(例如Supabase、Neon等)
- 在您的环境中设置
DATABASE_URL=postgresql://<user>:<password>@<host>:<port>/<dbname> - 设置一个
master key,这是您的代理管理密钥 - 您可以使用它来创建其他密钥(🚨 必须以sk-开头)。- 在 config.yaml 中设置 在
general_settings:master_key下设置您的 master key,示例如下 - 设置环境变量 设置
LITELLM_MASTER_KEY
- 在 config.yaml 中设置 在
(代理Dockerfile检查是否设置了 DATABASE_URL,然后初始化数据库连接)
export DATABASE_URL=postgresql://<user>:<password>@<host>:<port>/<dbname>
然后您可以通过访问 /key/generate 端点生成密钥。
快速开始 - 生成密钥
步骤1:保存postgres数据库URL
model_list:
- model_name: gpt-4
litellm_params:
model: ollama/llama2
- model_name: gpt-3.5-turbo
litellm_params:
model: ollama/llama2
general_settings:
master_key: sk-1234
database_url: "postgresql://<user>:<password>@<host>:<port>/<dbname>" # 👈 关键更改
步骤2:启动litellm
litellm --config /path/to/config.yaml
步骤3:生成密钥
curl 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"models": ["gpt-3.5-turbo", "gpt-4"], "metadata": {"user": "ishaan@berri.ai"}}'
支出追踪
按以下方式获取支出:
- 密钥 - 通过
/key/infoSwagger - 用户 - 通过
/user/infoSwagger - 团队 - 通过
/team/infoSwagger - ⏳ 最终用户 - 通过
/end_user/info- 在此问题中评论以进行最终用户成本追踪
如何计算?
每个模型的成本存储在这里,并通过 completion_cost 函数计算。
如何追踪?
支出会自动为密钥在 "LiteLLM_VerificationTokenTable" 中追踪。如果密钥附有 'user_id' 或 'team_id',则该用户的支出会在 "LiteLLM_UserTable" 中追踪,团队则在 "LiteLLM_TeamTable" 中追踪。
- 密钥支出
- 用户支出
- 团队支出
您可以通过使用 /key/info 端点获取密钥的支出。
curl 'http://0.0.0.0:4000/key/info?key=<user-key>' \
-X GET \
-H 'Authorization: Bearer <your-master-key>'
这会自动更新(以美元计)当调用 /completions、/chat/completions、/embeddings 时,使用 litellm 的 completion_cost() 函数。查看代码。
示例响应
{
"key": "sk-tXL0wt5-lOOVK9sfY2UacA",
"info": {
"token": "sk-tXL0wt5-lOOVK9sfY2UacA",
"spend": 0.0001065, # 👈 支出
"expires": "2023-11-24T23:19:11.131000Z",
"models": [
"gpt-3.5-turbo",
"gpt-4",
"claude-2"
],
"aliases": {
"mistral-7b": "gpt-3.5-turbo"
},
"config": {}
}
}
1. 创建用户
curl --location 'http://localhost:4000/user/new' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{user_email: "krrish@berri.ai"}'
预期响应
{
...
"expires": "2023-12-22T09:53:13.861000Z",
"user_id": "my-unique-id", # 👈 唯一ID
"max_budget": 0.0
}
2. 为该用户创建密钥
curl 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"models": ["gpt-3.5-turbo", "gpt-4"], "user_id": "my-unique-id"}'
返回一个密钥 - sk-...。
3. 查看用户的支出
curl 'http://0.0.0.0:4000/user/info?user_id=my-unique-id' \
-X GET \
-H 'Authorization: Bearer <your-master-key>'
预期响应
{
...
"spend": 0 # 👈 支出
}
如果你希望密钥由多人共同拥有(例如用于生产应用),请使用团队。
1. 创建团队
curl --location 'http://localhost:4000/team/new' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"team_alias": "my-awesome-team"}'
预期响应
{
...
"expires": "2023-12-22T09:53:13.861000Z",
"team_id": "my-unique-id", # 👈 唯一ID
"max_budget": 0.0
}
2. 为该团队创建密钥
curl 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"models": ["gpt-3.5-turbo", "gpt-4"], "team_id": "my-unique-id"}'
返回一个密钥 - sk-...。
3. 查看团队的支出
curl 'http://0.0.0.0:4000/team/info?team_id=my-unique-id' \
-X GET \
-H 'Authorization: Bearer <your-master-key>'
预期响应
{
...
"spend": 0 # 👈 支出
}
模型访问
通过虚拟密钥限制模型
使用 models 参数为密钥设置允许的模型
curl 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"models": ["gpt-3.5-turbo", "gpt-4"]}'
此密钥只能向 gpt-3.5-turbo 或 gpt-4 模型发出请求
验证设置是否正确
- 允许访问
- 不允许访问
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "gpt-4",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
期望此操作失败,因为 gpt-4o 不在生成的密钥的 models 中
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
通过 team_id 限制模型
litellm-dev 只能访问 azure-gpt-3.5
1. 通过 /team/new 创建团队
curl --location 'http://localhost:4000/team/new' \
--header 'Authorization: Bearer <your-master-key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"team_alias": "litellm-dev",
"models": ["azure-gpt-3.5"]
}'
# 返回 {...,"team_id": "my-unique-id"}
2. 为团队创建密钥
curl --location 'http://localhost:4000/key/generate' \
--header 'Authorization: Bearer sk-1234' \
--header 'Content-Type: application/json' \
--data-raw '{"team_id": "my-unique-id"}'
3. 测试
curl --location 'http://0.0.0.0:4000/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-qo992IjKOC2CHKZGRoJIGA' \
--data '{
"model": "BEDROCK_GROUP",
"messages": [
{
"role": "user",
"content": "hi"
}
]
}'
{"error":{"message":"Invalid model for team litellm-dev: BEDROCK_GROUP. Valid models for team are: ['azure-gpt-3.5']\n\n\nTraceback (most recent call last):\n File \"/Users/ishaanjaffer/Github/litellm/litellm/proxy/proxy_server.py\", line 2298, in chat_completion\n _is_valid_team_configs(\n File \"/Users/ishaanjaffer/Github/litellm/litellm/proxy/utils.py\", line 1296, in _is_valid_team_configs\n raise Exception(\nException: Invalid model for team litellm-dev: BEDROCK_GROUP. Valid models for team are: ['azure-gpt-3.5']\n\n","type":"None","param":"None","code":500}}%
授予新模型访问权限(访问组)
使用模型访问组为用户提供对选定模型的访问权限,并随着时间的推移向其添加新模型(例如 mistral、llama-2 等)
步骤 1. 在 config.yaml 中分配模型和访问组
model_list:
- model_name: gpt-4
litellm_params:
model: openai/fake
api_key: fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
model_info:
access_groups: ["beta-models"] # 👈 模型访问组
- model_name: fireworks-llama-v3-70b-instruct
litellm_params:
model: fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct
api_key: "os.environ/FIREWORKS"
model_info:
access_groups: ["beta-models"] # 👈 模型访问组
- 密钥访问组
- 团队访问组
创建带有访问组的密钥
curl --location 'http://localhost:4000/key/generate' \
-H 'Authorization: Bearer <your-master-key>' \
-H 'Content-Type: application/json' \
-d '{"models": ["beta-models"], # 👈 模型访问组
"max_budget": 0,}'
测试密钥
- 允许访问
- 不允许访问
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-<key-from-previous-step>" \
-d '{
"model": "gpt-4",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
预计此请求会失败,因为 gpt-4o 不在 beta-models 访问组中
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-<key-from-previous-step>" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
创建团队
curl --location 'http://localhost:4000/team/new' \
-H 'Authorization: Bearer sk-<key-from-previous-step>' \
-H 'Content-Type: application/json' \
-d '{"models": ["beta-models"]}'
为团队创建密钥
curl --location 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer sk-<key-from-previous-step>' \
--header 'Content-Type: application/json' \
--data '{"team_id": "0ac97648-c194-4c90-8cd6-40af7b0d2d2a"}
测试密钥
- 允许访问
- 不允许访问
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-<key-from-previous-step>" \
-d '{
"model": "gpt-4",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
预计此请求会失败,因为 gpt-4o 不在 beta-models 访问组中
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-<key-from-previous-step>" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
模型别名
如果用户预期使用给定的模型(例如 gpt3-5),而您希望:
- 尝试升级请求(例如 GPT4)
- 或降级请求(例如 Mistral)
- 或轮换 API KEY(例如 Open AI)
- 或通过不同的端点访问同一模型(例如 OpenAI vs Openrouter vs Azure)
以下是您可以执行的方法:
步骤 1:在 config.yaml 中创建模型组(保存模型名称、API 密钥等)
model_list:
- model_name: my-free-tier
litellm_params:
model: huggingface/HuggingFaceH4/zephyr-7b-beta
api_base: http://0.0.0.0:8001
- model_name: my-free-tier
litellm_params:
model: huggingface/HuggingFaceH4/zephyr-7b-beta
api_base: http://0.0.0.0:8002
- model_name: my-free-tier
litellm_params:
model: huggingface/HuggingFaceH4/zephyr-7b-beta
api_base: http://0.0.0.0:8003
- model_name: my-paid-tier
litellm_params:
model: gpt-4
api_key: my-api-key
步骤 2:生成用户密钥 - 允许他们访问特定模型、自定义模型别名等
curl -X POST "https://0.0.0.0:4000/key/generate" \
-H "Authorization: Bearer <your-master-key>" \
-H "Content-Type: application/json" \
-d '{
"models": ["my-free-tier"],
"aliases": {"gpt-3.5-turbo": "my-free-tier"},
"duration": "30min"
}'
- 如何升级/降级请求? 更改别名映射
- 如何进行不同密钥/API 基础之间的路由? litellm 通过在具有相同 model_name 的模型列表中随机选择不同的模型来处理此问题。查看代码
高级
在自定义标头中传递 LiteLLM 密钥
使用此功能使 LiteLLM 代理在自定义标头中查找虚拟密钥,而不是默认的 "Authorization" 标头
步骤 1 在 litellm config.yaml 中定义 litellm_key_header_name 名称
model_list:
- model_name: fake-openai-endpoint
litellm_params:
model: openai/fake
api_key: fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
general_settings:
master_key: sk-1234
litellm_key_header_name: "X-Litellm-Key" # 👈 关键更改
步骤 2 测试
在此请求中,litellm 将使用 X-Litellm-Key 标头中的虚拟密钥
- curl
- OpenAI Python SDK
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-Litellm-Key: Bearer sk-1234" \
-H "Authorization: Bearer bad-key" \
-d '{
"model": "fake-openai-endpoint",
"messages": [
{"role": "user", "content": "Hello, Claude gm!"}
]
}'
预期响应
预计会看到来自 litellm 代理的成功响应,因为 X-Litellm-Key 中传递的密钥是有效的
{"id":"chatcmpl-f9b2b79a7c30477ab93cd0e717d1773e","choices":[{"finish_reason":"stop","index":0,"message":{"content":"\n\n你好,今天有什么可以帮你的吗?","role":"assistant","tool_calls":null,"function_call":null}}],"created":1677652288,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":"fp_44709d6fcb","usage":{"completion_tokens":12,"prompt_tokens":9,"total_tokens":21}
client = openai.OpenAI(
api_key="not-used",
base_url="https://api-gateway-url.com/llmservc/api/litellmp",
default_headers={
"Authorization": f"Bearer {API_GATEWAY_TOKEN}", # (可选) 用于您的API网关
"X-Litellm-Key": f"Bearer sk-1234" # 用于LiteLLM代理
}
)
启用/禁用虚拟密钥
禁用密钥
curl -L -X POST 'http://0.0.0.0:4000/key/block' \
-H 'Authorization: Bearer LITELLM_MASTER_KEY' \
-H 'Content-Type: application/json' \
-d '{"key": "KEY-TO-BLOCK"}'
预期响应:
{
...
"blocked": true
}
启用密钥
curl -L -X POST 'http://0.0.0.0:4000/key/unblock' \
-H 'Authorization: Bearer LITELLM_MASTER_KEY' \
-H 'Content-Type: application/json' \
-d '{"key": "KEY-TO-UNBLOCK"}'
{
...
"blocked": false
}
自定义认证
您现在可以覆盖默认的API密钥认证。
方法如下:
1. 创建一个自定义认证文件。
确保响应类型遵循 UserAPIKeyAuth pydantic 对象。这用于记录特定用户密钥的使用情况。
from litellm.proxy._types import UserAPIKeyAuth
async def user_api_key_auth(request: Request, api_key: str) -> UserAPIKeyAuth:
try:
modified_master_key = "sk-my-master-key"
if api_key == modified_master_key:
return UserAPIKeyAuth(api_key=api_key)
raise Exception
except:
raise Exception
2. 传递文件路径(相对于 config.yaml)
将文件路径传递给 config.yaml
例如,如果它们都在同一个目录中 - ./config.yaml 和 ./custom_auth.py,如下所示:
model_list:
- model_name: "openai-model"
litellm_params:
model: "gpt-3.5-turbo"
litellm_settings:
drop_params: True
set_verbose: True
general_settings:
custom_auth: custom_auth.user_api_key_auth
3. 启动代理
$ litellm --config /path/to/config.yaml
自定义 /key/generate
如果您需要在生成代理API密钥之前添加自定义逻辑(例如验证 team_id)
1. 编写自定义 custom_generate_key_fn
custom_generate_key_fn 函数的输入是一个参数:data (类型: GenerateKeyRequest)
custom_generate_key_fn 的输出应为以下结构的字典
{
"decision": False,
"message": "This violates LiteLLM Proxy Rules. No team id provided.",
}
decision (类型: bool): 一个布尔值,指示是否允许生成密钥(True)或不允许(False)。
message (类型: str, 可选): 一个可选消息,提供有关决策的附加信息。当决策为False时,包含此字段。
async def custom_generate_key_fn(data: GenerateKeyRequest)-> dict:
"""
基于输入数据生成密钥的异步函数。
参数:
data (GenerateKeyRequest): 用于生成密钥的输入数据。
返回:
dict: 包含决策和可选消息的字典。
{
"decision": False,
"message": "This violates LiteLLM Proxy Rules. No team id provided.",
}
"""
# 决定是否生成密钥
print("使用自定义认证函数!")
data_json = data.json() # 类型: 忽略
# 解包变量
team_id = data_json.get("team_id")
duration = data_json.get("duration")
models = data_json.get("models")
aliases = data_json.get("aliases")
config = data_json.get("config")
spend = data_json.get("spend")
user_id = data_json.get("user_id")
max_parallel_requests = data_json.get("max_parallel_requests")
metadata = data_json.get("metadata")
tpm_limit = data_json.get("tpm_limit")
rpm_limit = data_json.get("rpm_limit")
if team_id is not None and team_id == "litellm-core-infra@gmail.com":
# 只有 team_id="litellm-core-infra@gmail.com" 可以生成密钥
return {
"decision": True,
}
else:
print("自定义认证失败")
return {
"decision": False,
"message": "This violates LiteLLM Proxy Rules. No team id provided.",
}
2. 传递文件路径(相对于 config.yaml)
将文件路径传递给 config.yaml
例如,如果它们都在同一个目录中 - ./config.yaml 和 ./custom_auth.py,如下所示:
model_list:
- model_name: "openai-model"
litellm_params:
model: "gpt-3.5-turbo"
litellm_settings:
drop_params: True
set_verbose: True
general_settings:
custom_key_generate: custom_auth.custom_generate_key_fn
上限 /key/generate 参数
如果需要为每个密钥设置 max_budget、budget_duration 或任何 key/generate 参数的默认上限,请使用此功能。
设置 litellm_settings:upperbound_key_generate_params:
litellm_settings:
upperbound_key_generate_params:
max_budget: 100 # 可选[浮点数], 可选): 所有 /key/generate 请求的上限为 $100
budget_duration: "10d" # 可选[字符串], 可选): budget_duration 值的上限为 10 天
duration: "30d" # 可选[字符串], 可选): 所有 /key/generate 请求的上限为 30 天
max_parallel_requests: 1000 # 可选[整数], 可选): 可以并行进行的请求最大数量。默认为 None。
tpm_limit: 1000 # 可选[整数], 可选): Tpm 限制。默认为 None。
rpm_limit: 1000 # 可选[整数], 可选): Rpm 限制。默认为 None。
预期行为
- 发送一个
max_budget=200的/key/generate请求 - 密钥将以
max_budget=100创建,因为 100 是上限
默认 /key/generate 参数
如果需要控制每个密钥的默认 max_budget 或任何 key/generate 参数,请使用此功能。
当 /key/generate 请求未指定 max_budget 时,它将使用 default_key_generate_params 中指定的 max_budget
设置 litellm_settings:default_key_generate_params:
litellm_settings:
default_key_generate_params:
max_budget: 1.5000
models: ["azure-gpt-3.5"]
duration: # 空白表示 `null`
metadata: {"setting":"default"}
team_id: "core-infra"
下一步 - 为每个虚拟密钥设置预算和速率限制
按照此文档使用 LiteLLM 为每个虚拟密钥设置预算和速率限制