Files
Alfred/openspec/changes/add-model-management/design.md
lanyuanxiaoyao 933c2133f0 feat: 新增模型管理功能(供应商 + 模型 CRUD)
- 新增 providers/models 数据库表、迁移和数据访问层
- 新增 15 个后端 API 路由(供应商/模型 CRUD + 连通性测试)
- 新增 AI 服务层(registry.ts: buildProviderRegistry + testProviderConnection)
- 新增前端模型管理页面(Tabs: 供应商/模型,含表格、表单、工具栏)
- 新增前端 hooks(use-providers, use-models)
- 新增共享类型和 MODEL_CAPABILITIES 常量
- 新增 10 个测试文件(66 个测试用例,4 个因 bun test ESM 兼容问题待修复)
- 更新开发文档(architecture, backend, frontend)
- 附带 apply-review 修复:统一错误响应、提取共享常量、清理重复测试

注意:registry.test.ts 中 4 个测试因 bun test 无法解析
createProviderRegistry ESM 导出而失败,详情见 context.md
2026-05-29 12:40:10 +08:00

14 KiB
Raw Blame History

背景

Alfred·阿福定位为"基于 AI 的信息综合处理平台"但当前项目v0.1.0)没有任何 AI/LLM 集成。项目已完成基础架构Bun 全栈、SQLite + Drizzle ORM、React 19 + Ant Design 6 + React Router 7、TanStack React Query并拥有管理控制台Dashboard + 项目管理)和工作台控制台。

本次变更在管理控制台中新增"模型管理"功能,让用户能够配置 AI 供应商和模型,为后续所有 AI 功能提供基础设施。这是项目 AI 能力的第一个里程碑。

当前状态:

  • 后端:src/server/ 使用 Bun.serve(),路由在 routes/ 目录按功能拆分DB schema 在 src/server/db/schema.ts,数据访问层在 src/server/db/projects.ts
  • 前端:src/web/ 使用 console 模式admin 菜单在 consoles/admin/menu.tsx,页面在 pages/ 目录
  • 零 AI/LLM 相关代码

