Architecture Design: - Add intent recognition and dialogue architecture design (Intent Router + DataContext) - Add tool system planning (4-layer 7-tool fusion solution: READ/INTERACT/THINK/ACT) - Add 4-layer 7-tool implementation mechanism details (Conversation Layer LLM + Node.js orchestration) Development Plan (v1.2): - Create 6-phase development plan (134h/22 days) for intelligent dialogue system - Add 8 architectural constraints (C1-C8): no Function Calling, Postgres-Only cache, streaming output, context guard, Zod dynamic validation - Correct Session Blackboard to use CacheFactory (Postgres-Only, no Redis) Status Updates: - Update SSA module status: QPER complete + dialogue architecture design complete - Update system-level status: add SSA architecture design milestone Other: - R tools minor fixes (chi_square, correlation, logistic_binary, mann_whitney, t_test_paired) - Frontend AIA chat workspace style adjustment Co-authored-by: Cursor <cursoragent@cursor.com>
629 lines
27 KiB
Markdown
629 lines
27 KiB
Markdown
# SSA-Pro 意图识别与对话架构设计
|
||
|
||
> **文档版本:** v1.0
|
||
> **创建日期:** 2026-02-21
|
||
> **文档类型:** 架构设计 (Architecture Design)
|
||
> **核心理念:** 从"统计参数提取器"升级为"数据感知的智能对话系统"
|
||
> **前置文档:** QPER 架构设计方案 V4、理想状态与智能化愿景设计
|
||
|
||
---
|
||
|
||
## 1. 问题诊断
|
||
|
||
### 1.1 当前架构的根本缺陷
|
||
|
||
当前 QPER 架构中,Q 层(QueryService)的本质是**统计分析参数提取器**,不是真正的用户意图识别:
|
||
|
||
```
|
||
当前流程:
|
||
用户消息 → QueryService(强制提取 goal/y/x/design)→ Planner → Execute → Reflection
|
||
```
|
||
|
||
它假设用户发出的**每一条消息**都是一个分析请求,试图从中提取四维参数(分析目标、结局变量、预测变量、研究设计)。
|
||
|
||
**这导致了三个核心问题:**
|
||
|
||
| # | 问题 | 表现 |
|
||
|---|------|------|
|
||
| 1 | **无法自由对话** | 用户说"这个数据有什么特点"→ 系统强行匹配到 descriptive,跑描述统计 |
|
||
| 2 | **跳过需求梳理** | 用户说"BMI 和血压有关系吗"→ 直接跑相关分析,但用户可能只是在咨询 |
|
||
| 3 | **LLM 能力浪费** | 只用 LLM 做参数提取,完全没利用 LLM 的知识库和推理能力 |
|
||
|
||
### 1.2 用户真实旅程 vs 系统假设
|
||
|
||
**系统假设的用户旅程:**
|
||
```
|
||
上传数据 → 说出分析需求 → 系统执行 → 查看结果
|
||
```
|
||
|
||
**医生的真实旅程:**
|
||
```
|
||
上传数据 → 理解数据全貌 → 与AI讨论探索 → 确定分析方案 → 执行分析 → 解读结果
|
||
↑ ↑ ↑
|
||
当前系统完全跳过了这三个关键阶段
|
||
```
|
||
|
||
### 1.3 一句话总结
|
||
|
||
> **当前系统只有"接单"能力,没有"对话"能力。QPER 是一个优秀的分析流水线,但它不应该是用户的唯一入口。**
|
||
|
||
---
|
||
|
||
## 2. 设计目标
|
||
|
||
### 2.1 核心目标
|
||
|
||
将 SSA 从"统计分析执行器"升级为"数据感知的统计顾问":
|
||
|
||
- 用户上传数据后,可以**自由与系统对话**,了解数据、讨论方案
|
||
- 系统基于**数据全貌**回答问题,像一个了解你数据的统计专家
|
||
- 只有当用户**明确表达分析意图**时,才触发 QPER 流水线
|
||
- 分析完成后,用户可以**继续讨论结果**,获得深入解读
|
||
|
||
### 2.2 设计原则
|
||
|
||
| 原则 | 含义 |
|
||
|------|------|
|
||
| **对话优先** | 默认是自由对话,分析执行是对话中的特殊行为 |
|
||
| **数据感知** | 所有 LLM 调用都携带数据全貌上下文 |
|
||
| **渐进深入** | 从数据概览 → PICO 分类 → 变量字典,逐步丰富理解 |
|
||
| **QPER 不变** | QPER 仍是核心分析引擎,但只在 analyze 意图时触发 |
|
||
| **用户主导** | 系统建议而非替用户决定,分析方案需用户确认 |
|
||
|
||
---
|
||
|
||
## 3. 总体架构
|
||
|
||
### 3.1 两层意图 + 数据全貌上下文
|
||
|
||
```
|
||
┌─────────────────────────────────┐
|
||
│ 数据全貌(DataContext) │
|
||
│ 持久存在于整个会话生命周期中 │
|
||
│ 在对话过程中逐步丰富 │
|
||
└──────────┬──────────────────────┘
|
||
│
|
||
│ 注入
|
||
▼
|
||
用户消息 ──→ 【意图路由器 Intent Router】──────────────────────────────────
|
||
│
|
||
├── 💬 自由对话(Chat)
|
||
│ LLM(DataContext) → 直接回复
|
||
│
|
||
├── 🔍 数据探索(Explore)
|
||
│ DataProfile + LLM(DataContext) → 直接回复
|
||
│
|
||
├── 📋 分析咨询(Consult)
|
||
│ LLM(DataContext + 统计知识) → 建议方案
|
||
│
|
||
├── 🎯 分析执行(Analyze)
|
||
│ → 进入 QPER 流水线(Q → P → E → R)
|
||
│
|
||
└── 📊 结果讨论(Discuss)
|
||
LLM(DataContext + 分析结果) → 解读回复
|
||
```
|
||
|
||
### 3.2 和现有架构的关系
|
||
|
||
```
|
||
现有 QPER(保持不变)
|
||
┌─────────────────────────┐
|
||
用户消息 → [Intent Router] → │ Q → P → E → R │
|
||
│ │ └─────────────────────────┘
|
||
│ │ ↑ 仅 analyze 意图触发
|
||
│ │
|
||
│ ├── chat → LLM(DataContext) → 回复
|
||
│ ├── explore → DataProfile/LLM → 回复
|
||
│ ├── consult → LLM(DataContext + 统计知识) → 建议
|
||
│ └── discuss → LLM(DataContext + 结果) → 解读
|
||
│
|
||
└── DataContext(数据全貌,贯穿会话)
|
||
```
|
||
|
||
**关键:不是推翻 QPER,而是在 QPER 前面加一层路由**。QPER 仍然是核心分析执行引擎,但它只在用户有明确分析意图时被触发。
|
||
|
||
---
|
||
|
||
## 4. 数据全貌(DataContext)
|
||
|
||
### 4.1 为什么需要数据全貌
|
||
|
||
当前系统中,DataProfile 只在 Q 层被使用,用于辅助 LLM 提取分析参数。但数据全貌的价值远不止于此 —— 它应该是贯穿整个会话的**持久化上下文**,让 LLM 在每一次回复中都"了解"用户的数据。
|
||
|
||
### 4.2 三层数据全貌模型
|
||
|
||
```
|
||
DataContext {
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Layer 1: 统计摘要(Statistical Summary) │
|
||
│ 来源:DataProfileService 自动生成 │
|
||
│ 时机:数据上传后立即生成 │
|
||
│ │
|
||
│ - totalRows: 200 │
|
||
│ - totalCols: 15 │
|
||
│ - missingRate: { overall: 3.2%, perColumn: {...} } │
|
||
│ - categoricalVars: ["group", "gender", "smoking"] │
|
||
│ - continuousVars: ["age", "bmi", "bp_baseline", ...] │
|
||
│ - dataStructure: "cross-sectional" │
|
||
│ - idLikeVars: ["patient_id"] │
|
||
└─────────────────────┬───────────────────────────────────┘
|
||
│ 自动
|
||
▼
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Layer 2: PICO 分类(Clinical Context) │
|
||
│ 来源:LLM 推断 + 用户确认/修正 │
|
||
│ 时机:数据探索阶段,LLM 主动推断或用户询问时 │
|
||
│ │
|
||
│ - population: "高血压患者,年龄 40-70 岁" │
|
||
│ - intervention: { │
|
||
│ var: "group", │
|
||
│ levels: ["treatment", "control"], │
|
||
│ description: "新型降压药 vs 安慰剂" │
|
||
│ } │
|
||
│ - comparator: "安慰剂对照" │
|
||
│ - outcomes: [ │
|
||
│ { var: "bp_change", type: "continuous", │
|
||
│ role: "primary", unit: "mmHg" } │
|
||
│ ] │
|
||
└─────────────────────┬───────────────────────────────────┘
|
||
│ LLM 推断 + 用户确认
|
||
▼
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Layer 3: 变量字典(Variable Dictionary) │
|
||
│ 来源:LLM 推断 + 用户逐步修正 │
|
||
│ 时机:对话过程中逐步丰富 │
|
||
│ │
|
||
│ - { name: "age", label: "年龄", │
|
||
│ type: "continuous", role: "baseline", │
|
||
│ unit: "years", description: "入组时年龄" } │
|
||
│ - { name: "group", label: "分组", │
|
||
│ type: "categorical", role: "intervention", │
|
||
│ levels: ["treatment", "control"] } │
|
||
│ - { name: "bp_change", label: "血压变化", │
|
||
│ type: "continuous", role: "outcome", │
|
||
│ unit: "mmHg", description: "治疗后-治疗前" } │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 4.3 数据全貌的生命周期
|
||
|
||
```
|
||
时间线:
|
||
─────────────────────────────────────────────────────────────→
|
||
│ │ │ │
|
||
上传数据 对话探索 分析执行 结果讨论
|
||
│ │ │ │
|
||
Layer 1 生成 Layer 2 推断 QPER 使用 解读引用
|
||
(自动) Layer 3 丰富 DataContext DataContext
|
||
(LLM+用户) (参数更准确) (结论更准确)
|
||
```
|
||
|
||
### 4.4 DataContext 接口定义
|
||
|
||
```typescript
|
||
interface DataContext {
|
||
sessionId: string;
|
||
uploadedAt: string;
|
||
|
||
// Layer 1: 自动生成
|
||
summary: {
|
||
totalRows: number;
|
||
totalCols: number;
|
||
missingOverview: { overall: number; perColumn: Record<string, number> };
|
||
categoricalVars: string[];
|
||
continuousVars: string[];
|
||
idLikeVars: string[];
|
||
dataStructure: 'cross-sectional' | 'longitudinal' | 'repeated-measures' | 'unknown';
|
||
sampleSizeWarning?: string;
|
||
};
|
||
|
||
// Layer 2: LLM 推断 + 用户确认
|
||
pico: {
|
||
population: string | null;
|
||
intervention: {
|
||
var: string | null;
|
||
levels: string[];
|
||
description: string | null;
|
||
};
|
||
comparator: string | null;
|
||
outcomes: Array<{
|
||
var: string;
|
||
type: 'continuous' | 'categorical' | 'time-to-event';
|
||
role: 'primary' | 'secondary';
|
||
unit?: string;
|
||
}>;
|
||
confirmed: boolean; // 用户是否已确认
|
||
};
|
||
|
||
// Layer 3: 变量字典
|
||
variableDictionary: Array<{
|
||
name: string; // 原始列名
|
||
label: string; // 中文标签(LLM 推断或用户提供)
|
||
type: 'continuous' | 'categorical' | 'ordinal' | 'datetime' | 'id';
|
||
role: 'baseline' | 'intervention' | 'outcome' | 'covariate' | 'id' | 'unknown';
|
||
unit?: string;
|
||
levels?: string[]; // 分类变量的水平
|
||
description?: string; // 变量含义
|
||
confirmed: boolean; // 用户是否已确认该条目
|
||
}>;
|
||
|
||
// 元数据
|
||
lastUpdated: string;
|
||
enrichmentHistory: Array<{
|
||
timestamp: string;
|
||
layer: 1 | 2 | 3;
|
||
source: 'auto' | 'llm' | 'user';
|
||
description: string;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 意图路由器(Intent Router)
|
||
|
||
### 5.1 设计理念
|
||
|
||
意图路由器不是提取分析参数,而是**判断用户当前想做什么**。它是一个轻量级 LLM 调用(或规则匹配),输出一个意图分类。
|
||
|
||
### 5.2 五种意图类型
|
||
|
||
| 意图 | 触发示例 | 系统行为 | LLM 上下文 |
|
||
|------|---------|---------|-----------|
|
||
| **chat** | "这个数据有多少样本?"<br>"BMI 一般正常范围是多少?"<br>"临床试验中 P 值多少算显著?" | 直接 LLM 对话 | DataContext |
|
||
| **explore** | "帮我看看各组的样本分布"<br>"哪些变量缺失比较严重?"<br>"能推断出结局指标是哪些吗?" | DataProfile 增强探索 | DataContext + 统计摘要 |
|
||
| **consult** | "我想比较两组差异,应该用什么方法?"<br>"这个数据适合做什么分析?"<br>"帮我制定一个分析计划" | LLM 给出分析建议(不执行) | DataContext + 统计知识 |
|
||
| **analyze** | "对 BMI 和血压做相关分析"<br>"比较治疗组和对照组的血压差异"<br>"执行之前建议的分析方案" | 进入 QPER 流水线 | DataContext → Q 层 |
|
||
| **discuss** | "这个 p 值说明什么?"<br>"结果和我预期不一样,为什么?"<br>"需要做哪些敏感性分析?" | LLM 结果解读 | DataContext + 分析结果 |
|
||
|
||
### 5.3 意图识别策略
|
||
|
||
```
|
||
意图路由器的判断策略(优先级从高到低):
|
||
|
||
1. 显式触发词
|
||
- "执行" "运行" "分析一下" "开始分析" → analyze
|
||
- "为什么" "说明什么" "怎么解读" (且有最近结果) → discuss
|
||
- "应该用什么方法" "建议" "计划" "方案" → consult
|
||
- "帮我看看" "分布" "缺失" "概况" → explore
|
||
|
||
2. 上下文推断
|
||
- 刚上传数据、尚无对话 → 倾向 explore / chat
|
||
- 已有分析结果、围绕结果提问 → 倾向 discuss
|
||
- 讨论过方法选择、确认执行 → 倾向 analyze
|
||
|
||
3. 默认兜底
|
||
- 无法判断 → chat(最安全的默认值)
|
||
- chat 意味着 LLM 携带 DataContext 直接回复,不触发任何流水线
|
||
```
|
||
|
||
### 5.4 Intent Router 接口
|
||
|
||
```typescript
|
||
interface IntentRouterInput {
|
||
userMessage: string;
|
||
sessionId: string;
|
||
dataContext: DataContext | null; // 可能尚未上传数据
|
||
recentAnalysisResult: AnalysisRecord | null; // 最近的分析结果(用于判断 discuss)
|
||
conversationHistory: Message[]; // 最近 N 条对话(用于上下文推断)
|
||
}
|
||
|
||
interface IntentRouterOutput {
|
||
intent: 'chat' | 'explore' | 'consult' | 'analyze' | 'discuss';
|
||
confidence: number;
|
||
reasoning: string; // LLM 给出的判断理由(用于调试)
|
||
suggestedResponse?: string; // chat/explore/consult/discuss 模式下的直接回复
|
||
}
|
||
```
|
||
|
||
### 5.5 关键设计决策:LLM 路由 vs 规则路由
|
||
|
||
| 方案 | 优势 | 劣势 |
|
||
|------|------|------|
|
||
| **纯规则路由** | 快速、确定性强、无 LLM 成本 | 覆盖面有限,边界情况多 |
|
||
| **纯 LLM 路由** | 理解力强,边界情况少 | 多一次 LLM 调用,增加延迟和成本 |
|
||
| **混合路由(推荐)** | 快速覆盖明确场景 + LLM 兜底模糊场景 | 实现略复杂 |
|
||
|
||
**推荐方案:混合路由**
|
||
- 先走规则匹配(关键词 + 上下文状态)
|
||
- 规则无法判断时,调用轻量级 LLM(仅分类,不生成长文)
|
||
- LLM 路由可与后续处理并行,减少感知延迟
|
||
|
||
---
|
||
|
||
## 6. 各意图的处理流程
|
||
|
||
### 6.1 Chat — 自由对话
|
||
|
||
```
|
||
用户: "BMI 在临床研究中一般怎么分类?"
|
||
|
||
系统处理:
|
||
1. Intent Router → chat
|
||
2. 构建 LLM Prompt:
|
||
- System: "你是一个临床统计顾问。用户上传了一份数据,以下是数据全貌..."
|
||
- System: {DataContext 的 JSON 摘要}
|
||
- User: "BMI 在临床研究中一般怎么分类?"
|
||
3. LLM 直接回复(利用自身知识库)
|
||
4. 回复展示在对话区
|
||
|
||
特点:
|
||
- 不触发任何分析流水线
|
||
- LLM 带着数据上下文回答,回复更有针对性
|
||
- 类似于和一个"读过你数据"的统计专家对话
|
||
```
|
||
|
||
### 6.2 Explore — 数据探索
|
||
|
||
```
|
||
用户: "帮我看看这个数据的缺失情况"
|
||
|
||
系统处理:
|
||
1. Intent Router → explore
|
||
2. 从 DataContext.summary 提取缺失率信息
|
||
3. 构建 LLM Prompt:
|
||
- System: "基于以下数据质量摘要,为用户解读缺失情况"
|
||
- System: {缺失率数据}
|
||
- User: "帮我看看这个数据的缺失情况"
|
||
4. LLM 生成结构化解读(哪些变量缺失严重、是否影响分析、建议处理方式)
|
||
5. 可选:生成缺失率可视化(调用 R 引擎)
|
||
|
||
进阶场景:
|
||
用户: "你觉得结局指标可能是哪些?"
|
||
→ LLM 基于 DataContext + 临床知识推断 PICO 分类
|
||
→ 生成推断结果,等待用户确认
|
||
→ 用户确认后更新 DataContext.pico
|
||
```
|
||
|
||
### 6.3 Consult — 分析咨询
|
||
|
||
```
|
||
用户: "我想比较治疗组和对照组的血压差异,应该用什么方法?"
|
||
|
||
系统处理:
|
||
1. Intent Router → consult
|
||
2. 构建 LLM Prompt:
|
||
- System: "你是统计方法学顾问。基于以下数据全貌,为用户推荐分析方法"
|
||
- System: {DataContext}
|
||
- System: "可用的分析方法列表: {tools_registry 摘要}"
|
||
- User: "我想比较治疗组和对照组的血压差异,应该用什么方法?"
|
||
3. LLM 回复:
|
||
- 推荐方法(如"建议使用独立样本 T 检验")
|
||
- 选择理由("因为结局变量是连续型,两组独立...")
|
||
- 前提条件("需要满足正态性和方差齐性")
|
||
- 替代方案("如果不满足正态性,可以使用 Wilcoxon 秩和检验")
|
||
4. 用户可以继续追问,或说"好,按这个方案执行"
|
||
|
||
关键区别:
|
||
- consult 只给建议,不执行
|
||
- 用户确认后再转为 analyze 意图
|
||
- 这让用户在执行前充分理解"为什么这样做"
|
||
```
|
||
|
||
### 6.4 Analyze — 分析执行(当前 QPER)
|
||
|
||
```
|
||
用户: "好的,按你说的方案,对血压做 T 检验"
|
||
或: "对 BMI 和 bp_change 做相关分析"
|
||
|
||
系统处理:
|
||
1. Intent Router → analyze
|
||
2. 进入 QPER 流水线:Q → P → E → R
|
||
3. 但此时 QPER 的 Q 层更轻松:
|
||
- DataContext 中已有 PICO 分类和变量字典
|
||
- consult 阶段已经讨论过方法选择
|
||
- Q 层只需确认参数,不需要"猜测"
|
||
|
||
提升点:
|
||
- Q 层可以直接从 DataContext.variableDictionary 获取变量类型和角色
|
||
- P 层的决策表匹配更准确(因为变量角色已确认)
|
||
- 用户的分析预期更明确(因为经过了 consult 阶段的讨论)
|
||
```
|
||
|
||
### 6.5 Discuss — 结果讨论
|
||
|
||
```
|
||
用户: "p 值 0.03 说明什么?为什么置信区间这么宽?"
|
||
|
||
系统处理:
|
||
1. Intent Router → discuss(检测到最近有分析结果)
|
||
2. 构建 LLM Prompt:
|
||
- System: "你是统计结果解读专家。以下是用户的数据全貌和最近的分析结果"
|
||
- System: {DataContext}
|
||
- System: {最近的 AnalysisRecord — 包含步骤结果和结论}
|
||
- User: "p 值 0.03 说明什么?为什么置信区间这么宽?"
|
||
3. LLM 深入解读结果
|
||
4. 可以建议后续分析("建议做一下亚组分析")
|
||
|
||
特点:
|
||
- 不重新跑分析,只是讨论已有结果
|
||
- LLM 带着完整的数据和结果上下文回答
|
||
- 可以引导用户进入下一轮分析(discuss → consult → analyze)
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 对话状态机
|
||
|
||
### 7.1 用户旅程状态流转
|
||
|
||
```
|
||
┌──────────┐
|
||
┌────────→│ Chat │←───────┐
|
||
│ └────┬─────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
┌────┴─────┐ ┌────────────┐ │
|
||
上传数据 ────────→ │ Explore │──→│ Consult │─────┤
|
||
└────┬─────┘ └────┬───────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌────────────┐ │
|
||
│ │ Analyze │ │
|
||
│ │ (QPER) │ │
|
||
│ └────┬───────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌────────────┐ │
|
||
└────────→│ Discuss │─────┘
|
||
└────────────┘
|
||
```
|
||
|
||
**说明:**
|
||
- 任何状态都可以跳转到 Chat(用户随时可以自由提问)
|
||
- Explore → Consult → Analyze 是推荐的"主线",但不强制
|
||
- Discuss 之后可以回到任何状态(继续探索、咨询新方案、执行新分析)
|
||
- **状态之间没有硬性约束**,用户完全自主决定对话方向
|
||
|
||
### 7.2 数据全貌的渐进丰富
|
||
|
||
```
|
||
阶段 1 — 上传完成:
|
||
DataContext.summary ← DataProfileService 自动填充
|
||
|
||
阶段 2 — 探索对话中:
|
||
DataContext.pico ← LLM 推断,用户确认
|
||
DataContext.variableDictionary ← LLM 推断,用户逐步修正
|
||
|
||
阶段 3 — 分析执行时:
|
||
QPER 的 Q 层直接引用 DataContext(参数提取更准确)
|
||
|
||
阶段 4 — 结果讨论时:
|
||
LLM 引用 DataContext + 分析结果(解读更精准)
|
||
```
|
||
|
||
---
|
||
|
||
## 8. LLM Prompt 策略
|
||
|
||
### 8.1 System Prompt 模板
|
||
|
||
所有意图类型共享一个**基础 System Prompt**,差异在于注入的上下文片段:
|
||
|
||
```
|
||
[基础角色]
|
||
你是 SSA-Pro 智能统计分析助手,专注于临床研究统计分析。
|
||
你了解用户上传的数据,可以回答关于数据的问题,推荐分析方法,解读分析结果。
|
||
|
||
[数据全貌 — 始终注入]
|
||
用户上传了一份数据集,以下是数据全貌:
|
||
{DataContext.summary 的结构化摘要}
|
||
|
||
[PICO 分类 — 如果已推断]
|
||
根据数据特征,推断的 PICO 分类如下:
|
||
{DataContext.pico}
|
||
|
||
[变量字典 — 如果已丰富]
|
||
各变量的定义和角色:
|
||
{DataContext.variableDictionary}
|
||
|
||
[意图特定指令 — 按路由结果注入]
|
||
- chat: "请基于你的统计知识和用户数据回答问题。不要主动建议分析。"
|
||
- explore: "请基于数据摘要为用户解读数据特征。可以推断 PICO 分类。"
|
||
- consult: "请推荐合适的分析方法,给出理由和前提条件,不要执行分析。"
|
||
- discuss: "以下是最近的分析结果:{结果}。请帮助用户解读。"
|
||
|
||
[最近分析结果 — discuss 意图时注入]
|
||
{AnalysisRecord 摘要}
|
||
```
|
||
|
||
### 8.2 Token 成本控制
|
||
|
||
DataContext 注入 LLM 会增加 token 消耗,需要控制:
|
||
|
||
| 层 | 预估 Token | 控制策略 |
|
||
|----|-----------|---------|
|
||
| Layer 1 摘要 | ~200 | 始终注入,成本低 |
|
||
| Layer 2 PICO | ~150 | 已推断时注入 |
|
||
| Layer 3 变量字典 | ~50/变量 × N | 仅注入相关变量(裁剪策略) |
|
||
| 分析结果 | ~500/步骤 | discuss 时注入,限制摘要长度 |
|
||
|
||
**变量字典裁剪策略:**
|
||
- 变量数 ≤ 20:全部注入
|
||
- 变量数 > 20:只注入 confirmed + role ≠ unknown 的变量
|
||
- 极端情况(>50 列):只注入 PICO 相关变量
|
||
|
||
---
|
||
|
||
## 9. 和现有代码的映射
|
||
|
||
### 9.1 需要新增的组件
|
||
|
||
| 组件 | 位置 | 职责 |
|
||
|------|------|------|
|
||
| **IntentRouterService** | `backend/src/modules/ssa/services/` | 意图分类(规则 + LLM) |
|
||
| **DataContextService** | `backend/src/modules/ssa/services/` | DataContext 生命周期管理 |
|
||
| **ChatService** | `backend/src/modules/ssa/services/` | chat/explore/consult/discuss 的 LLM 对话 |
|
||
| **DataContext 存储** | `prisma schema` 或内存 | 按 sessionId 持久化 DataContext |
|
||
|
||
### 9.2 需要改造的组件
|
||
|
||
| 组件 | 当前职责 | 改造方向 |
|
||
|------|---------|---------|
|
||
| **QueryService** | 意图解析 + 参数提取 | 仅保留参数提取,意图分类移到 IntentRouter |
|
||
| **workflow.routes** | `/api/ssa/workflow/plan` 直接调 QueryService | 新增路由入口,先走 IntentRouter |
|
||
| **DataProfileService** | 生成统计摘要 | 输出同时写入 DataContext.summary |
|
||
| **前端 SSAChatPane** | 消息 → 调用 workflow API | 消息 → 调用 IntentRouter API → 按意图分发 |
|
||
|
||
### 9.3 保持不变的组件
|
||
|
||
| 组件 | 原因 |
|
||
|------|------|
|
||
| **DecisionTableService** | P 层逻辑不变 |
|
||
| **FlowTemplateService** | P 层逻辑不变 |
|
||
| **WorkflowExecutorService** | E 层逻辑不变 |
|
||
| **ReflectionService** | R 层逻辑不变 |
|
||
| **RClientService** | R 引擎调用不变 |
|
||
| **所有 R 工具脚本** | R 层不变 |
|
||
|
||
---
|
||
|
||
## 10. 实施路线建议
|
||
|
||
### Phase 1: DataContext 基础(建议优先)
|
||
|
||
- 扩展 DataProfileService,上传后自动生成 DataContext.summary
|
||
- DataContext 按 sessionId 内存缓存(后续可持久化)
|
||
- 前端上传完成后展示数据概览卡片
|
||
|
||
### Phase 2: Intent Router
|
||
|
||
- 实现 IntentRouterService(先纯规则,后加 LLM 兜底)
|
||
- 新增 API 入口 `/api/ssa/chat`,前端消息统一走此入口
|
||
- analyze 意图 → 转发到现有 QPER 流水线
|
||
- 其他意图 → ChatService 处理
|
||
|
||
### Phase 3: 数据感知对话
|
||
|
||
- ChatService 实现 chat / explore / consult / discuss 四种模式
|
||
- LLM 调用时注入 DataContext
|
||
- 前端对话区支持非分析类回复(纯文本,无卡片)
|
||
|
||
### Phase 4: PICO 推断与变量字典
|
||
|
||
- explore 对话中 LLM 推断 PICO 分类
|
||
- 前端展示 PICO 确认面板
|
||
- 变量字典逐步丰富机制
|
||
- DataContext 反哺 QPER Q 层
|
||
|
||
---
|
||
|
||
## 11. 预期效果对比
|
||
|
||
| 维度 | 当前系统 | 新架构 |
|
||
|------|---------|-------|
|
||
| **用户上传数据后** | 等待用户发出分析指令 | 自动展示数据概览,邀请探索 |
|
||
| **用户问"这个数据有什么特点"** | 强行匹配 descriptive goal | 进入 explore 模式,LLM 解读数据 |
|
||
| **用户问"应该做什么分析"** | 强行猜测分析类型 | 进入 consult 模式,给出方法建议 |
|
||
| **用户确认"按这个方案做"** | N/A | 进入 analyze → QPER 执行 |
|
||
| **分析完成后用户追问** | 无法处理 | 进入 discuss 模式,解读结果 |
|
||
| **LLM 利用率** | 仅参数提取 | 全流程知识对话 |
|
||
| **数据理解深度** | 仅列名 + 类型 | PICO + 变量字典 + 临床含义 |
|
||
| **多轮对话能力** | 无(每条消息独立处理) | 完整对话上下文 + 数据全貌 |
|
||
|
||
---
|
||
|
||
**文档版本:** v1.0
|
||
**创建日期:** 2026-02-21
|
||
**下一步:** 评审确认后制定详细开发计划
|