# 技术债务:通用对话服务抽取计划 > **文档类型**: 技术债务 > **创建日期**: 2025-12-06 > **优先级**: P2(中期优化) > **预计工时**: 2-3天 > **影响模块**: AIA、PKB、Tool C、未来AI知识库模块 --- ## 📋 问题描述 ### 当前现状 **后端对话能力分布**: ``` ✅ 通用能力层(common/) ├── llm/adapters/ ← LLM适配器(完整) │ ├── LLMFactory.ts ← 统一工厂类 │ ├── DeepSeekAdapter.ts │ ├── QwenAdapter.ts │ ├── GPT5Adapter.ts │ └── ClaudeAdapter.ts ├── rag/ ← RAG检索(完整) │ └── DifyClient.ts └── storage/, logging/, cache/ ← 基础设施(完整) ⚠️ 业务层(legacy/) └── services/ └── conversationService.ts ← 对话管理逻辑(625行) ├── 创建对话 ├── 发送消息 ├── 流式输出 ├── 上下文组装 ├── 历史管理 └── 知识库检索集成 ``` **前端组件分布**: ``` ❌ 缺少通用对话组件 各模块重复实现: ├── AIA模块 - 自己实现对话UI ├── PKB模块 - 自己实现对话UI └── Tool C模块 - 自己实现对话UI(Day 3) ``` --- ## 🎯 问题分析 ### 代码重复 | 功能 | 当前状态 | 重复度 | |------|---------|--------| | **LLM调用** | ✅ 已抽取(common/llm) | 0% | | **对话管理** | ⚠️ 未抽取(legacy中) | 80% | | **消息存储** | ⚠️ 各模块独立表 | 60% | | **上下文组装** | ⚠️ 各模块重复实现 | 70% | | **流式输出** | ⚠️ 各模块重复实现 | 80% | | **前端对话UI** | ❌ 完全未抽取 | 90% | ### 影响范围 **现有模块**: - AIA(AI智能问答)- 使用legacy/conversationService - PKB(个人知识库)- 使用legacy/conversationService - Tool C(数据清洗)- Day 3自己实现(~150行重复代码) **未来模块**: - AI知识库模块 - 需要重复实现 - 其他AI对话场景 - 需要重复实现 --- ## 💡 优化方案 ### 方案:抽取通用对话服务 #### 第一阶段:后端服务抽取 **创建通用对话服务**: ```typescript // backend/src/common/conversation/ConversationService.ts export class ConversationService { /** * 通用对话接口 * 支持多种场景:AIA、PKB、Tool C等 */ async chat(config: ChatConfig): Promise { // 1. 构建消息上下文 const messages = await this.buildContext(config); // 2. 调用LLM(复用LLMFactory) const llm = LLMFactory.createAdapter(config.modelType); const response = await llm.chat(messages, config.options); // 3. 保存消息(根据配置决定存储位置) await this.saveMessage(config.conversationId, config.userMessage, response); return response; } /** * 流式对话 */ async streamChat(config: ChatConfig): AsyncGenerator { const messages = await this.buildContext(config); const llm = LLMFactory.createAdapter(config.modelType); for await (const chunk of llm.chatStream(messages, config.options)) { yield chunk; } // 保存完整响应 await this.saveMessage(...); } /** * 获取对话历史 * 支持多种存储方式(统一接口,不同表) */ async getHistory(conversationId: string, options?: HistoryOptions) { // 根据conversationType路由到不同的表 const adapter = this.getStorageAdapter(options.conversationType); return await adapter.getHistory(conversationId, options); } /** * 保存消息 * 支持多种存储方式 */ async saveMessage(conversationId: string, userMsg: string, aiResponse: any) { const adapter = this.getStorageAdapter(this.config.conversationType); await adapter.saveMessage(conversationId, userMsg, aiResponse); } /** * 构建上下文 * 支持:System Prompt + 历史消息 + 当前消息 + RAG检索 */ private async buildContext(config: ChatConfig): Promise { const messages: Message[] = []; // 1. System Prompt if (config.systemPrompt) { messages.push({ role: 'system', content: config.systemPrompt }); } // 2. 历史消息 if (config.includeHistory) { const history = await this.getHistory(config.conversationId, { limit: config.historyLimit || 5 }); messages.push(...history); } // 3. RAG检索(如果需要) if (config.knowledgeBaseIds?.length > 0) { const ragContext = await this.retrieveRAGContext( config.userMessage, config.knowledgeBaseIds ); messages.push({ role: 'system', content: ragContext }); } // 4. 当前用户消息 messages.push({ role: 'user', content: config.userMessage }); return messages; } } // 配置接口 interface ChatConfig { conversationId: string; conversationType: 'aia' | 'pkb' | 'tool-c' | 'knowledge-base'; // 路由到不同表 modelType: ModelType; userMessage: string; systemPrompt?: string; includeHistory?: boolean; historyLimit?: number; knowledgeBaseIds?: string[]; options?: { temperature?: number; maxTokens?: number; topP?: number; }; } ``` **存储适配器**(支持不同模块的不同表): ```typescript // backend/src/common/conversation/adapters/StorageAdapter.ts interface ConversationStorageAdapter { getHistory(conversationId: string, options?: HistoryOptions): Promise; saveMessage(conversationId: string, userMsg: string, aiResponse: any): Promise; } // AIA/PKB使用通用表 class GeneralStorageAdapter implements ConversationStorageAdapter { async getHistory(conversationId: string) { return await prisma.generalMessage.findMany({ where: { conversationId }, orderBy: { createdAt: 'desc' }, take: options.limit }); } } // Tool C使用独立表 class ToolCStorageAdapter implements ConversationStorageAdapter { async getHistory(conversationId: string) { return await prisma.dcToolCAiHistory.findMany({ where: { sessionId: conversationId }, orderBy: { createdAt: 'desc' }, take: options.limit }); } } ``` --- #### 第二阶段:前端组件抽取 **创建通用对话组件库**: ```tsx // frontend-v2/src/shared/components/Chat/ ├── ChatContainer.tsx // 对话容器(布局) ├── MessageList.tsx // 消息列表(虚拟滚动) ├── MessageItem.tsx // 单条消息(用户/AI) ├── MessageInput.tsx // 输入框(支持多行、快捷键) ├── StreamingMessage.tsx // 流式渲染(打字机效果) ├── CitationBadge.tsx // 引用标记 ├── LoadingIndicator.tsx // 加载动画 └── index.ts // 使用示例 import { ChatContainer } from '@/shared/components/Chat'; ``` **组件特性**: - ✅ 支持流式/非流式渲染 - ✅ 支持引用跳转 - ✅ 支持历史消息加载 - ✅ 支持Markdown渲染 - ✅ 支持代码高亮 - ✅ 响应式布局 --- ## 📊 改造前后对比 ### 代码量对比 | 模块 | 改造前 | 改造后 | 减少 | |------|--------|--------|------| | **后端** | | AIA对话逻辑 | 200行 | 50行(调用通用服务) | -75% | | PKB对话逻辑 | 180行 | 50行 | -72% | | Tool C对话逻辑 | 150行 | 50行 | -67% | | 通用服务 | 0行 | 300行(新建) | +300行 | | **总计** | 530行 | 450行 | **-15%** | | **前端** | | 各模块对话UI | 600行×3 | 200行×3(调用通用组件) | -67% | | 通用组件 | 0行 | 500行(新建) | +500行 | | **总计** | 1800行 | 1100行 | **-39%** | | **全部合计** | 2330行 | 1550行 | **-33%** | ### 质量提升 | 指标 | 改造前 | 改造后 | 提升 | |------|--------|--------|------| | 代码复用率 | 20% | 80% | +300% | | 统一交互体验 | ❌ | ✅ | 100% | | 未来扩展成本 | 高(每次重复) | 低(直接复用) | -80% | | 维护成本 | 高(多处修改) | 低(单点修改) | -70% | --- ## 🚀 实施计划 ### 阶段1:后端服务抽取(1.5天) **Day 1上午:设计** - [ ] 设计ConversationService接口 - [ ] 设计StorageAdapter接口 - [ ] 设计ChatConfig配置结构 **Day 1下午:实现核心服务** - [ ] 实现ConversationService核心逻辑 - [ ] 实现GeneralStorageAdapter - [ ] 实现ToolCStorageAdapter **Day 2上午:迁移现有模块** - [ ] AIA模块改造(使用通用服务) - [ ] PKB模块改造(使用通用服务) - [ ] Tool C模块改造(使用通用服务) **Day 2下午:测试** - [ ] 单元测试 - [ ] 集成测试 - [ ] 回归测试(确保原功能正常) --- ### 阶段2:前端组件抽取(1天) **Day 3上午:设计与实现** - [ ] 设计ChatContainer API - [ ] 实现核心组件(6个) - [ ] 样式统一 **Day 3下午:迁移与测试** - [ ] AIA模块前端改造 - [ ] PKB模块前端改造 - [ ] Tool C模块前端改造 - [ ] UI测试 --- ### 阶段3:文档与培训(0.5天) - [ ] 编写使用文档 - [ ] 编写最佳实践 - [ ] 团队培训 --- ## 📝 验收标准 ### 功能验收 - [ ] AIA模块对话功能正常 - [ ] PKB模块对话功能正常 - [ ] Tool C模块对话功能正常 - [ ] 流式输出正常 - [ ] 历史消息加载正常 - [ ] RAG检索集成正常 ### 代码质量 - [ ] 代码复用率≥80% - [ ] 单元测试覆盖率≥80% - [ ] 无TypeScript错误 - [ ] 无ESLint警告 ### 用户体验 - [ ] 对话交互流畅(响应<2秒) - [ ] 流式输出流畅(无卡顿) - [ ] UI统一美观 - [ ] 移动端适配良好 --- ## 💰 收益分析 ### 短期收益(1个月内) 1. **代码质量提升** - 减少重复代码33% - 提升代码复用率至80% - 降低维护成本70% 2. **开发效率提升** - 新模块对话功能开发时间:从2天→0.5天(-75%) - Bug修复效率:单点修改,影响全局(+200%) 3. **用户体验统一** - 统一交互模式 - 统一视觉风格 - 统一性能标准 ### 长期收益(3-6个月) 1. **支持未来模块** - AI知识库模块:直接复用,0额外开发 - 其他AI对话场景:快速实现 2. **技术架构优化** - 真正实现分层架构(业务层→通用层) - 为微服务拆分做准备 3. **商业价值** - 模块独立部署更容易 - 模块独立售卖更灵活 - 客户定制成本降低 --- ## ⚠️ 风险与应对 ### 风险1:回归测试工作量大 **应对**: - 优先实现自动化测试 - 分模块逐步迁移 - 保留原代码作为备份 ### 风险2:历史数据迁移 **应对**: - 不需要迁移数据 - 只迁移代码逻辑 - 各模块保留独立表 ### 风险3:前端组件复杂度 **应对**: - 采用渐进式重构 - 先抽取核心组件 - 后续迭代优化 --- ## 📅 建议执行时间 **推荐时间窗口**: - **选项1**:Tool C MVP完成后(Day 10-13) - **选项2**:所有DC模块完成后(Week 8-9) - **选项3**:AI知识库模块启动前(Quarter 2) **当前决策**:延后至Tool C MVP完成后 --- ## 🔗 相关文档 - [系统架构分层设计](../../00-系统总体设计/01-系统架构分层设计.md) - [云原生开发规范](../../04-开发规范/08-云原生开发规范.md) - [Tool C Day 3开发计划](../../03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day3开发计划.md) --- ## 📝 更新记录 | 日期 | 版本 | 更新内容 | 更新人 | |------|------|---------|--------| | 2025-12-06 | V1.0 | 初始创建 | AI Assistant | --- **文档状态**: ✅ 已创建 **优先级**: P2(中期优化) **下一步**: 完成Tool C Day 3 MVP后重新评估