Files
taiji-AI-PAD/Docs/项目文档/Agent发送给AgentManager的数据结构文档.md
T

569 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent 发送给 Agent Manager 的数据结构文档
本文档详细说明 mcp-server 中**平台 Agent** 和**自定义 Agent** 发送给 Agent Manager 服务端的请求数据结构和参数说明。
## 目录
1. [统一接口说明](#统一接口说明)
2. [平台 Agent 数据结构](#平台-agent-数据结构)
3. [自定义 Agent 数据结构](#自定义-agent-数据结构)
4. [请求参数详细说明](#请求参数详细说明)
5. [代码位置](#代码位置)
---
## 统一接口说明
无论是平台 Agent 还是自定义 Agent,最终都通过 **`POST /agents`** 接口发送请求到 Agent Manager。
**接口路径**: `POST {AGENT_MANAGER_URL}/agents`
**代码位置**: `services/mcp-server/app/agent_manager_client.py`
**统一方法**: `create_agent()`
---
## 平台 Agent 数据结构
### 请求体结构
```json
{
"name": "echo-agent-alice1234-abc123",
"template": "echo_agent",
"config": {
"user_id": "alice",
"cpu_request": "100m",
"cpu_limit": "500m",
"memory_request": "128Mi",
"memory_limit": "512Mi",
"replicas": 1
},
"env": {
"LLM_BASE_URL": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
"OPENAI_API_BASE": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
"OPENAI_API_KEY": "sk-...",
"MODEL_NAME": "gpt-4",
"LITELLM_MODEL": "gpt-4"
}
}
```
### 字段说明
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | ✅ | Agent 实例名称(1-63字符,小写字母、数字、连字符) |
| `template` | string | ✅ | 平台模板名称(如 `echo_agent`, `jina_search_agent`) |
| `config` | object | ✅ | 资源配置对象 |
| `config.user_id` | string | ✅ | 用户 ID(用于资源隔离和计费) |
| `config.cpu_request` | string | ✅ | CPU 请求量(如 `"100m"`) |
| `config.cpu_limit` | string | ✅ | CPU 限制量(如 `"500m"`) |
| `config.memory_request` | string | ✅ | 内存请求量(如 `"128Mi"`) |
| `config.memory_limit` | string | ✅ | 内存限制量(如 `"512Mi"`) |
| `config.replicas` | integer | ✅ | 副本数量(平台 Agent 默认为 1) |
| `env` | object | ✅ | 环境变量(至少包含 `LLM_BASE_URL`) |
| `env.LLM_BASE_URL` | string | ✅ | LiteLLM 服务地址(固定值,自动注入) |
| `env.OPENAI_API_BASE` | string | 否 | LiteLLM API 基础地址(如果用户指定了模型) |
| `env.OPENAI_API_KEY` | string | 否 | LiteLLM API 密钥(如果用户指定了模型) |
| `env.MODEL_NAME` | string | 否 | 模型名称(如果用户指定了模型) |
| `env.LITELLM_MODEL` | string | 否 | LiteLLM 模型名称(如果用户指定了模型) |
### 代码实现位置
**主要调用位置**:
- `services/mcp-server/app/routes/user.py` - `deploy_platform_agent()` (行 2261-2512)
- `services/mcp-server/app/routes/user.py` - `deploy_platform_agent_instances()` (行 1310-1509)
**关键代码片段**:
```808:847:services/mcp-server/app/agent_manager_client.py
payload: Dict[str, Any] = {
"name": name,
"template": template
}
if config:
payload["config"] = config.to_dict()
# 构建环境变量,确保 LLM_BASE_URL 始终被传递(平台 Agent 和自定义 Agent 都需要)
final_env = {"LLM_BASE_URL": LLM_BASE_URL}
if env:
# 用户传入的环境变量会覆盖默认值(但通常不应覆盖 LLM_BASE_URL)
final_env.update(env)
payload["env"] = final_env
```
**平台 Agent 创建示例**:
```2421:2445:services/mcp-server/app/routes/user.py
# 创建平台 Agent 实例
agent_config = AgentConfig(
user_id=str(user_id),
cpu_request=quota.cpu_per_pod or "100m",
cpu_limit=quota.cpu_per_pod or "500m",
memory_request=quota.memory_per_pod or "128Mi",
memory_limit=quota.memory_per_pod or "512Mi",
replicas=1, # 平台 Agent 默认单副本
)
# 如果有环境变量,使用 create_agent;否则使用 create_platform_agent
if env_vars:
result = await client.create_agent(
name=instance_name,
template=req.agentType,
config=agent_config,
env=env_vars
)
else:
result = await client.create_platform_agent(
name=instance_name,
template=req.agentType,
user_id=str(user_id),
config=agent_config
)
```
---
## 自定义 Agent 数据结构
### 请求体结构
```json
{
"name": "my-mysql-agent",
"template": "mysql_agent",
"config": {
"user_id": "alice",
"cpu_request": "1000m",
"cpu_limit": "2000m",
"memory_request": "1Gi",
"memory_limit": "2Gi",
"replicas": 1
},
"env": {
"LLM_BASE_URL": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
"FRAMEWORK_TYPE": "MCP",
"MYSQL_HOST": "mysql.example.com",
"MYSQL_USER": "root",
"MYSQL_PASSWORD": "password123",
"MYSQL_DATABASE": "mydb",
"OPENAI_API_BASE": "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io",
"OPENAI_API_KEY": "sk-...",
"MODEL_NAME": "gpt-4",
"LITELLM_MODEL": "gpt-4",
"TOOLS": "[\"tool-uuid-1\", \"tool-uuid-2\"]",
"TOOLS_CONFIG": "[{\"id\": \"tool-uuid-1\", \"name\": \"mysql_query\", \"endpoint\": \"...\", ...}]",
"AGENT_ID": "my-mysql-agent-1704067200",
"AGENT_ROLE": "data_analyzer",
"AGENT_CAPABILITIES": "[\"sql_query\", \"data_analysis\"]"
}
}
```
### 字段说明
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | ✅ | Agent 名称(1-63字符,小写字母、数字、连字符) |
| `template` | string | ✅ | 自定义模板名称(如 `mysql_agent`, `postgresql_agent`) |
| `config` | object | ✅ | 资源配置对象 |
| `config.user_id` | string | ✅ | 用户 ID |
| `config.cpu_request` | string | ✅ | CPU 请求量(用户自定义,如 `"1000m"`) |
| `config.cpu_limit` | string | ✅ | CPU 限制量(用户自定义,如 `"2000m"`) |
| `config.memory_request` | string | ✅ | 内存请求量(用户自定义,如 `"1Gi"`) |
| `config.memory_limit` | string | ✅ | 内存限制量(用户自定义,如 `"2Gi"`) |
| `config.replicas` | integer | ✅ | 副本数量(自定义 Agent 默认为 1) |
| `env` | object | ✅ | 环境变量(必需,包含数据库连接、API Key 等) |
| `env.LLM_BASE_URL` | string | ✅ | LiteLLM 服务地址(固定值,自动注入) |
| `env.FRAMEWORK_TYPE` | string | ✅ | 框架类型(`MCP` / `A2A` / `langchain`) |
| `env.ENDPOINT` | string | 否 | 用户自定义终结点 |
| `env.API_KEY` | string | 否 | 用户 API 密钥 |
| `env.MYSQL_HOST` | string | 否 | MySQL 主机地址(模板相关) |
| `env.MYSQL_USER` | string | 否 | MySQL 用户名(模板相关) |
| `env.MYSQL_PASSWORD` | string | 否 | MySQL 密码(模板相关) |
| `env.MYSQL_DATABASE` | string | 否 | MySQL 数据库名(模板相关) |
| `env.OPENAI_API_BASE` | string | 否 | LiteLLM API 基础地址(如果指定了模型) |
| `env.OPENAI_API_KEY` | string | 否 | LiteLLM API 密钥(如果指定了模型或自动注入) |
| `env.MODEL_NAME` | string | 否 | 模型名称(如果指定了模型) |
| `env.LITELLM_MODEL` | string | 否 | LiteLLM 模型名称(如果指定了模型) |
| `env.TOOLS` | string | 否 | 工具 ID 列表(JSON 字符串格式) |
| `env.TOOLS_CONFIG` | string | 否 | 工具详细配置(JSON 字符串格式,包含 endpoint、method、schema 等) |
| `env.AGENT_ID` | string | 否 | A2A 框架专用:Agent ID |
| `env.AGENT_ROLE` | string | 否 | A2A 框架专用:Agent 角色(如 `data_analyzer`) |
| `env.AGENT_CAPABILITIES` | string | 否 | A2A 框架专用:Agent 能力列表(JSON 字符串格式) |
### 环境变量构建优先级
自定义 Agent 的环境变量按以下优先级合并(从低到高):
1. **工具的 `env_config`**(如果选择了工具)
2. **请求中的 `envConfig`**(用户手动配置)
3. **系统自动注入**(如 `LLM_BASE_URL`、模型配置等)
### 代码实现位置
**主要调用位置**:
- `services/mcp-server/app/routes/user.py` - `create_custom_agent()` (行 2871-3341)
**关键代码片段**:
```3067:3087:services/mcp-server/app/routes/user.py
# ========== 构建环境变量 ==========
# 1. 先使用工具的环境变量配置作为基础
env_vars = tool_env_config.copy()
# 2. 再合并请求中的 envConfig(请求中的优先)
if req.envConfig:
env_vars.update(req.envConfig)
# 3. 注入框架模板类型
env_vars["FRAMEWORK_TYPE"] = framework_template
if req.endpoint:
env_vars["ENDPOINT"] = req.endpoint
if req.apiKey:
env_vars["API_KEY"] = req.apiKey
logger.info(
f"环境变量构建完成: tool_env_keys={list(tool_env_config.keys())}, "
f"req_env_keys={list((req.envConfig or {}).keys())}, "
f"final_env_keys={list(env_vars.keys())}"
)
# =================================
```
**工具配置传递**:
```3089:3145:services/mcp-server/app/routes/user.py
# ========== 工具配置传递给 Agent Manager ==========
import json
if req.tools:
# 1. 传递工具 ID 列表(JSON 字符串格式)
env_vars["TOOLS"] = json.dumps(req.tools)
# 2. 查询工具详情,构建完整工具配置
try:
tool_ids = []
for tid in req.tools:
try:
tool_ids.append(PyUUID(tid))
except (ValueError, TypeError):
logger.warning(f"无效的工具 ID 格式: {tid}")
if tool_ids:
tool_result = await db.execute(
select(Tool).where(
Tool.id.in_(tool_ids),
or_(
Tool.is_public == True,
Tool.owner_id == PyUUID(user_id)
)
)
)
tools = tool_result.scalars().all()
# 构建工具配置列表(包含 Agent 运行时需要的信息)
tools_config = []
for tool in tools:
tool_config = {
"id": str(tool.id),
"name": tool.name,
"description": tool.description,
"endpoint": tool.endpoint,
"method": tool.method,
"schema": tool.schema,
"timeout": tool.timeout,
"auth_type": tool.auth_type,
}
# 如果是用户自己的工具,传递认证配置
if tool.owner_id and str(tool.owner_id) == user_id and tool.auth_config:
tool_config["auth_config"] = tool.auth_config
tools_config.append(tool_config)
# 传递工具详细配置(供 Agent 运行时使用)
if tools_config:
env_vars["TOOLS_CONFIG"] = json.dumps(tools_config)
logger.info(
f"工具配置已准备: user_id={user_id}, tool_count={len(tools_config)}, "
f"tool_names={[t['name'] for t in tools_config]}"
)
except Exception as e:
logger.warning(f"查询工具详情失败,仅传递工具 ID 列表: {str(e)}")
# ================================================
```
**A2A 框架配置**:
```3147:3168:services/mcp-server/app/routes/user.py
# ========== A2A 框架配置 ==========
if framework_template == "A2A":
import time as time_module
# 生成 Agent ID(使用名称和时间戳确保唯一性)
agent_id = f"{req.name}-{int(time_module.time())}"
env_vars["AGENT_ID"] = agent_id
# 设置 Agent 角色
agent_role = req.agentRole or env_vars.get("AGENT_ROLE", "custom_agent")
env_vars["AGENT_ROLE"] = agent_role
# 设置 Agent 能力
capabilities = req.agentCapabilities or req.tools or []
if capabilities:
env_vars["AGENT_CAPABILITIES"] = json.dumps(capabilities)
logger.info(
f"A2A 配置已准备: agent_id={agent_id}, agent_role={agent_role}, "
f"capabilities={capabilities}"
)
# ==================================
```
**自定义 Agent 创建调用**:
```3240:3260:services/mcp-server/app/routes/user.py
try:
client = get_agent_manager_client()
# 创建 Agent 配置
agent_config = AgentConfig(
user_id=str(user_id),
cpu_request=req.cpuRequest,
cpu_limit=req.cpuLimit or req.cpuRequest,
memory_request=req.memoryRequest,
memory_limit=req.memoryLimit or req.memoryRequest,
replicas=1, # 自定义 Agent 默认单副本
)
# 创建自定义 Agent(使用从工具获取的模板名称)
result = await client.create_custom_agent(
name=req.name,
template=template_name, # 使用从工具获取或请求中指定的模板
user_id=str(user_id),
env_vars=env_vars,
config=agent_config
)
```
---
## 请求参数详细说明
### AgentConfig 对象
**定义位置**: `services/mcp-server/app/agent_manager_client.py` (行 33-62)
```python
@dataclass
class AgentConfig:
user_id: Optional[str] = None
cpu_request: Optional[str] = "100m"
cpu_limit: Optional[str] = "500m"
memory_request: Optional[str] = "128Mi"
memory_limit: Optional[str] = "512Mi"
replicas: Optional[int] = 1
```
**转换为字典方法**:
```47:62:services/mcp-server/app/agent_manager_client.py
def to_dict(self) -> Dict[str, Any]:
"""Converts to API request format"""
result = {}
if self.user_id:
result["user_id"] = self.user_id
if self.cpu_request:
result["cpu_request"] = self.cpu_request
if self.cpu_limit:
result["cpu_limit"] = self.cpu_limit
if self.memory_request:
result["memory_request"] = self.memory_request
if self.memory_limit:
result["memory_limit"] = self.memory_limit
if self.replicas is not None:
result["replicas"] = self.replicas
return result
```
### 环境变量说明
#### 固定环境变量
| 变量名 | 值 | 说明 | 来源 |
|--------|-----|------|------|
| `LLM_BASE_URL` | `https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io` | LiteLLM 服务地址 | 环境变量 `LLM_BASE_URL`,默认值见代码 |
**代码位置**: `services/mcp-server/app/agent_manager_client.py` (行 20-21)
```20:21:services/mcp-server/app/agent_manager_client.py
# LLM_BASE_URL - 所有 Agent(平台和自定义)都必须传递的固定参数
LLM_BASE_URL = os.getenv("LLM_BASE_URL", "https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io")
```
#### 可选环境变量(根据用户配置注入)
| 变量名 | 说明 | 注入条件 |
|--------|------|----------|
| `OPENAI_API_BASE` | LiteLLM API 基础地址 | 用户指定了模型或自动注入 |
| `OPENAI_API_KEY` | LiteLLM API 密钥 | 用户指定了模型或自动注入 |
| `MODEL_NAME` | 模型名称 | 用户指定了模型 |
| `LITELLM_MODEL` | LiteLLM 模型名称 | 用户指定了模型 |
| `FRAMEWORK_TYPE` | 框架类型(MCP/A2A/langchain) | 自定义 Agent 必填 |
| `ENDPOINT` | 用户自定义终结点 | 用户提供了 endpoint |
| `API_KEY` | 用户 API 密钥 | 用户提供了 apiKey |
| `TOOLS` | 工具 ID 列表(JSON 字符串) | 用户选择了工具 |
| `TOOLS_CONFIG` | 工具详细配置(JSON 字符串) | 用户选择了工具 |
| `AGENT_ID` | A2A Agent ID | 框架类型为 A2A |
| `AGENT_ROLE` | A2A Agent 角色 | 框架类型为 A2A |
| `AGENT_CAPABILITIES` | A2A Agent 能力列表(JSON 字符串) | 框架类型为 A2A |
#### 模板相关环境变量
根据不同的模板类型,可能需要不同的环境变量。例如:
- **MySQL Agent**: `MYSQL_HOST`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE`
- **PostgreSQL Agent**: `PG_HOST`, `PG_USER`, `PG_PASSWORD`, `PG_DATABASE`
- **其他模板**: 参考 Agent Manager 的模板定义
**获取模板环境变量要求**:
```742:759:services/mcp-server/app/agent_manager_client.py
async def get_template(self, template_name: str) -> TemplateInfo:
"""
Get template details
Call: GET /templates/{template_name}
Args:
template_name: Template name
Returns:
Template information
"""
data = await self._request("GET", f"/templates/{template_name}")
return TemplateInfo(
template=data["template"],
port=data.get("port"),
env_info=data.get("env_info", {})
)
```
### 工具配置格式
#### TOOLS 环境变量
**格式**: JSON 字符串数组
**示例**:
```json
["tool-uuid-1", "tool-uuid-2", "tool-uuid-3"]
```
#### TOOLS_CONFIG 环境变量
**格式**: JSON 字符串数组,每个元素包含工具的完整配置
**示例**:
```json
[
{
"id": "tool-uuid-1",
"name": "mysql_query",
"description": "MySQL 查询工具",
"endpoint": "https://api.example.com/mysql/query",
"method": "POST",
"schema": {
"type": "object",
"properties": {
"query": {"type": "string"}
}
},
"timeout": 30,
"auth_type": "bearer",
"auth_config": {
"token": "secret-token"
}
}
]
```
**代码位置**: `services/mcp-server/app/routes/user.py` (行 3117-3137)
---
## 代码位置
### 核心文件
1. **Agent Manager 客户端**
- 文件: `services/mcp-server/app/agent_manager_client.py`
- 主要类: `AgentManagerClient`
- 主要方法: `create_agent()`, `create_platform_agent()`, `create_custom_agent()`
2. **平台 Agent 路由**
- 文件: `services/mcp-server/app/routes/user.py`
- 主要函数:
- `deploy_platform_agent()` (行 2261-2512)
- `deploy_platform_agent_instances()` (行 1310-1509)
3. **自定义 Agent 路由**
- 文件: `services/mcp-server/app/routes/user.py`
- 主要函数: `create_custom_agent()` (行 2871-3341)
4. **数据模型定义**
- 文件: `services/mcp-server/app/schemas.py`
- 主要类:
- `CreateCustomAgentRequest` (行 815-851)
- `UsePlatformAgentRequest` (行 794-799)
### 关键方法调用链
#### 平台 Agent
```
deploy_platform_agent()
└─> AgentManagerClient.create_agent()
└─> AgentManagerClient._request("POST", "/agents", json=payload)
```
#### 自定义 Agent
```
create_custom_agent()
└─> AgentManagerClient.create_custom_agent()
└─> AgentManagerClient.create_agent()
└─> AgentManagerClient._request("POST", "/agents", json=payload)
```
---
## 总结
### 平台 Agent vs 自定义 Agent 对比
| 特性 | 平台 Agent | 自定义 Agent |
|------|-----------|-------------|
| **模板来源** | 平台预定义模板 | 用户选择的数据存储模板 |
| **环境变量** | 最少(仅 LLM_BASE_URL + 可选的模型配置) | 丰富(包含数据库连接、API Key、工具配置等) |
| **资源配置** | 从配额获取 | 用户自定义 |
| **框架类型** | 固定(由模板决定) | 用户选择(MCP/A2A/langchain) |
| **工具配置** | 不支持 | 支持(通过 TOOLS 和 TOOLS_CONFIG) |
| **A2A 配置** | 不支持 | 支持(如果 frameworkTemplate="A2A") |
### 共同点
1. 都通过 `POST /agents` 接口发送请求
2. 都包含 `name`, `template`, `config`, `env` 四个主要字段
3. 都自动注入 `LLM_BASE_URL` 环境变量
4. 都支持模型配置注入(如果用户指定了模型)
---
**文档生成时间**: 2025-01-XX
**代码版本**: 基于当前代码库状态