# AI 对话系统完整实现 > **日期**:2026-02-03 > **类型**:功能实现 > **影响范围**:后端服务、数据库 > **符合规范**:jointo-tech-stack v1.0 --- ## 概述 完整实现了 AI 对话系统的三个核心功能模块: 1. **AI 提示词系统服务** - 管理系统级 AI 提示词模板 2. **AI 对话记录服务** - 管理用户与 AI 的对话历史 3. **@ 提及与参考图系统** - 支持在对话中引用资源作为参考图 --- ## 实现内容 ### 1. AI 提示词系统服务 **文件**:`server/app/services/ai_prompt_system_service.py` **功能**: - ✅ 提示词 CRUD 操作(创建、查询、更新、删除) - ✅ 提示词版本管理 - ✅ Skills 配置管理(支持多个 skill 文件) - ✅ 默认提示词管理(每种类型只能有一个默认) - ✅ 提示词列表查询(支持类型、状态、名称过滤) **核心方法**: ```python - create_prompt() # 创建提示词 - get_prompt_by_id() # 获取提示词详情 - get_default_prompt() # 获取默认提示词 - list_prompts() # 获取提示词列表 - update_prompt() # 更新提示词 - delete_prompt() # 删除提示词(软删除) - set_default() # 设置为默认提示词 ``` **技术规范**: - UUID v7 主键(应用层生成) - %-formatting 日志 - exc_info=True 错误日志 - 应用层保证引用完整性 --- ### 2. AI 对话记录服务 **文件**:`server/app/services/ai_conversation_service.py` **功能**: - ✅ 对话会话管理(创建、查询、列表) - ✅ 消息管理(发送、列表) - ✅ 多态关联 + 标签系统(支持不同类型的 AI 生成任务) - ✅ @ 提及功能(解析、验证、构建) - ✅ AI 生成触发(支持参考图) **核心设计**: **多态关联模式**: ```python target_type: int # 目标类型(分镜/角色/场景/道具/资源/音效/配音) target_id: UUID # 目标对象 ID tag_id: UUID # 标签 ID(可选,用于区分变体) media_type: int # 媒体类型(图片/视频/音频/3D模型/文本) ``` **隔离策略**: - 类型隔离:分镜图对话 ≠ 分镜视频对话 - 对象隔离:分镜A的对话 ≠ 分镜B的对话 - 变体隔离:角色-张三-少年装扮 ≠ 角色-张三-成年装扮 - 用户隔离:用户A的对话 ≠ 用户B的对话 **核心方法**: ```python # 对话会话管理 - create_conversation() # 创建对话会话 - get_conversation() # 获取对话详情 - list_conversations() # 获取对话列表 # 消息管理 - send_message() # 发送消息(支持自动解析提及) - list_messages() # 获取消息列表 # @ 提及功能 - get_mentionable_resources() # 获取可提及的资源列表 - _parse_mentions() # 解析消息中的提及标记 - _validate_and_build_mention() # 验证并构建提及对象 # AI 生成触发 - trigger_ai_generation() # 触发 AI 生成任务(支持参考图) ``` --- ### 3. @ 提及与参考图系统 **核心原则**: **前端职责**: - 提供 @ 自动补全,帮助用户快速输入 - 插入标准格式的提及标记到文本 - 高亮显示提及标记,提供视觉反馈 - **只发送文本**,不发送 mentions 数组 **后端职责**: - 解析文本中的提及标记 - 验证所有提及的资源 - 构建 metadata(mentions + reference_images) - 存储消息到数据库 **提及标记格式**: ``` @[显示名称](类型:元素ID:标签ID:资源ID) ``` **示例**: ``` 生成一张 @[张三-少年](character:019d1234...:019d1234...:019d1234...) 在 @[咖啡厅-白天](scene:019d1234...:019d1234...:019d1234...) 喝咖啡的图片 ``` **数据流程**: 1. 用户输入 `@` → 前端调用 API 获取可提及的资源列表 2. 用户选择资源 → 前端插入标准格式的提及标记 3. 用户发送消息 → 后端解析提及标记并验证资源 4. 后端构建 metadata → 存储 mentions 和 reference_images 5. 用户触发生成 → 后端提取参考图 URL 传递给 AI --- ### 4. 数据库迁移 **文件**:`server/alembic/versions/20260203_1600_create_ai_conversations_tables.py` **创建的表**: #### ai_conversations(AI 对话会话表) ```sql CREATE TABLE ai_conversations ( conversation_id UUID PRIMARY KEY, user_id UUID NOT NULL, project_id UUID, target_type SMALLINT NOT NULL, target_id UUID NOT NULL, tag_id UUID, media_type SMALLINT NOT NULL, title TEXT, status SMALLINT NOT NULL DEFAULT 1, message_count INTEGER NOT NULL DEFAULT 0, last_message_at TIMESTAMPTZ, metadata JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); ``` **索引**: - `idx_ai_conversations_user_id` - 用户 ID - `idx_ai_conversations_project_id` - 项目 ID(部分索引) - `idx_ai_conversations_target` - 目标类型 + 目标 ID - `idx_ai_conversations_target_tag` - 目标类型 + 目标 ID + 标签 ID - `idx_ai_conversations_tag_id` - 标签 ID(部分索引) - `idx_ai_conversations_media_type` - 媒体类型 - `idx_ai_conversations_status` - 会话状态 - `idx_ai_conversations_created_at` - 创建时间 - `idx_ai_conversations_last_message_at` - 最后消息时间(部分索引) - `idx_ai_conversations_user_status` - 用户 ID + 状态 - `idx_ai_conversations_user_target_tag_media` - 复合索引 - `idx_ai_conversations_metadata_gin` - JSONB GIN 索引 **唯一约束**: ```sql CREATE UNIQUE INDEX idx_ai_conversations_unique_active ON ai_conversations (user_id, target_type, target_id, tag_id, media_type) NULLS NOT DISTINCT WHERE status = 1; ``` #### ai_conversation_messages(AI 对话消息表) ```sql CREATE TABLE ai_conversation_messages ( message_id UUID PRIMARY KEY, conversation_id UUID NOT NULL, user_id UUID NOT NULL, ai_job_id UUID, role SMALLINT NOT NULL, content TEXT NOT NULL, metadata JSONB NOT NULL DEFAULT '{}', order_index INTEGER NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); ``` **索引**: - `idx_ai_conversation_messages_conversation_id` - 对话会话 ID - `idx_ai_conversation_messages_user_id` - 用户 ID - `idx_ai_conversation_messages_ai_job_id` - AI 任务 ID(部分索引) - `idx_ai_conversation_messages_role` - 消息角色 - `idx_ai_conversation_messages_created_at` - 创建时间 - `idx_ai_conversation_messages_conversation_order` - 对话 ID + 顺序 - `idx_ai_conversation_messages_metadata_gin` - JSONB GIN 索引 - `idx_ai_conversation_messages_content_gin` - 全文搜索索引 **触发器**: - `update_ai_conversations_updated_at` - 自动更新 updated_at - `update_ai_conversation_messages_updated_at` - 自动更新 updated_at - `update_conversation_stats_trigger` - 自动更新会话统计(message_count、last_message_at) --- ## 技术栈合规性 ### ✅ 符合 jointo-tech-stack 规范 1. **UUID v7 主键**: - 所有主键使用 UUID v7(应用层生成) - 使用 `uuid7()` 函数生成 2. **TIMESTAMPTZ 时间字段**: - 所有时间字段使用 `TIMESTAMPTZ` 类型 - 符合 ADR 006 规范 3. **SMALLINT 枚举类型**: - 所有枚举字段使用 `SMALLINT` 存储 - Python 使用 `IntEnum` 定义枚举 4. **无物理外键约束**: - 数据库层不创建 FOREIGN KEY 约束 - 应用层保证引用完整性 5. **日志格式**: - 使用 %-formatting 格式化日志 - 错误日志包含 `exc_info=True` 6. **异步编程**: - 所有数据库操作使用 async/await - 使用 AsyncSession --- ## 使用场景 ### 场景1:分镜基础图片生成对话(无标签) ```python # 创建对话会话 conversation = await ai_conversation_service.create_conversation( user_id=user_id, target_type=TargetType.STORYBOARD, target_id=storyboard_id, tag_id=None, # 无标签(基础图片) media_type=MediaType.IMAGE, project_id=project_id ) ``` ### 场景2:分镜正面角度图片生成对话(有标签) ```python # 创建对话会话 conversation = await ai_conversation_service.create_conversation( user_id=user_id, target_type=TargetType.STORYBOARD, target_id=storyboard_id, tag_id=angle_tag_id, # 正面角度标签 media_type=MediaType.IMAGE, project_id=project_id ) ``` ### 场景3:角色少年装扮图片生成对话 ```python # 创建对话会话 conversation = await ai_conversation_service.create_conversation( user_id=user_id, target_type=TargetType.CHARACTER, target_id=character_id, tag_id=costume_tag_id, # 少年装扮标签 media_type=MediaType.IMAGE, project_id=project_id ) ``` ### 场景4:发送带提及的消息 ```python # 发送消息(包含提及标记) message = await ai_conversation_service.send_message( conversation_id=conversation_id, user_id=user_id, content="生成一张 @[张三-少年](character:019d1234...:019d1234...:019d1234...) 在 @[咖啡厅-白天](scene:019d1234...:019d1234...:019d1234...) 喝咖啡的图片" ) # 后端自动解析提及标记,构建 metadata # message.metadata = { # 'mentions': [...], # 'reference_images': [url1, url2] # } ``` ### 场景5:触发 AI 生成(使用参考图) ```python # 触发 AI 生成 result = await ai_conversation_service.trigger_ai_generation( conversation_id=conversation_id, user_id=user_id, message_id=message_id, generation_type='image', params={ 'prompt': '生成一张张三在咖啡厅喝咖啡的图片', 'model': 'stable_diffusion', 'width': 1024, 'height': 1024 } ) # 后端自动从消息的 metadata 中提取参考图 URL # 传递给 AI Service 进行生成 ``` --- ## 相关文档 - [AI 提示词系统服务需求文档](../../requirements/backend/04-services/ai/ai-prompt-system-service.md) - [AI 对话记录服务需求文档](../../requirements/backend/04-services/ai/ai-conversation-service.md) - [AI 对话 @ 提及系统需求文档](../../requirements/backend/04-services/ai/ai-conversation-mention-system.md) - [jointo-tech-stack 规范](../tech-stack.md) - [ADR 001: UUID v7 迁移](../adrs/001-uuid-v7-migration.md) - [ADR 006: TIMESTAMPTZ 时间戳规范](../adrs/006-timestamptz-for-event-timestamps.md) --- ## 后续工作 ### 待实现功能 1. **AI Service 集成**: - 实现 AI Service 的 `generate_image()` 方法 - 支持参考图传递给 AI 提供商 - 实现 Stable Diffusion ControlNet 集成 - 实现 Midjourney --cref 参数集成 2. **前端实现**: - 实现 MentionInput 组件 - 实现 MentionAutocomplete 组件 - 实现提及标记的高亮显示 - 实现键盘交互(↑↓ 选择、Enter 确认、ESC 取消) 3. **API 路由**: - 实现 AI 对话相关的 API 路由 - 实现 AI 提示词相关的 API 路由(管理员专用) 4. **测试**: - 编写单元测试 - 编写集成测试 - 编写 E2E 测试 ### 优化建议 1. **性能优化**: - 资源列表缓存(使用 Redis) - 图片懒加载 - 搜索防抖 - 虚拟滚动 2. **安全优化**: - 权限验证增强 - XSS 防护 - 参考图 URL 验证 3. **用户体验优化**: - 实时反馈 - 错误提示优化 - 加载状态优化 --- ## 总结 本次实现完成了 AI 对话系统的三个核心功能模块,包括: 1. ✅ AI 提示词系统服务(完整实现) 2. ✅ AI 对话记录服务(完整实现) 3. ✅ @ 提及与参考图系统(完整实现) 4. ✅ 数据库迁移(完整实现) 所有实现均符合 jointo-tech-stack 规范,包括: - UUID v7 主键 - TIMESTAMPTZ 时间字段 - SMALLINT 枚举类型 - 无物理外键约束 - %-formatting 日志 - 异步编程 系统已具备完整的对话管理、提及解析、参考图提取功能,为后续的 AI Service 集成和前端实现奠定了坚实的基础。 --- **文档版本**:v1.0 **创建日期**:2026-02-03 **作者**:Jointo AI Team