10 KiB
AIHubMixClient 重构继承 BaseHTTPClient 及 Skill 文档更新
日期: 2026-01-30
类型: 架构优化 + 文档更新
影响范围: Client 层、Skill 文档
背景
在完成 Client-Provider 层职责分离后,发现 AIHubMixClient 仍然自己实现 HTTP 逻辑,而 StabilityClient 和 RunwayClient 已经继承了 BaseHTTPClient。这导致了架构不一致。
同时,jointo-tech-stack skill 文档中缺少 AI Provider 架构说明,不利于新开发者理解和遵循架构规范。
问题
1. AIHubMixClient 架构不一致
# ❌ 当前:AIHubMixClient 自己实现 HTTP 逻辑
class AIHubMixClient:
def _get_headers(self, content_type: str = "application/json"):
...
async def generate_image(self, ...):
async with httpx.AsyncClient(timeout=self.timeout) as client:
response = await client.post(...)
response.raise_for_status()
data = response.json()
return data
# ✅ 其他 Client:继承 BaseHTTPClient
class StabilityClient(BaseHTTPClient):
async def text_to_image(self, ...):
return await self.post('/generation/...', json=request_data)
问题:
- 代码重复:AIHubMixClient 重复实现了 HTTP 逻辑
- 架构不一致:三个 Client 使用不同的实现方式
- 维护困难:HTTP 逻辑变更需要修改多处
2. Skill 文档缺失
.claude/skills/jointo-tech-stack/references/backend.md 中:
- ❌ 缺少 AI Provider 架构说明
- ❌ 项目结构中没有
clients/和ai_providers/目录 - ❌ 新开发者无法快速了解 AI 集成架构
解决方案
任务 1:重构 AIHubMixClient 继承 BaseHTTPClient
变更前
class AIHubMixClient:
"""AIHubMix API 统一客户端"""
def __init__(self, api_key: str, base_url: str, timeout: int = 300):
self.api_key = api_key
self.base_url = base_url
self.timeout = timeout
def _get_headers(self, content_type: str = "application/json"):
headers = {'Authorization': f'Bearer {self.api_key}'}
if content_type:
headers['Content-Type'] = content_type
return headers
async def generate_image(self, model: str, prompt: str, ...):
async with httpx.AsyncClient(timeout=self.timeout) as client:
response = await client.post(
f"{self.base_url}/images/generations",
headers=self._get_headers(),
json=request_data
)
response.raise_for_status()
data = response.json()
return data
变更后
class AIHubMixClient(BaseHTTPClient):
"""AIHubMix API 统一客户端(继承 BaseHTTPClient)"""
def __init__(self, api_key: str, base_url: str, timeout: int = 300):
super().__init__(api_key, base_url, timeout)
logger.info("初始化 AIHubMix 客户端: base_url=%s", base_url)
async def generate_image(self, model: str, prompt: str, ...):
request_data = {
'model': model,
'prompt': prompt,
'size': size
}
# 使用基类的 post 方法
data = await self.post('/images/generations', json=request_data)
return data
重构的方法
所有方法都已重构为使用基类方法:
-
图片生成 (
generate_image)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.post('/images/generations', json=...)
- 旧:
-
视频生成 (
generate_video)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.post('/videos', json=...)或await self.post('/videos', files=..., data=...)
- 旧:
-
视频状态查询 (
get_video_status)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.get(f'/videos/{video_id}')
- 旧:
-
视频下载 (
download_video)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.get(endpoint, params=..., follow_redirects=True)
- 旧:
-
TTS 生成 (
generate_speech)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.post('/audio/speech', json=...)
- 旧:
-
STT 转录 (
transcribe_audio)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.post('/audio/transcriptions', files=..., data=...)
- 旧:
-
Chat 补全 (
chat_completion)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.post('/chat/completions', json=...)
- 旧:
-
模型查询 (
list_models)- 旧:
async with httpx.AsyncClient(...) - 新:
await self.get('/models', params=...)
- 旧:
任务 2:更新 Skill 文档
更新项目结构
在 .claude/skills/jointo-tech-stack/references/backend.md 中更新项目结构:
server/app/
├── clients/ # HTTP 客户端层 ✅ 新增
│ ├── __init__.py
│ ├── base_client.py # HTTP 客户端基类
│ ├── aihubmix_client.py # AIHubMix 客户端
│ ├── stability_client.py # Stability AI 客户端
│ └── runway_client.py # Runway 客户端
├── services/
│ ├── ai_service.py # AI Service 层
│ └── ai_providers/ # AI Provider 层 ✅ 新增
│ ├── __init__.py
│ ├── base.py # Provider 基类
│ ├── aihubmix_provider.py # AIHubMix Provider
│ ├── stability_provider.py # Stability Provider
│ ├── runway_provider.py # Runway Provider
│ ├── mock_provider.py # Mock Provider
│ └── factory.py # Provider 工厂
新增 AI Provider 架构章节
添加完整的 AI Provider 架构说明,包括:
-
四层架构设计
- API 层 → Service 层 → Provider 层 → Client 层
-
Client 层规范
- 必须继承
BaseHTTPClient - 只负责 HTTP 通信
- 示例代码
- 必须继承
-
Provider 层规范
- 必须继承
BaseAIProvider - 负责业务逻辑适配
- 必须实现的方法
- 必须继承
-
Service 层规范
- 负责业务编排
- 积分扣除、任务队列、文件存储
-
Provider Factory
- 工厂模式创建 Provider
- 支持的模型列表
-
配置管理
- API Key 配置示例
-
支持的 AI 厂商
- AIHubMixProvider
- StabilityProvider
- RunwayProvider
-
新增 AI 厂商指南
- 步骤 1:创建 Client
- 步骤 2:创建 Provider
- 步骤 3:更新 Factory
- 步骤 4:添加配置
-
最佳实践
- Client 层只负责 HTTP
- Provider 层负责业务适配
- Service 层负责业务编排
- 错误处理
-
测试
- Client 层测试
- Provider 层测试
- Service 层测试
优势
1. 架构一致性
所有 Client 都继承 BaseHTTPClient
↓
统一的 HTTP 逻辑
↓
易于维护和扩展
2. 代码复用
- ✅ 移除了 AIHubMixClient 中的重复 HTTP 逻辑
- ✅ 自动获得错误处理、重试、日志等功能
- ✅ HTTP 逻辑变更只需修改 BaseHTTPClient
3. 功能统一
所有 Client 自动获得:
- ✅ 错误处理(4xx 不重试,5xx 重试)
- ✅ 重试逻辑(指数退避)
- ✅ 日志记录
- ✅ 超时控制
4. 文档完善
- ✅ 新开发者可以快速了解 AI Provider 架构
- ✅ 清晰的职责划分和最佳实践
- ✅ 完整的示例代码和测试指南
影响范围
修改的文件
- ✅
server/app/clients/aihubmix_client.py- 重构继承 BaseHTTPClient - ✅
.claude/skills/jointo-tech-stack/references/backend.md- 更新项目结构和新增 AI Provider 架构章节
不受影响的文件
- ✅
server/app/services/ai_providers/aihubmix_provider.py- Provider 层接口不变 - ✅
server/app/services/ai_service.py- Service 层接口不变 - ✅
server/app/api/v1/ai.py- API 层接口不变 - ✅
server/app/tasks/ai_tasks.py- Celery 任务接口不变
测试验证
1. 语法检查
docker exec jointo-server-app python -m py_compile app/clients/aihubmix_client.py
2. 功能测试
# 测试图片生成
docker exec jointo-server-app python scripts/test_ai_image_generation_e2e.py
# 测试 TTS
docker exec jointo-server-app python scripts/test_tts_generation.py
# 测试视频生成
docker exec jointo-server-app python scripts/test_ai_video_generation_e2e.py
3. 验证 Client 方法
所有方法都应该正常工作:
- ✅
generate_image()- 图片生成 - ✅
generate_video()- 视频生成 - ✅
get_video_status()- 视频状态查询 - ✅
download_video()- 视频下载 - ✅
wait_for_video_completion()- 等待视频完成 - ✅
generate_speech()- TTS 生成 - ✅
transcribe_audio()- STT 转录 - ✅
chat_completion()- Chat 补全 - ✅
list_models()- 模型查询
最终架构
Client 层(统一继承 BaseHTTPClient)
BaseHTTPClient
├── AIHubMixClient ✅ 已重构
├── StabilityClient ✅ 已重构
└── RunwayClient ✅ 已重构
完整四层架构
API 层 (ai_api.py)
↓
Service 层 (ai_service.py)
├─ 积分扣除
├─ Celery 任务队列
└─ MinIO 文件存储
↓
Provider 层 (aihubmix_provider.py / stability_provider.py / runway_provider.py)
├─ 业务逻辑适配
├─ 参数转换
└─ 统一接口
↓
Client 层 (aihubmix_client.py / stability_client.py / runway_client.py)
├─ 纯 HTTP 调用(继承 BaseHTTPClient)
├─ 错误处理
└─ 重试逻辑
后续优化
可选优化
-
性能优化
- 在 BaseHTTPClient 中添加连接池配置
- 优化 httpx 客户端参数
-
监控增强
- 记录 HTTP 请求耗时
- 统计成功率和失败率
-
缓存机制
- 在 Client 层添加响应缓存
- 减少重复请求
-
限流控制
- 在 Client 层添加 Rate Limiting
- 防止 API 调用超限
总结
本次重构完成了两个重要任务:
- AIHubMixClient 重构:统一了所有 Client 的实现方式,消除了代码重复,提升了架构一致性
- Skill 文档更新:完善了 AI Provider 架构文档,为新开发者提供了清晰的指导
核心改进:
- ✅ 架构一致:所有 Client 都继承 BaseHTTPClient
- ✅ 代码复用:移除重复的 HTTP 逻辑
- ✅ 功能统一:自动获得错误处理、重试、日志
- ✅ 文档完善:新增完整的 AI Provider 架构说明
- ✅ 易于扩展:新增 AI 厂商只需 4 步
现在整个 AI Provider 架构清晰、一致、易于维护和扩展!