18 KiB
18 KiB
资源管控系统文档
概述
资源管控系统负责在请求执行前进行配额检查、速率限制,并在执行后记录资源消耗,确保平台资源的合理使用和成本控制。
层级式资源管理架构
系统采用三级层级式资源管理:
平台 (Platform)
├── 超级管理员配置平台资源
│
└── 渠道 (Channel)
├── 模型供应商配额
├── Agent配额 (quantity)
├── 自定义Agent资源配置 (CPU/内存)
└── 渠道授信额度
│
└── 租户 (Tenant)
├── Agent使用次数配额
├── 模型RPM/TPM限制
├── 自定义Agent资源配额
└── 余额和授信额度
关键特性:
- 层级继承:租户可以继承渠道的资源配置
- 灵活分配:渠道可以为不同租户设置不同的资源限制
- 独立计费:每个层级独立计费和统计
- 资源隔离:平台Agent和自定义Agent使用不同的资源配置
核心功能
1. 配额检查(Quota Check)
在每次工具或Agent执行前,系统会检查:
-
用户余额配额:检查用户账户余额是否充足
balance:当前余额credit_limit:授信额度available = balance + credit_limit:可用额度- 预警机制:余额不足7天时发出预警,不足3天时严重预警
-
渠道配额:如果用户属于某个渠道,检查渠道配额
channel_credit:渠道总额度monthly_usage:当月使用量- 预警机制:使用超过80%时预警,超过95%时严重预警
-
Agent资源配额:检查Agent使用权限和配额
- 平台Agent配额:
- 检查租户是否有该Agent的使用权限
- 检查使用次数配额(
quantity)是否充足 - 使用平台Agent自身配置的CPU/内存资源
- 自定义Agent资源配额:
- 检查租户是否有创建自定义Agent的权限
- 使用租户分配的
customAgentResources配额 - CPU范围:0.5-16核(推荐)
- 内存范围:0.5-64GB(推荐)
- 基于实际资源使用时间计费
- 平台Agent配额:
2. 速率限制(Rate Limiting)
基于滑动窗口算法实现的速率限制:
-
RPM限制(Requests Per Minute):每分钟请求数
- 默认:60 RPM
- 可在用户表的
rpm_limit字段配置 - 窗口大小:60秒
-
TPM限制(Tokens Per Minute):每分钟Token数
- 默认:10,000 TPM
- 可在用户表的
tpm_limit字段配置
3. 成本限制(Cost Limiting)
-
每日成本限制:
daily_cost_limit- 默认:100.00 元/天
- 防止用户单日消费过高
-
预估成本检查:
- 执行前预估操作成本
- 确保余额足以支付本次操作
4. 资源使用记录(Resource Usage Recording)
执行完成后,系统会记录:
-
ResourceUsage表:按小时聚合的资源使用
cpu_seconds:CPU使用秒数memory_mb_seconds:内存使用(MB*秒)network_bytes:网络流量字节api_calls:API调用次数granularity:粒度(hourly/daily/monthly)
-
BillingRecord表:详细的计费记录
tenant_id:用户IDresource_type:资源类型(tool/agent/model)cost:成本details:详细信息(执行时间、CPU、内存等)
自定义Agent资源管理
1. 渠道级配置
渠道可以配置租户创建自定义Agent时的默认资源限制:
# Channel表结构
class Channel(Base):
custom_agent_cpu = Column(Numeric(12, 2), default=2) # CPU核心数
custom_agent_memory = Column(Numeric(12, 2), default=4) # 内存GB
channel_credit = Column(Numeric(12, 2), default=0) # 渠道授信额度
配置API:
PUT /api/admin/channels/{channel_id}/resources
{
"customAgentResources": {
"cpu": 2.0,
"memory": 4.0
}
}
2. 租户级配置
租户可以从渠道分配的资源中获得自定义Agent配额:
PUT /api/channel/tenants/{tenant_id}/resources
{
"customAgentResources": {
"cpu": 2.0,
"memory": 4.0
}
}
资源继承规则:
- 如果租户未配置,继承渠道的
customAgentResources - 如果渠道未配置,使用系统默认值(CPU: 2核, 内存: 4GB)
3. 创建自定义Agent
租户通过API创建自定义Agent:
POST /api/user/agents/custom/create
{
"name": "my-custom-agent",
"role": "客服助手",
"goal": "帮助客户解答问题",
"tools": ["search_kb", "create_ticket"]
}
响应:
{
"id": "agent-custom-uuid",
"name": "my-custom-agent",
"type": "custom",
"cpu": 2.0,
"memory": 4.0,
"status": "active"
}
4. 资源使用计费
自定义Agent的计费基于实际资源使用:
# 计费公式
cost = (cpu_cores * cpu_seconds * CPU_PRICE) + \
(memory_gb * memory_seconds * MEMORY_PRICE) + \
(api_calls * API_CALL_PRICE)
# 示例价格(可配置)
CPU_PRICE = 0.0001 USD/核·秒
MEMORY_PRICE = 0.00005 USD/GB·秒
API_CALL_PRICE = 0.001 USD/次
5. 平台Agent vs 自定义Agent
| 特性 | 平台Agent | 自定义Agent |
|---|---|---|
| 资源配置 | Agent自身定义的CPU/内存 | 租户分配的customAgentResources |
| 创建权限 | 平台创建 | 租户创建 |
| 配额类型 | 使用次数配额(quantity) | 资源时间配额(CPU/内存·秒) |
| 计费方式 | 按次计费 | 按资源使用时间计费 |
| 资源隔离 | 使用自身资源 | 受租户配额限制 |
| 可定制性 | 固定功能 | 自定义角色、目标、工具 |
使用方式
在路由中集成资源管控
from app.resource_control import enforce_resource_control, resource_controller
from decimal import Decimal
@router.post("/agents/{agent_id}/execute")
async def execute_agent(
agent_id: str,
request: MCPRequest,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
# 1. 执行前检查
await enforce_resource_control(
user_id=current_user["user_id"],
resource_type="agent",
resource_id=agent_id,
estimated_cost=Decimal("0.01"), # 预估成本
db=db
)
# 2. 执行操作
start_time = time.time()
result = await handler.execute_request(agent_id, request)
duration = time.time() - start_time
# 3. 记录资源消耗
await resource_controller.record_resource_consumption(
user_id=current_user["user_id"],
resource_type="agent",
resource_id=agent_id,
cost=Decimal(str(execution.eu_consumed)),
execution_time_ms=duration * 1000,
cpu_usage=execution.cpu_usage,
memory_usage=execution.memory_usage,
network_io=execution.network_io,
db=db
)
错误处理
资源管控失败时会抛出 HTTPException,状态码:
402 Payment Required:余额不足403 Forbidden:渠道配额不足429 Too Many Requests:速率限制超出404 Not Found:用户不存在
错误响应示例:
{
"error": "insufficient_balance",
"message": "账户余额不足",
"balance": 10.50,
"creditLimit": 50.00,
"available": 60.50,
"dailyAvgCost": 15.30,
"estimatedDays": 3.9
}
配置项
用户级别配置(users表)
ALTER TABLE users ADD COLUMN rpm_limit INTEGER DEFAULT 60;
ALTER TABLE users ADD COLUMN tpm_limit INTEGER DEFAULT 10000;
ALTER TABLE users ADD COLUMN daily_cost_limit NUMERIC(12, 2) DEFAULT 100.00;
系统级别配置
在 app/resource_control.py 中:
# 速率限制窗口(秒)
RATE_LIMIT_WINDOW = 60 # 1分钟窗口
在 app/quota_manager.py 中:
# 配额预警阈值配置
QUOTA_THRESHOLDS = {
"balance_warning": 20, # 余额低于20%时预警
"balance_critical": 10, # 余额低于10%时严重预警
"quota_warning": 80, # 配额使用超过80%时预警
"quota_critical": 95, # 配额使用超过95%时严重预警
}
监控和查询
查看用户配额信息
GET /api/billing-admin/quota/user/{user_id}
查看资源使用趋势
GET /api/billing-admin/resources/trends?user_id={user_id}&period=7d&granularity=daily
查看配额预警
GET /api/billing-admin/quota/alerts?user_id={user_id}
数据库表结构
channels 表(渠道配置)
CREATE TABLE channels (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
custom_agent_cpu NUMERIC(12, 2) DEFAULT 2.0, -- 自定义Agent CPU配额
custom_agent_memory NUMERIC(12, 2) DEFAULT 4.0, -- 自定义Agent 内存配额(GB)
channel_credit NUMERIC(12, 2) DEFAULT 0, -- 渠道授信额度
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
agents 表(Agent配置)
CREATE TABLE agents (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL,
type VARCHAR(20) NOT NULL DEFAULT 'platform', -- platform | custom
description TEXT,
category VARCHAR(50),
role VARCHAR(200),
goal TEXT,
tools JSON DEFAULT '[]',
-- 资源配置
cpu NUMERIC(5, 2) NOT NULL DEFAULT 2,
memory NUMERIC(5, 2) NOT NULL DEFAULT 4, -- GB
max_instances INTEGER DEFAULT 100,
-- 所有者
owner_id UUID, -- 自定义Agent的创建者
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
resource_allocations 表(资源分配)
CREATE TABLE resource_allocations (
id UUID PRIMARY KEY,
target_id UUID NOT NULL, -- 渠道ID或租户ID
target_type VARCHAR(20) NOT NULL, -- 'channel' | 'tenant'
resource_type VARCHAR(20) NOT NULL, -- 'agent' | 'model'
resource_id UUID NOT NULL, -- Agent ID 或 模型供应商ID
-- Agent资源配置
quantity INTEGER, -- Agent使用次数配额
-- 模型资源配置
rpm INTEGER, -- 模型RPM限制
tpm INTEGER, -- 模型TPM限制
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
INDEX idx_target (target_id, target_type),
INDEX idx_resource (resource_id, resource_type)
);
resource_usage 表(资源使用记录)
CREATE TABLE resource_usage (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
agent_id UUID,
cpu_seconds FLOAT DEFAULT 0.0,
memory_mb_seconds FLOAT DEFAULT 0.0,
network_bytes BIGINT DEFAULT 0,
storage_bytes BIGINT DEFAULT 0,
api_calls INTEGER DEFAULT 0,
period_start TIMESTAMP NOT NULL,
period_end TIMESTAMP NOT NULL,
granularity VARCHAR(20) DEFAULT 'hourly',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
INDEX idx_user_period (user_id, period_start),
INDEX idx_agent (agent_id)
);
quota_alerts 表
CREATE TABLE quota_alerts (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
channel_id UUID,
alert_type VARCHAR(50) NOT NULL,
threshold_percent INTEGER,
current_value NUMERIC(12, 4),
threshold_value NUMERIC(12, 4),
status VARCHAR(20) DEFAULT 'active',
acknowledged_at TIMESTAMP,
resolved_at TIMESTAMP,
notification_sent BOOLEAN DEFAULT FALSE,
notification_channel VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
性能优化
- 速率限制缓存:使用内存缓存减少数据库查询
- 批量聚合:按小时聚合资源使用记录,减少存储
- 异步记录:资源消耗记录采用异步方式,不阻塞主流程
- 索引优化:在关键字段上建立索引,提高查询性能
迁移步骤
1. 运行数据库迁移
cd /home/taiji/tools/taiji-AI-PAD/services/mcp-server
python3 migrations/add_resource_control_fields.py
2. 重启服务
# 如果使用docker-compose
docker-compose restart mcp-server
# 如果直接运行
pkill -f "python.*main.py"
python3 main.py
3. 验证功能
# 测试执行Agent(应该触发资源管控检查)
curl -X POST "http://localhost:8002/api/agents/{agent_id}/execute" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"method": "test", "params": {}}'
故障排查
问题1:速率限制不生效
检查:
- 确认
rpm_limit字段已添加到数据库 - 查看日志中的
resource_control_rate_limit_exceeded事件 - 验证
resource_usage表是否正常记录
问题2:余额检查总是失败
检查:
- 用户的
balance和credit_limit字段值 - 查看
billing_records表中的消费记录 - 确认计费逻辑是否正确扣费
问题3:资源消耗未记录
检查:
resource_controller.record_resource_consumption是否被调用- 查看日志中的
resource_consumption_recorded或resource_consumption_recording_failed事件 - 确认数据库写入权限
完整工作流程
场景:租户创建并使用自定义Agent
步骤1: 超级管理员配置渠道资源
curl -X PUT "http://localhost:8002/api/admin/channels/{channel_id}/resources" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-d '{
"models": ["model-uuid-1"],
"agents": [{"agentId": "agent-uuid-1", "quantity": 100}],
"customAgentResources": {"cpu": 2.0, "memory": 4.0},
"channelCredit": 10000.00
}'
步骤2: 渠道管理员为租户分配资源
curl -X PUT "http://localhost:8002/api/channel/tenants/{tenant_id}/resources" \
-H "Authorization: Bearer $CHANNEL_TOKEN" \
-d '{
"agents": [{"agentId": "agent-uuid-1", "quantity": 20}],
"models": [{"modelName": "OpenAI", "rpm": 60, "tpm": 60000}],
"customAgentResources": {"cpu": 2.0, "memory": 4.0}
}'
步骤3: 租户创建自定义Agent
curl -X POST "http://localhost:8002/api/user/agents/custom/create" \
-H "Authorization: Bearer $TENANT_TOKEN" \
-d '{
"name": "sales-agent",
"role": "销售助手",
"goal": "帮助客户选择产品"
}'
步骤4: 系统执行资源检查
# 执行前检查流程
async def check_and_enforce(
user_id: str,
resource_type: str,
resource_id: str,
estimated_cost: Decimal
) -> Tuple[bool, Optional[str], Dict]:
# 1. 检查用户余额
if not check_balance(user_id, estimated_cost):
return False, "insufficient_balance", {...}
# 2. 检查渠道配额
if user.channel_id:
if not check_channel_quota(user.channel_id, estimated_cost):
return False, "channel_quota_exceeded", {...}
# 3. 检查Agent配额
if resource_type == "agent":
agent = get_agent(resource_id)
if agent.type == "platform":
# 平台Agent: 检查使用次数配额
if not check_agent_quantity_quota(user_id, agent.id):
return False, "agent_quota_exceeded", {...}
elif agent.type == "custom":
# 自定义Agent: 检查资源配额
if not check_custom_agent_resources(user_id, agent):
return False, "resource_quota_exceeded", {...}
# 4. 检查速率限制
if not check_rate_limit(user_id):
return False, "rate_limit_exceeded", {...}
return True, None, {}
步骤5: 执行Agent并记录资源消耗
# 执行Agent
start_time = time.time()
result = await agent.execute(request)
execution_time = time.time() - start_time
# 记录资源消耗
await resource_controller.record_resource_consumption(
user_id=user_id,
resource_type="agent",
resource_id=agent.id,
cost=calculated_cost,
execution_time_ms=execution_time * 1000,
cpu_usage=agent.cpu,
memory_usage=agent.memory,
db=db
)
步骤6: 更新配额和余额
# 扣除余额
user.balance -= calculated_cost
# 更新渠道月度使用量
if user.channel_id:
channel.monthly_usage += calculated_cost
# 更新Agent使用次数(平台Agent)
if agent.type == "platform":
allocation.used_quantity += 1
await db.commit()
最佳实践
1. 渠道资源配置建议
| 渠道规模 | Agent配额 | CPU配额 | 内存配额 | 授信额度 |
|---|---|---|---|---|
| 小型 | 50 | 1.0核 | 2GB | $1,000 |
| 中型 | 200 | 2.0核 | 4GB | $10,000 |
| 大型 | 1000 | 4.0核 | 8GB | $50,000 |
| 企业 | 5000+ | 8.0核 | 16GB | $100,000+ |
2. 租户资源分配建议
| 租户类型 | Agent配额 | CPU配额 | 内存配额 | 推荐用途 |
|---|---|---|---|---|
| 试用 | 5-10 | 0.5核 | 1GB | 功能测试 |
| 基础 | 10-30 | 1.0核 | 2GB | 小规模应用 |
| 标准 | 30-100 | 2.0核 | 4GB | 中等规模应用 |
| 高级 | 100-500 | 4.0核 | 8GB | 大规模应用 |
| 企业 | 500+ | 8.0核+ | 16GB+ | 企业级应用 |
3. 监控与优化
- 合理设置限制:根据用户等级设置不同的RPM/TPM限制
- 监控预警:定期检查配额预警,及时处理
- 余额预警:< 7天 (warning), < 3天 (critical)
- 配额预警:> 80% (warning), > 95% (critical)
- 成本估算:为不同类型的操作提供准确的成本估算
- 日志记录:保留详细的资源使用日志,便于分析和审计
- 定期清理:定期归档或删除旧的资源使用记录
- 性能优化:
- 自定义Agent使用合适的资源配置,避免过度配置
- 监控Agent执行性能,及时调整资源分配
- 使用缓存减少重复计算
扩展方向
- 分级限制:基于用户订阅等级实现不同的限制
- 动态调整:根据系统负载动态调整速率限制
- 预付费模式:支持用户预充值,按使用扣费
- 实时监控:提供实时的资源使用监控面板
- 成本优化建议:基于历史数据提供成本优化建议