You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
15 KiB
15 KiB
Changelog: AI 对话生成参数分离
日期: 2026-02-13
版本: v1.0
类型: 架构优化 (架构改进)
影响范围: ai_conversations API + Service
📋 概述
将对话 AI 生成接口 /{conversation_id}/generate 的参数从单一 params 字典拆分为:
aiParams: AI 模型参数(独立对象)businessParams: 业务参数(独立对象,可选)
这使得参数职责更清晰,易于验证和扩展。
🎯 改动目标
问题背景
原有的 params 字段混合了两类参数:
{
"params": {
"modelId": "dall-e-3",
"resolution": "1024", // AI 参数
"aspectRatio": "1:1", // AI 参数
"outputFormat": "png", // AI 参数
"saveToProject": true, // 业务参数
"autoPublish": false // 业务参数
}
}
问题:
- ❌ 职责不清:AI 参数和业务参数混在一起
- ❌ 扩展困难:新增业务参数可能与 AI 参数命名冲突
- ❌ 验证复杂:无法分别验证 AI 参数和业务参数
改进方案
采用嵌套结构,将参数分为三层:
{
"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
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
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]](通用字典)- 不预先定义具体字段,由业务需求决定
- 当前仅记录日志,后续根据需求实现具体功能
示例字段(未来可能使用):
{
"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 方法签名
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)
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)
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
@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
)
# 返回结果(略)
关键变化:
- 使用
.model_dump()将aiParamsPydantic 对象转换为字典 businessParams为Dict或None,直接传递- 分别传递
model_id,ai_params,business_params给 Service
📊 对比总结
请求格式对比
Before (旧格式)
{
"messageId": "xxx",
"generationType": "image",
"params": {
"modelId": "dall-e-3", // ❌ 混合在一起
"resolution": "1024", // ❌ AI 参数
"aspectRatio": "1:1", // ❌ AI 参数
"saveToProject": true // ❌ 业务参数
}
}
After (新格式)
{
"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. 易于验证
# AI 参数验证
ai_params = AIGenerationParams(**request.aiParams) # Pydantic 验证
# 业务参数验证(通用字典,由业务逻辑决定)
business_params = request.businessParams # Dict[str, Any] 或 None
3. 易于扩展
- 新增 AI 参数:只需修改
AIGenerationParams - 新增业务参数:直接在
businessParams字典中添加字段,无需修改 Schema - 无命名冲突:两类参数完全隔离
4. 灵活的业务参数
# 业务参数为通用字典(可选)
business_params: Optional[Dict[str, Any]] = None
# 字段由业务需求决定
{
"businessParams": {
"saveToProject": true, // 未来可能使用
"autoPublish": false, // 未来可能使用
"customField": "value" // 灵活扩展
}
}
🧪 验证测试
测试场景
1. 纯 AI 参数请求(无业务参数)
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 + 业务参数请求
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: 前端适配(高)
前端需要适配新的请求格式:
// 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 的具体功能:
if business_params:
# 根据业务需求实现具体逻辑
# 示例字段(未来可能使用):
# - saveToProject: 保存到项目
# - autoPublish: 自动发布
# - tagIds: 关联标签
logger.info("收到业务参数(待实现): %s", business_params)
建议实现位置: ai_conversation_service.py 的 trigger_ai_generation 方法
优先级 3: 参数验证增强(中)
在 Service 层增加参数验证:
# 验证 AI 参数是否符合模型 capabilities
if not self._validate_ai_params(model_id, ai_params):
raise ValidationError("参数不符合模型能力")
🔗 相关文档
- RFC 144: AI Models Capability Configuration
- Parameter Mapper Refactor
- API Schema Advanced Params
- AI Capabilities Adapter Architecture
📌 影响范围
破坏性变更 (Breaking Changes)
- ✅ API 请求格式: 从单一
params改为modelId+aiParams+businessParams - ✅ 前端调用: 需要更新所有对话生成接口调用
建议迁移策略
1. 临时兼容期(可选)
如果需要兼容旧格式,可以在 Service 层增加兼容逻辑:
# 兼容旧格式
if 'params' in request_dict:
params = request_dict['params']
model_id = params.pop('modelId')
ai_params = params
business_params = None
2. 直接迁移(推荐)
直接要求前端适配新格式,避免维护兼容代码。
✅ 验证清单
- Schema 定义(
AIGenerationParams,BusinessGenerationParams,GenerateRequest) - Service 层方法签名更新
- Service 层参数处理逻辑更新
- API Router 更新
- Python 语法检查通过
- Docker 服务重启成功
- 前端适配新格式
- 业务参数逻辑实现
- 端到端测试
最新更新: 2026-02-13
版本: v1.0
状态: ✅ 已完成(待前端适配)