forked from xiaohei/taiji-AI-PAD
1118 lines
32 KiB
Markdown
1118 lines
32 KiB
Markdown
# 自定义外部数据工具功能方案
|
||
|
||
> **版本**: v1.0
|
||
> **日期**: 2026-01-23
|
||
> **状态**: ✅ 已实现
|
||
|
||
---
|
||
|
||
## 1. 功能概述
|
||
|
||
### 1.1 背景
|
||
|
||
用户需要能够创建自定义的外部数据工具,这些工具可以连接到外部 API 服务(如第三方数据接口、企业内部系统等),并在部署自定义 Agent 时使用这些工具。
|
||
|
||
### 1.2 核心流程
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
||
│ 自定义外部数据工具流程 │
|
||
├─────────────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ① 用户上传工具配置 ② MCP-Server 处理 ③ Agent Manager 生成工具 │
|
||
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
|
||
│ │ 表单填写 或 │ ───→ │ 验证配置格式 │ ───→ │ 生成 Pydantic │ │
|
||
│ │ 上传JSON文件 │ │ 发送给AM服务 │ │ 工具代码文件 │ │
|
||
│ └───────────────┘ └───────────────┘ └───────────────┘ │
|
||
│ │ │ │
|
||
│ ↓ ↓ │
|
||
│ ┌───────────────┐ ┌───────────────┐ │
|
||
│ │ 存储工具信息 │ ←─── │ 返回工具标识 │ │
|
||
│ │ 到 PostgreSQL │ │ (tool_ref_id) │ │
|
||
│ └───────────────┘ └───────────────┘ │
|
||
│ │
|
||
│ ④ 创建自定义Agent时 ⑤ 部署Agent │
|
||
│ ┌───────────────┐ ┌───────────────┐ │
|
||
│ │ 选择已创建的 │ ───────────────→ │ 传递工具标识 │ │
|
||
│ │ 外部数据工具 │ │ 给AgentManager │ │
|
||
│ └───────────────┘ └───────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 1.3 变更说明
|
||
|
||
| 变更项 | 旧方案 | 新方案 |
|
||
|--------|--------|--------|
|
||
| 工具类型 | 模板工具 + API工具 | **统一为外部数据工具** |
|
||
| 工具代码生成 | 无 | **Agent Manager 生成并存储 Pydantic 工具文件** |
|
||
| MCP-Server 存储 | 存储完整配置 | **只存储工具基本信息 + tool_ref_id 标识** |
|
||
| 部署方式 | 传递环境变量配置 | **传递工具标识列表,AM 根据标识加载文件部署** |
|
||
|
||
### 1.4 存储职责划分
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 存储职责划分 │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ MCP-Server (PostgreSQL) Agent Manager (文件系统/存储) │
|
||
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
||
│ │ • 工具名称、描述 │ │ • Pydantic 工具代码文件 │ │
|
||
│ │ • URL、方法、认证类型 │ │ • 工具运行时配置 │ │
|
||
│ │ • tool_ref_id (标识) │ ←───→ │ • 根据 tool_ref_id 索引 │ │
|
||
│ │ • 用户归属信息 │ │ │ │
|
||
│ │ • 创建/更新时间 │ │ │ │
|
||
│ └─────────────────────────┘ └─────────────────────────┘ │
|
||
│ │
|
||
│ 部署流程: │
|
||
│ MCP-Server 传 tool_ref_ids → Agent Manager 查找对应文件 → 部署到 AKS │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 数据结构设计
|
||
|
||
### 2.1 外部数据工具 JSON 模板格式
|
||
|
||
用户上传的 JSON 文件格式定义:
|
||
|
||
```json
|
||
{
|
||
"name": "weather-query-tool",
|
||
"description": "查询天气信息的外部数据工具",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "POST",
|
||
"headers": {
|
||
"Content-Type": "application/json",
|
||
"Accept": "application/json"
|
||
},
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "your-api-key-here",
|
||
"in": "header",
|
||
"name": "X-API-Key"
|
||
},
|
||
"request_params": {
|
||
"type": "object",
|
||
"properties": {
|
||
"city": {
|
||
"type": "string",
|
||
"description": "城市名称",
|
||
"required": true
|
||
},
|
||
"days": {
|
||
"type": "integer",
|
||
"description": "预报天数",
|
||
"default": 7,
|
||
"required": false
|
||
}
|
||
}
|
||
},
|
||
"request_body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"query": {
|
||
"type": "string",
|
||
"description": "查询内容"
|
||
},
|
||
"options": {
|
||
"type": "object",
|
||
"description": "查询选项",
|
||
"properties": {
|
||
"format": {
|
||
"type": "string",
|
||
"enum": ["json", "xml"],
|
||
"default": "json"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"response_mapping": {
|
||
"success_field": "status",
|
||
"success_value": "ok",
|
||
"data_field": "data.result",
|
||
"error_field": "error.message"
|
||
},
|
||
"timeout": 30,
|
||
"retry": {
|
||
"max_attempts": 3,
|
||
"delay_seconds": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.2 JSON 字段说明
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| `name` | string | ✅ | 工具名称(唯一标识,1-100字符,支持中英文) |
|
||
| `description` | string | ❌ | 工具描述 |
|
||
| `url` | string | ✅ | API 端点 URL |
|
||
| `method` | string | ✅ | HTTP 方法(GET/POST/PUT/DELETE/PATCH) |
|
||
| `headers` | object | ❌ | 自定义请求头(键值对) |
|
||
| `auth` | object | ❌ | 认证配置 |
|
||
| `auth.type` | string | ✅ | 认证类型:`api_key`/`bearer`/`basic`/`none` |
|
||
| `auth.key` | string | 条件 | API Key 或 Bearer Token |
|
||
| `auth.in` | string | 条件 | Key 位置:`header`/`query`/`body` |
|
||
| `auth.name` | string | 条件 | Key 名称(如 `X-API-Key`、`Authorization`) |
|
||
| `auth.username` | string | 条件 | Basic Auth 用户名 |
|
||
| `auth.password` | string | 条件 | Basic Auth 密码 |
|
||
| `request_params` | object | ❌ | URL 查询参数定义(JSON Schema 格式) |
|
||
| `request_body` | object | ❌ | 请求体定义(JSON Schema 格式) |
|
||
| `response_mapping` | object | ❌ | 响应字段映射 |
|
||
| `timeout` | integer | ❌ | 超时时间(秒),默认 30 |
|
||
| `retry` | object | ❌ | 重试配置 |
|
||
|
||
### 2.3 认证类型详解
|
||
|
||
#### API Key 认证
|
||
```json
|
||
{
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "sk-xxxxxxxxxxxx",
|
||
"in": "header",
|
||
"name": "X-API-Key"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Bearer Token 认证
|
||
```json
|
||
{
|
||
"auth": {
|
||
"type": "bearer",
|
||
"key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Basic Auth 认证
|
||
```json
|
||
{
|
||
"auth": {
|
||
"type": "basic",
|
||
"username": "admin",
|
||
"password": "password123"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 无认证
|
||
```json
|
||
{
|
||
"auth": {
|
||
"type": "none"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.4 数据库模型设计
|
||
|
||
#### ExternalDataTool 模型(新增)
|
||
|
||
> **设计原则**:MCP-Server 只存储必要的元信息和关联标识,工具的实际代码和运行配置由 Agent Manager 管理。
|
||
|
||
```python
|
||
class ExternalDataTool(BaseModel, Base):
|
||
"""外部数据工具模型
|
||
|
||
存储工具的基本信息和 Agent Manager 返回的标识,
|
||
工具的 Pydantic 代码文件由 Agent Manager 生成并存储。
|
||
"""
|
||
__tablename__ = "external_data_tools"
|
||
|
||
# 基本信息(用于前端展示)
|
||
name = Column(String(100), nullable=False)
|
||
description = Column(Text)
|
||
url = Column(String(500), nullable=False) # 仅用于展示,实际配置在 AM
|
||
method = Column(String(10), nullable=False, default="POST")
|
||
auth_type = Column(String(20), default="none") # 仅用于展示
|
||
|
||
# Agent Manager 关联(核心字段)
|
||
tool_ref_id = Column(String(100), unique=True) # AM 返回的工具标识,部署时传给 AM
|
||
status = Column(String(20), default="pending") # pending, active, error
|
||
error_message = Column(Text) # 生成失败时的错误信息
|
||
|
||
# 归属信息
|
||
owner_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||
tenant_id = Column(UUID(as_uuid=True), ForeignKey("tenants.id"))
|
||
is_active = Column(Boolean, default=True)
|
||
|
||
# 统计信息
|
||
usage_count = Column(Integer, default=0) # 被 Agent 使用次数
|
||
|
||
# 关系
|
||
owner = relationship("User", back_populates="external_data_tools")
|
||
|
||
__table_args__ = (
|
||
Index("idx_external_data_tool_owner", owner_id),
|
||
Index("idx_external_data_tool_ref", tool_ref_id),
|
||
)
|
||
```
|
||
|
||
**说明**:
|
||
- `tool_ref_id` 是核心字段,部署 Agent 时传递给 Agent Manager
|
||
- URL、method、auth_type 仅用于前端列表展示,实际的完整配置在 Agent Manager 侧
|
||
- 不存储敏感信息(API Key 等),这些信息只传给 Agent Manager,不在 MCP-Server 落库
|
||
|
||
#### 删除旧的 Tool 模型相关字段
|
||
|
||
需要删除 `Tool` 模型中的以下字段(或废弃整个模型):
|
||
- `template`
|
||
- `env_config`
|
||
- 其他模板工具相关字段
|
||
|
||
---
|
||
|
||
## 3. API 接口设计(MCP-Server 侧)
|
||
|
||
### 3.1 接口列表
|
||
|
||
| 序号 | 接口 | 方法 | 说明 |
|
||
|:---:|------|------|------|
|
||
| 1 | `/api/user/external-tools` | POST | 创建外部数据工具 |
|
||
| 2 | `/api/user/external-tools` | GET | 获取用户的外部数据工具列表 |
|
||
| 3 | `/api/user/external-tools/{tool_id}` | GET | 获取工具详情 |
|
||
| 4 | `/api/user/external-tools/{tool_id}` | PUT | 更新工具配置 |
|
||
| 5 | `/api/user/external-tools/{tool_id}` | DELETE | 删除工具 |
|
||
| 6 | `/api/user/external-tools/upload` | POST | 上传 JSON 文件创建工具 |
|
||
| 7 | `/api/user/external-tools/{tool_id}/test` | POST | 测试工具连接 |
|
||
| 8 | `/api/user/custom-agents` | POST | 创建自定义 Agent(更新) |
|
||
|
||
### 3.2 创建外部数据工具
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST /api/user/external-tools
|
||
```
|
||
|
||
#### 请求体
|
||
|
||
```json
|
||
{
|
||
"name": "weather-query-tool",
|
||
"description": "查询天气信息的外部数据工具",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "POST",
|
||
"headers": {
|
||
"Content-Type": "application/json"
|
||
},
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "sk-xxxxxxxxxxxx",
|
||
"in": "header",
|
||
"name": "X-API-Key"
|
||
},
|
||
"request_params": {
|
||
"type": "object",
|
||
"properties": {
|
||
"city": {
|
||
"type": "string",
|
||
"description": "城市名称",
|
||
"required": true
|
||
}
|
||
}
|
||
},
|
||
"request_body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"query": {
|
||
"type": "string",
|
||
"description": "查询内容"
|
||
}
|
||
}
|
||
},
|
||
"response_mapping": {
|
||
"data_field": "data.result"
|
||
},
|
||
"timeout": 30
|
||
}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "weather-query-tool",
|
||
"tool_ref_id": "tool-weather-abc123",
|
||
"status": "active",
|
||
"created_at": "2026-01-23T10:00:00Z"
|
||
},
|
||
"message": "外部数据工具创建成功"
|
||
}
|
||
```
|
||
|
||
### 3.3 上传 JSON 文件创建工具
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST /api/user/external-tools/upload
|
||
Content-Type: multipart/form-data
|
||
```
|
||
|
||
#### 请求参数
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| `file` | File | ✅ | JSON 配置文件(.json) |
|
||
|
||
#### 响应
|
||
|
||
同 3.2 创建接口
|
||
|
||
### 3.4 获取工具列表
|
||
|
||
#### 接口
|
||
|
||
```
|
||
GET /api/user/external-tools
|
||
```
|
||
|
||
#### 查询参数
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| `status` | string | ❌ | 过滤状态:active/pending/error |
|
||
| `page` | integer | ❌ | 页码,默认 1 |
|
||
| `page_size` | integer | ❌ | 每页数量,默认 20 |
|
||
|
||
#### 响应
|
||
|
||
> **说明**:列表只返回基本展示信息,完整配置由 Agent Manager 管理。
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"tools": [
|
||
{
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "weather-query-tool",
|
||
"description": "查询天气信息的外部数据工具",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "POST",
|
||
"auth_type": "api_key",
|
||
"status": "active",
|
||
"usage_count": 15,
|
||
"created_at": "2026-01-23T10:00:00Z"
|
||
}
|
||
],
|
||
"total": 1,
|
||
"page": 1,
|
||
"page_size": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.5 获取工具详情
|
||
|
||
#### 接口
|
||
|
||
```
|
||
GET /api/user/external-tools/{tool_id}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
> **注意**:MCP-Server 只存储基本展示信息,不存储完整配置和敏感信息。
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "weather-query-tool",
|
||
"description": "查询天气信息的外部数据工具",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "POST",
|
||
"auth_type": "api_key",
|
||
"tool_ref_id": "tool-weather-abc123",
|
||
"status": "active",
|
||
"usage_count": 15,
|
||
"created_at": "2026-01-23T10:00:00Z",
|
||
"updated_at": "2026-01-23T10:00:00Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
> 如需查看工具的完整配置(包括参数定义等),可调用 Agent Manager 的接口获取。
|
||
|
||
### 3.6 更新工具配置
|
||
|
||
#### 接口
|
||
|
||
```
|
||
PUT /api/user/external-tools/{tool_id}
|
||
```
|
||
|
||
#### 请求体
|
||
|
||
与创建接口格式相同,需要传递完整的工具配置(因为 MCP-Server 不存储完整配置)。
|
||
|
||
```json
|
||
{
|
||
"name": "weather-query-tool-v2",
|
||
"description": "更新后的天气查询工具",
|
||
"url": "https://api.weather.com/v2/forecast",
|
||
"method": "POST",
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "new-api-key",
|
||
"in": "header",
|
||
"name": "X-API-Key"
|
||
},
|
||
"request_params": {
|
||
"type": "object",
|
||
"properties": {
|
||
"city": {
|
||
"type": "string",
|
||
"description": "城市名称",
|
||
"required": true
|
||
}
|
||
}
|
||
},
|
||
"timeout": 30
|
||
}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "weather-query-tool-v2",
|
||
"tool_ref_id": "tool-weather-abc123-v2",
|
||
"status": "active",
|
||
"updated_at": "2026-01-23T11:00:00Z"
|
||
},
|
||
"message": "外部数据工具更新成功"
|
||
}
|
||
```
|
||
|
||
#### 处理流程
|
||
|
||
1. MCP-Server 接收完整配置
|
||
2. 调用 Agent Manager 更新接口(传递新配置)
|
||
3. Agent Manager 重新生成工具文件,返回新的 `tool_ref_id`
|
||
4. MCP-Server 更新数据库中的基本信息和 `tool_ref_id`
|
||
|
||
### 3.7 删除工具
|
||
|
||
#### 接口
|
||
|
||
```
|
||
DELETE /api/user/external-tools/{tool_id}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "550e8400-e29b-41d4-a716-446655440000"
|
||
},
|
||
"message": "外部数据工具删除成功"
|
||
}
|
||
```
|
||
|
||
> **注意**:删除工具时需要通知 Agent Manager 删除对应的工具文件。
|
||
|
||
### 3.8 测试工具连接
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST /api/user/external-tools/{tool_id}/test
|
||
```
|
||
|
||
#### 请求体(可选测试参数)
|
||
|
||
```json
|
||
{
|
||
"test_params": {
|
||
"city": "北京"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"connected": true,
|
||
"response_time_ms": 156,
|
||
"status_code": 200,
|
||
"sample_response": {
|
||
"status": "ok",
|
||
"data": {
|
||
"city": "北京",
|
||
"temperature": "15°C"
|
||
}
|
||
}
|
||
},
|
||
"message": "工具连接测试成功"
|
||
}
|
||
```
|
||
|
||
### 3.9 创建自定义 Agent(更新)
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST /api/user/custom-agents
|
||
```
|
||
|
||
#### 请求体
|
||
|
||
```json
|
||
{
|
||
"name": "my-data-agent",
|
||
"description": "我的数据处理 Agent",
|
||
"external_tools": [
|
||
"550e8400-e29b-41d4-a716-446655440000",
|
||
"550e8400-e29b-41d4-a716-446655440001"
|
||
],
|
||
"cpuRequest": "500m",
|
||
"cpuLimit": "1000m",
|
||
"memoryRequest": "512Mi",
|
||
"memoryLimit": "1Gi",
|
||
"model": "gpt-4"
|
||
}
|
||
```
|
||
|
||
#### 字段说明
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| `name` | string | ✅ | Agent 名称 |
|
||
| `description` | string | ❌ | Agent 描述 |
|
||
| `external_tools` | string[] | ✅ | **外部数据工具 ID 列表** |
|
||
| `cpuRequest` | string | ❌ | CPU 请求量,默认 "100m" |
|
||
| `cpuLimit` | string | ❌ | CPU 限制量 |
|
||
| `memoryRequest` | string | ❌ | 内存请求量,默认 "128Mi" |
|
||
| `memoryLimit` | string | ❌ | 内存限制量 |
|
||
| `model` | string | ❌ | 使用的模型名称 |
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"name": "my-data-agent",
|
||
"namespace": "ai-agents",
|
||
"status": "Pending",
|
||
"tools_attached": 2,
|
||
"quotaRemaining": {
|
||
"cpu": 3.5,
|
||
"memory": 7.0
|
||
}
|
||
},
|
||
"message": "自定义 Agent 创建成功"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Agent Manager 接口设计(模拟)
|
||
|
||
### 4.1 接口列表
|
||
|
||
| 序号 | 接口 | 方法 | 说明 |
|
||
|:---:|------|------|------|
|
||
| 1 | `/tools/generate` | POST | 生成 Pydantic 工具文件 |
|
||
| 2 | `/tools/{tool_ref_id}` | PUT | 更新工具文件 |
|
||
| 3 | `/tools/{tool_ref_id}` | DELETE | 删除工具文件 |
|
||
| 4 | `/agents` | POST | 创建 Agent(更新:支持工具标识列表) |
|
||
|
||
### 4.2 生成工具文件
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST {AGENT_MANAGER_URL}/tools/generate
|
||
```
|
||
|
||
#### 请求体
|
||
|
||
```json
|
||
{
|
||
"name": "weather-query-tool",
|
||
"description": "查询天气信息的外部数据工具",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "POST",
|
||
"headers": {
|
||
"Content-Type": "application/json"
|
||
},
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "sk-xxxxxxxxxxxx",
|
||
"in": "header",
|
||
"name": "X-API-Key"
|
||
},
|
||
"request_params": {
|
||
"type": "object",
|
||
"properties": {
|
||
"city": {
|
||
"type": "string",
|
||
"description": "城市名称",
|
||
"required": true
|
||
}
|
||
}
|
||
},
|
||
"request_body": {},
|
||
"response_mapping": {
|
||
"data_field": "data.result"
|
||
},
|
||
"timeout": 30,
|
||
"user_id": "user-123",
|
||
"tenant_id": "tenant-456"
|
||
}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"tool_ref_id": "tool-weather-abc123",
|
||
"tool_name": "weather_query_tool",
|
||
"status": "active",
|
||
"message": "Pydantic 工具文件生成成功"
|
||
}
|
||
```
|
||
|
||
### 4.3 更新工具文件
|
||
|
||
#### 接口
|
||
|
||
```
|
||
PUT {AGENT_MANAGER_URL}/tools/{tool_ref_id}
|
||
```
|
||
|
||
#### 请求体
|
||
|
||
同 4.2 生成接口(需要传递完整的工具配置)
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"tool_ref_id": "tool-weather-abc123-v2",
|
||
"status": "active",
|
||
"message": "工具文件更新成功"
|
||
}
|
||
```
|
||
|
||
> **说明**:Agent Manager 会生成新的工具文件,可能返回新的 `tool_ref_id`(版本更新)。
|
||
|
||
### 4.4 删除工具文件
|
||
|
||
#### 接口
|
||
|
||
```
|
||
DELETE {AGENT_MANAGER_URL}/tools/{tool_ref_id}
|
||
```
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "工具文件删除成功"
|
||
}
|
||
```
|
||
|
||
### 4.5 创建 Agent(更新)
|
||
|
||
#### 接口
|
||
|
||
```
|
||
POST {AGENT_MANAGER_URL}/agents
|
||
```
|
||
|
||
#### 请求体(新增 tool_refs 字段)
|
||
|
||
```json
|
||
{
|
||
"name": "my-data-agent",
|
||
"template": "custom_agent",
|
||
"config": {
|
||
"user_id": "user-123",
|
||
"cpu_request": "500m",
|
||
"cpu_limit": "1000m",
|
||
"memory_request": "512Mi",
|
||
"memory_limit": "1Gi",
|
||
"replicas": 1
|
||
},
|
||
"env": {
|
||
"LLM_BASE_URL": "https://litellm.xxx.io",
|
||
"OPENAI_API_KEY": "sk-xxx",
|
||
"MODEL_NAME": "gpt-4"
|
||
},
|
||
"tool_refs": [
|
||
"tool-weather-abc123",
|
||
"tool-stock-def456"
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 新增字段说明
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| `tool_refs` | string[] | ❌ | 外部数据工具标识列表,Agent 运行时加载这些工具 |
|
||
|
||
---
|
||
|
||
## 5. 工作流程详解
|
||
|
||
### 5.1 创建工具流程
|
||
|
||
```
|
||
┌──────────┐ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐
|
||
│ 前端 │────→│ MCP-Server │────→│ Agent Manager │────→│ MCP-Server │
|
||
└──────────┘ └──────────────┘ └───────────────┘ └──────────────┘
|
||
│ │ │ │
|
||
│ 1.提交配置 │ │ │
|
||
│ (表单/JSON) │ │ │
|
||
│ ───────────────>│ │ │
|
||
│ │ │ │
|
||
│ │ 2.验证配置格式 │ │
|
||
│ │ 3.调用 AM 接口 │ │
|
||
│ │ ───────────────────>│ │
|
||
│ │ │ │
|
||
│ │ │ 4.生成 Pydantic │
|
||
│ │ │ 工具文件 │
|
||
│ │ │ │
|
||
│ │ 5.返回 tool_ref_id │ │
|
||
│ │ <───────────────────│ │
|
||
│ │ │ │
|
||
│ │ 6.存储到数据库 │ │
|
||
│ │ (关联 tool_ref_id) │ │
|
||
│ │ │ │
|
||
│ 7.返回结果 │ │ │
|
||
│ <───────────────│ │ │
|
||
│ │ │ │
|
||
```
|
||
|
||
### 5.2 创建 Agent 并使用工具流程
|
||
|
||
```
|
||
┌──────────┐ ┌──────────────┐ ┌───────────────┐
|
||
│ 前端 │────→│ MCP-Server │────→│ Agent Manager │
|
||
└──────────┘ └──────────────┘ └───────────────┘
|
||
│ │ │
|
||
│ 1.创建Agent │ │
|
||
│ 选择工具列表 │ │
|
||
│ ───────────────>│ │
|
||
│ │ │
|
||
│ │ 2.查询工具信息 │
|
||
│ │ 获取 tool_ref_ids │
|
||
│ │ │
|
||
│ │ 3.调用 AM 创建 │
|
||
│ │ 传递 tool_refs │
|
||
│ │ ───────────────────>│
|
||
│ │ │
|
||
│ │ │ 4.部署 Agent
|
||
│ │ │ 加载工具文件
|
||
│ │ │
|
||
│ │ 5.返回部署结果 │
|
||
│ │ <───────────────────│
|
||
│ │ │
|
||
│ 6.返回结果 │ │
|
||
│ <───────────────│ │
|
||
│ │ │
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 前端对接说明
|
||
|
||
### 6.1 工具管理页面
|
||
|
||
#### 功能需求
|
||
|
||
1. **工具列表展示**
|
||
- 显示用户创建的所有外部数据工具
|
||
- 显示状态(active/pending/error)
|
||
- 显示使用次数
|
||
- 支持搜索和筛选
|
||
|
||
2. **创建工具**
|
||
- 方式一:表单填写
|
||
- 方式二:上传 JSON 文件
|
||
- 实时验证配置格式
|
||
|
||
3. **工具详情**
|
||
- 查看完整配置(敏感信息脱敏)
|
||
- 编辑配置
|
||
- 测试连接
|
||
|
||
4. **删除工具**
|
||
- 检查是否被 Agent 使用
|
||
- 确认删除
|
||
|
||
#### 表单字段
|
||
|
||
| 字段 | 组件类型 | 说明 |
|
||
|------|---------|------|
|
||
| 工具名称 | Input | 必填,1-100字符 |
|
||
| 描述 | Textarea | 可选 |
|
||
| API URL | Input | 必填,URL 格式 |
|
||
| HTTP 方法 | Select | GET/POST/PUT/DELETE/PATCH |
|
||
| 请求头 | 键值对编辑器 | 可选 |
|
||
| 认证类型 | Select | api_key/bearer/basic/none |
|
||
| 认证配置 | 动态表单 | 根据认证类型显示 |
|
||
| 请求参数 | Schema 编辑器 | 可选 |
|
||
| 请求体 | Schema 编辑器 | 可选 |
|
||
| 超时时间 | InputNumber | 默认 30 秒 |
|
||
|
||
### 6.2 创建 Agent 时选择工具
|
||
|
||
#### 流程
|
||
|
||
1. 获取用户的外部数据工具列表
|
||
2. 多选工具
|
||
3. 提交创建 Agent 请求时包含 `external_tools` 字段
|
||
|
||
#### UI 建议
|
||
|
||
- 使用穿梭框或多选列表
|
||
- 显示工具名称、描述、状态
|
||
- 禁用 error 状态的工具
|
||
|
||
---
|
||
|
||
## 7. 实现步骤
|
||
|
||
### 7.1 Phase 1: 数据库和模型(预计 1 天)
|
||
|
||
- [ ] 创建 `ExternalDataTool` 模型
|
||
- [ ] 编写数据库迁移脚本
|
||
- [ ] 添加模型关系
|
||
- [ ] 废弃/清理旧的 Tool 模型相关代码
|
||
|
||
### 7.2 Phase 2: Agent Manager 客户端(预计 0.5 天)
|
||
|
||
- [ ] 在 `agent_manager_client.py` 中添加工具相关方法
|
||
- `generate_tool()`
|
||
- `update_tool()`
|
||
- `delete_tool()`
|
||
- [ ] 更新 `create_agent()` 方法,支持 `tool_refs` 参数
|
||
|
||
### 7.3 Phase 3: API 接口实现(预计 2 天)
|
||
|
||
- [ ] 实现 `POST /api/user/external-tools` 创建工具
|
||
- [ ] 实现 `POST /api/user/external-tools/upload` 上传 JSON
|
||
- [ ] 实现 `GET /api/user/external-tools` 获取列表
|
||
- [ ] 实现 `GET /api/user/external-tools/{tool_id}` 获取详情
|
||
- [ ] 实现 `PUT /api/user/external-tools/{tool_id}` 更新工具
|
||
- [ ] 实现 `DELETE /api/user/external-tools/{tool_id}` 删除工具
|
||
- [ ] 实现 `POST /api/user/external-tools/{tool_id}/test` 测试连接
|
||
- [ ] 更新 `POST /api/user/custom-agents` 支持外部工具
|
||
|
||
### 7.4 Phase 4: 删除旧接口和代码(预计 0.5 天)
|
||
|
||
- [ ] 删除旧的 `/api/user/tools/*` 接口
|
||
- [ ] 删除旧的 `/api/user/custom-agents/templates` 接口
|
||
- [ ] 清理相关的 Schema 定义
|
||
- [ ] 更新文档
|
||
|
||
### 7.5 Phase 5: 测试和文档(预计 1 天)
|
||
|
||
- [ ] 编写单元测试
|
||
- [ ] 编写集成测试
|
||
- [ ] 更新 API 文档
|
||
- [ ] 更新前端对接文档
|
||
|
||
---
|
||
|
||
## 8. 错误码定义
|
||
|
||
| HTTP状态码 | 错误代码 | 说明 |
|
||
|-----------|---------|------|
|
||
| 400 | `invalid_config` | 工具配置格式无效 |
|
||
| 400 | `invalid_url` | URL 格式无效 |
|
||
| 400 | `invalid_auth` | 认证配置无效 |
|
||
| 400 | `invalid_json_file` | JSON 文件格式无效 |
|
||
| 400 | `tool_in_use` | 工具正在被 Agent 使用,无法删除 |
|
||
| 404 | `tool_not_found` | 工具不存在 |
|
||
| 409 | `tool_name_exists` | 工具名称已存在 |
|
||
| 500 | `am_generate_failed` | Agent Manager 生成工具失败 |
|
||
| 503 | `am_unavailable` | Agent Manager 服务不可用 |
|
||
|
||
---
|
||
|
||
## 9. 安全考虑
|
||
|
||
### 9.1 敏感信息处理
|
||
|
||
1. **敏感信息不落库**
|
||
- API Key、Bearer Token、密码等敏感信息**不存储在 MCP-Server**
|
||
- 敏感信息只在创建时传递给 Agent Manager,由 AM 安全存储
|
||
|
||
2. **传输安全**
|
||
- MCP-Server 与 Agent Manager 之间通过 HTTPS 传输
|
||
- 敏感信息在传输层加密
|
||
|
||
### 9.2 权限控制
|
||
|
||
1. 用户只能操作自己创建的工具
|
||
2. 删除工具前检查是否被 Agent 使用
|
||
3. API 调用需要 JWT 认证
|
||
|
||
### 9.3 输入验证
|
||
|
||
1. URL 格式验证(必须是有效的 HTTP/HTTPS URL)
|
||
2. JSON Schema 格式验证
|
||
3. 超时时间范围限制(1-300 秒)
|
||
|
||
---
|
||
|
||
## 10. 附录
|
||
|
||
### 10.1 JSON 配置文件示例
|
||
|
||
#### 示例 1:天气查询工具
|
||
|
||
```json
|
||
{
|
||
"name": "weather-api",
|
||
"description": "查询城市天气信息",
|
||
"url": "https://api.weather.com/v1/forecast",
|
||
"method": "GET",
|
||
"auth": {
|
||
"type": "api_key",
|
||
"key": "your-weather-api-key",
|
||
"in": "query",
|
||
"name": "apikey"
|
||
},
|
||
"request_params": {
|
||
"type": "object",
|
||
"properties": {
|
||
"city": {
|
||
"type": "string",
|
||
"description": "城市名称",
|
||
"required": true
|
||
},
|
||
"units": {
|
||
"type": "string",
|
||
"description": "温度单位",
|
||
"enum": ["metric", "imperial"],
|
||
"default": "metric"
|
||
}
|
||
}
|
||
},
|
||
"response_mapping": {
|
||
"data_field": "data.forecast"
|
||
},
|
||
"timeout": 10
|
||
}
|
||
```
|
||
|
||
#### 示例 2:企业内部 API
|
||
|
||
```json
|
||
{
|
||
"name": "internal-crm-api",
|
||
"description": "查询客户信息",
|
||
"url": "https://internal.company.com/api/v2/customers",
|
||
"method": "POST",
|
||
"headers": {
|
||
"Content-Type": "application/json",
|
||
"X-Request-ID": "{{uuid}}"
|
||
},
|
||
"auth": {
|
||
"type": "bearer",
|
||
"key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||
},
|
||
"request_body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"customer_id": {
|
||
"type": "string",
|
||
"description": "客户ID",
|
||
"required": true
|
||
},
|
||
"include_orders": {
|
||
"type": "boolean",
|
||
"description": "是否包含订单信息",
|
||
"default": false
|
||
}
|
||
}
|
||
},
|
||
"response_mapping": {
|
||
"success_field": "code",
|
||
"success_value": 0,
|
||
"data_field": "data",
|
||
"error_field": "message"
|
||
},
|
||
"timeout": 30,
|
||
"retry": {
|
||
"max_attempts": 3,
|
||
"delay_seconds": 2
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 示例 3:数据库查询服务
|
||
|
||
```json
|
||
{
|
||
"name": "db-query-service",
|
||
"description": "执行 SQL 查询",
|
||
"url": "https://db-gateway.company.com/query",
|
||
"method": "POST",
|
||
"auth": {
|
||
"type": "basic",
|
||
"username": "readonly",
|
||
"password": "secure-password-123"
|
||
},
|
||
"request_body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"database": {
|
||
"type": "string",
|
||
"description": "数据库名称",
|
||
"required": true
|
||
},
|
||
"sql": {
|
||
"type": "string",
|
||
"description": "SQL 查询语句",
|
||
"required": true
|
||
},
|
||
"params": {
|
||
"type": "array",
|
||
"description": "查询参数",
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"timeout": 60
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
**文档结束**
|
||
|