# 本地模型上传与开放平台API服务模块需求文档 ## 一、需求概述 ### 1.1 背景 当前系统的模型广场仅支持云端模型(由平台统一托管的AI模型),用户无法接入自己部署的本地模型。同时,平台缺乏对外开放API的能力,用户无法通过标准API协议调用平台上的模型资源。 本需求旨在: 1. 支持用户上传并管理本地部署的OpenAI API兼容模型 2. 建立开放平台,提供标准化的API调用能力,支持用户通过API Key调用平台模型 ### 1.2 术语说明 | 术语 | 说明 | |------|------| | 云端模型 | 平台统一托管的AI模型,由平台管理员配置,所有用户共享 | | 本地模型 | 用户自行部署的AI模型,仅对上传用户可见,需提供OpenAI API兼容接口 | | 阿里云APIKey | 现有系统中用于调用阿里云百炼服务的密钥,存储在users.apikey字段 | | 平台APIKey | 本次新增,用于调用本平台开放API的密钥,需新建表存储 | | OpenAI API兼容 | 遵循OpenAI Chat Completions API格式的接口规范 | --- ## 二、功能需求 ### 2.1 本地模型上传与管理 #### 2.1.1 模型广场导航切换 **需求描述**: - 在模型广场页面顶部新增导航栏,包含"云端模型"和"本地模型"两个选项卡 - 默认显示"云端模型"(当前所有模型) - 点击"本地模型"切换到本地模型列表视图 **交互设计**: ``` ┌─────────────────────────────────────────────────────────┐ │ 模型广场 │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ 云端模型 ✓ │ │ 本地模型 │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ [模型卡片列表...] │ └─────────────────────────────────────────────────────────┘ ``` #### 2.1.2 本地模型上传 **需求描述**: - 在"本地模型"视图中提供"添加本地模型"按钮 - 点击后弹出模态框,填写以下信息: - Base URL(必填):本地模型的API地址,如 `http://localhost:8080/v1` - API Key(选填):访问本地模型所需的密钥 - 模型名称(必填):用于显示和调用的模型标识 - 提交前支持"测试连接"功能,验证配置是否正确 - 上传成功后以卡片形式展示在本地模型列表中 **输入字段**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | base_url | string | 是 | 本地模型API地址,需符合URL格式 | | api_key | string | 否 | 访问密钥,部分本地部署可能不需要 | | name | string | 是 | 模型显示名称,用户自定义 | **连接测试**: - 调用 `{base_url}/chat/completions` 接口 - 发送简单测试消息验证连通性 - 返回成功/失败状态及错误信息 #### 2.1.3 本地模型存储 **数据库设计**: - 复用现有 `models` 表 - 新增字段 `is_local`(Boolean,默认false)区分本地/云端模型 - 新增字段 `user_id`(String,可空)关联上传用户(本地模型必填) - 新增字段 `base_url`(String,可空)存储本地模型API地址 - 新增字段 `local_api_key`(String,可空)存储本地模型访问密钥(加密存储) **models表新增字段**: | 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | is_local | Boolean | false | 是否为本地模型 | | user_id | String(50) | NULL | 上传用户ID(本地模型必填) | | base_url | String(500) | NULL | 本地模型API地址 | | local_api_key | String(500) | NULL | 本地模型访问密钥(加密) | #### 2.1.4 本地模型展示 **需求描述**: - 本地模型以卡片形式展示,与云端模型样式一致 - 卡片需显示"本地"标签以区分 - 本地模型仅对上传用户可见 - 支持编辑和删除操作 **卡片信息**: - 模型名称 - Base URL(脱敏显示) - 连接状态(在线/离线) - 创建时间 - 操作按钮(编辑/删除/测试连接) #### 2.1.5 本地模型调用 **需求描述**: - 本地模型可在文本交互页面使用 - 调用时后端代理请求到用户配置的Base URL - 不计费(本地模型免费使用) --- ### 2.2 开放平台与API服务 #### 2.2.1 开放平台入口 **需求描述**: - 在侧边栏新增"开放平台"菜单项 - 开放平台页面包含: - API Key管理 - API文档说明 - 调用统计 - 费用明细 #### 2.2.2 平台API Key管理 **需求描述**: - 用户可申请平台API Key用于调用开放API - 每个用户最多持有5个有效API Key - 支持API Key的创建、查看、禁用、删除操作 - API Key创建时可设置备注名称 - API Key仅在创建时完整显示一次,之后仅显示前后部分 **API Key格式**: - 前缀:`sk-aigc-` - 长度:48字符 - 示例:`sk-aigc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` **数据库设计 - 新建 `platform_api_key` 表**: | 字段 | 类型 | 说明 | |------|------|------| | id | Integer | 主键 | | user_id | String(50) | 用户ID,外键关联users表 | | api_key | String(100) | API Key(哈希存储) | | api_key_prefix | String(20) | API Key前缀(用于显示) | | name | String(100) | 备注名称 | | status | String(20) | 状态:active/disabled | | last_used_at | DateTime | 最后使用时间 | | created_at | DateTime | 创建时间 | | updated_at | DateTime | 更新时间 | #### 2.2.3 OpenAI API兼容协议实现 **需求描述**: - 提供符合OpenAI API规范的接口 - 支持 `/v1/chat/completions` 端点 - 支持流式和非流式响应 - 通过Header中的 `Authorization: Bearer {api_key}` 进行认证 **API端点**: ``` POST /api/v1/chat/completions Headers: Authorization: Bearer sk-aigc-xxxxx Content-Type: application/json Request Body: { "model": "qwen-max", // 模型标识(models.title) "messages": [ {"role": "user", "content": "Hello"} ], "stream": false, // 是否流式 "temperature": 0.7, // 可选参数 "max_tokens": 2048 // 可选参数 } Response (非流式): { "id": "chatcmpl-xxx", "object": "chat.completion", "created": 1234567890, "model": "qwen-max", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help you?" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 10, "completion_tokens": 20, "total_tokens": 30 } } ``` #### 2.2.4 模型API调用权限控制 **需求描述**: - 利用现有 `models.is_api_enabled` 字段控制模型是否支持API调用 - 后台管理员可配置每个模型的API调用权限 - 用户调用未开放API的模型时返回错误 **权限检查流程**: 1. 验证API Key有效性 2. 检查目标模型是否存在 3. 检查模型 `is_api_enabled` 是否为true 4. 检查用户余额是否充足(云端模型) 5. 执行调用 #### 2.2.5 API调用计费 **计费规则**: - **云端模型**:按模型价格表计费,每次HTTP请求计费一次 - **本地模型**:不计费(用户自有资源) **计费流程**: 1. API请求完成后计算费用 2. 从用户余额扣除 3. 记录到账单日志 4. 更新API调用统计 **数据库设计 - 新建 `api_call_log` 表**: | 字段 | 类型 | 说明 | |------|------|------| | id | BigInteger | 主键 | | user_id | String(50) | 用户ID | | api_key_id | Integer | 使用的API Key ID | | model_id | Integer | 调用的模型ID | | model_name | String(255) | 模型名称 | | is_local | Boolean | 是否本地模型 | | input_tokens | Integer | 输入token数 | | output_tokens | Integer | 输出token数 | | bill | Decimal(12,4) | 费用(本地模型为0) | | status | String(20) | 状态:success/failed | | error_message | Text | 错误信息(失败时) | | request_ip | String(50) | 请求IP | | created_at | DateTime | 创建时间 | #### 2.2.6 开放平台统计展示 **需求描述**: - 显示API调用统计: - 今日调用次数 - 本月调用次数 - 总调用次数 - 今日消费金额 - 本月消费金额 - 显示调用趋势图(按日/周/月) - 显示各模型调用占比 #### 2.2.7 费用明细查询 **需求描述**: - 在开放平台和个人账单中均可查看API调用费用 - 支持按时间、模型、API Key筛选 - 显示每次调用的详细信息: - 调用时间 - 模型名称 - Token用量 - 费用金额 - 使用的API Key --- ## 三、后台管理需求 ### 3.1 模型API权限管理 **需求描述**: - 在后台模型管理页面,支持配置 `is_api_enabled` 字段 - 批量开启/关闭模型的API调用权限 ### 3.2 本地模型审核(可选) **需求描述**: - 管理员可查看所有用户上传的本地模型 - 支持禁用违规的本地模型配置 --- ## 四、接口设计 ### 4.1 本地模型相关接口 | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/models/local | 添加本地模型 | | GET | /api/models/local | 获取当前用户的本地模型列表 | | PUT | /api/models/local/{id} | 更新本地模型配置 | | DELETE | /api/models/local/{id} | 删除本地模型 | | POST | /api/models/local/test | 测试本地模型连接 | ### 4.2 开放平台相关接口 | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/platform/api-keys | 创建API Key | | GET | /api/platform/api-keys | 获取API Key列表 | | PUT | /api/platform/api-keys/{id} | 更新API Key(禁用/启用) | | DELETE | /api/platform/api-keys/{id} | 删除API Key | | GET | /api/platform/stats | 获取调用统计 | | GET | /api/platform/call-logs | 获取调用日志 | ### 4.3 OpenAI兼容API | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/chat/completions | Chat Completions API | | GET | /api/v1/models | 获取可用模型列表 | --- ## 五、数据模型变更汇总 ### 5.1 修改现有表 **models表新增字段**: ```sql ALTER TABLE aigcspace.models ADD COLUMN is_local BOOLEAN NOT NULL DEFAULT FALSE; ALTER TABLE aigcspace.models ADD COLUMN user_id VARCHAR(50) NULL; ALTER TABLE aigcspace.models ADD COLUMN base_url VARCHAR(500) NULL; ALTER TABLE aigcspace.models ADD COLUMN local_api_key VARCHAR(500) NULL; CREATE INDEX idx_models_is_local ON aigcspace.models(is_local); CREATE INDEX idx_models_user_id ON aigcspace.models(user_id); ``` ### 5.2 新建表 **platform_api_key表**: ```sql CREATE TABLE aigcspace.platform_api_key ( id SERIAL PRIMARY KEY, user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE, api_key VARCHAR(100) NOT NULL, api_key_prefix VARCHAR(20) NOT NULL, name VARCHAR(100), status VARCHAR(20) NOT NULL DEFAULT 'active', last_used_at TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_platform_api_key_user_id ON aigcspace.platform_api_key(user_id); CREATE INDEX idx_platform_api_key_api_key ON aigcspace.platform_api_key(api_key); CREATE INDEX idx_platform_api_key_status ON aigcspace.platform_api_key(status); ``` **api_call_log表**: ```sql CREATE TABLE aigcspace.api_call_log ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE, api_key_id INTEGER REFERENCES aigcspace.platform_api_key(id) ON DELETE SET NULL, model_id INTEGER REFERENCES aigcspace.models(id) ON DELETE SET NULL, model_name VARCHAR(255) NOT NULL, is_local BOOLEAN NOT NULL DEFAULT FALSE, input_tokens INTEGER NOT NULL DEFAULT 0, output_tokens INTEGER NOT NULL DEFAULT 0, bill DECIMAL(12,4) NOT NULL DEFAULT 0, status VARCHAR(20) NOT NULL DEFAULT 'success', error_message TEXT, request_ip VARCHAR(50), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_api_call_log_user_id ON aigcspace.api_call_log(user_id); CREATE INDEX idx_api_call_log_api_key_id ON aigcspace.api_call_log(api_key_id); CREATE INDEX idx_api_call_log_model_id ON aigcspace.api_call_log(model_id); CREATE INDEX idx_api_call_log_created_at ON aigcspace.api_call_log(created_at); CREATE INDEX idx_api_call_log_is_local ON aigcspace.api_call_log(is_local); ``` --- ## 六、安全考虑 ### 6.1 API Key安全 - 平台API Key使用SHA256哈希存储,仅保留前缀用于显示 - 本地模型的API Key使用AES加密存储 - API Key传输使用HTTPS加密 ### 6.2 本地模型安全 - 验证Base URL格式,防止SSRF攻击 - 限制可访问的端口范围 - 代理请求时不暴露服务器内部信息 ### 6.3 访问控制 - 本地模型仅对上传用户可见 - API调用需验证用户身份和权限 - 记录所有API调用日志用于审计 --- ## 七、非功能需求 ### 7.1 性能要求 - API响应时间:非流式 < 30s,流式首字节 < 3s - 支持并发API调用:单用户 100 QPS ### 7.2 可用性要求 - 开放API可用性 > 99.9% - 本地模型连接测试超时时间:10s ### 7.3 兼容性要求 - 完全兼容OpenAI Chat Completions API v1规范 - 支持主流OpenAI SDK直接调用 --- ## 八、待确认事项 1. **本地模型分类**:本地模型是否需要支持分类(语言模型/多模态等)? 2. **API Key配额**:是否需要对API Key设置调用频率限制? 3. **本地模型共享**:是否支持用户将本地模型共享给其他用户? 4. **API调用限流**:是否需要实现API调用限流机制? 5. **Webhook通知**:API调用失败或余额不足时是否需要通知用户? --- ## 九、参考资料 - [OpenAI API Reference](https://platform.openai.com/docs/api-reference/chat) - 现有系统模型定义:`backend/app/models/model.py` - 现有系统用户定义:`backend/app/models/user.py` - 现有系统计费模块:`backend/app/models/billing.py`