# AI Provider 架构简化 - 统一使用 OpenAI SDK **日期**: 2026-01-31 **类型**: 架构重构 **影响范围**: AI Provider 层、测试脚本 ## 背景 之前的架构设计存在过度工程化的问题: 1. **自定义 HTTP 客户端层**:创建了 `app/clients/` 目录,包含 `BaseHTTPClient`、`AIHubMixClient`、`StabilityClient`、`RunwayClient` 2. **重复造轮子**:手动实现 HTTP 请求、响应解析、错误处理 3. **维护成本高**:需要适配不同模型的响应格式差异(`url` vs `b64_json`) 4. **未使用官方 SDK**:AIHubMix 完全兼容 OpenAI API,但没有使用官方 SDK ## 问题分析 ### 为什么之前这样设计? 1. **架构一致性误导**:看到 `StabilityClient` 和 `RunwayClient` 都继承 `BaseHTTPClient`,为了保持一致性,让 `AIHubMixClient` 也继承它 2. **忽略关键事实**:Stability 和 Runway 没有官方 Python SDK,但 OpenAI 有(AIHubMix 兼容) 3. **没有质疑现有实现**:盲目追求架构一致性,而不是选择最佳工具 ### 正确的架构应该是什么? ✅ **有官方 SDK 的 → 使用 SDK**(如 AIHubMix) ✅ **没有官方 SDK 的 → 自己实现**(如 Stability、Runway) ## 重构方案 ### 1. 删除 `app/clients/` 目录 ```bash rm -rf server/app/clients/ ``` 删除的文件: - `base_client.py` - 基础 HTTP 客户端 - `aihubmix_client.py` - AIHubMix 客户端 - `stability_client.py` - Stability 客户端(未实现) - `runway_client.py` - Runway 客户端(未实现) ### 2. 重写 `AIHubMixProvider`(直接使用 OpenAI SDK) **之前**: ```python from app.clients.aihubmix_client import AIHubMixClient class AIHubMixProvider(BaseAIProvider): def __init__(self, model_name: str): self.client = AIHubMixClient(...) async def generate_image(self, ...): data = await self.client.generate_image(...) url = data['data'][0]['url'] # 手动解析 ``` **现在**: ```python from openai import AsyncOpenAI class AIHubMixProvider(BaseAIProvider): def __init__(self, model_name: str): self.client = AsyncOpenAI(...) async def generate_image(self, ...): response = await self.client.images.generate(...) # SDK 自动处理 url 和 b64_json image_data = response.data[0] ``` ### 3. 删除未实现的 Provider 删除的文件: - `stability_provider.py` - 未实现 - `runway_provider.py` - 未实现 ### 4. 更新所有导入 修改的文件: - `server/app/services/ai_providers/__init__.py` - `server/scripts/test_real_image_generation.py` - `server/scripts/sync_models_from_api.py` - 删除 `server/scripts/test_tts_generation.py`(待重写) - 删除 `server/scripts/test_text_generation.py`(待重写) ## 架构对比 ### 之前(过度设计) ``` app/ ├── clients/ ❌ 整个目录 │ ├── base_client.py │ ├── aihubmix_client.py │ ├── stability_client.py │ └── runway_client.py └── services/ └── ai_providers/ ├── aihubmix_provider.py → 依赖 AIHubMixClient ├── stability_provider.py └── runway_provider.py ``` ### 现在(简洁) ``` app/ └── services/ └── ai_providers/ ├── aihubmix_provider.py ✅ 直接使用 OpenAI SDK └── mock_provider.py ✅ 保留用于测试 ``` ## 优势 ### 1. 代码量减少 70% - **之前**: 400+ 行自定义 HTTP 客户端 - **现在**: 100 行 Provider(直接使用 SDK) ### 2. 自动处理响应格式 SDK 内部已处理: - `url` vs `b64_json` - 不同模型的参数差异 - 错误处理和重试 ### 3. 类型安全 OpenAI SDK 提供完整的类型提示: ```python response: ImagesResponse = await client.images.generate(...) image: Image = response.data[0] url: str = image.url # 类型安全 ``` ### 4. 维护成本低 - 官方 SDK 自动更新 - API 变更会自动适配 - 不需要手动维护 HTTP 逻辑 ### 5. 统一的 API 接口 所有 AIHubMix 支持的功能都使用 OpenAI SDK: - ✅ 图片生成:`client.images.generate()` - ✅ 视频生成:`client.videos.create()` - ✅ TTS:`client.audio.speech.create()` - ✅ STT:`client.audio.transcriptions.create()` - ✅ Chat:`client.chat.completions.create()` ## 影响范围 ### 修改的文件 1. **Provider 层** - `server/app/services/ai_providers/aihubmix_provider.py` - 完全重写 2. **导入声明** - `server/app/services/ai_providers/__init__.py` - 移除未实现的 Provider 3. **测试脚本** - `server/scripts/test_real_image_generation.py` - 更新为使用 OpenAI SDK - `server/scripts/sync_models_from_api.py` - 更新为使用 httpx 直接调用 ### 删除的文件 1. **Client 层**(整个目录) - `server/app/clients/base_client.py` - `server/app/clients/aihubmix_client.py` - `server/app/clients/stability_client.py` - `server/app/clients/runway_client.py` 2. **未实现的 Provider** - `server/app/services/ai_providers/stability_provider.py` - `server/app/services/ai_providers/runway_provider.py` 3. **测试脚本**(待重写) - `server/scripts/test_tts_generation.py` - `server/scripts/test_text_generation.py` ## 迁移指南 ### 如果需要添加新的 AI Provider **有官方 SDK 的**: ```python from some_ai_sdk import AsyncClient class NewAIProvider(BaseAIProvider): def __init__(self, model_name: str): self.client = AsyncClient(...) # 直接使用 SDK ``` **没有官方 SDK 的**: ```python import httpx class NewAIProvider(BaseAIProvider): def __init__(self, model_name: str): self.http_client = httpx.AsyncClient(...) # 使用 httpx ``` ## 经验教训 1. ❌ **不要盲目追求架构一致性** - 不同的场景应该使用不同的工具 2. ❌ **不要重复造轮子** - 优先使用官方 SDK 3. ✅ **质疑现有实现** - 即使代码已经写好,也要问"有没有更好的方式" 4. ✅ **选择最佳工具** - 有 SDK 就用 SDK,没有再自己实现 ## 后续工作 1. ✅ 重写 `AIHubMixProvider`(已完成) 2. ✅ 删除 `clients/` 目录(已完成) 3. ✅ 更新导入(已完成) 4. ⏳ 重新运行端到端测试 5. ⏳ 验证图片生成功能 6. ⏳ 验证视频生成功能 7. ⏳ 验证 TTS 功能 ## 参考 - [OpenAI Python SDK](https://github.com/openai/openai-python) - [AIHubMix 文档](https://docs.aihubmix.com/) - [ADR: 为什么不使用自定义 HTTP 客户端](../architecture/adrs/)