forked from xiaohei/taiji-AI-PAD
更新信息查询
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
# 用户资源信息查询接口文档
|
||||
|
||||
> **版本**: 2026-01-13 v1
|
||||
> **接口路径**: `GET /api/user/resources/info`
|
||||
> **认证方式**: Bearer Token(JWT)
|
||||
|
||||
---
|
||||
|
||||
## 📋 接口概述
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| **接口路径** | `GET /api/user/resources/info` |
|
||||
| **接口描述** | 获取用户的 LiteLLM 密钥和已部署 Agent 的详细信息 |
|
||||
| **认证方式** | Bearer Token(JWT) |
|
||||
| **Content-Type** | application/json |
|
||||
|
||||
### 功能说明
|
||||
|
||||
该接口用于获取当前用户的以下资源信息:
|
||||
|
||||
1. **LiteLLM 密钥**:解密后的完整 API Key,可直接用于调用 AI 模型
|
||||
2. **平台 Agent**:已部署的平台 Agent 列表,包含实时 IP 和访问地址
|
||||
3. **自定义 Agent**:已部署的自定义 Agent 列表,包含实时 IP 和访问地址
|
||||
|
||||
---
|
||||
|
||||
## 📥 请求参数
|
||||
|
||||
### 请求头(Headers)
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|:----:|------|
|
||||
| `Authorization` | string | ✅ | Bearer Token,格式:`Bearer <JWT Token>` |
|
||||
|
||||
### 请求体(Body)
|
||||
|
||||
无
|
||||
|
||||
### 查询参数(Query)
|
||||
|
||||
无
|
||||
|
||||
---
|
||||
|
||||
## 📤 请求示例
|
||||
|
||||
```http
|
||||
GET /api/user/resources/info HTTP/1.1
|
||||
Host: api.taiji-ai.com
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 响应参数
|
||||
|
||||
### 响应结构
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `success` | boolean | 请求是否成功 |
|
||||
| `message` | string | 响应消息 |
|
||||
| `data` | object | 响应数据 |
|
||||
|
||||
### data 对象
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `litellmKeys` | array | LiteLLM 密钥列表 |
|
||||
| `litellmApiBase` | string | LiteLLM 网关地址(全局) |
|
||||
| `platformAgents` | array | 已部署的平台 Agent 列表 |
|
||||
| `customAgents` | array | 已部署的自定义 Agent 列表 |
|
||||
| `summary` | object | 汇总统计信息 |
|
||||
|
||||
---
|
||||
|
||||
### litellmKeys 数组元素
|
||||
|
||||
| 字段 | 类型 | 说明 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `modelName` | string | 模型名称 | `"azure/gpt-4"` |
|
||||
| `apiKey` | string | **解密后的完整 API Key**(用于调用模型) | `"sk-xxxxxxxxxxxxxxxx"` |
|
||||
| `apiBase` | string | LiteLLM 网关地址 | `"https://litellm.xxx.azurecontainerapps.io"` |
|
||||
| `rpmLimit` | integer | 每分钟请求数限制 | `60` |
|
||||
| `tpmLimit` | integer | 每分钟 Token 数限制 | `10000` |
|
||||
| `maxBudget` | number \| null | 最大预算(美元) | `100.0` |
|
||||
| `budgetDuration` | string | 预算周期 | `"monthly"` |
|
||||
| `status` | string | 密钥状态 | `"active"` |
|
||||
| `createdAt` | string | 创建时间(ISO 8601) | `"2026-01-13T10:00:00"` |
|
||||
| `error` | string | 错误信息(仅解密失败时返回) | `"密钥解密失败"` |
|
||||
|
||||
---
|
||||
|
||||
### platformAgents / customAgents 数组元素
|
||||
|
||||
| 字段 | 类型 | 说明 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `name` | string | Agent 实例名称 | `"user-123-echo-agent-abc"` |
|
||||
| `template` | string | Agent 类型/模板 | `"echo_agent"` |
|
||||
| `templateName` | string | 模板名称 | `"echo_agent"` |
|
||||
| `status` | string | 运行状态(AKS 实时) | `"Running"` / `"Pending"` / `"Failed"` |
|
||||
| `healthStatus` | string | 健康状态(AKS 实时) | `"healthy"` / `"unhealthy"` / `"unknown"` |
|
||||
| `podIp` | string \| null | **Pod IP 地址**(AKS 实时) | `"10.244.1.100"` |
|
||||
| `accessUrl` | string \| null | **访问 URL**(AKS 实时) | `"http://xxx.ai-agents.svc.cluster.local:8080"` |
|
||||
| `servicePort` | integer \| null | 服务端口 | `8080` |
|
||||
| `namespace` | string | K8s 命名空间 | `"ai-agents"` |
|
||||
| `hostIp` | string \| null | 宿主机 IP(AKS 实时) | `"192.168.1.10"` |
|
||||
| `nodeName` | string \| null | 节点名称(AKS 实时) | `"aks-agentpool-xxxxx"` |
|
||||
| `cpu` | string | CPU 配置 | `"100m"` |
|
||||
| `memory` | string | 内存配置 | `"256Mi"` |
|
||||
| `replicas` | integer | 副本数量 | `1` |
|
||||
| `startTime` | string | 启动时间(ISO 8601) | `"2026-01-13T08:00:00"` |
|
||||
| `runningSeconds` | integer | 已运行秒数 | `7200` |
|
||||
| `endpoints` | array | 端点列表(可选) | 见下表 |
|
||||
|
||||
### endpoints 数组元素(可选)
|
||||
|
||||
| 字段 | 类型 | 说明 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `name` | string | 端点名称 | `"http"` |
|
||||
| `port` | integer | 端口号 | `8080` |
|
||||
| `protocol` | string | 协议 | `"TCP"` |
|
||||
| `targetPort` | integer | 目标端口 | `8080` |
|
||||
|
||||
---
|
||||
|
||||
### summary 对象
|
||||
|
||||
| 字段 | 类型 | 说明 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `totalLitellmKeys` | integer | LiteLLM 密钥总数 | `2` |
|
||||
| `totalPlatformAgents` | integer | 已部署的平台 Agent 数量 | `1` |
|
||||
| `totalCustomAgents` | integer | 已部署的自定义 Agent 数量 | `1` |
|
||||
|
||||
---
|
||||
|
||||
## 📝 响应示例
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "用户资源信息获取成功",
|
||||
"data": {
|
||||
"litellmKeys": [
|
||||
{
|
||||
"modelName": "azure/gpt-4",
|
||||
"apiKey": "sk-1234567890abcdef1234567890abcdef",
|
||||
"apiBase": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
|
||||
"rpmLimit": 60,
|
||||
"tpmLimit": 10000,
|
||||
"maxBudget": 100.0,
|
||||
"budgetDuration": "monthly",
|
||||
"status": "active",
|
||||
"createdAt": "2026-01-10T10:30:00"
|
||||
},
|
||||
{
|
||||
"modelName": "azure/gpt-3.5-turbo",
|
||||
"apiKey": "sk-abcdef1234567890abcdef1234567890",
|
||||
"apiBase": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
|
||||
"rpmLimit": 120,
|
||||
"tpmLimit": 50000,
|
||||
"maxBudget": 50.0,
|
||||
"budgetDuration": "monthly",
|
||||
"status": "active",
|
||||
"createdAt": "2026-01-10T10:30:00"
|
||||
}
|
||||
],
|
||||
"litellmApiBase": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
|
||||
"platformAgents": [
|
||||
{
|
||||
"name": "user-abc123-echo-agent-def456",
|
||||
"template": "echo_agent",
|
||||
"templateName": "echo_agent",
|
||||
"status": "Running",
|
||||
"healthStatus": "healthy",
|
||||
"podIp": "10.244.1.100",
|
||||
"accessUrl": "http://user-abc123-echo-agent-def456.ai-agents.svc.cluster.local:8080",
|
||||
"servicePort": 8080,
|
||||
"namespace": "ai-agents",
|
||||
"hostIp": "192.168.1.10",
|
||||
"nodeName": "aks-agentpool-12345678-vmss000001",
|
||||
"cpu": "100m",
|
||||
"memory": "256Mi",
|
||||
"replicas": 1,
|
||||
"startTime": "2026-01-13T08:00:00",
|
||||
"runningSeconds": 7200,
|
||||
"endpoints": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 8080,
|
||||
"protocol": "TCP",
|
||||
"targetPort": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"customAgents": [
|
||||
{
|
||||
"name": "user-abc123-mysql-agent-xyz789",
|
||||
"template": "mysql_agent",
|
||||
"templateName": "mysql_agent",
|
||||
"status": "Running",
|
||||
"healthStatus": "healthy",
|
||||
"podIp": "10.244.1.101",
|
||||
"accessUrl": "http://user-abc123-mysql-agent-xyz789.ai-agents.svc.cluster.local:8080",
|
||||
"servicePort": 8080,
|
||||
"namespace": "ai-agents",
|
||||
"hostIp": "192.168.1.11",
|
||||
"nodeName": "aks-agentpool-12345678-vmss000002",
|
||||
"cpu": "200m",
|
||||
"memory": "512Mi",
|
||||
"replicas": 1,
|
||||
"startTime": "2026-01-13T09:30:00",
|
||||
"runningSeconds": 1800,
|
||||
"endpoints": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 8080,
|
||||
"protocol": "TCP",
|
||||
"targetPort": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"totalLitellmKeys": 2,
|
||||
"totalPlatformAgents": 1,
|
||||
"totalCustomAgents": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 无资源时的响应
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "用户资源信息获取成功",
|
||||
"data": {
|
||||
"litellmKeys": [],
|
||||
"litellmApiBase": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
|
||||
"platformAgents": [],
|
||||
"customAgents": [],
|
||||
"summary": {
|
||||
"totalLitellmKeys": 0,
|
||||
"totalPlatformAgents": 0,
|
||||
"totalCustomAgents": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 认证失败响应
|
||||
|
||||
**HTTP Status Code**: `401 Unauthorized`
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Not authenticated"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 使用说明
|
||||
|
||||
### LiteLLM 密钥使用方式
|
||||
|
||||
获取到的 `apiKey` 可以直接用于调用 AI 模型(OpenAI 兼容格式):
|
||||
|
||||
```python
|
||||
import openai
|
||||
|
||||
# 从接口返回的数据中获取
|
||||
api_key = response["data"]["litellmKeys"][0]["apiKey"]
|
||||
api_base = response["data"]["litellmKeys"][0]["apiBase"]
|
||||
|
||||
client = openai.OpenAI(
|
||||
api_key=api_key,
|
||||
base_url=api_base
|
||||
)
|
||||
|
||||
response = client.chat.completions.create(
|
||||
model="azure/gpt-4",
|
||||
messages=[{"role": "user", "content": "Hello!"}]
|
||||
)
|
||||
```
|
||||
|
||||
### Agent 访问方式
|
||||
|
||||
通过 `accessUrl` 可以在集群内部访问 Agent 服务:
|
||||
|
||||
```bash
|
||||
# 在集群内部调用 Agent
|
||||
curl http://user-abc123-echo-agent-def456.ai-agents.svc.cluster.local:8080/api/chat
|
||||
```
|
||||
|
||||
通过 `podIp` 和 `servicePort` 也可以直接访问:
|
||||
|
||||
```bash
|
||||
# 直接通过 Pod IP 访问
|
||||
curl http://10.244.1.100:8080/api/chat
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📌 数据来源说明
|
||||
|
||||
| 数据类型 | 来源 | 实时性 |
|
||||
|---------|------|--------|
|
||||
| LiteLLM 密钥 | PostgreSQL 数据库 | 静态(创建时存储) |
|
||||
| Agent 基本信息(名称、模板、CPU/内存) | PostgreSQL 数据库 | 静态(创建时存储) |
|
||||
| Agent 状态(status, healthStatus) | AKS 集群(通过 Agent Manager) | **实时查询** |
|
||||
| Agent 网络信息(podIp, accessUrl) | AKS 集群(通过 Agent Manager) | **实时查询** |
|
||||
|
||||
### 调用链路
|
||||
|
||||
```
|
||||
前端 → mcp-server → Agent Manager → AKS (Kubernetes API)
|
||||
↓
|
||||
查询 Pod/Service 真实状态
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **密钥安全**:返回的 `apiKey` 是完整的解密密钥,请妥善保管,不要泄露
|
||||
2. **实时性**:Agent 的 `podIp`、`status` 等信息是实时从 AKS 查询的,可能有轻微延迟
|
||||
3. **服务可用性**:如果 Agent Manager 服务不可用,Agent 的实时信息将显示为 `null` 或 `unknown`
|
||||
4. **Pod IP 变化**:Pod 重启后 IP 地址会改变,建议使用 `accessUrl`(Service DNS)访问
|
||||
|
||||
@@ -38,18 +38,6 @@ scrape_configs:
|
||||
scrape_interval: 10s
|
||||
scrape_timeout: 5s
|
||||
|
||||
# LiteLLM Gateway (如果有metrics端点)
|
||||
- job_name: 'litellm-gateway'
|
||||
static_configs:
|
||||
- targets: ['litellm-gateway:4000']
|
||||
labels:
|
||||
service: 'litellm-gateway'
|
||||
component: 'gateway'
|
||||
metrics_path: '/metrics'
|
||||
scrape_interval: 10s
|
||||
scrape_timeout: 5s
|
||||
# 如果端点不存在,Prometheus会记录错误但不会影响其他服务
|
||||
|
||||
# PostgreSQL (需要postgres_exporter,当前未部署)
|
||||
# - job_name: 'postgres'
|
||||
# static_configs:
|
||||
|
||||
@@ -20,28 +20,6 @@ services:
|
||||
- taiji-network
|
||||
restart: unless-stopped
|
||||
|
||||
# LiteLLM网关服务
|
||||
litellm-gateway:
|
||||
build:
|
||||
context: ./services/model-gateway
|
||||
dockerfile: Dockerfile
|
||||
container_name: taiji-litellm-gateway
|
||||
ports:
|
||||
- "4000:4000"
|
||||
environment:
|
||||
- LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY}
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- REDIS_URL=${REDIS_URL}
|
||||
# OpenRouter 配置
|
||||
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
|
||||
- OPENROUTER_BASE_URL=${OPENROUTER_BASE_URL}
|
||||
volumes:
|
||||
- ./services/model-gateway/config:/app/config
|
||||
- ./logs:/app/logs
|
||||
networks:
|
||||
- taiji-network
|
||||
restart: unless-stopped
|
||||
|
||||
# 数据接入服务 (Python)
|
||||
data-ingestion:
|
||||
build:
|
||||
@@ -101,7 +79,6 @@ services:
|
||||
- ./logs:/app/logs
|
||||
depends_on:
|
||||
- nats
|
||||
- litellm-gateway
|
||||
networks:
|
||||
- taiji-network
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -3820,3 +3820,162 @@ async def update_user_profile(
|
||||
"company": getattr(user, "company", None),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# ============= 用户资源信息综合查询 =============
|
||||
|
||||
@router.get("/resources/info", response_model=SuccessResponse)
|
||||
async def get_user_resources_info(
|
||||
principal: dict = Depends(require_auth),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
获取用户的资源信息综合查询
|
||||
|
||||
返回:
|
||||
1. LiteLLM 密钥列表(解密后的完整密钥)
|
||||
2. 已部署的平台 Agent 列表(包含 IP 地址和访问信息)
|
||||
3. 已部署的自定义 Agent 列表(包含 IP 地址和访问信息)
|
||||
|
||||
注意:
|
||||
- LiteLLM 密钥用于调用 AI 模型(OpenAI 兼容格式)
|
||||
- Agent 信息包含实时状态和访问地址
|
||||
"""
|
||||
from app.litellm_client import get_litellm_client
|
||||
from config import settings
|
||||
|
||||
user_id = principal.get("user_id")
|
||||
|
||||
# ========== 1. 获取 LiteLLM 密钥 ==========
|
||||
litellm_keys = []
|
||||
try:
|
||||
# 查询用户的模型密钥
|
||||
result = await db.execute(
|
||||
select(TenantModelKey).where(
|
||||
and_(
|
||||
TenantModelKey.tenant_id == user_id,
|
||||
TenantModelKey.status == "active"
|
||||
)
|
||||
)
|
||||
)
|
||||
tenant_keys = result.scalars().all()
|
||||
|
||||
litellm_client = get_litellm_client()
|
||||
|
||||
for key in tenant_keys:
|
||||
try:
|
||||
# 解密密钥
|
||||
decrypted_key = litellm_client.decrypt_key(key.litellm_key_hash)
|
||||
litellm_keys.append({
|
||||
"modelName": key.model_name,
|
||||
"apiKey": decrypted_key,
|
||||
"apiBase": settings.litellm_url,
|
||||
"rpmLimit": key.rpm_limit,
|
||||
"tpmLimit": key.tpm_limit,
|
||||
"maxBudget": float(key.max_budget) if key.max_budget else None,
|
||||
"budgetDuration": key.budget_duration,
|
||||
"status": key.status,
|
||||
"createdAt": key.created_at.isoformat() if key.created_at else None,
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning(f"解密 LiteLLM 密钥失败: {e}")
|
||||
litellm_keys.append({
|
||||
"modelName": key.model_name,
|
||||
"apiKey": None,
|
||||
"apiBase": settings.litellm_url,
|
||||
"error": "密钥解密失败",
|
||||
"status": key.status,
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"查询 LiteLLM 密钥失败: {e}")
|
||||
|
||||
# ========== 2. 获取已部署的 Agent ==========
|
||||
platform_agents = []
|
||||
custom_agents = []
|
||||
|
||||
# 查询用户的活跃 Agent(未停止的)
|
||||
result = await db.execute(
|
||||
select(AgentBillingRecord).where(
|
||||
and_(
|
||||
AgentBillingRecord.user_id == user_id,
|
||||
AgentBillingRecord.end_time == None # 正在运行
|
||||
)
|
||||
)
|
||||
)
|
||||
billing_records = result.scalars().all()
|
||||
|
||||
# 尝试获取 Agent Manager 客户端
|
||||
agent_manager_available = False
|
||||
client = None
|
||||
try:
|
||||
from app.agent_manager_client import get_agent_manager_client, AgentManagerError
|
||||
client = get_agent_manager_client()
|
||||
agent_manager_available = True
|
||||
except Exception as e:
|
||||
logger.warning(f"Agent Manager 客户端不可用: {e}")
|
||||
|
||||
for record in billing_records:
|
||||
agent_info = {
|
||||
"name": record.agent_name,
|
||||
"template": record.agent_type,
|
||||
"templateName": record.template_name,
|
||||
"status": "unknown",
|
||||
"healthStatus": "unknown",
|
||||
"podIp": None,
|
||||
"accessUrl": None,
|
||||
"servicePort": None,
|
||||
"namespace": "ai-agents",
|
||||
"cpu": record.cpu_used,
|
||||
"memory": record.memory_used,
|
||||
"replicas": record.replicas,
|
||||
"startTime": record.start_time.isoformat() if record.start_time else None,
|
||||
"runningSeconds": int((datetime.utcnow() - record.start_time).total_seconds()) if record.start_time else 0,
|
||||
}
|
||||
|
||||
# 从 Agent Manager 获取详细状态
|
||||
if agent_manager_available and client:
|
||||
try:
|
||||
agent_status = await client.get_agent_status(record.agent_name)
|
||||
agent_info["status"] = agent_status.status
|
||||
agent_info["healthStatus"] = agent_status.health_status
|
||||
agent_info["podIp"] = agent_status.pod_ip
|
||||
agent_info["accessUrl"] = agent_status.access_url
|
||||
agent_info["servicePort"] = agent_status.service_port
|
||||
agent_info["namespace"] = agent_status.namespace
|
||||
agent_info["hostIp"] = agent_status.host_ip
|
||||
agent_info["nodeName"] = agent_status.node_name
|
||||
|
||||
# 端点信息
|
||||
if agent_status.endpoints:
|
||||
agent_info["endpoints"] = [
|
||||
{
|
||||
"name": ep.name,
|
||||
"port": ep.port,
|
||||
"protocol": ep.protocol,
|
||||
"targetPort": ep.target_port,
|
||||
}
|
||||
for ep in agent_status.endpoints
|
||||
]
|
||||
except Exception as e:
|
||||
logger.warning(f"获取 Agent {record.agent_name} 状态失败: {e}")
|
||||
|
||||
# 分类存储
|
||||
if record.is_platform_agent:
|
||||
platform_agents.append(agent_info)
|
||||
else:
|
||||
custom_agents.append(agent_info)
|
||||
|
||||
return SuccessResponse(
|
||||
data={
|
||||
"litellmKeys": litellm_keys,
|
||||
"litellmApiBase": settings.litellm_url,
|
||||
"platformAgents": platform_agents,
|
||||
"customAgents": custom_agents,
|
||||
"summary": {
|
||||
"totalLitellmKeys": len(litellm_keys),
|
||||
"totalPlatformAgents": len(platform_agents),
|
||||
"totalCustomAgents": len(custom_agents),
|
||||
}
|
||||
},
|
||||
message="用户资源信息获取成功"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user