Summary: - Implement PKB Dashboard and Workspace pages based on V3 prototype - Add single-layer header with integrated Tab navigation - Implement 3 work modes: Full Text, Deep Read, Batch Processing - Integrate Ant Design X Chat component for AI conversations - Create BatchModeComplete with template selection and document processing - Add compact work mode selector with dropdown design Backend: - Migrate PKB controllers and services to /modules/pkb structure - Register v2 API routes at /api/v2/pkb/knowledge - Maintain dual API routes for backward compatibility Technical details: - Use Zustand for state management - Handle SSE streaming responses for AI chat - Support document selection for Deep Read mode - Implement batch processing with progress tracking Known issues: - Batch processing API integration pending - Knowledge assets page navigation needs optimization Status: Frontend functional, pending refinement
493 lines
12 KiB
Markdown
493 lines
12 KiB
Markdown
# 技术债务:通用对话服务抽取计划
|
||
|
||
> **文档类型**: 技术债务
|
||
> **创建日期**: 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<ChatResponse> {
|
||
// 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<StreamChunk> {
|
||
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<Message[]> {
|
||
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<Message[]>;
|
||
saveMessage(conversationId: string, userMsg: string, aiResponse: any): Promise<void>;
|
||
}
|
||
|
||
// 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';
|
||
|
||
<ChatContainer
|
||
conversationId={sessionId}
|
||
conversationType="tool-c"
|
||
systemPrompt={buildSystemPrompt()}
|
||
onSendMessage={handleSendMessage}
|
||
enableHistory={true}
|
||
enableRAG={false}
|
||
/>
|
||
```
|
||
|
||
**组件特性**:
|
||
- ✅ 支持流式/非流式渲染
|
||
- ✅ 支持引用跳转
|
||
- ✅ 支持历史消息加载
|
||
- ✅ 支持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后重新评估
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|