# AI Provider Factory 数据库驱动重构 **日期**: 2026-02-10 **类型**: 重构 **影响范围**: AI Provider 选择逻辑 ## 背景 之前的 `AIProviderFactory` 使用硬编码的模型列表(`ELEVENLABS_MODELS` 和 `AIHUBMIX_MODELS`)来判断使用哪个 Provider,存在以下问题: 1. **数据冗余**:模型信息既在数据库 `ai_models` 表中,又在代码中硬编码 2. **维护困难**:新增模型需要同时修改数据库和代码 3. **不一致风险**:数据库中的模型可能与代码中的列表不同步 4. **灵活性差**:无法动态启用/禁用模型,必须修改代码 ## 解决方案 采用**启动时缓存**方案: - 应用启动时从数据库加载所有活跃模型到内存缓存 - `create_provider()` 方法从缓存查询模型的 `provider` 字段 - 根据 `provider` 动态选择对应的 Provider 实例 - 提供 `refresh_cache()` 方法支持运行时刷新缓存 ## 变更内容 ### 1. 修改 `AIProviderFactory` (server/app/services/ai_providers/factory.py) **新增:** - `_provider_cache: Dict[str, int]` - 内存缓存,存储 `{model_name: provider}` - `initialize(db)` - 应用启动时初始化缓存 - `refresh_cache(db)` - 运行时刷新缓存 - `get_cached_provider(model_name)` - 从缓存获取 Provider ID **修改:** - `create_provider()` - 从缓存查询 Provider,而非硬编码列表 - 根据 `AIProvider` 枚举值动态选择 Provider 实例 **移除:** - `ELEVENLABS_MODELS` - 硬编码的 ElevenLabs 模型列表 - `AIHUBMIX_MODELS` - 硬编码的 AIHubMix 模型列表 ### 2. 修改 `main.py` (server/app/main.py) 在 `lifespan()` 函数中添加 AI Provider Factory 初始化逻辑: ```python # 初始化 AI Provider Factory 缓存 try: from app.core.database import get_db from app.services.ai_providers.factory import AIProviderFactory async for db in get_db(): await AIProviderFactory.initialize(db) logger.info("✅ AI Provider Factory initialized") break except Exception as e: logger.error(f"❌ Failed to initialize AI Provider Factory: {e}") # 不抛出异常,允许应用继续运行(降级到 Mock Provider) ``` ## 优势 1. ✅ **单一数据源**:模型配置完全由数据库管理 2. ✅ **动态配置**:通过数据库启用/禁用模型,无需修改代码 3. ✅ **高性能**:启动时加载到内存,运行时无需查询数据库 4. ✅ **易维护**:新增模型只需在数据库中添加记录 5. ✅ **可扩展**:支持运行时刷新缓存(通过 `refresh_cache()` 方法) ## 降级策略 - 如果缓存初始化失败,应用仍可正常启动 - 未在缓存中的模型会自动降级到 `MockAIProvider` - 保留 `use_mock` 配置选项,支持强制使用 Mock Provider ## 后续优化 可选的后续改进: 1. **缓存刷新 API**:添加管理员 API 端点,支持手动刷新缓存 2. ~~**缓存预热**:在模型同步脚本执行后自动刷新缓存~~ ✅ 已实现 3. **缓存监控**:添加缓存命中率监控和日志 ## 自动刷新机制 **已实现**:模型同步脚本自动刷新缓存 在 `sync_models_from_api.py` 执行完成后,会自动调用 `AIProviderFactory.refresh_cache()` 刷新缓存: ```python # 刷新 AI Provider Factory 缓存 try: from app.services.ai_providers.factory import AIProviderFactory await AIProviderFactory.refresh_cache(session) logger.info("✅ AI Provider Factory 缓存已刷新") except Exception as e: logger.warning("刷新 AI Provider Factory 缓存失败: %s", str(e)) # 不影响同步结果 ``` **使用方式:** ```bash # 同步模型(自动刷新缓存) docker exec jointo-server-app python scripts/sync_models_from_api.py # 输出示例: # ============================================================ # 同步完成 # 新增: 5 # 更新: 0 # 跳过: 16 # ============================================================ # ✅ AI Provider Factory 缓存已刷新 ``` ## 测试建议 1. 启动应用,检查日志中的缓存初始化信息 2. 验证不同 Provider 的模型是否正确创建 3. 测试未激活模型是否正确降级到 Mock Provider 4. 测试数据库不可用时的降级行为 ## 相关文件 - `server/app/services/ai_providers/factory.py` - AI Provider Factory - `server/app/main.py` - 应用入口 - `server/app/repositories/ai_model_repository.py` - AI Model Repository - `server/app/models/ai_model.py` - AI Model 数据模型