15 KiB
15 KiB
LiteLLM 和 Agent Manager 回调接口文档
概述
本文档描述了 mcp-server 接收 LiteLLM 和 Agent Manager 服务的回调接口规范,包括请求体格式、响应体格式以及处理逻辑。
1. LiteLLM 回调接口
1.1 接口信息
- 接口路径:
/api/v1/billing/litellm-callback - 请求方法:
POST - Content-Type:
application/json - 功能: 接收 LiteLLM 的实时 Token 计费数据,支持单个对象或批量数组格式
1.2 请求体格式
1.2.1 单个对象格式
{
"id": "call-abc123", // 必填:调用ID(别名:call_id)
"trace_id": "trace-xyz789", // 可选:追踪ID
"model": "gpt-4", // 必填:模型名称
"call_type": "completion", // 可选:调用类型
"cache_hit": false, // 可选:是否缓存命中
"stream": false, // 可选:是否流式响应
"status": "success", // 可选:状态(默认:success)
"custom_llm_provider": "openai", // 可选:LLM提供商
"startTime": "2026-01-11T10:00:00Z", // 可选:开始时间(ISO 8601 或 Unix 时间戳)
"endTime": "2026-01-11T10:00:05Z", // 可选:结束时间(ISO 8601 或 Unix 时间戳)
"response_time": 5.2, // 可选:响应时间(秒)
"response_cost": 0.001, // 可选:响应成本(美元)
"total_tokens": 1500, // 可选:总Token数
"prompt_tokens": 1000, // 可选:Prompt Token数
"completion_tokens": 500, // 可选:Completion Token数
"api_key": "sk-xxx", // 可选:API密钥
"team_id": "team-123", // 可选:团队ID
"api_base": "https://api.openai.com", // 可选:API基础URL
"model_group": "gpt-4", // 可选:模型组
"model_id": "gpt-4-0613", // 可选:模型ID
"messages": [ // 可选:消息列表
{
"role": "user",
"content": "Hello"
}
],
"response": { // 可选:响应内容
"choices": [...]
},
"metadata": { // 可选:元数据(重要:包含租户信息)
"user_api_key_hash": "hash-xxx", // API密钥哈希
"user_api_key_team_id": "team-123", // 团队ID
"user_api_key_auth_metadata": { // 租户认证元数据(优先使用)
"tenant_id": "tenant-123",
"channel_id": "channel-456",
"tenant_name": "租户名称"
},
"usage_object": { // Token使用量对象
"total_tokens": 1500,
"prompt_tokens": 1000,
"completion_tokens": 500
}
},
"hidden_params": {}, // 可选:隐藏参数
"model_map_information": {}, // 可选:模型映射信息
"cost_breakdown": {}, // 可选:成本明细
"error_str": null, // 可选:错误信息
"error_information": {} // 可选:错误详情
}
1.2.2 批量数组格式
[
{
"id": "call-abc123",
"model": "gpt-4",
"total_tokens": 1500,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
},
{
"id": "call-xyz789",
"model": "gpt-3.5-turbo",
"total_tokens": 800,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
}
]
1.2.3 字段说明
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
id / call_id |
string | 是 | 调用唯一标识符,用于幂等性检查 |
trace_id |
string | 否 | 追踪ID,当 id 不存在时作为备用 |
model |
string | 是 | 模型名称(如:gpt-4, gpt-3.5-turbo) |
total_tokens |
integer | 否 | 总Token数,用于计算EU消耗 |
prompt_tokens |
integer | 否 | Prompt Token数 |
completion_tokens |
integer | 否 | Completion Token数 |
startTime |
string/float | 否 | 开始时间(ISO 8601 字符串或 Unix 时间戳) |
endTime |
string/float | 否 | 结束时间(ISO 8601 字符串或 Unix 时间戳) |
response_cost |
float | 否 | 响应成本(美元) |
metadata |
object | 否 | 元数据对象,包含租户信息 |
metadata.user_api_key_hash |
string | 否 | API密钥哈希值 |
metadata.user_api_key_team_id |
string | 否 | 团队ID |
metadata.user_api_key_auth_metadata |
object | 否 | 优先使用:租户认证元数据 |
metadata.user_api_key_auth_metadata.tenant_id |
string | 否 | 租户ID |
metadata.user_api_key_auth_metadata.channel_id |
string | 否 | 渠道ID |
metadata.usage_object |
object | 否 | Token使用量对象(备用) |
1.3 响应体格式
1.3.1 单个对象响应
{
"message": "Success",
"call_id": "call-abc123",
"record_id": "550e8400-e29b-41d4-a716-446655440000",
"eu_consumed": 0.15,
"balance_updated": true
}
1.3.2 批量数组响应
{
"message": "Batch processed",
"count": 2,
"results": [
{
"message": "Success",
"call_id": "call-abc123",
"record_id": "550e8400-e29b-41d4-a716-446655440000",
"eu_consumed": 0.15,
"balance_updated": true
},
{
"message": "Success",
"call_id": "call-xyz789",
"record_id": "550e8400-e29b-41d4-a716-446655440001",
"eu_consumed": 0.08,
"balance_updated": true
}
]
}
1.3.3 错误响应
{
"detail": "无法解析租户ID"
}
HTTP 状态码:
200: 成功处理400: 请求参数错误(如无法解析租户ID)500: 服务器内部错误
1.3.4 响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
message |
string | 处理结果消息("Success" / "Already processed" / "Skipped - no call_id") |
call_id |
string | 调用ID |
record_id |
string | 计费记录ID(UUID) |
eu_consumed |
float | 消耗的EU数量 |
balance_updated |
boolean | 是否成功更新余额 |
1.4 处理逻辑
- 幂等性检查: 根据
call_id检查是否已处理过,避免重复计费 - 租户信息解析:
- 优先从
metadata.user_api_key_auth_metadata获取租户信息 - 如果不存在,则通过
metadata.user_api_key_hash从数据库查询
- 优先从
- Token计算:
- 优先使用顶级字段
total_tokens、prompt_tokens、completion_tokens - 如果不存在,从
metadata.usage_object获取
- 优先使用顶级字段
- EU计算: 根据模型类型和Token数量计算EU消耗
- GPT-4: 0.0001 EU/token
- GPT-3.5-turbo: 0.00005 EU/token
- 默认: 0.0001 EU/token
- 余额扣减: 使用数据库行锁确保并发安全,原子性更新用户余额
- 计费记录: 创建
ModelBillingRecord记录,保存完整的回调数据
1.5 健康检查接口
- 接口路径:
/api/v1/billing/litellm-callback/health - 请求方法:
GET - 响应:
{
"status": "ok",
"endpoint": "/api/v1/billing/litellm-callback"
}
2. Agent Manager 回调接口
2.1 接口信息
- 接口路径:
/api/v1/billing/agent-callback - 请求方法:
POST - Content-Type:
application/json - 功能: 接收 Agent Manager 的 Agent 运行时信息,用于记录运行时长并计费
2.2 请求体格式
{
"agentName": "taiji-assistant-abc123", // 必填:Agent 名称
"userId": "user-123-456", // 必填:用户 ID
"podRunningTimeSeconds": 120, // 必填:Pod 运行时间(秒),即 VM 运行时间
"toolsUsed": [ // 可选:使用的工具列表
"web_search",
"calculator",
"file_reader"
],
"startTime": "2026-01-11T10:00:00Z", // 可选:开始时间(ISO 8601 格式)
"endTime": "2026-01-11T10:02:00Z", // 可选:结束时间(ISO 8601 格式)
"requestId": "req-abc-123" // 可选:请求 ID
}
2.3 请求字段说明
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
agentName |
string | 是 | Agent 名称,用于标识具体的 Agent 实例 |
userId |
string | 是 | 用户 ID,必须是系统中存在的用户 |
podRunningTimeSeconds |
integer | 是 | Pod 运行时间(秒),即 VM 实际运行时长,用于计费 |
toolsUsed |
array[string] | 否 | 使用的工具列表,用于记录 Agent 调用的工具 |
startTime |
string | 否 | 开始时间,ISO 8601 格式(如:2026-01-11T10:00:00Z) |
endTime |
string | 否 | 结束时间,ISO 8601 格式(如:2026-01-11T10:02:00Z) |
requestId |
string | 否 | 请求 ID,用于追踪和关联请求 |
2.4 响应体格式
2.4.1 成功响应
{
"success": true,
"message": "Agent 计费记录创建成功",
"recordId": "550e8400-e29b-41d4-a716-446655440000"
}
2.4.2 错误响应
用户不存在:
{
"detail": "用户不存在: user-123-456"
}
HTTP 状态码: 404
服务器错误:
{
"detail": "回调处理失败: [错误详情]"
}
HTTP 状态码: 500
2.4.3 响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
success |
boolean | 是否成功处理 |
message |
string | 处理结果消息 |
recordId |
string | 创建的计费记录ID(UUID),失败时为 null |
2.5 处理逻辑
- 用户验证: 验证
userId是否存在,不存在则返回 404 错误 - 时间解析: 解析
startTime和endTime(ISO 8601 格式),转换为 UTC 时间 - 成本计算:
- 根据
podRunningTimeSeconds计算 EU 消耗 - 根据 Agent 类型和运行时长计算成本(平台 Agent 使用
calculate_platform_agent_cost)
- 根据
- 计费记录: 创建
AgentBillingRecord记录,包含:- 用户ID、渠道ID
- Agent 名称、类型
- 运行时长、EU消耗、成本
- 开始时间、结束时间
- 使用的工具列表
- 请求ID
- 余额扣减: 调用
deduct_balance扣除用户余额 - 事务提交: 所有操作在数据库事务中执行,失败时回滚
2.6 健康检查接口
- 接口路径:
/api/v1/billing/agent-callback/health - 请求方法:
GET - 响应:
{
"status": "ok",
"endpoint": "/api/v1/billing/agent-callback"
}
3. 通用说明
3.1 认证
目前两个回调接口均未实现认证机制,建议在生产环境中添加:
- API Key 认证
- IP 白名单
- 签名验证
3.2 幂等性
- LiteLLM 回调: 通过
call_id实现幂等性,相同call_id的请求只会处理一次 - Agent Manager 回调: 目前未实现幂等性,建议添加
requestId的唯一性检查
3.3 错误处理
- 所有错误都会记录到日志中
- 数据库操作失败时会自动回滚事务
- 返回适当的 HTTP 状态码和错误信息
3.4 性能考虑
- LiteLLM 回调支持批量处理,提高吞吐量
- 使用数据库行锁确保并发安全
- 余额更新使用原子操作
3.5 数据存储
- LiteLLM 回调: 数据存储在
ModelBillingRecord表中 - Agent Manager 回调: 数据存储在
AgentBillingRecord表中 - 所有回调的原始数据都会保存,便于后续审计和分析
4. 示例代码
4.1 LiteLLM 回调示例(cURL)
# 单个对象
curl -X POST http://mcp-server:8002/api/v1/billing/litellm-callback \
-H "Content-Type: application/json" \
-d '{
"id": "call-abc123",
"model": "gpt-4",
"total_tokens": 1500,
"prompt_tokens": 1000,
"completion_tokens": 500,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
}'
# 批量数组
curl -X POST http://mcp-server:8002/api/v1/billing/litellm-callback \
-H "Content-Type: application/json" \
-d '[
{
"id": "call-abc123",
"model": "gpt-4",
"total_tokens": 1500,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
},
{
"id": "call-xyz789",
"model": "gpt-3.5-turbo",
"total_tokens": 800,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
}
]'
4.2 Agent Manager 回调示例(cURL)
curl -X POST http://mcp-server:8002/api/v1/billing/agent-callback \
-H "Content-Type: application/json" \
-d '{
"agentName": "taiji-assistant-abc123",
"userId": "user-123-456",
"podRunningTimeSeconds": 120,
"toolsUsed": ["web_search", "calculator"],
"startTime": "2026-01-11T10:00:00Z",
"endTime": "2026-01-11T10:02:00Z",
"requestId": "req-abc-123"
}'
4.3 Python 示例
import requests
# LiteLLM 回调
litellm_data = {
"id": "call-abc123",
"model": "gpt-4",
"total_tokens": 1500,
"metadata": {
"user_api_key_auth_metadata": {
"tenant_id": "tenant-123",
"channel_id": "channel-456"
}
}
}
response = requests.post(
"http://mcp-server:8002/api/v1/billing/litellm-callback",
json=litellm_data
)
print(response.json())
# Agent Manager 回调
agent_data = {
"agentName": "taiji-assistant-abc123",
"userId": "user-123-456",
"podRunningTimeSeconds": 120,
"toolsUsed": ["web_search", "calculator"],
"startTime": "2026-01-11T10:00:00Z",
"endTime": "2026-01-11T10:02:00Z",
"requestId": "req-abc-123"
}
response = requests.post(
"http://mcp-server:8002/api/v1/billing/agent-callback",
json=agent_data
)
print(response.json())
5. 配置说明
5.1 LiteLLM 配置
在 LiteLLM 配置文件中设置回调地址:
general_settings:
success_callback: ["webhook"]
failure_callback: ["webhook"]
webhook_url: "http://mcp-server:8002/api/v1/billing/litellm-callback"
webhook_headers:
Content-Type: "application/json"
5.2 Agent Manager 配置
Agent Manager 需要在 Agent 运行结束后调用回调接口,配置回调地址:
CALLBACK_URL=http://mcp-server:8002/api/v1/billing/agent-callback
6. 注意事项
-
时间格式:
- LiteLLM 回调支持 ISO 8601 字符串和 Unix 时间戳
- Agent Manager 回调仅支持 ISO 8601 格式
-
租户信息:
- LiteLLM 回调优先从
metadata.user_api_key_auth_metadata获取租户信息 - 如果不存在,会尝试从数据库查询,但可能失败
- LiteLLM 回调优先从
-
Token 计算:
- 优先使用顶级字段,其次使用
metadata.usage_object - 如果都不存在,Token 数默认为 0
- 优先使用顶级字段,其次使用
-
并发安全:
- 使用数据库行锁确保余额更新的原子性
- 建议在生产环境中使用连接池和适当的并发控制
-
日志记录:
- 所有回调都会记录详细日志
- 建议配置日志轮转和监控告警
7. 更新日志
- 2026-01-11: 初始版本,包含 LiteLLM 和 Agent Manager 回调接口文档