更新mcp-server

This commit is contained in:
Ubuntu
2026-01-05 01:41:05 +00:00
parent 085dd9c84e
commit 0768288788
5 changed files with 662 additions and 1471 deletions
-191
View File
@@ -1,191 +0,0 @@
# AI Agent Manager API 集成计划
## 概述
将项目中的 Agent 管理功能与新的 AI Agent Manager API 集成,实现真正的 Kubernetes Pod 部署和资源管控。
## 当前状态分析
### 现有实现
- **Agent 数据模型** ([`models.py`](../services/mcp-server/models.py:122)):数据库级别的 Agent 记录
- **Agent 路由** ([`agents.py`](../services/mcp-server/app/routes/agents.py:1)):CRUD 操作,无真正 K8s 部署
- **资源管控** ([`resource_control.py`](../services/mcp-server/app/resource_control.py:1)):配额检查和速率限制
- **部署功能** ([`user.py:deploy_agent`](../services/mcp-server/app/routes/user.py:327)):仅模拟,未实际调用 K8s
### 新 API 能力
- 真正的 Kubernetes Pod 创建/删除/查询
- 模板系统(echo_agent, jina_search_agent, mysql_agent 等)
- 资源配置(cpu_request, cpu_limit, memory_request, memory_limit)
- Pod 状态监控和访问信息
## 架构设计
```mermaid
flowchart TB
subgraph Frontend[前端]
UI[用户界面]
end
subgraph MCPServer[MCP Server]
AgentRoutes[Agent 路由]
ResourceControl[资源管控]
AgentClient[Agent Manager 客户端]
DB[(PostgreSQL)]
end
subgraph K8sCluster[Kubernetes 集群]
AgentManager[AI Agent Manager API]
AgentPods[Agent Pods]
end
UI --> AgentRoutes
AgentRoutes --> ResourceControl
ResourceControl --> AgentClient
AgentClient --> AgentManager
AgentManager --> AgentPods
AgentRoutes --> DB
```
## 实施任务清单
### 阶段一:创建 Agent Manager 客户端
- [x] **1.1** 创建 `services/mcp-server/app/agent_manager_client.py`
- 封装对 AI Agent Manager API 的 HTTP 调用
- 支持健康检查、模板列表、创建/删除/查询 Agent
- 使用 httpx 异步客户端
- 配置通过环境变量 `AGENT_MANAGER_URL` 设置
- [x] **1.2** 创建请求/响应模型(集成到 `schemas.py`)
- K8sResourceConfig(cpu_request, cpu_limit, memory_request, memory_limit, env)
- AgentStatusResponse(Pod 状态、IP、端点信息)
- AgentMetricsResponse(资源使用情况)
- TemplateInfo, TemplateListResponse
### 阶段二:修改 Agent 路由
- [x] **2.1** 更新 `services/mcp-server/app/routes/agents.py`
- 修改 `create_agent` 函数:
- 保留资源管控检查
- 调用 Agent Manager API 创建 Pod
- 同步更新数据库记录(添加 pod_name, pod_ip, template 等字段)
- 新增 `delete_agent` 函数:调用 API 删除 Pod
- 新增 `get_agent_status` 函数:获取 Pod 实时状态
- 新增 `get_agent_metrics` 函数:获取资源使用情况
- 新增 `list_templates` 和 `get_template` 函数
- [x] **2.2** 更新 Agent 数据模型 `services/mcp-server/models.py`
- 添加字段:`pod_name`, `pod_ip`, `template`, `service_port`
- 添加字段:`cpu_request`, `cpu_limit`, `memory_request`, `memory_limit`
- 添加字段:`k8s_status`(Pending, Running, Failed 等)
- 添加字段:`k8s_namespace`, `access_url`, `endpoints`, `env_config`, `pod_created_at`
- [x] **2.3** 创建数据库迁移脚本
- `services/mcp-server/migrations/004_add_k8s_agent_fields.sql`
### 阶段三:更新资源管控
- [ ] **3.1** 更新 `services/mcp-server/app/resource_control.py`
- 添加 Agent 资源配额检查(用户可创建的 Agent 数量限制)
- 添加 CPU/内存总量限制检查
- 集成 Agent Manager 的 metrics API 获取实际资源使用
- [x] **3.2** 更新 `services/mcp-server/app/routes/admin.py`
- 修改 `update_agent_config` 函数:
- 支持更新 cpu_request, cpu_limit, memory_request, memory_limit
- 注意:已运行的 Pod 需要重新创建才能更新资源配置
### 阶段四:更新用户侧功能
- [x] **4.1** 更新 `services/mcp-server/app/routes/user.py`
- 修改 `deploy_agent` 函数:调用 Agent Manager API
- 修改 `generate_tool` 函数:支持自定义资源配置(待完成)
- [x] **4.2** 更新 `services/mcp-server/app/schemas.py`
- 更新 `UpdateAgentConfigRequest`:添加 K8s 资源配置字段
### 阶段五:模板管理
- [x] **5.1** 模板路由已集成到 `services/mcp-server/app/routes/agents.py`
- `GET /agents/templates`:获取可用模板列表
- `GET /agents/templates/{name}`:获取模板详情和所需环境变量
- [ ] **5.2** 更新路由注册 `services/mcp-server/app/routes/__init__.py`(无需修改,已自动包含)
### 阶段六:资源监控集成
- [ ] **6.1** 更新 `services/mcp-server/app/routes/resource_monitoring.py`
- 集成 Agent Manager 的 `/agents/{name}/metrics` API
- 提供实时 Pod 资源使用数据
- [ ] **6.2** 更新 `services/mcp-server/app/routes/monitoring.py`
- 添加 Agent Pod 健康状态监控
- 添加 Agent Manager 服务健康检查
### 阶段七:配置和部署
- [x] **7.1** 更新环境变量配置
- `.env.example`:添加 `AGENT_MANAGER_URL`
- `services/mcp-server/config.py`:添加配置项
- [ ] **7.2** 更新 Kubernetes 部署配置
- `k8s/mcp-server.yaml`:添加环境变量
- `k8s/configmap.yaml`:添加 Agent Manager URL 配置
- [ ] **7.3** 更新 Docker Compose 配置
- `docker-compose.yml`:添加 Agent Manager 服务依赖
## API 映射关系
| MCP Server 功能 | AI Agent Manager API | 说明 |
|----------------|---------------------|------|
| 创建 Agent | `POST /agents` | 创建 K8s Pod |
| 删除 Agent | `DELETE /agents/{name}` | 删除 K8s Pod |
| 获取 Agent 状态 | `GET /agents/{name}/status` | 获取 Pod 状态和 IP |
| 获取资源使用 | `GET /agents/{name}/metrics` | 获取 CPU/内存配置 |
| 列出所有 Agent | `GET /agents` | 列出所有 Pod |
| 获取模板列表 | `GET /templates` | 获取可用模板 |
| 获取模板详情 | `GET /templates/{name}` | 获取模板所需参数 |
## 资源配置映射
| 用户配置 | API 参数 | 默认值 |
|---------|---------|-------|
| CPU 请求 | `cpu_request` | `100m` |
| CPU 限制 | `cpu_limit` | `500m` |
| 内存请求 | `memory_request` | `128Mi` |
| 内存限制 | `memory_limit` | `512Mi` |
## 需要新增的接口
根据业务需求,建议新增以下接口:
1. **Agent 日志查询**
- `GET /agents/{name}/logs` - 获取 Pod 日志
- 需要 Agent Manager API 支持
2. **Agent 重启**
- `POST /agents/{name}/restart` - 重启 Pod
- 可通过删除后重新创建实现
3. **Agent 扩缩容**
- `PUT /agents/{name}/scale` - 调整副本数
- 需要 Agent Manager API 支持 replicas 参数
4. **批量操作**
- `POST /agents/batch/create` - 批量创建
- `DELETE /agents/batch` - 批量删除
## 注意事项
1. **数据一致性**:数据库记录和 K8s Pod 状态需要保持同步
2. **错误处理**:API 调用失败时需要回滚数据库操作
3. **权限控制**:保留现有的资源管控和权限检查
4. **向后兼容**:保留现有 API 接口格式,扩展返回字段
## 测试计划
- [ ] 单元测试:Agent Manager 客户端
- [ ] 集成测试:创建/删除/查询 Agent 流程
- [ ] 端到端测试:前端到 K8s Pod 完整流程
- [ ] 性能测试:并发创建 Agent 场景
-374
View File
@@ -1,374 +0,0 @@
# Agent 设计重构计划
## 概述
根据业务需求重新设计 Agent 系统,明确区分**平台端 Agent** 和**自定义 Agent** 两种类型,并完善资源分配和监控机制。
## 当前问题分析
### 现有设计的问题
1. **Agent 类型定义模糊**
- 当前 [`Agent.type`](services/mcp-server/models.py:130) 字段只有 `platform` 和 `custom` 两个值
- 但没有明确区分两种 Agent 的部署方式和资源管理逻辑
2. **资源分配逻辑不完整**
- 渠道的 [`custom_agent_cpu`](services/mcp-server/models.py:305) 和 [`custom_agent_memory`](services/mcp-server/models.py:306) 字段被当作"默认值"使用
- 实际应该是"资源配额上限",租户在配额内创建多个自定义 Agent
3. **资源统计不完整**
- [`get_admin_dashboard_stats`](services/mcp-server/app/routes/admin.py:375) 只统计了平台端 Agent
- 应该同时统计平台端 Agent + 自定义 Agent
4. **健康监控不完整**
- [`monitor_agents`](services/mcp-server/app/routes/admin.py:1299) 只监控 `type == "platform"` 的 Agent
- 应该同时监控平台端 Agent + 自定义 Agent
## 新设计方案
### 1. Agent 类型定义
```
┌─────────────────────────────────────────────────────────────────┐
│ Agent 类型 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────────┐ │
│ │ 平台端 Agent │ │ 自定义 Agent │ │
│ │ type=platform │ │ type=custom │ │
│ ├─────────────────────────┤ ├─────────────────────────────┤ │
│ │ - 平台打镜像到仓库 │ │ - 租户上传自己的程序 │ │
│ │ - K8s 部署管理 │ │ - 在分配的资源配额内运行 │ │
│ │ - 管理员分配给渠道 │ │ - 渠道分配资源配额给租户 │ │
│ │ - 渠道分配给租户 │ │ - 租户可创建多个 Agent │ │
│ └─────────────────────────┘ └─────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 2. 资源分配流程
```mermaid
flowchart TB
subgraph Platform[平台层]
Admin[超级管理员]
PlatformAgents[平台端Agent镜像仓库]
CustomQuota[自定义Agent资源池]
end
subgraph ChannelLayer[渠道层]
Channel[渠道]
ChannelPlatformAgents[分配的平台端Agent]
ChannelCustomQuota[分配的自定义Agent配额]
end
subgraph TenantLayer[租户层]
Tenant[租户]
TenantPlatformAgents[可用的平台端Agent]
TenantCustomAgents[创建的自定义Agent]
end
Admin -->|分配平台端Agent| Channel
Admin -->|分配自定义Agent配额| Channel
PlatformAgents --> ChannelPlatformAgents
CustomQuota --> ChannelCustomQuota
Channel -->|分配平台端Agent| Tenant
Channel -->|分配自定义Agent配额| Tenant
ChannelPlatformAgents --> TenantPlatformAgents
ChannelCustomQuota --> TenantCustomAgents
Tenant -->|使用| TenantPlatformAgents
Tenant -->|在配额内创建多个| TenantCustomAgents
```
### 3. 数据模型修改
#### 3.1 Channel 模型修改
当前字段:
- `custom_agent_cpu` - 自定义 Agent CPU(当前作为默认值)
- `custom_agent_memory` - 自定义 Agent 内存(当前作为默认值)
修改为:
- `custom_agent_cpu_quota` - 自定义 Agent CPU 配额上限
- `custom_agent_memory_quota` - 自定义 Agent 内存配额上限
#### 3.2 新增 TenantCustomAgentQuota 模型
```python
class TenantCustomAgentQuota(BaseModel, Base):
"""租户自定义 Agent 资源配额"""
__tablename__ = "tenant_custom_agent_quotas"
tenant_id = Column(GUID, ForeignKey users.id, nullable=False, unique=True)
# 配额上限(由渠道分配)
cpu_quota = Column(Numeric 12 2, default=0) # CPU 核心数上限
memory_quota = Column(Numeric 12 2, default=0) # 内存 GB 上限
# 已使用量(由系统计算)
cpu_used = Column(Numeric 12 2, default=0) # 已使用 CPU
memory_used = Column(Numeric 12 2, default=0) # 已使用内存
agent_count = Column(Integer, default=0) # 已创建的自定义 Agent 数量
```
#### 3.3 Agent 模型增强
在 [`Agent`](services/mcp-server/models.py:125) 模型中添加:
```python
# 自定义 Agent 特有字段
image_url = Column(String 500) # 用户上传的镜像地址
program_path = Column(String 500) # 程序路径
runtime_type = Column(String 50) # 运行时类型:python, nodejs, docker 等
```
### 4. API 修改
#### 4.1 渠道资源管理 API
修改 [`allocate_channel_resources`](services/mcp-server/app/routes/admin.py:875):
```python
# 请求体增加
class ChannelResourceAllocation:
# 现有字段...
customAgentQuota: CustomAgentQuotaConfig # 新增
class CustomAgentQuotaConfig:
cpuQuota: float # CPU 配额上限
memoryQuota: float # 内存配额上限
```
#### 4.2 租户资源分配 API
修改 [`allocate_tenant_resources`](services/mcp-server/app/routes/channel.py:193):
```python
# 请求体增加
class AllocateResourcesRequest:
# 现有字段...
customAgentQuota: Optional[CustomAgentQuotaConfig] # 新增
```
#### 4.3 自定义 Agent 创建 API
修改用户创建自定义 Agent 的逻辑,增加配额检查:
```python
async def create_custom_agent:
# 1. 检查租户的自定义 Agent 配额
quota = await get_tenant_custom_agent_quota tenant_id
# 2. 检查请求的资源是否超过剩余配额
remaining_cpu = quota.cpu_quota - quota.cpu_used
remaining_memory = quota.memory_quota - quota.memory_used
if request.cpu > remaining_cpu or request.memory > remaining_memory:
raise HTTPException 400, 资源配额不足
# 3. 创建 Agent 并更新已使用量
agent = create_agent...
quota.cpu_used += request.cpu
quota.memory_used += request.memory
quota.agent_count += 1
```
#### 4.4 资源统计 API
修改 [`get_admin_dashboard_stats`](services/mcp-server/app/routes/admin.py:375):
```python
# 统计所有 Agent(平台端 + 自定义)
total_agents = await db.execute select func.count Agent.id
# 分别统计
platform_agents = await db.execute select func.count Agent.id where Agent.type == platform
custom_agents = await db.execute select func.count Agent.id where Agent.type == custom
# 资源统计也要包含两种类型
total_cpu = sum of all agents cpu
total_memory = sum of all agents memory
```
#### 4.5 健康监控 API
修改 [`monitor_agents`](services/mcp-server/app/routes/admin.py:1299):
```python
# 监控所有 Agent(移除 type == platform 的过滤条件)
result = await db.execute select Agent # 不再过滤 type
# 返回数据增加 type 字段,便于前端区分
data = [
{
id: str agent.id,
name: agent.name,
type: agent.type, # 新增:platform 或 custom
# ...其他字段
}
]
```
### 5. 前端展示修改
#### 5.1 平台资源分配统计
在概览页面展示:
- 平台端 Agent 数量和资源使用
- 自定义 Agent 数量和资源使用
- 总计资源使用
#### 5.2 Agent 健康监控
在监控页面:
- 支持按类型筛选(全部/平台端/自定义)
- 显示 Agent 类型标签
- 分别展示两种类型的健康状态统计
## 实施任务清单
### 阶段一:数据模型修改 ✅ 已完成
- [x] **1.1** 修改 [`Channel`](services/mcp-server/models.py:311) 模型 ✅
- 添加 `custom_agent_cpu_quota` 字段(配额上限)
- 添加 `custom_agent_memory_quota` 字段(配额上限)
- 保留旧字段 `custom_agent_cpu/memory` 作为向后兼容
- 添加字段注释说明这是配额上限
- [x] **1.2** 创建 `TenantCustomAgentQuota` 模型 ✅
- 新增表 `tenant_custom_agent_quotas`(第974-1004行)
- 包含配额上限(cpu_quota, memory_quota)和已使用量(cpu_used, memory_used, agent_count)字段
- [x] **1.3** 创建 `ChannelCustomAgentQuota` 模型 ✅
- 新增表 `channel_custom_agent_quotas`(第1007-1030行)
- 包含配额上限和已分配量字段
- [x] **1.4** 增强 [`Agent`](services/mcp-server/models.py:125) 模型 ✅
- 添加 `image_url` 字段(自定义 Agent 镜像地址,第170行)
- 添加 `program_path` 字段(程序路径,第171行)
- 添加 `runtime_type` 字段(运行时类型,第172行)
- 添加 `health_status` 字段(健康状态,第179行)
- 添加 `last_health_check` 字段(最后健康检查时间,第180行)
- 添加 `health_message` 字段(健康状态消息,第181行)
- 添加 `idx_agent_health_status` 索引(第206行)
- [x] **1.5** 创建数据库迁移脚本 ✅
- `migrations/005_refactor_agent_quota_system.sql`(180行完整迁移脚本)
### 阶段二:API 修改 ✅ 已完成
- [x] **2.1** 修改渠道资源管理 API ✅
- 更新 [`ChannelResourceAllocation`](services/mcp-server/app/schemas.py:372) schema - 添加 customAgentQuota 字段
- 更新 [`allocate_channel_resources`](services/mcp-server/app/routes/admin.py:924) 逻辑 - 支持配额分配
- [x] **2.2** 修改租户资源分配 API ✅
- 更新 [`AllocateResourcesRequest`](services/mcp-server/app/schemas.py:298) schema - 添加 customAgentQuota 字段
- 更新 [`allocate_tenant_resources`](services/mcp-server/app/routes/channel.py:193) 逻辑 - 支持配额分配和验证
- 添加租户配额记录创建/更新逻辑
- [x] **2.3** 修改自定义 Agent 创建 API ✅
- 在 [`generate_tool`](services/mcp-server/app/routes/user.py:287) 中添加配额检查
- 创建 Agent 后更新已使用量
- 在 [`delete_agent`](services/mcp-server/app/routes/agents.py:396) 中释放配额
- [x] **2.4** 新增配额查询 API ✅
- `GET /api/user/custom-agent-quota` - 租户查询自己的配额使用情况 ([`get_my_custom_agent_quota`](services/mcp-server/app/routes/user.py:227))
- `GET /api/channel/tenants/{tenant_id}/custom-agent-quota` - 渠道查询租户配额 ([`get_tenant_custom_agent_quota`](services/mcp-server/app/routes/channel.py:796))
### 阶段三:资源统计修改 ✅ 已完成
- [x] **3.1** 修改 [`get_admin_dashboard_stats`](services/mcp-server/app/routes/admin.py:375) ✅
- 统计所有 Agent(平台端 + 自定义)
- 分别返回两种类型的数量和资源使用(platformAgents, customAgents)
- 返回总计资源使用(totalAllocatedCpu, totalAllocatedMemory)
- [x] **3.2** 修改 [`get_platform_overview`](services/mcp-server/app/routes/resource_monitoring.py:31) ✅
- 包含自定义 Agent 的统计
- 返回 platformAgents 和 customAgents 分类统计
- 返回 totalResources 总资源使用
- [x] **3.3** 新增资源分配统计 API ✅
- `GET /api/admin/resources/allocation-stats` - 返回详细的资源分配统计
- 实现:[`get_resource_allocation_stats`](services/mcp-server/app/routes/admin.py:1064)
### 阶段四:健康监控修改 ✅ 已完成
- [x] **4.1** 修改 [`monitor_agents`](services/mcp-server/app/routes/admin.py:1477) ✅
- 移除 `type == "platform"` 过滤条件,查询所有活跃 Agent
- 返回数据增加 `type` 字段
- 支持按类型筛选参数(agent_type)
- 支持按健康状态筛选参数(health_status)
- 返回汇总统计(summary)
- [x] **4.2** 增强自定义 Agent 健康检查 ✅
- 在 Agent 模型中添加 health_status, last_health_check, health_message 字段
- monitor_agents API 支持查询和筛选自定义 Agent 的健康状态
- 注:实际的健康检查逻辑需要后台任务定期执行(可后续实现)
- [x] **4.3** 统一健康状态定义 ✅
- 在 Agent 模型中添加 health_status 字段
- 定义统一的健康状态枚举:healthy, warning, critical, unknown
- 平台端和自定义 Agent 使用相同的状态定义
### 阶段五:前端适配
- [ ] **5.1** 更新概览页面
- 展示平台端 Agent + 自定义 Agent 的资源统计
- 添加类型区分的图表
- [ ] **5.2** 更新资源管理页面
- 渠道资源管理增加自定义 Agent 配额设置
- 租户资源分配增加自定义 Agent 配额设置
- [ ] **5.3** 更新监控页面
- Agent 健康监控支持类型筛选
- 显示 Agent 类型标签
## 数据迁移策略
1. **向后兼容**:保留旧字段名,添加新字段,逐步迁移
2. **默认值处理**:现有渠道的 `custom_agent_cpu/memory` 值迁移为配额上限
3. **租户配额初始化**:为现有租户创建配额记录,初始值从渠道继承
## 注意事项
1. **资源配额检查**:创建自定义 Agent 时必须检查配额
2. **配额释放**:删除自定义 Agent 时必须释放配额
3. **并发控制**:配额更新需要考虑并发场景
4. **审计日志**:配额变更需要记录审计日志
## 问题修复记录
### 2026-01-04: 渠道配额显示问题修复
**问题描述**:
- 通过 API 更新渠道的自定义 Agent 配额后,数据库中 `custom_agent_cpu_quota` 和 `custom_agent_memory_quota` 字段正确更新
- 但渠道列表 API (`/api/admin/channels`) 返回的 `customAgentCpu` 和 `customAgentMemory` 仍然显示旧值
**根本原因**:
- Channel 模型中同时存在新旧两组字段:
- 新字段:`custom_agent_cpu_quota`, `custom_agent_memory_quota`
- 旧字段:`custom_agent_cpu`, `custom_agent_memory`
- API 代码中部分地方使用新字段,部分地方使用旧字段,导致不一致
**修复方案**:
1. 修改 [`admin_channels`](services/mcp-server/app/routes/frontend_integration.py:933) 函数
- 优先使用新字段 `custom_agent_cpu_quota`,如果为空则回退到旧字段
- 添加调试日志便于排查
2. 修改 [`admin_get_channel_resources`](services/mcp-server/app/routes/frontend_integration.py:1020) 函数
- 同样优先使用新字段,回退到旧字段
3. 修改 [`admin_update_channel_resources`](services/mcp-server/app/routes/frontend_integration.py:1063) 函数
- 同时更新新旧两组字段,确保数据一致性
- 添加日志记录更新操作
- 返回更新后的配额值便于验证
## 测试计划
- [ ] 单元测试:配额检查逻辑
- [ ] 集成测试:完整的资源分配流程
- [ ] 端到端测试:从渠道分配到租户创建 Agent 的完整流程
- [ ] 性能测试:大量 Agent 场景下的统计性能
-740
View File
@@ -1,740 +0,0 @@
# AKS Agent 执行方案设计
## 1. 问题分析
### 当前状态
```
用户请求 → MCP Server → 本地 MCP 协议处理 → 工具执行
↓
(未使用 AKS Pod 的 access_url)
```
**问题**:虽然 AKS 部署后返回了 `access_url` 和 `endpoints`,但当前代码并没有使用这些 URL 来调用 AKS 中运行的 Pod。
### 目标状态
```
用户请求 → MCP Server → 判断 Agent 类型 → 转发到 AKS Pod → 返回结果
↓
本地执行(无 K8s 部署)
```
---
## 2. 架构设计
### 2.1 整体架构图
```mermaid
flowchart TB
subgraph Client[客户端]
User[用户]
end
subgraph MCPServer[MCP Server]
API[API Gateway]
Router[Agent Router]
LocalHandler[本地 MCP Handler]
K8sProxy[K8s Agent Proxy]
end
subgraph AKS[Azure Kubernetes Service]
Pod1[Agent Pod 1]
Pod2[Agent Pod 2]
Pod3[Agent Pod N]
end
subgraph AgentManager[Agent Manager Service]
AM[Agent Manager API]
end
User --> API
API --> Router
Router -->|无 K8s 部署| LocalHandler
Router -->|有 K8s 部署| K8sProxy
K8sProxy --> Pod1
K8sProxy --> Pod2
K8sProxy --> Pod3
AM -.->|管理| Pod1
AM -.->|管理| Pod2
AM -.->|管理| Pod3
```
### 2.2 执行流程图
```mermaid
sequenceDiagram
participant User as 用户
participant API as MCP Server API
participant Router as Agent Router
participant DB as 数据库
participant Proxy as K8s Proxy
participant Pod as AKS Agent Pod
participant Local as 本地 Handler
User->>API: POST /agents/{id}/execute
API->>DB: 获取 Agent 信息
DB-->>API: Agent 数据
API->>Router: 路由决策
alt Agent 有 access_url
Router->>Proxy: 转发请求
Proxy->>Pod: HTTP POST /execute
Pod-->>Proxy: 执行结果
Proxy-->>API: 返回结果
else Agent 无 K8s 部署
Router->>Local: 本地执行
Local-->>API: 执行结果
end
API->>DB: 记录执行和计费
API-->>User: 返回结果
```
---
## 3. 详细设计
### 3.1 新增组件:K8s Agent Proxy
**文件位置**: `services/mcp-server/app/k8s_agent_proxy.py`
```python
"""
K8s Agent Proxy - 负责转发请求到 AKS 部署的 Agent Pod
"""
import httpx
import structlog
from typing import Dict, Any, Optional
from dataclasses import dataclass
from datetime import datetime
logger = structlog.get_logger(__name__)
@dataclass
class ProxyConfig:
"""代理配置"""
timeout: float = 30.0
max_retries: int = 3
retry_delay: float = 1.0
health_check_interval: int = 30
@dataclass
class ProxyResult:
"""代理执行结果"""
success: bool
result: Optional[Dict[str, Any]] = None
error: Optional[str] = None
execution_time_ms: float = 0.0
pod_name: Optional[str] = None
status_code: Optional[int] = None
class K8sAgentProxy:
"""K8s Agent 代理类"""
def __init__(self, config: Optional[ProxyConfig] = None):
self.config = config or ProxyConfig()
self._client: Optional[httpx.AsyncClient] = None
async def _get_client(self) -> httpx.AsyncClient:
"""获取或创建 HTTP 客户端"""
if self._client is None or self._client.is_closed:
self._client = httpx.AsyncClient(
timeout=self.config.timeout,
headers={"Content-Type": "application/json"}
)
return self._client
async def execute(
self,
access_url: str,
request_data: Dict[str, Any],
pod_name: Optional[str] = None,
headers: Optional[Dict[str, str]] = None
) -> ProxyResult:
"""
转发执行请求到 AKS Agent Pod
Args:
access_url: Agent Pod 的访问 URL
request_data: MCP 请求数据
pod_name: Pod 名称(用于日志)
headers: 额外的请求头
Returns:
ProxyResult: 执行结果
"""
start_time = datetime.utcnow()
try:
client = await self._get_client()
# 构建完整的执行 URL
execute_url = f"{access_url.rstrip('/')}/execute"
logger.info(
"转发请求到 AKS Agent",
url=execute_url,
pod_name=pod_name,
method=request_data.get("method")
)
# 合并请求头
request_headers = {"Content-Type": "application/json"}
if headers:
request_headers.update(headers)
# 发送请求(带重试)
response = await self._request_with_retry(
client, execute_url, request_data, request_headers
)
execution_time = (datetime.utcnow() - start_time).total_seconds() * 1000
if response.status_code == 200:
result_data = response.json()
return ProxyResult(
success=True,
result=result_data,
execution_time_ms=execution_time,
pod_name=pod_name,
status_code=response.status_code
)
else:
error_detail = response.text
try:
error_detail = response.json()
except Exception:
pass
return ProxyResult(
success=False,
error=f"Pod 返回错误: {response.status_code} - {error_detail}",
execution_time_ms=execution_time,
pod_name=pod_name,
status_code=response.status_code
)
except httpx.TimeoutException as e:
execution_time = (datetime.utcnow() - start_time).total_seconds() * 1000
logger.error("请求 AKS Agent 超时", pod_name=pod_name, error=str(e))
return ProxyResult(
success=False,
error=f"请求超时: {str(e)}",
execution_time_ms=execution_time,
pod_name=pod_name
)
except httpx.ConnectError as e:
execution_time = (datetime.utcnow() - start_time).total_seconds() * 1000
logger.error("无法连接到 AKS Agent", pod_name=pod_name, error=str(e))
return ProxyResult(
success=False,
error=f"连接失败: {str(e)}",
execution_time_ms=execution_time,
pod_name=pod_name
)
except Exception as e:
execution_time = (datetime.utcnow() - start_time).total_seconds() * 1000
logger.error("转发请求失败", pod_name=pod_name, error=str(e))
return ProxyResult(
success=False,
error=f"执行失败: {str(e)}",
execution_time_ms=execution_time,
pod_name=pod_name
)
async def _request_with_retry(
self,
client: httpx.AsyncClient,
url: str,
data: Dict[str, Any],
headers: Dict[str, str]
) -> httpx.Response:
"""带重试的请求"""
import asyncio
last_exception = None
for attempt in range(self.config.max_retries):
try:
response = await client.post(url, json=data, headers=headers)
return response
except (httpx.TimeoutException, httpx.ConnectError) as e:
last_exception = e
if attempt < self.config.max_retries - 1:
await asyncio.sleep(self.config.retry_delay * (attempt + 1))
logger.warning(
f"重试请求 {attempt + 1}/{self.config.max_retries}",
url=url,
error=str(e)
)
raise last_exception
async def health_check(self, access_url: str) -> bool:
"""检查 Agent Pod 健康状态"""
try:
client = await self._get_client()
health_url = f"{access_url.rstrip('/')}/health"
response = await client.get(health_url, timeout=5.0)
return response.status_code == 200
except Exception:
return False
async def close(self):
"""关闭客户端"""
if self._client and not self._client.is_closed:
await self._client.aclose()
self._client = None
# 全局代理实例
_k8s_proxy: Optional[K8sAgentProxy] = None
def get_k8s_agent_proxy() -> K8sAgentProxy:
"""获取全局 K8s Agent 代理实例"""
global _k8s_proxy
if _k8s_proxy is None:
_k8s_proxy = K8sAgentProxy()
return _k8s_proxy
async def close_k8s_agent_proxy():
"""关闭全局代理"""
global _k8s_proxy
if _k8s_proxy:
await _k8s_proxy.close()
_k8s_proxy = None
```
### 3.2 修改 Agent 执行端点
**文件位置**: `services/mcp-server/app/routes/agents.py`
修改 `execute_agent` 函数:
```python
@router.post("/{agent_id}/execute", response_model=ExecutionResult)
async def execute_agent(
agent_id: str,
request: MCPRequest,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
session_id: Optional[str] = None,
) -> ExecutionResult:
"""
执行 Agent 请求。
如果 Agent 部署在 AKS 中,请求将被转发到对应的 Pod。
否则,请求将在本地执行。
"""
state = get_state()
try:
agent_uuid = uuid.UUID(agent_id)
user_id = uuid.UUID(current_user["user_id"])
except ValueError as exc:
raise HTTPException(status_code=400, detail="Invalid agent ID or user ID") from exc
agent = await db.get(Agent, agent_uuid)
if not agent:
raise HTTPException(status_code=404, detail="Agent not found")
# 权限检查
if agent.owner_id != user_id and current_user.get("role") != "super_admin":
raise HTTPException(status_code=403, detail="Access denied")
# 资源管控检查
await enforce_resource_control(
user_id=str(user_id),
resource_type="agent",
resource_id=agent_id,
estimated_cost=Decimal("0.01"),
db=db
)
start_time = time.time()
execution_id = str(uuid.uuid4())
try:
# ========== 路由决策:K8s Pod 或本地执行 ==========
if agent.access_url and agent.k8s_status == "Running":
# 转发到 AKS Agent Pod
result = await _execute_on_k8s_pod(
agent=agent,
request=request,
execution_id=execution_id,
user_id=str(user_id)
)
else:
# 本地执行
result = await _execute_locally(
agent=agent,
request=request,
execution_id=execution_id,
user_id=str(user_id),
db=db
)
# ================================================
duration = time.time() - start_time
# 记录执行和计费
await _record_execution_and_billing(
db=db,
agent=agent,
request=request,
result=result,
execution_id=execution_id,
start_time=start_time,
duration=duration,
session_id=session_id
)
return result
except Exception as exc:
duration = time.time() - start_time
logger.error("执行Agent任务失败", error=str(exc))
raise HTTPException(status_code=500, detail=str(exc)) from exc
async def _execute_on_k8s_pod(
agent: Agent,
request: MCPRequest,
execution_id: str,
user_id: str
) -> ExecutionResult:
"""转发请求到 AKS Agent Pod"""
from ..k8s_agent_proxy import get_k8s_agent_proxy
proxy = get_k8s_agent_proxy()
# 构建请求数据
request_data = {
"jsonrpc": request.jsonrpc,
"id": str(request.id),
"method": request.method,
"params": request.params or {},
"metadata": {
"execution_id": execution_id,
"user_id": user_id,
"agent_id": str(agent.id)
}
}
# 转发请求
proxy_result = await proxy.execute(
access_url=agent.access_url,
request_data=request_data,
pod_name=agent.pod_name
)
if proxy_result.success:
return ExecutionResult(
execution_id=execution_id,
success=True,
result=proxy_result.result,
execution_time=proxy_result.execution_time_ms,
started_at=datetime.utcnow(),
completed_at=datetime.utcnow()
)
else:
return ExecutionResult(
execution_id=execution_id,
success=False,
error=proxy_result.error,
execution_time=proxy_result.execution_time_ms,
started_at=datetime.utcnow(),
completed_at=datetime.utcnow()
)
async def _execute_locally(
agent: Agent,
request: MCPRequest,
execution_id: str,
user_id: str,
db: AsyncSession
) -> ExecutionResult:
"""本地执行 MCP 请求"""
state = get_state()
handler = state.mcp_handler
if not handler:
raise HTTPException(status_code=500, detail="MCP handler not initialized")
return await handler.execute_request(
str(agent.id),
request,
user_id=user_id,
db_session=db
)
```
### 3.3 AKS Agent Pod 端点规范
每个部署在 AKS 中的 Agent Pod 需要实现以下端点:
| 端点 | 方法 | 描述 |
|-----|------|------|
| `/health` | GET | 健康检查 |
| `/execute` | POST | 执行 MCP 请求 |
| `/status` | GET | 获取 Agent 状态 |
| `/metrics` | GET | 获取资源使用指标 |
#### 3.3.1 `/execute` 端点请求格式
```json
{
"jsonrpc": "2.0",
"id": "request-uuid",
"method": "tools/call",
"params": {
"name": "tool_name",
"arguments": {}
},
"metadata": {
"execution_id": "exec-uuid",
"user_id": "user-uuid",
"agent_id": "agent-uuid"
}
}
```
#### 3.3.2 `/execute` 端点响应格式
```json
{
"success": true,
"result": {
"content": [
{
"type": "text",
"text": "执行结果"
}
]
},
"execution_time_ms": 150.5,
"resource_usage": {
"cpu_ms": 50,
"memory_mb": 128
}
}
```
---
## 4. 数据库变更
### 4.1 Agent 表新增字段(已存在)
当前 `Agent` 模型已包含必要字段:
| 字段 | 类型 | 描述 |
|-----|------|------|
| `access_url` | String(500) | Pod 访问 URL |
| `pod_name` | String(100) | Pod 名称 |
| `pod_ip` | String(45) | Pod IP |
| `k8s_status` | String(20) | Pod 状态 |
| `service_port` | Integer | Service 端口 |
| `endpoints` | JSON | 端点字典 |
### 4.2 新增执行记录字段
在 `Execution` 表中添加:
```python
# 执行位置
execution_location = Column(String(20), default="local") # local, k8s
pod_name = Column(String(100)) # 执行的 Pod 名称
```
---
## 5. 配置变更
### 5.1 环境变量
```bash
# K8s Agent Proxy 配置
K8S_PROXY_TIMEOUT=30.0
K8S_PROXY_MAX_RETRIES=3
K8S_PROXY_RETRY_DELAY=1.0
K8S_PROXY_HEALTH_CHECK_INTERVAL=30
```
### 5.2 应用配置
在 `config.py` 中添加:
```python
class K8sProxyConfig:
timeout: float = float(os.getenv("K8S_PROXY_TIMEOUT", "30.0"))
max_retries: int = int(os.getenv("K8S_PROXY_MAX_RETRIES", "3"))
retry_delay: float = float(os.getenv("K8S_PROXY_RETRY_DELAY", "1.0"))
health_check_interval: int = int(os.getenv("K8S_PROXY_HEALTH_CHECK_INTERVAL", "30"))
```
---
## 6. 实施计划
### 6.1 任务清单
- [ ] **Phase 1: 基础设施**
- [ ] 创建 `k8s_agent_proxy.py` 模块
- [ ] 添加配置项
- [ ] 编写单元测试
- [ ] **Phase 2: 路由逻辑**
- [ ] 修改 `execute_agent` 端点
- [ ] 实现路由决策逻辑
- [ ] 添加本地执行回退
- [ ] **Phase 3: 监控和日志**
- [ ] 添加执行位置记录
- [ ] 添加 Prometheus 指标
- [ ] 完善日志记录
- [ ] **Phase 4: 健康检查**
- [ ] 实现 Pod 健康检查
- [ ] 添加自动故障转移
- [ ] 实现连接池管理
- [ ] **Phase 5: 测试和文档**
- [ ] 集成测试
- [ ] 性能测试
- [ ] 更新 API 文档
### 6.2 文件变更清单
| 文件 | 操作 | 描述 |
|-----|------|------|
| `services/mcp-server/app/k8s_agent_proxy.py` | 新增 | K8s Agent 代理模块 |
| `services/mcp-server/app/routes/agents.py` | 修改 | 添加路由逻辑 |
| `services/mcp-server/config.py` | 修改 | 添加代理配置 |
| `services/mcp-server/app/lifecycle.py` | 修改 | 添加代理生命周期管理 |
| `services/mcp-server/models.py` | 修改 | 添加执行位置字段 |
---
## 7. 错误处理
### 7.1 错误场景和处理策略
| 场景 | 处理策略 |
|-----|---------|
| Pod 不可达 | 重试 3 次后返回错误 |
| Pod 返回 5xx | 记录错误,返回给用户 |
| 请求超时 | 返回超时错误,建议重试 |
| Pod 状态非 Running | 回退到本地执行或返回错误 |
| access_url 为空 | 使用本地执行 |
### 7.2 故障转移策略
```python
async def execute_with_fallback(agent, request, ...):
"""带故障转移的执行"""
# 1. 尝试 K8s Pod 执行
if agent.access_url and agent.k8s_status == "Running":
result = await _execute_on_k8s_pod(...)
if result.success:
return result
# 2. K8s 执行失败,检查是否可以本地执行
if agent.tools and not agent.template:
logger.warning("K8s 执行失败,回退到本地执行")
return await _execute_locally(...)
# 3. 本地执行
return await _execute_locally(...)
```
---
## 8. 监控指标
### 8.1 新增 Prometheus 指标
```python
# K8s Agent 执行指标
k8s_agent_requests_total = Counter(
"k8s_agent_requests_total",
"Total K8s agent requests",
["pod_name", "status"]
)
k8s_agent_request_duration = Histogram(
"k8s_agent_request_duration_seconds",
"K8s agent request duration",
["pod_name"]
)
k8s_agent_health_status = Gauge(
"k8s_agent_health_status",
"K8s agent health status",
["pod_name"]
)
```
### 8.2 日志格式
```json
{
"timestamp": "2024-01-01T00:00:00Z",
"level": "INFO",
"message": "转发请求到 AKS Agent",
"execution_id": "exec-uuid",
"agent_id": "agent-uuid",
"pod_name": "my-agent-abc123",
"access_url": "http://my-agent.ai-agents.svc.cluster.local:8080",
"method": "tools/call",
"execution_location": "k8s"
}
```
---
## 9. 安全考虑
### 9.1 网络安全
- Pod 间通信使用 K8s 内部网络
- 不暴露 Pod 到公网
- 使用 NetworkPolicy 限制访问
### 9.2 认证授权
- 请求中携带 `user_id` 和 `execution_id`
- Pod 可验证请求来源
- 支持 mTLS(可选)
### 9.3 数据安全
- 敏感数据不在日志中记录
- 请求/响应数据加密传输
- 执行结果脱敏存储
---
## 10. 总结
本方案实现了 MCP Server 与 AKS Agent Pod 的集成,主要特点:
1. **智能路由**:根据 Agent 配置自动选择执行位置
2. **故障转移**:K8s 执行失败时可回退到本地
3. **可观测性**:完整的日志、指标和追踪
4. **安全性**:网络隔离和认证机制
5. **可扩展性**:支持多 Pod 负载均衡(未来)
通过此方案,用户可以透明地使用部署在 AKS 中的 Agent,无需关心底层执行细节。
-166
View File
@@ -1,166 +0,0 @@
# 数据库迁移计划:postgres → taiji
**创建时间**: 2025-12-31
**目标**: 将 postgres 库的表结构和数据完全覆盖到 taiji 库
---
## 📋 任务概述
将 Azure PostgreSQL 服务器上的 `postgres` 数据库(新结构)完全复制到 `taiji` 数据库(旧结构),包括:
- 表结构
- 索引
- 约束
- 数据
- 序列
---
## 🔄 迁移流程图
```mermaid
flowchart TD
A[开始迁移] --> B[连接 postgres 源数据库]
B --> C[连接 taiji 目标数据库]
C --> D[备份 taiji 数据库 - 可选]
D --> E[删除 taiji 中的所有表]
E --> F[从 postgres 获取表结构]
F --> G[在 taiji 中创建表]
G --> H[创建索引和约束]
H --> I[复制数据]
I --> J[同步序列值]
J --> K[验证迁移结果]
K --> L[完成]
```
---
## ✅ 任务清单
### 1. 准备工作
- [ ] 确认数据库连接信息正确
- [ ] 确认 postgres 库中有最新的表结构
- [ ] 备份 taiji 库现有数据(可选但推荐)
### 2. 创建迁移脚本
- [ ] 修改现有 `copy_database.py` 脚本,交换源和目标数据库
- [ ] 或创建新脚本 `sync_postgres_to_taiji.py`
### 3. 脚本功能实现
- [ ] 连接源数据库(postgres)
- [ ] 连接目标数据库(taiji)
- [ ] 获取 postgres 库所有表列表
- [ ] 删除 taiji 库中的所有现有表(CASCADE)
- [ ] 复制表结构(DDL)
- [ ] 复制索引定义
- [ ] 复制数据
- [ ] 同步序列值
### 4. 验证和测试
- [ ] 验证表数量一致
- [ ] 验证数据行数一致
- [ ] 验证索引创建成功
- [ ] 测试应用连接 taiji 库正常工作
---
## 📝 技术细节
### 数据库连接信息
```python
DB_HOST = "taijipda.postgres.database.azure.com"
DB_USER = "taiji"
DB_PASSWORD = "By@123456."
DB_PORT = 5432
# 源数据库(新结构)
SOURCE_DB = "postgres"
# 目标数据库(需要更新)
TARGET_DB = "taiji"
```
### 主要表列表(基于 models.py)
| 表名 | 说明 |
|------|------|
| users | 用户表(租户使用者) |
| agents | Agent表(平台Agent和自定义Agent) |
| tools | 工具表 |
| sessions | 会话表 |
| executions | 执行记录表 |
| api_keys | API密钥表 |
| billing | 计费详情表 |
| balances | 用户余额表 |
| billing_records | 计费记录表 |
| channels | 渠道合作伙伴表 |
| model_providers | 模型供应商表 |
| resource_allocations | 资源分配表 |
| applications | 申请审批表 |
| workflows | 工作流表 |
| audit_logs | 审计日志表 |
| channel_agent_quotas | 渠道Agent配额表 |
| provider_models | 模型提供商表 |
| token_blacklist | Token黑名单表 |
| resource_usage | 资源使用记录表 |
| quota_alerts | 配额预警记录表 |
| model_pricing | 模型定价配置表 |
| provider_health_checks | 供应商健康检查记录表 |
| agent_traces | Agent执行轨迹表 |
| billing_events | 计费事件表 |
| channel_provider_access | 渠道供应商授权表 |
| provider_applications | 供应商使用申请表 |
| gateway_apis | 网关API定义表 |
| data_templates | 数据模板表 |
| recharge_records | 充值记录表 |
---
## ⚠️ 注意事项
1. **数据丢失风险**: 此操作会删除 taiji 库中的所有现有数据,请确保已备份
2. **外键约束**: 删除表时使用 CASCADE 处理外键依赖
3. **序列同步**: 确保序列值正确同步,避免主键冲突
4. **连接中断**: 迁移过程中确保网络稳定
5. **应用停机**: 建议在迁移期间停止连接 taiji 库的应用服务
---
## 🚀 执行步骤
1. **运行迁移脚本**:
```bash
cd /home/taiji/tools/taiji-AI-PAD
python scripts/sync_postgres_to_taiji.py
```
2. **验证迁移结果**:
```bash
# 连接 taiji 库检查表
psql "host=taijipda.postgres.database.azure.com port=5432 dbname=taiji user=taiji password=By@123456. sslmode=require"
# 查看所有表
\dt
# 检查数据行数
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM agents;
```
3. **更新应用配置**(如需要):
确保应用的 DATABASE_URL 指向 taiji 库
---
## 📊 预期结果
迁移完成后:
- taiji 库将拥有与 postgres 库完全相同的表结构
- 所有数据将从 postgres 库复制到 taiji 库
- 索引和约束将正确创建
- 序列值将同步
---
**下一步**: 切换到 Code 模式创建迁移脚本
+662
View File
@@ -0,0 +1,662 @@
# MCP Server 重构需求文档
## 1. 概述
### 1.1 服务定位
MCP Server 是平台的核心业务服务,负责:
- 用户认证与授权
- 渠道和租户管理
- Agent 资源分配与配额管理
- 计费与账单
- 与 Agent Manager 的集成
- 工具和工作流管理
### 1.2 系统架构
```mermaid
flowchart TB
subgraph Frontend[前端]
AdminUI[管理员控制台]
ChannelUI[渠道控制台]
UserUI[用户控制台]
end
subgraph MCPServer[MCP Server]
subgraph Auth[认证授权]
AuthModule[认证模块]
PermModule[权限模块]
end
subgraph Business[业务模块]
ChannelMgmt[渠道管理]
TenantMgmt[租户管理]
AgentMgmt[Agent管理]
QuotaMgmt[配额管理]
end
subgraph Billing[计费模块]
BillingCalc[计费计算]
BillingRecord[计费记录]
end
subgraph Integration[集成模块]
AMClient[Agent Manager客户端]
ProviderClient[供应商客户端]
end
DB[(PostgreSQL)]
end
subgraph External[外部服务]
AgentManager[Agent Manager]
ModelProviders[模型供应商]
end
Frontend --> MCPServer
MCPServer --> External
Business --> DB
Billing --> DB
```
### 1.3 调用链路
```
前端 → MCP Server(认证、权限、配额、计费)→ Agent Manager(K8s 操作)
```
---
## 2. 现有功能模块
### 2.1 路由模块清单
| 模块 | 文件 | 功能 | 重构优先级 |
|------|------|------|-----------|
| 认证 | `auth.py` | 登录、注册、Token管理 | 保留 |
| 管理员 | `admin.py` | 超级管理员功能 | 重构 |
| 渠道 | `channel.py` | 渠道管理、资源分配 | 重构 |
| 用户 | `user.py` | 租户功能、Agent使用 | 重构 |
| Agent | `agents.py` | Agent CRUD、K8s集成 | **重点重构** |
| 计费 | `billing_admin.py` | 计费管理 | 保留 |
| 配额 | `quota_management.py` | 配额管理 | 重构 |
| 监控 | `monitoring.py` | 系统监控 | 保留 |
| 资源监控 | `resource_monitoring.py` | 资源使用监控 | 重构 |
| 前端集成 | `frontend_integration.py` | 前端API适配 | 重构 |
| 工具 | `tools.py` | 工具管理 | 保留 |
| 会话 | `sessions.py` | 会话管理 | 保留 |
| 健康检查 | `health.py` | 服务健康检查 | 保留 |
### 2.2 数据模型清单
| 模型 | 说明 | 重构内容 |
|------|------|----------|
| User | 用户/租户 | 新增平台Agent配额字段 |
| Channel | 渠道 | 已有自定义Agent配额字段 |
| Agent | Agent | 区分平台/自定义类型 |
| ResourceAllocation | 资源分配 | 新增平台Agent分配 |
| ChannelAgentQuota | 渠道Agent配额 | 重构为平台Agent配额 |
| TenantCustomAgentQuota | 租户自定义Agent配额 | 保留 |
| ChannelCustomAgentQuota | 渠道自定义Agent配额 | 保留 |
---
## 3. Agent 相关功能重构
### 3.1 平台 Agent 管理
#### 3.1.1 管理员功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看平台Agent模板列表 | `GET /api/admin/platform-agents/templates` | 从Agent Manager获取 |
| 设置平台Agent配置 | `PUT /api/admin/platform-agents/templates/{name}/config` | 设置CPU/内存/最大Pod数 |
| 分配平台Agent给渠道 | `POST /api/admin/channels/{id}/platform-agents` | 分配Pod数量配额 |
| 查看平台Agent分配情况 | `GET /api/admin/platform-agents/allocations` | 查看所有分配 |
| 查看平台Agent运行状态 | `GET /api/admin/platform-agents/status` | 从Agent Manager获取 |
**分配平台Agent给渠道请求体**:
```json
{
"templateName": "jina_search_agent",
"podQuota": 10,
"description": "分配Jina搜索Agent给渠道A"
}
```
#### 3.1.2 渠道功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看已分配的平台Agent | `GET /api/channel/platform-agents` | 查看渠道拥有的配额 |
| 分配平台Agent给租户 | `POST /api/channel/tenants/{id}/platform-agents` | 分配Pod数量配额 |
| 查看租户平台Agent使用情况 | `GET /api/channel/tenants/{id}/platform-agents/usage` | 查看使用统计 |
**分配平台Agent给租户请求体**:
```json
{
"templateName": "jina_search_agent",
"podQuota": 3,
"description": "分配给租户使用"
}
```
#### 3.1.3 租户功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看可用的平台Agent | `GET /api/user/platform-agents` | 查看已分配的Agent |
| 使用平台Agent | `POST /api/user/platform-agents/{template}/use` | 创建Pod实例 |
| 停止平台Agent | `DELETE /api/user/platform-agents/{name}` | 删除Pod实例 |
| 查看平台Agent状态 | `GET /api/user/platform-agents/{name}/status` | 查看Pod状态 |
| 查看配额使用情况 | `GET /api/user/platform-agents/quota` | 查看配额和使用量 |
**使用平台Agent请求体**:
```json
{
"name": "my-jina-search-001",
"queryParams": {
"searchType": "semantic",
"maxResults": 10
}
}
```
### 3.2 自定义 Agent 管理
#### 3.2.1 管理员功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看自定义Agent模板列表 | `GET /api/admin/custom-agents/templates` | 从Agent Manager获取 |
| 分配自定义Agent资源给渠道 | `POST /api/admin/channels/{id}/custom-agent-quota` | 分配CPU/内存配额 |
| 查看自定义Agent资源分配 | `GET /api/admin/custom-agents/allocations` | 查看所有分配 |
**分配自定义Agent资源给渠道请求体**:
```json
{
"cpuQuota": 8,
"memoryQuota": 16,
"description": "分配自定义Agent资源给渠道A"
}
```
#### 3.2.2 渠道功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看自定义Agent资源配额 | `GET /api/channel/custom-agent-quota` | 查看渠道配额 |
| 分配自定义Agent资源给租户 | `POST /api/channel/tenants/{id}/custom-agent-quota` | 分配CPU/内存配额 |
| 查看租户自定义Agent使用情况 | `GET /api/channel/tenants/{id}/custom-agents` | 查看租户创建的Agent |
**分配自定义Agent资源给租户请求体**:
```json
{
"cpuQuota": 4,
"memoryQuota": 8,
"description": "分配自定义Agent资源给租户"
}
```
#### 3.2.3 租户功能
| 功能 | API | 说明 |
|------|-----|------|
| 查看自定义Agent模板 | `GET /api/user/custom-agents/templates` | 查看可用模板 |
| 创建自定义Agent | `POST /api/user/custom-agents` | 创建并启动Agent |
| 更新自定义Agent配置 | `PUT /api/user/custom-agents/{name}` | 更新环境变量等 |
| 删除自定义Agent | `DELETE /api/user/custom-agents/{name}` | 删除Agent |
| 查看自定义Agent状态 | `GET /api/user/custom-agents/{name}/status` | 查看Pod状态 |
| 查看配额使用情况 | `GET /api/user/custom-agent-quota` | 查看配额和使用量 |
| 扩缩容自定义Agent | `PUT /api/user/custom-agents/{name}/scale` | 调整Pod数量 |
**创建自定义Agent请求体**:
```json
{
"name": "my-openai-agent",
"template": "openai_agent_template",
"envVars": {
"OPENAI_API_KEY": "sk-xxx",
"OPENAI_API_BASE": "https://api.openai.com/v1",
"MODEL_NAME": "gpt-4"
},
"resourceConfig": {
"cpuRequest": "200m",
"cpuLimit": "1000m",
"memoryRequest": "256Mi",
"memoryLimit": "1Gi"
},
"scalingConfig": {
"minReplicas": 2,
"maxReplicas": 4
}
}
```
---
## 4. 配额管理重构
### 4.1 平台 Agent 配额
#### 4.1.1 数据模型
```python
class PlatformAgentQuota(BaseModel, Base):
"""平台 Agent 配额分配"""
__tablename__ = "platform_agent_quotas"
# 分配目标
target_id = Column(GUID(), nullable=False) # 渠道ID或租户ID
target_type = Column(String(20), nullable=False) # channel, tenant
# Agent模板
template_name = Column(String(100), nullable=False) # 平台Agent模板名称
# 配额
pod_quota = Column(Integer, nullable=False, default=0) # Pod数量配额
pod_used = Column(Integer, default=0) # 已使用Pod数量
# 分配信息
allocated_by = Column(GUID(), ForeignKey("users.id")) # 分配人
allocated_at = Column(DateTime, default=datetime.utcnow)
__table_args__ = (
Index("idx_platform_agent_quota_target", target_id, target_type),
Index("idx_platform_agent_quota_template", template_name),
UniqueConstraint("target_id", "target_type", "template_name", name="uq_platform_agent_quota"),
)
```
#### 4.1.2 配额检查流程
```mermaid
flowchart TD
A[用户请求使用平台Agent] --> B[验证用户身份]
B --> C[获取用户的平台Agent配额]
C --> D{配额是否充足?}
D -->|是| E[调用Agent Manager创建Pod]
D -->|否| F[返回配额不足错误]
E --> G{创建成功?}
G -->|是| H[更新已使用配额]
G -->|否| I[返回创建失败错误]
H --> J[返回成功]
```
### 4.2 自定义 Agent 配额
#### 4.2.1 现有数据模型
已有 `TenantCustomAgentQuota` 和 `ChannelCustomAgentQuota` 模型,保留使用。
#### 4.2.2 配额检查流程
```mermaid
flowchart TD
A[用户创建自定义Agent] --> B[验证用户身份]
B --> C[获取用户的自定义Agent配额]
C --> D[计算请求的资源总量]
D --> E{资源是否充足?}
E -->|是| F[调用Agent Manager创建Pod]
E -->|否| G[返回资源不足错误]
F --> H{创建成功?}
H -->|是| I[更新已使用资源]
H -->|否| J[返回创建失败错误]
I --> K[返回成功]
```
---
## 5. 与 Agent Manager 集成
### 5.1 客户端重构
现有 `agent_manager_client.py` 需要重构以支持新的 API:
```python
class AgentManagerClient:
"""Agent Manager API 客户端"""
# 模板管理
async def list_platform_templates(self) -> List[TemplateInfo]
async def list_custom_templates(self) -> List[TemplateInfo]
async def get_template(self, name: str) -> TemplateInfo
# 平台 Agent 管理
async def create_platform_agent(
self,
name: str,
template: str,
owner_id: str,
channel_id: str,
config: AgentConfig
) -> AgentCreateResult
async def delete_platform_agent(self, name: str) -> Dict
async def get_platform_agent_status(self, name: str) -> AgentStatusResult
async def list_platform_agents(self, owner_id: str = None) -> List[Dict]
# 自定义 Agent 管理
async def create_custom_agent(
self,
name: str,
template: str,
owner_id: str,
channel_id: str,
env_vars: Dict[str, str],
config: AgentConfig,
scaling_config: ScalingConfig
) -> AgentCreateResult
async def update_custom_agent_env(self, name: str, env_vars: Dict[str, str]) -> Dict
async def delete_custom_agent(self, name: str) -> Dict
async def get_custom_agent_status(self, name: str) -> AgentStatusResult
async def scale_custom_agent(self, name: str, replicas: int) -> Dict
async def list_custom_agents(self, owner_id: str = None) -> List[Dict]
# 统计
async def get_stats() -> Dict
```
### 5.2 调用时序
#### 5.2.1 使用平台 Agent
```mermaid
sequenceDiagram
participant User as 用户
participant MCP as MCP Server
participant AM as Agent Manager
participant K8s as Kubernetes
User->>MCP: POST /api/user/platform-agents/{template}/use
MCP->>MCP: 验证身份和权限
MCP->>MCP: 检查配额
MCP->>AM: POST /platform-agents
AM->>K8s: 创建Pod
K8s-->>AM: Pod创建成功
AM-->>MCP: 返回Agent信息
MCP->>MCP: 更新配额使用量
MCP->>MCP: 记录计费信息
MCP-->>User: 返回Agent信息
```
#### 5.2.2 创建自定义 Agent
```mermaid
sequenceDiagram
participant User as 用户
participant MCP as MCP Server
participant AM as Agent Manager
participant K8s as Kubernetes
User->>MCP: POST /api/user/custom-agents
MCP->>MCP: 验证身份和权限
MCP->>MCP: 检查资源配额
MCP->>MCP: 验证环境变量
MCP->>AM: POST /custom-agents
AM->>K8s: 创建Secret
AM->>K8s: 创建Deployment
K8s-->>AM: 资源创建成功
AM-->>MCP: 返回Agent信息
MCP->>MCP: 更新资源使用量
MCP->>MCP: 记录计费信息
MCP-->>User: 返回Agent信息
```
---
## 6. 计费重构
### 6.1 计费规则
#### 6.1.1 平台 Agent 计费
| 计费项 | 计算方式 | 说明 |
|--------|----------|------|
| Pod 运行时间 | 运行秒数 × 单价 | 按秒计费 |
| 请求次数 | 请求数 × 单价 | 可选 |
#### 6.1.2 自定义 Agent 计费
| 计费项 | 计算方式 | 说明 |
|--------|----------|------|
| CPU 使用 | CPU核心数 × 运行秒数 × 单价 | 按实际使用计费 |
| 内存使用 | 内存GB × 运行秒数 × 单价 | 按实际使用计费 |
| 请求次数 | 请求数 × 单价 | 可选 |
### 6.2 计费记录
```python
class AgentBillingRecord(BaseModel, Base):
"""Agent 计费记录"""
__tablename__ = "agent_billing_records"
user_id = Column(GUID(), ForeignKey("users.id"), nullable=False)
channel_id = Column(GUID(), ForeignKey("channels.id"))
agent_name = Column(String(100), nullable=False)
agent_type = Column(String(20), nullable=False) # platform, custom
template_name = Column(String(100), nullable=False)
# 使用量
duration_seconds = Column(Integer, nullable=False) # 运行时长
cpu_seconds = Column(sa.Float, default=0) # CPU秒数
memory_gb_seconds = Column(sa.Float, default=0) # 内存GB秒数
request_count = Column(Integer, default=0) # 请求次数
# 费用
cost = Column(sa.Numeric(12, 4), nullable=False)
currency = Column(String(10), default="EU")
# 时间
period_start = Column(DateTime, nullable=False)
period_end = Column(DateTime, nullable=False)
```
---
## 7. 权限控制
### 7.1 角色权限矩阵
| 功能 | super_admin | admin | channel_admin | user |
|------|-------------|-------|---------------|------|
| 管理平台Agent模板 | ✓ | ✓ | - | - |
| 分配平台Agent给渠道 | ✓ | ✓ | - | - |
| 分配自定义Agent资源给渠道 | ✓ | ✓ | - | - |
| 分配平台Agent给租户 | - | - | ✓ | - |
| 分配自定义Agent资源给租户 | - | - | ✓ | - |
| 使用平台Agent | - | - | - | ✓ |
| 创建自定义Agent | - | - | - | ✓ |
| 查看自己的Agent | - | - | ✓ | ✓ |
### 7.2 权限检查
```python
# 权限定义
PERMISSIONS = {
# 平台 Agent
"platform_agent:admin": ["super_admin", "admin"],
"platform_agent:allocate_channel": ["super_admin", "admin"],
"platform_agent:allocate_tenant": ["channel_admin"],
"platform_agent:use": ["user"],
# 自定义 Agent
"custom_agent:admin": ["super_admin", "admin"],
"custom_agent:allocate_channel": ["super_admin", "admin"],
"custom_agent:allocate_tenant": ["channel_admin"],
"custom_agent:create": ["user"],
"custom_agent:manage": ["user"],
}
```
---
## 8. 数据库迁移
### 8.1 新增表
```sql
-- 平台 Agent 配额表
CREATE TABLE platform_agent_quotas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
target_id UUID NOT NULL,
target_type VARCHAR(20) NOT NULL,
template_name VARCHAR(100) NOT NULL,
pod_quota INTEGER NOT NULL DEFAULT 0,
pod_used INTEGER DEFAULT 0,
allocated_by UUID REFERENCES users(id),
allocated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(target_id, target_type, template_name)
);
CREATE INDEX idx_platform_agent_quota_target ON platform_agent_quotas(target_id, target_type);
CREATE INDEX idx_platform_agent_quota_template ON platform_agent_quotas(template_name);
-- Agent 计费记录表
CREATE TABLE agent_billing_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
channel_id UUID REFERENCES channels(id),
agent_name VARCHAR(100) NOT NULL,
agent_type VARCHAR(20) NOT NULL,
template_name VARCHAR(100) NOT NULL,
duration_seconds INTEGER NOT NULL,
cpu_seconds FLOAT DEFAULT 0,
memory_gb_seconds FLOAT DEFAULT 0,
request_count INTEGER DEFAULT 0,
cost NUMERIC(12, 4) NOT NULL,
currency VARCHAR(10) DEFAULT 'EU',
period_start TIMESTAMP NOT NULL,
period_end TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_agent_billing_user ON agent_billing_records(user_id);
CREATE INDEX idx_agent_billing_channel ON agent_billing_records(channel_id);
CREATE INDEX idx_agent_billing_period ON agent_billing_records(period_start, period_end);
```
### 8.2 修改现有表
```sql
-- 在 users 表添加平台 Agent 相关字段(如果需要)
-- 注意:平台 Agent 配额通过 platform_agent_quotas 表管理
-- 在 agents 表确保有必要的字段
ALTER TABLE agents ADD COLUMN IF NOT EXISTS owner_channel_id UUID REFERENCES channels(id);
```
---
## 9. API 变更汇总
### 9.1 新增 API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/admin/platform-agents/templates | 获取平台Agent模板列表 |
| PUT | /api/admin/platform-agents/templates/{name}/config | 设置平台Agent配置 |
| POST | /api/admin/channels/{id}/platform-agents | 分配平台Agent给渠道 |
| GET | /api/admin/platform-agents/allocations | 查看平台Agent分配情况 |
| GET | /api/channel/platform-agents | 查看渠道的平台Agent配额 |
| POST | /api/channel/tenants/{id}/platform-agents | 分配平台Agent给租户 |
| GET | /api/user/platform-agents | 查看可用的平台Agent |
| POST | /api/user/platform-agents/{template}/use | 使用平台Agent |
| DELETE | /api/user/platform-agents/{name} | 停止平台Agent |
| GET | /api/user/platform-agents/{name}/status | 查看平台Agent状态 |
| GET | /api/user/platform-agents/quota | 查看平台Agent配额 |
### 9.2 修改 API
| 方法 | 路径 | 变更说明 |
|------|------|----------|
| POST | /api/user/custom-agents | 增加配额检查,调用Agent Manager |
| DELETE | /api/user/custom-agents/{name} | 释放配额,调用Agent Manager |
| GET | /api/admin/dashboard/stats | 增加平台Agent统计 |
| GET | /api/admin/resources/agents | 区分平台/自定义Agent |
### 9.3 废弃 API
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /api/user/agents/deploy | 改用 /api/user/platform-agents/{template}/use |
---
## 10. 实施计划
### 阶段一:数据模型和迁移
- [ ] 创建 `PlatformAgentQuota` 模型
- [ ] 创建 `AgentBillingRecord` 模型
- [ ] 创建数据库迁移脚本
- [ ] 执行迁移
### 阶段二:Agent Manager 客户端重构
- [ ] 重构 `agent_manager_client.py`
- [ ] 添加平台Agent API支持
- [ ] 添加自定义Agent API支持
- [ ] 添加单元测试
### 阶段三:管理员功能
- [ ] 实现平台Agent模板管理API
- [ ] 实现平台Agent分配给渠道API
- [ ] 实现自定义Agent资源分配给渠道API
- [ ] 更新管理员Dashboard统计
### 阶段四:渠道功能
- [ ] 实现渠道查看平台Agent配额API
- [ ] 实现渠道分配平台Agent给租户API
- [ ] 实现渠道分配自定义Agent资源给租户API
- [ ] 更新渠道Dashboard
### 阶段五:租户功能
- [ ] 实现租户查看可用平台Agent API
- [ ] 实现租户使用平台Agent API
- [ ] 重构租户创建自定义Agent API
- [ ] 实现配额查询API
### 阶段六:计费集成
- [ ] 实现Agent计费记录
- [ ] 集成计费到Agent使用流程
- [ ] 实现计费统计API
### 阶段七:测试和文档
- [ ] 单元测试
- [ ] 集成测试
- [ ] API文档更新
- [ ] 前端对接测试
---
## 11. 注意事项
1. **向后兼容**:保留现有API,新增API使用新路径
2. **配额一致性**:确保配额检查和更新的原子性
3. **错误处理**:Agent Manager调用失败时的回滚处理
4. **日志记录**:所有配额变更需要审计日志
5. **性能考虑**:配额检查需要高效,避免频繁数据库查询
---
## 12. 版本历史
| 版本 | 日期 | 说明 |
|------|------|------|
| v1.0 | 2026-01-04 | 初始版本 |