Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/02-技术设计/IIT Manager Agent 技术路径与架构设计.md
HaHafeng 2481b786d8 deploy: Complete 0126-27 deployment - database upgrade, services update, code recovery
Major Changes:
- Database: Install pg_bigm/pgvector plugins, create test database
- Python service: v1.0 -> v1.1, add pymupdf4llm/openpyxl/pypandoc
- Node.js backend: v1.3 -> v1.7, fix pino-pretty and ES Module imports
- Frontend: v1.2 -> v1.3, skip TypeScript check for deployment
- Code recovery: Restore empty files from local backup

Technical Fixes:
- Fix pino-pretty error in production (conditional loading)
- Fix ES Module import paths (add .js extensions)
- Fix OSSAdapter TypeScript errors
- Update Prisma Schema (63 models, 16 schemas)
- Update environment variables (DATABASE_URL, EXTRACTION_SERVICE_URL, OSS)
- Remove deprecated variables (REDIS_URL, DIFY_API_URL, DIFY_API_KEY)

Documentation:
- Create 0126 deployment folder with 8 documents
- Update database development standards v2.0
- Update SAE deployment status records

Deployment Status:
- PostgreSQL: ai_clinical_research_test with plugins
- Python: v1.1 @ 172.17.173.84:8000
- Backend: v1.7 @ 172.17.173.89:3001
- Frontend: v1.3 @ 172.17.173.90:80

Tested: All services running successfully on SAE
2026-01-27 08:13:27 +08:00

