new version

This commit is contained in:
zhanggangyong
2026-01-15 17:30:48 +00:00
parent f065b00d12
commit 6eaffba1aa
125 changed files with 13494 additions and 6529 deletions
@@ -0,0 +1,522 @@
# 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 单个对象格式
```json
{
"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 批量数组格式
```json
[
{
"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 单个对象响应
```json
{
"message": "Success",
"call_id": "call-abc123",
"record_id": "550e8400-e29b-41d4-a716-446655440000",
"eu_consumed": 0.15,
"balance_updated": true
}
```
#### 1.3.2 批量数组响应
```json
{
"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 错误响应
```json
{
"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 处理逻辑
1. **幂等性检查**: 根据 `call_id` 检查是否已处理过,避免重复计费
2. **租户信息解析**:
- 优先从 `metadata.user_api_key_auth_metadata` 获取租户信息
- 如果不存在,则通过 `metadata.user_api_key_hash` 从数据库查询
3. **Token计算**:
- 优先使用顶级字段 `total_tokens`、`prompt_tokens`、`completion_tokens`
- 如果不存在,从 `metadata.usage_object` 获取
4. **EU计算**: 根据模型类型和Token数量计算EU消耗
- GPT-4: 0.0001 EU/token
- GPT-3.5-turbo: 0.00005 EU/token
- 默认: 0.0001 EU/token
5. **余额扣减**: 使用数据库行锁确保并发安全,原子性更新用户余额
6. **计费记录**: 创建 `ModelBillingRecord` 记录,保存完整的回调数据
### 1.5 健康检查接口
- **接口路径**: `/api/v1/billing/litellm-callback/health`
- **请求方法**: `GET`
- **响应**:
```json
{
"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 请求体格式
```json
{
"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 成功响应
```json
{
"success": true,
"message": "Agent 计费记录创建成功",
"recordId": "550e8400-e29b-41d4-a716-446655440000"
}
```
#### 2.4.2 错误响应
**用户不存在**:
```json
{
"detail": "用户不存在: user-123-456"
}
```
HTTP 状态码: `404`
**服务器错误**:
```json
{
"detail": "回调处理失败: [错误详情]"
}
```
HTTP 状态码: `500`
#### 2.4.3 响应字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| `success` | boolean | 是否成功处理 |
| `message` | string | 处理结果消息 |
| `recordId` | string | 创建的计费记录ID(UUID),失败时为 null |
### 2.5 处理逻辑
1. **用户验证**: 验证 `userId` 是否存在,不存在则返回 404 错误
2. **时间解析**: 解析 `startTime` 和 `endTime`(ISO 8601 格式),转换为 UTC 时间
3. **成本计算**:
- 根据 `podRunningTimeSeconds` 计算 EU 消耗
- 根据 Agent 类型和运行时长计算成本(平台 Agent 使用 `calculate_platform_agent_cost`)
4. **计费记录**: 创建 `AgentBillingRecord` 记录,包含:
- 用户ID、渠道ID
- Agent 名称、类型
- 运行时长、EU消耗、成本
- 开始时间、结束时间
- 使用的工具列表
- 请求ID
5. **余额扣减**: 调用 `deduct_balance` 扣除用户余额
6. **事务提交**: 所有操作在数据库事务中执行,失败时回滚
### 2.6 健康检查接口
- **接口路径**: `/api/v1/billing/agent-callback/health`
- **请求方法**: `GET`
- **响应**:
```json
{
"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)
```bash
# 单个对象
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)
```bash
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 示例
```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 配置文件中设置回调地址:
```yaml
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. 注意事项
1. **时间格式**:
- LiteLLM 回调支持 ISO 8601 字符串和 Unix 时间戳
- Agent Manager 回调仅支持 ISO 8601 格式
2. **租户信息**:
- LiteLLM 回调优先从 `metadata.user_api_key_auth_metadata` 获取租户信息
- 如果不存在,会尝试从数据库查询,但可能失败
3. **Token 计算**:
- 优先使用顶级字段,其次使用 `metadata.usage_object`
- 如果都不存在,Token 数默认为 0
4. **并发安全**:
- 使用数据库行锁确保余额更新的原子性
- 建议在生产环境中使用连接池和适当的并发控制
5. **日志记录**:
- 所有回调都会记录详细日志
- 建议配置日志轮转和监控告警
---
## 7. 更新日志
- **2026-01-11**: 初始版本,包含 LiteLLM 和 Agent Manager 回调接口文档