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.
6.7 KiB
6.7 KiB
修复 AI 任务 output_data 存储 Base64 数据问题
日期: 2026-02-14
类型: Bug Fix
影响范围: AI 图片生成任务
严重程度: Medium (数据库膨胀、查询性能)
问题描述
背景
在图片生成任务 (generate_image_task) 中,当 AI Provider 返回 Base64 格式的图片数据时,系统会:
- 解码 Base64 数据为二进制
- 上传到 MinIO 获取永久 URL
- 更新任务的
output_data字段
问题
在第 3 步时,原始的 b64_json 字段没有被移除,导致:
- 1024x1024 PNG 图片的 Base64 约 1-2 MB
- 频繁生成图片会导致数据库快速膨胀
- 查询
ai_jobs表时加载大量无用数据 - 影响 API 响应性能
受影响的 Provider
- OpenAI (DALL-E): 默认返回 Base64
- Gemini (Imagen): 返回 Base64
- 其他使用 Base64 响应格式的 Provider
对比
视频/音频生成任务已正确处理此问题:
result.pop('audio_data', None) # ✅ 显式移除二进制数据
result.update(file_metadata)
修复方案
代码变更
文件: server/app/tasks/ai_tasks.py
修改前 (第 471-494 行):
if result.get('b64_json'):
file_data = base64.b64decode(result['b64_json'])
file_metadata = await _upload_file_from_bytes(...)
# ❌ 仅更新 result,未移除 b64_json
result.update(file_metadata)
elif result.get('url'):
file_metadata = await _download_and_upload_file(...)
# ❌ 仅更新 result,未移除 url
result.update(file_metadata)
修改后:
if result.get('b64_json'):
file_data = base64.b64decode(result['b64_json'])
file_metadata = await _upload_file_from_bytes(...)
# ✅ 移除 Base64 数据(避免存入数据库)
result.pop('b64_json', None)
result.pop('url', None)
result.update(file_metadata)
elif result.get('url'):
file_metadata = await _download_and_upload_file(...)
# ✅ 移除临时 URL(避免存入数据库)
result.pop('url', None)
result.pop('b64_json', None)
result.update(file_metadata)
修复后的 output_data 结构
{
"file_url": "http://minio:9000/jointo/ai-generated/images/...",
"file_size": 245678,
"checksum": "sha256:abc123...",
"mime_type": "image/png",
"storage_provider": "minio",
"storage_path": "ai-generated/images/image_xxx.png",
"metadata": {
"model": "dall-e-3",
"size": "1024x1024",
"quality": "standard",
"style": "vivid",
"revised_prompt": "..."
}
}
移除的字段:
- ❌
b64_json: Base64 编码的图片数据 (1-2 MB) - ❌
url: AI Provider 的临时 URL (已过期)
保留的字段:
- ✅
file_url: MinIO 永久 URL - ✅
metadata: 模型元数据 (< 1 KB)
影响评估
数据库影响
修复前:
- 单个图片任务
output_data: 1-2 MB - 100 个图片任务: 100-200 MB
修复后:
- 单个图片任务
output_data: < 10 KB - 100 个图片任务: < 1 MB
节省空间: 约 99% (200MB → 1MB)
API 性能影响
- 查询
ai_jobs表时数据传输量减少 99% - 前端轮询任务状态的响应速度提升
- 数据库 JSONB 索引效率提升
历史数据
- 已存储的历史任务不受影响
- 可选:运行清理脚本移除历史数据中的 Base64 字段
验证方法
1. 测试图片生成
# 生成测试图片
curl -X POST http://localhost:8000/api/v1/ai/jobs/generate-image \
-H "Authorization: Bearer $TOKEN" \
-d '{
"prompt": "A beautiful sunset",
"model": "dall-e-3",
"width": 1024,
"height": 1024
}'
# 查询任务结果
curl http://localhost:8000/api/v1/ai/jobs/{job_id}
2. 验证 output_data 大小
-- 查询最新图片任务的 output_data 大小
SELECT
ai_job_id,
created_at,
pg_column_size(output_data) as size_bytes,
pg_column_size(output_data) / 1024 as size_kb,
jsonb_object_keys(output_data) as keys
FROM ai_jobs
WHERE job_type = 1 -- IMAGE
AND status = 3 -- COMPLETED
ORDER BY created_at DESC
LIMIT 5;
预期结果: size_kb 应 < 10 KB
3. 验证字段不存在
-- 确认 output_data 中不包含 b64_json 或临时 url
SELECT
ai_job_id,
output_data ? 'b64_json' as has_base64,
output_data ? 'file_url' as has_file_url,
output_data->'metadata'->>'model' as model
FROM ai_jobs
WHERE job_type = 1 AND status = 3
ORDER BY created_at DESC
LIMIT 5;
预期结果: has_base64 应为 false
清理历史数据(可选)
如需清理历史数据中的 Base64 字段:
-- 1. 查看需要清理的任务数量
SELECT
COUNT(*) as count,
SUM(pg_column_size(output_data)) / 1024 / 1024 as total_mb
FROM ai_jobs
WHERE job_type = 1
AND output_data ? 'b64_json';
-- 2. 清理 Base64 字段(谨慎操作,建议先备份)
UPDATE ai_jobs
SET output_data = output_data - 'b64_json' - 'url'
WHERE job_type = 1
AND output_data ? 'b64_json';
-- 3. 验证清理结果
SELECT
COUNT(*) as remaining_count
FROM ai_jobs
WHERE job_type = 1
AND output_data ? 'b64_json';
-- 应返回 0
回滚方案
如需回滚此修复:
cd server
git revert <commit_hash>
注意: 回滚后新生成的图片任务会再次存储 Base64 数据。
相关问题
其他任务类型状态
- ✅ 视频生成: 已正确移除
video_data - ✅ 音频生成: 已正确移除
audio_data - ✅ 配音生成: 已正确移除
audio_data - ✅ 批量对话配音: 无大字段问题
- ⚠️ 剧本解析:
parsed_data可能包含大量文本 (待优化)
剧本解析优化建议
剧本解析任务的 output_data.parsed_data 可能包含:
- 完整剧本内容
- 角色/场景/道具描述
- 分镜详情和对白
建议:
- 仅保存摘要统计(角色数、场景数、分镜数)
- 详细数据已存入业务表,无需重复存储
- 或标记为大字段,允许 API 选择性加载
测试清单
- 修复代码并通过 Linter 检查
- 测试 OpenAI DALL-E 图片生成
- 测试 Gemini Imagen 图片生成
- 验证 output_data 大小 < 10 KB
- 验证不包含 b64_json 字段
- 查询历史数据统计
- (可选) 执行历史数据清理
参考文档
- AI 任务模型:
server/app/models/ai_job.py - AI 任务处理:
server/app/tasks/ai_tasks.py - OpenAI Adapter:
server/app/services/ai_providers/sdk_adapters/openai_sdk_adapter.py - Gemini Adapter:
server/app/services/ai_providers/sdk_adapters/gemini_sdk_adapter.py
总结
此修复解决了图片生成任务中 Base64 数据存入数据库的问题,预期可:
- 节省数据库空间 99%
- 提升查询性能
- 优化 API 响应速度
- 与视频/音频任务保持一致的处理逻辑
修复已生效,新生成的图片任务将不再存储 Base64 数据。