讨论记录

  • 已确认结论:
    • 使用 Vercel AI SDKai + @ai-sdk/openai + @ai-sdk/anthropic + @ai-sdk/openai-compatible)作为统一 AI 调用层
    • 三种供应商类型:openaianthropicopenai-compatible(覆盖 DeepSeek、Qwen、Ollama 等)
    • API Key 明文存储于 SQLite可接受本地/自部署单用户工具)
    • AI 注册表不使用缓存层:每次 AI 调用时从 DB 查询供应商+模型 → 构建 createProviderRegistry → 调用 AI SDK开销 ~1ms远小于网络 I/O
    • 功能调用function calling视为基础能力不列入 capability 标签
  • 用户偏好:
    • 前端使用 antd Tabs 组件在同一页面内展示供应商和模型两个标签页
    • 供应商表单中 type 默认值为 openai-compatiblebaseURL 不设默认值
    • 连通性测试为可选功能,不阻塞模型创建
  • 约束:
    • 严格遵循现有代码模式路由拆分、数据访问函数、hooks、页面组件结构
    • 不引入新的样式系统
  • 被否决方案:
    • API Key 加密存储:对本地/自部署单用户场景过度设计
    • AI 注册表缓存:增加复杂度但收益极小(~1ms vs 数百毫秒网络 I/O
    • LangChain 等重量级框架Vercel AI SDK 更轻量且 API 更统一

需求

需求 验收标准
供应商 CRUD 管理员可新增、查看、编辑、删除供应商名称、类型、baseURL、apiKey
供应商类型支持 支持 openai、anthropic、openai-compatible 三种类型,各自对应 AI SDK 不同 provider 工厂
模型 CRUD 管理员可新增、查看、编辑、删除模型名称、所属供应商、modelId、能力标签、可选参数
能力标签多选 模型表单中可多选能力标签text / reasoning / image-generation / video-generation / audio-generation / image-recognition / video-recognition / audio-recognition
连通性测试 供应商编辑/创建时可测试 API 连通性,返回成功/失败提示
模型启用/禁用 供应商和模型均可启用/禁用,不影响数据
管理控制台菜单 Admin 控制台侧栏新增"模型管理"菜单项
AI 注册表服务 后端提供 AI 注册表构建服务,按需从 DB 查询构建,供后续 AI 功能调用
级联约束 删除供应商时,若存在关联模型则阻止删除,用户需先处理关联模型

数据模型规格

providers 表

字段 类型 约束 说明
id TEXT PK, UUID 自动生成
name TEXT NOT NULL, UNIQUE 供应商显示名称
type TEXT NOT NULL 枚举:openai | anthropic | openai-compatible,默认 openai-compatible
baseUrl TEXT NOT NULL API 基础 URL不设默认值由用户填写
apiKey TEXT NOT NULL API 密钥明文存储GET 接口完整返回
enabled INTEGER NOT NULL, DEFAULT 1 1=启用, 0=禁用
createdAt TEXT NOT NULL ISO 8601 时间戳
updatedAt TEXT NOT NULL ISO 8601 时间戳

models 表

字段 类型 约束 说明
id TEXT PK, UUID 自动生成
name TEXT NOT NULL 模型显示名称
providerId TEXT NOT NULL, FK → providers.id 所属供应商
modelId TEXT NOT NULL API 调用用的模型标识(如 gpt-4o
capabilities TEXT NOT NULL JSON 数组,能力标签(见下方定义)
contextLength INTEGER 可选 上下文窗口长度
maxOutputTokens INTEGER 可选 最大输出 token 数
enabled INTEGER NOT NULL, DEFAULT 1 1=启用, 0=禁用
createdAt TEXT NOT NULL ISO 8601 时间戳
updatedAt TEXT NOT NULL ISO 8601 时间戳

唯一约束: (providerId, modelId) 联合唯一——同一供应商下 modelId 不可重复,不同供应商可以有相同 modelId。

能力标签定义ModelCapability

"text" | "reasoning" | "image-generation" | "video-generation" | "audio-generation" | "image-recognition" | "video-recognition" | "audio-recognition"

存储为 JSON 数组字符串,如 ["text","reasoning","image-recognition"]

目标 / 非目标

目标:

  • 在管理控制台提供完整的供应商和模型管理界面
  • 建立后端 AI 服务层(注册表 + 类型定义),为后续 AI 功能提供可复用基础
  • 完成 Vercel AI SDK 集成的依赖安装和基础配置
  • 新增 DB migration 支持 providers 和 models 表

非目标:

  • 不实现实际的 AI 调用功能(文本生成、图片生成等)——这是后续变更的内容
  • 不实现 API Key 加密存储
  • 不实现供应商/模型的导入导出功能
  • 不实现多用户权限控制

执行约束

  • 依赖限制:
    • 新增 npm 依赖仅限 ai@ai-sdk/openai@ai-sdk/anthropic@ai-sdk/openai-compatible
    • 使用 bun add 安装,严禁 npm/pnpm
    • 优先使用项目已有依赖Drizzle ORM、antd、TanStack React Query 等)
  • 约束:
    • 后端遵循 Bun 内置 API > es-toolkit > 三方库优先级
    • 前端遵循 antd 组件默认能力优先,禁止内联 style、覆盖 antd 内部类名
    • Git 提交格式:中文,"类型: 简短描述"
  • 质量门禁:
    • 新增代码必须编写完善的测试
    • 不允许跳过任何测试
    • 代码变更需执行文档影响分析
  • 相关方:
    • 本变更为基础设施层,所有后续 AI 功能变更将依赖本变更的 AI 注册表服务
  • 文档 / 沟通:
    • 每次代码变更执行文档影响分析:用户可见行为变更 → docs/user/,开发流程/架构变更 → docs/development/
  • 兼容性 / 连续性:
    • 无需考虑向前兼容性

影响范围

范围 Artifacts / 参考资料 预期变更 备注
DB Schema src/server/db/schema.ts 新增 providers 和 models 表定义 遵循现有 projects 表模式
DB Migration drizzle/ 新增 migration SQL 文件 自动生成
数据访问层 src/server/db/projects.ts(参考模式) 新增 providers.tsmodels.ts CRUD + 启用/禁用
DB 导出 src/server/db/index.ts 新增 providers 和 models schema 导出 遵循现有导出模式
共享类型 src/shared/api.ts 新增供应商和模型相关类型定义 前后端共用
后端路由 src/server/routes/ 新增 providers/models/ 目录 CRUD + 连通性测试
服务器入口 src/server/server.ts 注册新路由 懒加载导入
AI 服务层 src/server/ai/(新建) 新增 registry.tstypes.ts AI 注册表构建服务
前端菜单 src/web/consoles/admin/menu.tsx 新增"模型管理"菜单项
前端页面 src/web/pages/models/(新建) 新增模型管理页面Tabs + 表格 + 表单) 遵循 projects 页面模式
前端组件 src/web/pages/models/components/(新建) ProviderTable、ProviderFormModal、ModelTable、ModelFormModal
前端路由 src/web/routes.tsx 新增 /models 路由
前端 Hooks src/web/hooks/ 新增 use-providers.tsuse-models.ts TanStack React Query
依赖 package.json 新增 ai@ai-sdk/openai@ai-sdk/anthropic@ai-sdk/openai-compatible
测试 tests/ 新增后端路由、数据访问、前端 hooks 和组件测试
文档 docs/development/backend.md 更新后端架构说明,补充 AI 服务层 开发文档
文档 docs/development/frontend.md 补充模型管理页面组件说明 开发文档

