# Changelog: AI 对话生成参数分离 **日期**: 2026-02-13 **版本**: v1.0 **类型**: 架构优化 (架构改进) **影响范围**: `ai_conversations` API + Service --- ## 📋 概述 将对话 AI 生成接口 `/{conversation_id}/generate` 的参数从单一 `params` 字典拆分为: - **`aiParams`**: AI 模型参数(独立对象) - **`businessParams`**: 业务参数(独立对象,可选) 这使得参数职责更清晰,易于验证和扩展。 --- ## 🎯 改动目标 ### 问题背景 原有的 `params` 字段混合了两类参数: ```json { "params": { "modelId": "dall-e-3", "resolution": "1024", // AI 参数 "aspectRatio": "1:1", // AI 参数 "outputFormat": "png", // AI 参数 "saveToProject": true, // 业务参数 "autoPublish": false // 业务参数 } } ``` **问题**: 1. ❌ **职责不清**:AI 参数和业务参数混在一起 2. ❌ **扩展困难**:新增业务参数可能与 AI 参数命名冲突 3. ❌ **验证复杂**:无法分别验证 AI 参数和业务参数 ### 改进方案 采用**嵌套结构**,将参数分为三层: ```json { "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", // ✅ 模型 ID(顶层字段) "aiParams": { // ✅ AI 模型参数(独立对象) "resolution": "1024", "aspectRatio": "1:1", "outputFormat": "png", "seed": 42 }, "businessParams": { // ✅ 业务参数(通用字典,可选) "customField1": "value1", "customField2": true } } ``` **说明**: - `businessParams` 为**通用字典**(`Dict[str, Any]`),字段由业务需求决定 - 当前仅记录日志,等业务需求明确后再实现具体逻辑 --- ## 🛠️ 技术实现 ### 1. 新增 Schema 定义 #### 文件: `server/app/schemas/ai_conversation.py` ##### 1.1 AI 模型参数 Schema ```python class AIGenerationParams(BaseModel): """AI 生成参数(模型参数)""" model_config = ConfigDict(populate_by_name=True) # 简单模式参数 resolution: Optional[str] = None aspect_ratio: Optional[str] = Field(None, alias="aspectRatio") quality: Optional[str] = None # 高级模式参数 width: Optional[int] = None height: Optional[int] = None duration: Optional[int] = None fps: Optional[int] = None # 高级参数 - 输出控制 output_format: Optional[str] = Field(None, alias="outputFormat") num_images: Optional[int] = Field(None, alias="numImages") # 高级参数 - 控制参数 seed: Optional[int] = None watermark: Optional[bool] = None # 参考图片 reference_images: Optional[list[str]] = Field(None, alias="referenceImages") # Wan 视频模式 video_mode: Optional[str] = Field(None, alias="videoMode") ``` **说明**: - 包含所有 AI 模型相关参数 - 支持简单模式(`resolution`, `aspectRatio`)和高级模式(`width`, `height`, `seed`) - 与 RFC 144 的统一参数协议保持一致 ##### 1.2 业务参数 Schema ```python class GenerateRequest(BaseModel): """触发 AI 生成请求 参数分层: - modelId: 模型 ID(顶层字段) - aiParams: AI 模型参数(独立对象) - businessParams: 业务参数(通用字典,可选,字段待业务需求明确) """ model_config = ConfigDict(populate_by_name=True) message_id: UUID = Field(..., alias="messageId", description="消息 ID(用于关联)") generation_type: str = Field(..., alias="generationType", description="生成类型(image/video)") model_id: str = Field(..., alias="modelId", description="模型 ID") # AI 模型参数(独立对象) ai_params: AIGenerationParams = Field(..., alias="aiParams", description="AI 模型参数") # 业务参数(通用字典,可选,待业务需求明确) business_params: Optional[Dict[str, Any]] = Field( None, alias="businessParams", description="业务参数(保存、发布、通知等,字段待定义)" ) ``` **说明**: - `businessParams` 为 **`Optional[Dict[str, Any]]`**(通用字典) - 不预先定义具体字段,由业务需求决定 - 当前仅记录日志,后续根据需求实现具体功能 **示例字段**(未来可能使用): ```json { "businessParams": { "saveToProject": true, // 是否保存到项目 "autoPublish": false, // 是否自动发布 "tagIds": ["tag1", "tag2"], // 关联标签 "createVersion": false, // 是否创建版本 "notifyOnComplete": true // 完成时通知 } } ``` --- ### 2. Service 层改动 #### 文件: `server/app/services/ai_conversation_service.py` #### 2.1 更新 `trigger_ai_generation` 方法签名 ```python async def trigger_ai_generation( self, conversation_id: UUID, user_id: UUID, message_id: UUID, generation_type: str, model_id: str, # ✅ 新增:从参数提升到方法参数 ai_params: Dict[str, Any], # ✅ 新增:AI 模型参数(独立) business_params: Optional[Dict[str, Any]] = None # ✅ 新增:业务参数(独立) ) -> Dict[str, Any]: ``` **变化**: - 原有单一 `params` 拆分为 `model_id`, `ai_params`, `business_params` - `business_params` 为可选参数(默认 `None`) #### 2.2 更新参数处理逻辑 ##### 图片生成 (Image Generation) ```python if generation_type == 'image': prompt = message.content # 使用 ParamMapper 转换 AI 参数 from app.utils.param_mapper import ParamMapper generate_params = ParamMapper.convert_image_params(ai_params) # 添加参考图片 if reference_images: generate_params['reference_images'] = reference_images # 处理业务参数(如果提供,当前仅记录日志) if business_params: logger.info("收到业务参数(待实现): %s", business_params) # TODO: 等业务需求明确后,实现具体逻辑 # 调用生成图片方法 result = await ai_service.generate_image( user_id=str(user_id), prompt=prompt, model=model_id, project_id=str(conversation.project_id) if conversation.project_id else None, **generate_params ) ``` ##### 视频生成 (Video Generation) ```python elif generation_type == 'video': video_type = ai_params.get('videoType', 'text2video') prompt = message.content # 使用 ParamMapper 转换 AI 参数 from app.utils.param_mapper import ParamMapper generate_params = ParamMapper.convert_video_params(ai_params) # 处理业务参数(如果提供,当前仅记录日志) if business_params: logger.info("收到业务参数(待实现): %s", business_params) # 调用生成视频方法 result = await ai_service.generate_video( user_id=str(user_id), video_type=video_type, prompt=prompt, image_url=image_url, model=model_id, project_id=str(conversation.project_id) if conversation.project_id else None, **generate_params ) ``` --- ### 3. API Router 改动 #### 文件: `server/app/api/v1/ai_conversations.py` ```python @router.post("/{conversation_id}/generate", response_model=SuccessResponse[TriggerAIGenerationResponse], summary="触发 AI 生成") async def trigger_generation( conversation_id: UUID, request: GenerateRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """从对话触发 AI 生成任务 参数分层(RFC 144 扩展): - **modelId**: 模型 ID(顶层字段) - **aiParams**: AI 模型参数(resolution, aspectRatio, seed 等) - **businessParams**: 业务参数(通用字典,可选,字段待业务需求明确) 示例请求 1(仅 AI 参数): ```json { "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", "aiParams": { "resolution": "1024", "aspectRatio": "1:1" } } ``` 示例请求 2(AI + 业务参数): ```json { "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", "aiParams": { "resolution": "1024", "aspectRatio": "1:1" }, "businessParams": { "customField1": "value1" } } ``` """ service = AIConversationService(db) # 将 Pydantic 对象转换为字典 ai_params_dict = request.ai_params.model_dump(by_alias=False, exclude_none=True) business_params_dict = request.business_params # 已经是 Dict 或 None result = await service.trigger_ai_generation( conversation_id=conversation_id, user_id=current_user.user_id, message_id=request.message_id, generation_type=request.generation_type, model_id=request.model_id, ai_params=ai_params_dict, business_params=business_params_dict ) # 返回结果(略) ``` **关键变化**: 1. 使用 `.model_dump()` 将 `aiParams` Pydantic 对象转换为字典 2. `businessParams` 为 `Dict` 或 `None`,直接传递 3. 分别传递 `model_id`, `ai_params`, `business_params` 给 Service --- ## 📊 对比总结 ### 请求格式对比 #### Before (旧格式) ```json { "messageId": "xxx", "generationType": "image", "params": { "modelId": "dall-e-3", // ❌ 混合在一起 "resolution": "1024", // ❌ AI 参数 "aspectRatio": "1:1", // ❌ AI 参数 "saveToProject": true // ❌ 业务参数 } } ``` #### After (新格式) ```json { "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", // ✅ 提升为顶级字段 "aiParams": { // ✅ AI 参数(独立对象) "resolution": "1024", "aspectRatio": "1:1", "outputFormat": "png", "seed": 42 }, "businessParams": { // ✅ 业务参数(通用字典,可选) "customField1": "value1", "customField2": true } } ``` --- ## 🎯 改进效果 ### 1. 职责清晰 - ✅ **AI 参数**:只包含模型相关参数(`resolution`, `seed` 等) - ✅ **业务参数**:只包含业务逻辑参数(`saveToProject`, `autoPublish` 等) - ✅ **modelId**:提升为顶级字段,明确模型选择 ### 2. 易于验证 ```python # AI 参数验证 ai_params = AIGenerationParams(**request.aiParams) # Pydantic 验证 # 业务参数验证(通用字典,由业务逻辑决定) business_params = request.businessParams # Dict[str, Any] 或 None ``` ### 3. 易于扩展 - **新增 AI 参数**:只需修改 `AIGenerationParams` - **新增业务参数**:直接在 `businessParams` 字典中添加字段,无需修改 Schema - **无命名冲突**:两类参数完全隔离 ### 4. 灵活的业务参数 ```python # 业务参数为通用字典(可选) business_params: Optional[Dict[str, Any]] = None # 字段由业务需求决定 { "businessParams": { "saveToProject": true, // 未来可能使用 "autoPublish": false, // 未来可能使用 "customField": "value" // 灵活扩展 } } ``` --- ## 🧪 验证测试 ### 测试场景 #### 1. 纯 AI 参数请求(无业务参数) ```bash curl -X POST http://localhost:8000/api/v1/ai-conversations/{id}/generate \ -H "Authorization: Bearer xxx" \ -H "Content-Type: application/json" \ -d '{ "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", "aiParams": { "resolution": "1024", "aspectRatio": "1:1" } }' ``` **预期结果**: ✅ 仅使用 AI 参数生成图片 #### 2. AI + 业务参数请求 ```bash curl -X POST http://localhost:8000/api/v1/ai-conversations/{id}/generate \ -H "Authorization: Bearer xxx" \ -H "Content-Type: application/json" \ -d '{ "messageId": "xxx", "generationType": "image", "modelId": "dall-e-3", "aiParams": { "resolution": "1024", "aspectRatio": "1:1", "seed": 42 }, "businessParams": { "customField1": "value1", "customField2": true } }' ``` **预期结果**: ✅ 使用 AI 参数生成图片 + 记录业务参数日志(待实现具体逻辑) --- ## 📝 后续工作 ### 优先级 1: 前端适配(高) 前端需要适配新的请求格式: ```typescript // Before const params = { modelId: 'dall-e-3', resolution: '1024', aspectRatio: '1:1', saveToProject: true }; // After const request = { modelId: 'dall-e-3', aiParams: { resolution: '1024', aspectRatio: '1:1' }, businessParams: { // 可选字典,字段自定义 customField1: 'value1' } }; ``` ### 优先级 2: 业务参数逻辑实现(中) 根据业务需求,实现 `businessParams` 的具体功能: ```python if business_params: # 根据业务需求实现具体逻辑 # 示例字段(未来可能使用): # - saveToProject: 保存到项目 # - autoPublish: 自动发布 # - tagIds: 关联标签 logger.info("收到业务参数(待实现): %s", business_params) ``` **建议实现位置**: `ai_conversation_service.py` 的 `trigger_ai_generation` 方法 ### 优先级 3: 参数验证增强(中) 在 Service 层增加参数验证: ```python # 验证 AI 参数是否符合模型 capabilities if not self._validate_ai_params(model_id, ai_params): raise ValidationError("参数不符合模型能力") ``` --- ## 🔗 相关文档 - [RFC 144: AI Models Capability Configuration](../rfcs/144-ai-models-capability-config.md) - [Parameter Mapper Refactor](./2026-02-13-param-mapper-refactor.md) - [API Schema Advanced Params](./2026-02-13-api-schema-advanced-params.md) - [AI Capabilities Adapter Architecture](../guides/ai-capabilities-adapter-architecture.md) --- ## 📌 影响范围 ### 破坏性变更 (Breaking Changes) - ✅ **API 请求格式**: 从单一 `params` 改为 `modelId` + `aiParams` + `businessParams` - ✅ **前端调用**: 需要更新所有对话生成接口调用 ### 建议迁移策略 #### 1. 临时兼容期(可选) 如果需要兼容旧格式,可以在 Service 层增加兼容逻辑: ```python # 兼容旧格式 if 'params' in request_dict: params = request_dict['params'] model_id = params.pop('modelId') ai_params = params business_params = None ``` #### 2. 直接迁移(推荐) 直接要求前端适配新格式,避免维护兼容代码。 --- ## ✅ 验证清单 - [x] Schema 定义(`AIGenerationParams`, `BusinessGenerationParams`, `GenerateRequest`) - [x] Service 层方法签名更新 - [x] Service 层参数处理逻辑更新 - [x] API Router 更新 - [x] Python 语法检查通过 - [x] Docker 服务重启成功 - [ ] 前端适配新格式 - [ ] 业务参数逻辑实现 - [ ] 端到端测试 --- **最新更新**: 2026-02-13 **版本**: v1.0 **状态**: ✅ 已完成(待前端适配)