11 KiB
11 KiB
MCP-Server 设计问题审查报告
概述
本报告检查了 MCP-Server 的设计代码,发现了多个设计错误和冲突问题。
一、严重问题(会导致运行时错误)
1.1 PlatformAgentQuota 模型字段缺失 ❌
问题描述:user.py 中使用了 PlatformAgentQuota 的多个字段,但这些字段在 models.py 中不存在。
models.py 中的定义(第 1095-1131 行):
class PlatformAgentQuota(BaseModel, Base):
__tablename__ = "platform_agent_quotas"
target_id = Column(GUID(), nullable=False)
target_type = Column(String(20), nullable=False) # channel, tenant
template_name = Column(String(100), nullable=False)
pod_quota = Column(Integer, nullable=False, default=0)
pod_used = Column(Integer, default=0)
allocated_by = Column(GUID(), ForeignKey("users.id"))
allocated_at = Column(DateTime, default=datetime.utcnow)
user.py 中使用的缺失字段:
| 缺失字段 | 使用位置 | 用途 |
|---|---|---|
is_active |
user.py:835, 881, 1011 | 过滤活跃配额 |
agent_type |
user.py:844, 880, 1010 | Agent 类型标识 |
cpu_per_pod |
user.py:849, 909, 935 | 每个 Pod 的 CPU 配置 |
memory_per_pod |
user.py:850, 911, 936 | 每个 Pod 的内存配置 |
影响:
- 用户调用
/api/user/platform-agents/available会报错 - 用户调用
/api/user/platform-agents/use会报错 - 用户停止平台 Agent 时会报错
修复建议:在 models.py 的 PlatformAgentQuota 类中添加缺失字段:
class PlatformAgentQuota(BaseModel, Base):
__tablename__ = "platform_agent_quotas"
target_id = Column(GUID(), nullable=False)
target_type = Column(String(20), nullable=False) # channel, tenant
template_name = Column(String(100), nullable=False)
# 新增字段
agent_type = Column(String(100)) # Agent 类型名称(与 template_name 可能相同)
is_active = Column(Boolean, default=True) # 是否活跃
cpu_per_pod = Column(String(20), default="100m") # 每个 Pod 的 CPU
memory_per_pod = Column(String(20), default="128Mi") # 每个 Pod 的内存
# 原有字段
pod_quota = Column(Integer, nullable=False, default=0)
pod_used = Column(Integer, default=0)
allocated_by = Column(GUID(), ForeignKey("users.id"))
allocated_at = Column(DateTime, default=datetime.utcnow)
1.2 AgentBillingRecord 模型字段缺失 ❌
问题描述:user.py 中使用了 AgentBillingRecord 的多个字段,但这些字段在 models.py 中不存在。
models.py 中的定义(第 1134-1172 行):
class AgentBillingRecord(BaseModel, Base):
__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)
memory_gb_seconds = Column(sa.Float, default=0)
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)
user.py 中使用的缺失字段:
| 缺失字段 | 使用位置 | 用途 |
|---|---|---|
is_platform_agent |
user.py:933, 1054, 1207, 1264, 1469, 1659, 1682 | 区分平台/自定义 Agent |
start_time |
user.py:934, 1071, 1209, 1285, 1488, 1684 | 开始时间 |
end_time |
user.py:992, 1054, 1265, 1469, 1685 | 结束时间 |
cpu_used |
user.py:935, 1211, 1291, 1378, 1421, 1487, 1687 | CPU 使用量 |
memory_used |
user.py:936, 1212, 1291, 1379, 1424, 1488, 1688 | 内存使用量 |
eu_consumed |
user.py:1002, 1287, 1687 | EU 消耗量 |
影响:
- 用户使用平台 Agent 时计费记录创建失败
- 用户创建自定义 Agent 时计费记录创建失败
- 计费历史查询失败
修复建议:在 models.py 的 AgentBillingRecord 类中添加缺失字段:
class AgentBillingRecord(BaseModel, Base):
__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) # 模板名称
template_name = Column(String(100), nullable=False)
# 新增字段
is_platform_agent = Column(Boolean, nullable=False) # 是否为平台 Agent
start_time = Column(DateTime) # 开始时间
end_time = Column(DateTime) # 结束时间(None 表示运行中)
cpu_used = Column(String(20)) # CPU 使用量(如 "100m")
memory_used = Column(String(20)) # 内存使用量(如 "128Mi")
eu_consumed = Column(sa.Float, default=0) # EU 消耗量
# 原有字段
duration_seconds = Column(Integer) # 改为可空,运行中时为 None
cpu_seconds = Column(sa.Float, default=0)
memory_gb_seconds = Column(sa.Float, default=0)
request_count = Column(Integer, default=0)
cost = Column(sa.Numeric(12, 4)) # 改为可空
currency = Column(String(10), default="EU")
period_start = Column(DateTime) # 改为可空
period_end = Column(DateTime) # 改为可空
二、设计冲突问题
2.1 平台 Agent 模板硬编码 ⚠️
问题描述:平台 Agent 模板在 admin.py 和 channel.py 中重复硬编码,而不是从 Agent Manager 获取。
位置:
admin.py:2507-2547-PLATFORM_AGENT_TEMPLATESchannel.py:1737-1777-PLATFORM_AGENT_TEMPLATES
问题:
- 两处代码需要保持同步,容易出错
- 新增模板需要修改代码并重新部署
- 与 Agent Manager 的模板管理功能冲突
修复建议:
- 删除硬编码的
PLATFORM_AGENT_TEMPLATES - 调用
agent_manager_client.list_platform_templates()获取模板 - 或者在数据库中存储模板配置
2.2 字段命名不一致 ⚠️
问题描述:同一概念在不同地方使用不同的字段名。
| 概念 | models.py | user.py | 说明 |
|---|---|---|---|
| Agent 类型 | agent_type |
agent_type / template_name |
有时混用 |
| 开始时间 | period_start |
start_time |
不一致 |
| 结束时间 | period_end |
end_time |
不一致 |
修复建议:统一字段命名,或者在模型中同时保留两个字段作为别名。
三、业务逻辑问题
3.1 平台 Agent 启动时机不符合需求 ⚠️
当前实现:
user.py中的/api/user/platform-agents/use接口是用户主动调用才启动 Pod
需求:
- 平台 Agent 应该在渠道分配给用户时立即启动,用户可以直接使用
影响位置:
channel.py中的租户资源分配接口
修复建议: 在渠道分配平台 Agent 配额给租户时,自动调用 Agent Manager 创建 Pod:
# channel.py 中分配平台 Agent 给租户时
async def allocate_platform_agent_to_tenant(...):
# 1. 创建配额记录
tenant_quota = PlatformAgentQuota(...)
# 2. 立即调用 Agent Manager 启动 Pod
client = get_agent_manager_client()
result = await client.create_platform_agent(
name=f"{template_name}-{tenant_id[:8]}",
template=template_name,
user_id=tenant_id,
channel_id=channel_id,
config=AgentConfig(
cpu_request=cpu_per_pod,
memory_request=memory_per_pod,
...
)
)
# 3. 更新配额使用量
tenant_quota.pod_used = 1
tenant_quota.pod_name = result.name
3.2 自定义 Agent 配额检查逻辑正确 ✅
当前实现:
- 渠道分配配额给租户时只记录配额,不启动 Pod
- 用户创建自定义 Agent 时检查配额并启动 Pod
符合需求:自定义 Agent 需要用户填写配置后才启动。
四、数据库迁移需求
根据上述问题,需要创建数据库迁移脚本:
4.1 迁移脚本 007_fix_platform_agent_quota.sql
-- 为 platform_agent_quotas 表添加缺失字段
ALTER TABLE platform_agent_quotas
ADD COLUMN IF NOT EXISTS agent_type VARCHAR(100),
ADD COLUMN IF NOT EXISTS is_active BOOLEAN DEFAULT TRUE,
ADD COLUMN IF NOT EXISTS cpu_per_pod VARCHAR(20) DEFAULT '100m',
ADD COLUMN IF NOT EXISTS memory_per_pod VARCHAR(20) DEFAULT '128Mi';
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_platform_agent_quota_active
ON platform_agent_quotas(is_active);
4.2 迁移脚本 008_fix_agent_billing_record.sql
-- 为 agent_billing_records 表添加缺失字段
ALTER TABLE agent_billing_records
ADD COLUMN IF NOT EXISTS is_platform_agent BOOLEAN,
ADD COLUMN IF NOT EXISTS start_time TIMESTAMP,
ADD COLUMN IF NOT EXISTS end_time TIMESTAMP,
ADD COLUMN IF NOT EXISTS cpu_used VARCHAR(20),
ADD COLUMN IF NOT EXISTS memory_used VARCHAR(20),
ADD COLUMN IF NOT EXISTS eu_consumed FLOAT DEFAULT 0;
-- 修改原有字段为可空
ALTER TABLE agent_billing_records
ALTER COLUMN duration_seconds DROP NOT NULL,
ALTER COLUMN cost DROP NOT NULL,
ALTER COLUMN period_start DROP NOT NULL,
ALTER COLUMN period_end DROP NOT NULL;
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_agent_billing_is_platform
ON agent_billing_records(is_platform_agent);
CREATE INDEX IF NOT EXISTS idx_agent_billing_end_time
ON agent_billing_records(end_time);
五、问题汇总
| 问题类型 | 问题描述 | 严重程度 | 状态 |
|---|---|---|---|
| 模型字段缺失 | PlatformAgentQuota 缺少 is_active, agent_type, cpu_per_pod, memory_per_pod | 严重 | 待修复 |
| 模型字段缺失 | AgentBillingRecord 缺少 is_platform_agent, start_time, end_time, cpu_used, memory_used, eu_consumed | 严重 | 待修复 |
| 代码重复 | PLATFORM_AGENT_TEMPLATES 在两处硬编码 | 中等 | 待修复 |
| 字段命名不一致 | period_start/start_time, period_end/end_time | 低 | 待修复 |
| 业务逻辑 | 平台 Agent 启动时机不符合需求 | 中等 | 待修复 |
六、修复优先级
- 高优先级:修复
PlatformAgentQuota和AgentBillingRecord模型字段缺失 - 中优先级:修改平台 Agent 启动时机(渠道分配时启动)
- 低优先级:移除硬编码模板,改为从 Agent Manager 获取
七、版本历史
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.0 | 2026-01-05 | 初始审查报告 |