决策

决策 理由 已否决替代方案
使用 Vercel AI SDK 轻量、统一 API、支持多供应商、TypeScript 优先、与 Bun 兼容 LangChain过重API 复杂)、自行封装 fetch维护成本高无法统一接口
三种供应商类型 覆盖主流场景OpenAIResponses API + Chat Completions API、Anthropic、OpenAI 兼容协议DeepSeek/Qwen/Ollama 等) 仅区分"OpenAI 协议"和"其他"(丢失 Anthropic 特有能力)
API Key 明文存储 本地/自部署单用户场景,加密增加复杂度但安全性提升有限 加密存储(过度设计)
AI 注册表不缓存 DB 查询 + 注册表构建开销 ~1ms远小于网络 I/O无缓存则无需处理失效/一致性问题 内存缓存(增加复杂度,收益极小)
capability 标签用 JSON 数组 灵活可扩展SQLite 中 TEXT 字段存储 JSON 数组 关联表(过度设计,标签数量有限且固定)
连通性测试不阻塞操作 测试是辅助功能,网络波动不应阻止用户保存配置 强制测试通过才能保存(用户体验差)
删除供应商时阻止而非级联删除 防止误删导致模型数据丢失,用户需先处理关联模型 CASCADE 删除(数据安全风险)
GET 接口完整返回 apiKey 本地/自部署单用户场景,前端使用 antd Password 组件隐藏显示,无需脱敏 apiKey 脱敏返回(增加复杂度,编辑时需额外处理)
providerId + modelId 联合唯一 同一供应商下 modelId 不可重复,不同供应商可有相同 modelId符合 AI SDK 注册表 key 格式 providerId:modelId modelId 全局唯一(限制过严)、无约束(可能导致注册表冲突)
连通性测试使用 generateText 最小请求 调用 generateText({ model, prompt: 'hi' }) 验证连通性和 apiKey 有效性,简单直接 仅验证 HTTP 连接(不验证 apiKey、listModels并非所有供应商支持
启用/禁用使用 enable/disable 双端点 语义明确,与 archive/restore 模式一致;供应商/模型的启用禁用是布尔切换,双端点更清晰 toggle 单端点(语义含糊,前端需知道当前状态才能确定操作)
供应商 type 默认 openai-compatible 覆盖最广DeepSeek/Qwen/Ollama 等),用户只需填写 baseURL 和 apiKey 即可使用 默认 openai限制性强不适合自部署场景
baseURL 不设默认值 不同部署环境的 baseURL 差异大,自动填充可能误导用户填错地址 设默认值(看似方便,但可能掩盖配置错误)