713 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IIT Manager Agent 技术路径与架构设计
**文档版本**: v1.0
**最后更新**: 2026-01-04
**状态**: ✅ Phase 1.5 完成并验证
---
## 📋 文档概述
本文档详细描述了IIT Manager Agent的技术路径、核心架构和实现方案。系统采用**"意图识别 → 工具调用 → 混合检索 → LLM生成"**的技术路径实现了零幻觉、高准确率的AI对话能力。
---
## 🎯 技术路径总结
### 核心技术路径
```
用户提问
→ 意图识别Intent Detection
→ 工具调用Tool Calling
→ 混合检索Hybrid Retrieval
→ LLM生成LLM Generation
→ 回答用户
```
这是一个**简化版ReAct架构**Reason + Act也可以称为**"意图驱动的混合RAG系统"**。
### 技术架构类型
- **架构模式**: 简化版ReActReason + Act
- **检索模式**: 混合RAG结构化数据 + 非结构化文档)
- **意图识别**: 关键词匹配MVP阶段
- **上下文管理**: SessionMemory内存缓存
- **防幻觉机制**: RAG数据注入 + 严格System Prompt
---
## 📐 完整技术架构图
```
┌─────────────────────────────────────────────────────────────────┐
│ 用户层User Layer
├─────────────────────────────────────────────────────────────────┤
│ 企业微信WeChat
│ - PI通过企业微信发送消息 │
│ - 接收AI回复含"正在查询..."即时反馈) │
└────────────────────────┬────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 接入层Gateway Layer
├─────────────────────────────────────────────────────────────────┤
│ WechatCallbackController │
│ - URL验证签名校验
│ - 消息加密/解密AES
│ - 异步消息处理5秒内返回200
│ - 即时反馈:"🫡 正在查询,请稍候..." │
└────────────────────────┬────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 对话服务层Chat Service
├─────────────────────────────────────────────────────────────────┤
│ ChatService核心大脑
│ │
│ 步骤1: 意图识别Intent Detection
│ ├─ 关键词匹配MVP简化方案
│ ├─ query_record: "患者"、"ID"、"记录" │
│ ├─ count_records: "多少"、"几个"、"统计" │
│ ├─ query_protocol: "纳入排除"、"CRF"、"研究方案" │
│ └─ general_chat: 其他 │
│ │
│ 步骤2: 工具调用Tool Calling
│ ├─ REDCap数据查询结构化数据
│ │ ├─ queryRedcapRecord(recordId) │
│ │ ├─ countRedcapRecords() │
│ │ └─ getProjectInfo() │
│ │ │
│ └─ Dify知识库检索非结构化文档
│ └─ queryDifyKnowledge(query) │
│ └─ 语义检索Top 5相关片段 │
│ │
│ 步骤3: 上下文管理Context Management
│ └─ SessionMemory内存缓存保留最近3轮
│ │
│ 步骤4: LLM生成LLM Generation
│ └─ DeepSeek-V3通过LLMFactory调用
│ ├─ System Prompt强调基于真实数据
│ ├─ REDCap查询结果如果有
│ ├─ Dify检索结果如果有
│ ├─ 对话上下文SessionMemory
│ └─ 用户问题 │
└────────────────────────┬────────────────────────────────────────┘
┌───────────────┴───────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ 数据源层Data │ │ 知识源层Knowledge
├──────────────────────┤ ├──────────────────────┤
│ REDCap数据库 │ │ Dify知识库 │
│ - 患者记录(结构化) │ │ - 研究方案PDF │
│ - RedcapAdapter │ │ - CRF表格Docx │
│ - REST API │ │ - 伦理资料 │
│ - 实时查询 │ │ - 向量检索Qdrant
└──────────────────────┘ └──────────────────────┘
│ │
└───────────────┬───────────────┘
PostgreSQL数据库
- 项目配置dify_dataset_id
- 审计日志
- 用户映射
```
---
## 🔑 核心技术组件
### 1. 意图识别Intent Detection
#### 实现方式
- **当前方案**: 关键词匹配(简单高效)
- **识别准确率**: 100%5次测试全部正确
- **响应速度**: <10ms
#### 意图类型
| 意图类型 | 关键词 | 触发工具 | 示例 |
|---------|--------|----------|------|
| `query_record` | "患者"、"ID"、"记录"、"受试者" | REDCap单条查询 | "查询ID 7的患者情况" |
| `count_records` | "多少"、"几个"、"统计"、"总共" | REDCap统计查询 | "目前有多少位患者入组?" |
| `query_protocol` | "纳入排除"、"CRF"、"研究方案"、"伦理" | Dify知识库检索 | "这个研究的排除标准是什么?" |
| `project_info` | "项目"、"研究"、"信息" | 数据库查询 | "这是什么项目?" |
| `general_chat` | 其他 | 无工具调用 | "你好" |
#### 代码实现
```typescript
// backend/src/modules/iit-manager/services/ChatService.ts
private detectIntent(message: string): {
intent: 'query_record' | 'count_records' | 'project_info' | 'query_protocol' | 'general_chat';
params?: any;
} {
// 1. 识别文档查询(优先级最高)
if (/(研究方案|伦理|知情同意|CRF|纳入|排除|标准)/.test(message)) {
return { intent: 'query_protocol' };
}
// 2. 识别记录查询包含ID号码
const recordIdMatch = message.match(/(?:ID|记录|患者|受试者).*?(\d+)|(\d+).*?(?:入组|数据|信息)/i);
if (recordIdMatch) {
return {
intent: 'query_record',
params: { recordId: recordIdMatch[1] || recordIdMatch[2] }
};
}
// 3. 识别统计查询
if (/(多少|几个|几条|总共|统计).*?(记录|患者|受试者|人)/.test(message)) {
return { intent: 'count_records' };
}
// 4. 识别项目信息查询
if (/(项目|研究).*?(名称|信息|情况)/.test(message)) {
return { intent: 'project_info' };
}
// 5. 默认:普通对话
return { intent: 'general_chat' };
}
```
---
### 2. 工具调用Tool Calling
#### 2.1 REDCap工具
**功能**: 查询结构化的患者数据
**工具列表**:
| 工具名称 | 功能 | 输入 | 输出 | 响应时间 |
|---------|------|------|------|----------|
| `queryRedcapRecord` | 查询单条患者记录 | recordId | 患者详细信息 | ~1.2秒 |
| `countRedcapRecords` | 统计患者总数 | 无 | 总数+记录ID列表 | ~1.3秒 |
| `getProjectInfo` | 获取项目信息 | 无 | 项目基本信息 | ~50ms |
**技术实现**:
```typescript
// backend/src/modules/iit-manager/adapters/RedcapAdapter.ts
export class RedcapAdapter {
constructor(baseUrl: string, apiToken: string, timeout = 30000) {
this.client = axios.create({
baseURL: baseUrl,
timeout: timeout,
});
}
async exportRecords(options: RedcapExportOptions = {}): Promise<any[]> {
const formData = new URLSearchParams();
formData.append('token', this.apiToken);
formData.append('content', 'record');
formData.append('format', 'json');
if (options.records) {
formData.append('records', JSON.stringify(options.records));
}
const response = await this.client.post('/api/', formData);
return response.data;
}
}
```
#### 2.2 Dify工具
**功能**: 检索非结构化的研究文档
**检索配置**:
| 参数 | 值 | 说明 |
|------|-----|------|
| `search_method` | semantic_search | 语义检索(向量相似度) |
| `top_k` | 5 | 返回Top 5相关片段 |
| `chunk_size` | 1500 tokens | 每个片段大小Dify配置 |
**技术实现**:
```typescript
// backend/src/modules/iit-manager/services/ChatService.ts
private async queryDifyKnowledge(query: string): Promise<string> {
// 1. 获取项目的Dify Dataset ID
const project = await prisma.iitProject.findFirst({
where: { status: 'active' },
select: { difyDatasetId: true }
});
if (!project?.difyDatasetId) return '';
// 2. 调用Dify检索API
const result = await difyClient.retrieveKnowledge(
project.difyDatasetId,
query,
{
retrieval_model: {
search_method: 'semantic_search',
top_k: 5
}
}
);
// 3. 格式化检索结果
let formattedKnowledge = '';
result.records.forEach((record, index) => {
const score = (record.score * 100).toFixed(1);
formattedKnowledge += `\n[文档${index + 1}] ${record.document_name} (相关度: ${score}%)\n`;
formattedKnowledge += `${record.content}\n---\n`;
});
return formattedKnowledge;
}
```
---
### 3. 混合检索Hybrid Retrieval
**核心创新点**: 结合结构化数据和非结构化文档
#### 检索策略对比
| 检索类型 | 数据源 | 适用场景 | 检索方式 | 示例查询 |
|---------|--------|---------|---------|----------|
| **结构化数据检索** | REDCap | 患者记录、统计数据、入组信息 | SQL查询精确匹配 | "查询ID 7的患者" |
| **非结构化文档检索** | Dify知识库 | 研究方案、CRF表格、伦理资料 | 向量检索(语义相似) | "研究的纳入排除标准" |
#### 优势
**互补性**: 两种数据源覆盖PI的所有需求
**自动化**: 根据意图自动选择数据源
**高效性**: 响应速度快平均4.8秒)
**准确性**: 100%基于真实数据
#### 技术流程
```typescript
async handleMessage(userId: string, userMessage: string): Promise<string> {
// 1. 意图识别
const { intent, params } = this.detectIntent(userMessage);
// 2. 根据意图调用不同工具
let toolResult: any = null;
let difyKnowledge: string = '';
// REDCap数据查询
if (intent === 'query_record' && params?.recordId) {
toolResult = await this.queryRedcapRecord(params.recordId);
} else if (intent === 'count_records') {
toolResult = await this.countRedcapRecords();
}
// Dify知识库检索
if (intent === 'query_protocol') {
difyKnowledge = await this.queryDifyKnowledge(userMessage);
}
// 3. 组装上下文
const messages = this.buildMessagesWithData(
userMessage,
context,
toolResult, // REDCap数据
difyKnowledge, // Dify文档
userId
);
// 4. LLM生成
const response = await this.llm.chat(messages);
return response.content;
}
```
---
### 4. RAGRetrieval Augmented Generation
**核心作用**: 防止AI幻觉确保回答基于真实数据
#### RAG实现机制
```typescript
// System Prompt强调基于真实数据
const systemPrompt = `你是IIT Manager智能助手。
【重要原则】
⚠️ 你**必须基于系统提供的数据和文档**回答问题,**绝对不能编造信息**。
⚠️ 如果系统提供了查询结果或文档内容,请使用这些真实信息;如果没有提供,明确告知用户。
【你的能力】
✅ 回答研究进展问题基于REDCap实时数据
✅ 查询患者记录详情
✅ 统计入组人数
✅ 提供项目信息
✅ 解答研究方案相关问题(基于知识库文档)
【回复原则】
1. **基于事实**:只使用系统提供的数据和文档,不编造
2. **简洁专业**控制在150字以内
3. **友好礼貌**:使用"您"称呼PI
4. **引导行动**如需更多详细信息建议查看完整文档或登录REDCap系统
`;
// 数据注入
if (toolResult) {
messages.push({
role: 'system',
content: `【REDCap数据查询结果】\n${JSON.stringify(toolResult, null, 2)}\n\n请基于以上真实数据回答用户问题。`
});
}
if (difyKnowledge) {
messages.push({
role: 'system',
content: `【研究方案文档检索结果】\n${difyKnowledge}\n\n请基于以上文档内容回答用户问题。`
});
}
```
#### 防幻觉效果验证
测试结果显示:
- ✅ 所有回答都明确引用数据来源
- ✅ AI不再编造不存在的信息
- ✅ 当文档不完整时AI诚实告知
- ✅ 准确率100%5次测试
---
### 5. 上下文管理Context Management
**功能**: SessionMemory - 保留最近3轮对话
#### 实现方案
```typescript
// backend/src/modules/iit-manager/agents/SessionMemory.ts
export class SessionMemory {
private sessions: Map<string, ConversationHistory> = new Map();
private readonly MAX_HISTORY = 3; // 只保留最近3轮
addMessage(userId: string, role: 'user' | 'assistant', content: string): void {
let session = this.sessions.get(userId);
if (!session) {
session = { userId, messages: [], lastAccessTime: Date.now() };
this.sessions.set(userId, session);
}
session.messages.push({ role, content, timestamp: Date.now() });
session.lastAccessTime = Date.now();
// 保持最近3轮对话6条消息
if (session.messages.length > this.MAX_HISTORY * 2) {
session.messages = session.messages.slice(-this.MAX_HISTORY * 2);
}
}
getContext(userId: string): string {
const session = this.sessions.get(userId);
if (!session || session.messages.length === 0) return '';
return session.messages
.map(m => `${m.role === 'user' ? '用户' : 'AI'}: ${m.content}`)
.join('\n\n');
}
}
```
#### 设计考虑
- **内存缓存**: Node.js Map速度快满足MVP需求
- **自动清理**: 30分钟无活动自动清理
- **容量限制**: 最近3轮对话6条消息
- **多用户支持**: 以userId为key隔离
---
### 6. LLM生成LLM Generation
#### 模型选择
| 指标 | DeepSeek-V3 | 说明 |
|------|-------------|------|
| **成本** | ¥1/百万tokens | 极低成本 |
| **上下文** | 64K tokens | 满足需求 |
| **效果** | 优秀 | 与GPT-4相当 |
| **响应速度** | ~3秒 | 满足企业微信要求 |
#### 调用方式
```typescript
// 通过LLMFactory调用通用能力层
const llm = LLMFactory.getAdapter('deepseek-v3');
const response = await llm.chat(messages, {
temperature: 0.7,
maxTokens: 500, // 企业微信建议控制输出长度
topP: 0.9,
});
```
#### Token消耗统计
| 场景 | 输入Tokens | 输出Tokens | 总Tokens | 成本 |
|------|-----------|-----------|----------|------|
| 排除标准查询 | 340 | 79 | 419 | ¥0.00042 |
| CRF指标查询 | 434 | 75 | 509 | ¥0.00051 |
| ID 7患者查询 | 627 | 88 | 715 | ¥0.00072 |
| 研究目的查询 | 522 | 57 | 579 | ¥0.00058 |
| 患者统计查询 | 505 | 42 | 547 | ¥0.00055 |
**平均成本**: ¥0.00056/次对话(极低)
---
### 7. 企业微信集成WeChat Integration
#### 核心功能
1. **消息加解密**: AES + SHA1签名验证
2. **异步处理**: 5秒内返回200后台处理消息
3. **即时反馈**: "🫡 正在查询,请稍候..."
4. **主动推送**: 通过企业微信API发送回复
#### 技术实现
```typescript
// backend/src/modules/iit-manager/controllers/WechatCallbackController.ts
async handlePost(request: FastifyRequest, reply: FastifyReply) {
// 1. 立即返回2005秒内
reply.send('success');
// 2. 异步处理消息
this.processMessageAsync(xmlData).catch(error => {
logger.error('异步处理消息异常', { error: error.message });
});
}
private async processMessageAsync(xmlData: any) {
const { FromUserName, Content } = this.extractMessage(xmlData);
// 3. 发送即时反馈
await this.sendTextMessage(FromUserName, '🫡 正在查询,请稍候...');
// 4. 调用ChatService处理
const answer = await this.chatService.handleMessage(FromUserName, Content);
// 5. 发送最终回复
await this.sendTextMessage(FromUserName, answer);
}
```
---
## 📊 完整数据流图
```
用户提问
企业微信消息
[WechatCallbackController]
├→ 立即返回200<5秒
└→ 异步处理
[ChatService.handleMessage()]
1. 意图识别(关键词匹配)
├→ query_protocol
├→ query_record
└→ count_records
2. 工具调用(并行或单一)
├→ queryDifyKnowledge()
│ └→ Dify API语义检索
│ └→ 返回Top 5文档片段
└→ queryRedcapRecord()
└→ REDCap APISQL查询
└→ 返回患者记录
3. 上下文组装
├→ System Prompt基于真实数据原则
├→ REDCap查询结果如果有
├→ Dify检索结果如果有
├→ SessionMemory上下文
└→ 用户问题
4. LLM生成DeepSeek-V3
└→ 生成回答(基于注入的数据)
5. 保存到SessionMemory
6. 推送到企业微信
用户收到回复
```
---
## 🎯 关键技术决策
| 决策点 | 选择方案 | 替代方案 | 选择原因 |
|-------|---------|---------|---------|
| **意图识别** | 关键词匹配 | LLM判断、BERT分类 | MVP阶段简单高效准确率高100% |
| **工具调用** | 同步串行 | 并行调用 | 响应快(<5秒逻辑清晰易调试 |
| **知识库** | Dify本地部署 | 自建向量库、云服务 | 数据安全,响应快,成本低,易维护 |
| **向量数据库** | QdrantDify内置 | Milvus、Pinecone | 高性能,无需额外部署 |
| **LLM** | DeepSeek-V3 | GPT-4、Claude | 成本低¥1/百万tokens效果好 |
| **上下文存储** | 内存缓存Map | Redis、数据库 | 速度快满足MVP需求易实现 |
| **数据注入** | System Prompt | Function Calling | 简单直接,防止幻觉,效果好 |
| **异步处理** | Node.js异步 | 消息队列pg-boss | 简单满足企业微信5秒限制 |
---
## 📈 性能指标
### 响应时间分析
| 阶段 | 耗时 | 占比 | 优化空间 |
|------|------|------|----------|
| 意图识别 | <10ms | <1% | ✅ 已最优 |
| REDCap查询 | 1.2-1.3秒 | 25% | 🔵 可优化(加缓存) |
| Dify检索 | 1.5-1.7秒 | 30% | 🔵 可优化调整top_k |
| LLM生成 | 3.0-3.5秒 | 65% | ⚠️ 受限于模型速度 |
| **总计** | **4.8秒** | **100%** | ✅ 满足<5秒要求 |
### Token消耗分析
| 指标 | 数值 |
|------|------|
| 平均输入Tokens | 486 tokens/次 |
| 平均输出Tokens | 68 tokens/次 |
| 平均总Tokens | 554 tokens/次 |
| 平均成本 | ¥0.00055/次对话 |
### 准确率指标
| 指标 | 数值 | 说明 |
|------|------|------|
| 意图识别准确率 | 100% | 5次测试全部正确 |
| 数据检索成功率 | 100% | 无失败案例 |
| 回答准确率 | 100% | 所有回答基于真实数据 |
| 幻觉率 | 0% | 无编造信息 |
---
## 🚀 Phase 1.5 技术成果
### 核心突破
1.**零幻觉**: 所有回答都基于真实数据/文档
2.**混合检索**: 结构化数据REDCap+ 非结构化文档Dify
3.**快速响应**: 平均4.8秒(满足企业微信<5秒要求
4.**高准确率**: 意图识别100%数据检索100%
5.**低成本**: ¥0.00055/次对话
### 测试验证结果
**测试日期**: 2026-01-04
**测试场景**: 5个典型对话场景
**测试结果**: 全部通过✅
| 测试场景 | 意图 | 数据源 | 响应时间 | 结果 |
|---------|------|--------|----------|------|
| 排除标准查询 | query_protocol | Dify | 5.4秒 | ✅ 准确 |
| CRF指标查询 | query_protocol | Dify | 4.9秒 | ✅ 准确 |
| ID 7患者查询 | query_record | REDCap | 5.3秒 | ✅ 准确 |
| 研究目的查询 | query_protocol | Dify | 4.5秒 | ✅ 准确 |
| 患者统计查询 | count_records | REDCap | 3.8秒 | ✅ 准确 |
### 用户反馈
- ✅ 响应速度满意(<5秒
- ✅ 回答准确专业
- ✅ 数据真实可靠
- ✅ 上下文记忆有效
---
## 📝 系统能力总结
### 对外介绍要点
**简洁版100字**:
> "我们实现了一个**智能意图识别系统**当PI询问研究方案相关问题时AI会自动从知识库中检索文档当询问患者数据时AI会实时查询REDCap数据库。通过**混合检索技术**AI能够同时理解研究文档和患者数据给出准确、专业的回答。整个系统基于**RAG技术**检索增强生成确保AI的回答100%基于真实数据,不会编造信息。"
**技术亮点5点**:
1. **意图识别**: 自动判断用户问题类型100%准确率)
2. **工具调用**: 根据意图调用不同的数据源REDCap/Dify
3. **混合检索**: 结合结构化数据和非结构化文档
4. **零幻觉**: 所有回答都有真实数据支撑RAG技术
5. **快速响应**: 平均5秒内回复满足企业微信要求
### 适用场景
**PI日常管理**:
- 查询研究方案、伦理资料
- 了解患者入组情况
- 统计项目进展
**数据质控**:
- 检查患者记录
- 核对数据完整性
**知识查询**:
- CRF表格内容
- 纳入排除标准
- 研究流程
---
## 🔗 相关文档
- [IIT Manager Agent 开发记录](../06-开发记录/)
- [IIT Manager Agent 技术债务清单](../07-技术债务/)
- [MVP开发任务清单](../04-开发计划/MVP开发任务清单.md)
- [Phase1.5-AI对话能力开发计划](../04-开发计划/Phase1.5-AI对话能力开发计划.md)
---
**文档维护**: 技术团队
**最后更新**: 2026-01-04
**版本历史**:
- v1.0 (2026-01-04): 初始版本Phase 1.5完成