local_models_and_API_platform.md 14 KB

本地模型上传与开放平台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表新增字段

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表

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表

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
  • 现有系统模型定义:backend/app/models/model.py
  • 现有系统用户定义:backend/app/models/user.py
  • 现有系统计费模块:backend/app/models/billing.py