执行计划

阶段 1基础层DB + 类型 + 依赖)

  1. 安装 Vercel AI SDK 相关依赖
  2. src/server/db/schema.ts 新增 providers 和 models 表定义
  3. 生成 DB migration
  4. src/shared/api.ts 新增供应商和模型相关类型定义
  5. src/server/ai/types.ts 新增 AI 相关类型定义ModelCapability 等)

阶段 2后端数据访问 + 路由 + AI 服务) 6. 新增 src/server/db/providers.ts 数据访问函数 7. 新增 src/server/db/models.ts 数据访问函数 8. 新增 src/server/routes/providers/ 目录下的 CRUD 路由处理器(含 enable/disable 双端点) 9. 新增 src/server/routes/models/ 目录下的 CRUD 路由处理器(含 enable/disable 双端点) 10. 新增 src/server/routes/providers/test.ts 连通性测试路由 11. 在 src/server/server.ts 注册所有新路由 12. 新增 src/server/ai/registry.ts,包含 buildProviderRegistry(db)(从 DB 查询启用的供应商构建 AI SDK Provider RegistrytestProviderConnection(config)(使用 generateText 测试连通性)

阶段 3前端页面 + 组件 + Hooks 13. 新增 src/web/hooks/use-providers.tssrc/web/hooks/use-models.ts 14. 在 src/web/consoles/admin/menu.tsx 新增"模型管理"菜单项 15. 在 src/web/routes.tsx 新增 /models 路由 16. 新增 src/web/pages/models/index.tsx 页面Tabs 布局) 17. 新增 src/web/pages/models/components/ProviderTable.tsx 18. 新增 src/web/pages/models/components/ProviderFormModal.tsx 19. 新增 src/web/pages/models/components/ModelTable.tsx 20. 新增 src/web/pages/models/components/ModelFormModal.tsx

阶段 4测试 21. 后端数据访问层测试providers.ts、models.ts 22. 后端路由测试providers/、models/ 23. AI 注册表测试 24. 前端 hooks 测试 25. 前端组件测试

阶段 5文档 26. 执行文档影响分析,更新 docs/development/ 相关文档

验证计划

需求 / 风险 验证方式
供应商 CRUD API 后端路由测试覆盖创建、查询、更新、删除、启用/禁用
模型 CRUD API 后端路由测试覆盖创建、查询、更新、删除、启用/禁用
供应商删除约束 测试删除有关联模型的供应商时返回错误
连通性测试 API 测试 mock 场景下的成功/失败响应
AI 注册表构建 测试从 DB 数据正确构建 AI SDK provider 实例
DB Migration 测试 migration 正确创建表和索引
前端供应商管理 组件测试覆盖表格渲染、表单提交、启用/禁用操作
前端模型管理 组件测试覆盖表格渲染、表单提交、能力标签多选
前端菜单和路由 测试菜单项显示和路由跳转
文档完整性 检查 docs/development/ 和 docs/user/ 是否已更新

风险 / 权衡

  • [Vercel AI SDK 与 Bun 的兼容性] -> AI SDK 基于 Web 标准 APIBun 对 Web API 支持良好;安装后需验证 import 正常
  • [OpenAI-compatible 供应商行为不一致] -> 注册表构建时使用 createOpenAICompatible 标准接口;连通性测试帮助用户提前发现问题
  • [API Key 明文存储安全风险] -> 文档中说明安全模型(单用户本地部署);未来可按需增加加密
  • [migration 与现有数据兼容性] -> 新增表不影响现有 projects 表migration 为增量操作

待解决问题

状态 问题 所需决策
无待解决问题。 无需决策