Files
AIclinicalresearch/docs/03-业务模块/SSA-智能统计分析/04-开发计划/11-智能对话与工具体系开发计划.md
HaHafeng 3446909ff7 feat(ssa): Complete Phase I-IV intelligent dialogue and tool system development
Phase I - Session Blackboard + READ Layer:
- SessionBlackboardService with Postgres-Only cache
- DataProfileService for data overview generation
- PicoInferenceService for LLM-driven PICO extraction
- Frontend DataContextCard and VariableDictionaryPanel
- E2E tests: 31/31 passed

Phase II - Conversation Layer LLM + Intent Router:
- ConversationService with SSE streaming
- IntentRouterService (rule-first + LLM fallback, 6 intents)
- SystemPromptService with 6-segment dynamic assembly
- TokenTruncationService for context management
- ChatHandlerService as unified chat entry
- Frontend SSAChatPane and useSSAChat hook
- E2E tests: 38/38 passed

Phase III - Method Consultation + AskUser Standardization:
- ToolRegistryService with Repository Pattern
- MethodConsultService with DecisionTable + LLM enhancement
- AskUserService with global interrupt handling
- Frontend AskUserCard component
- E2E tests: 13/13 passed

Phase IV - Dialogue-Driven Analysis + QPER Integration:
- ToolOrchestratorService (plan/execute/report)
- analysis_plan SSE event for WorkflowPlan transmission
- Dual-channel confirmation (ask_user card + workspace button)
- PICO as optional hint for LLM parsing
- E2E tests: 25/25 passed

R Statistics Service:
- 5 new R tools: anova_one, baseline_table, fisher, linear_reg, wilcoxon
- Enhanced guardrails and block helpers
- Comprehensive test suite (run_all_tools_test.js)

Documentation:
- Updated system status document (v5.9)
- Updated SSA module status and development plan (v1.8)

Total E2E: 107/107 passed (Phase I: 31, Phase II: 38, Phase III: 13, Phase IV: 25)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-22 18:53:39 +08:00

1026 lines
62 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.
# SSA-Pro 智能对话与工具体系开发计划
> **文档版本:** v1.8
> **创建日期:** 2026-02-21
> **最后更新:** 2026-02-22v1.8 — Phase IV 开发完成E2E 25/25 通过)
> **文档类型:** 开发计划 (Development Plan)
> **前置设计:**
> - `00-系统设计/SSA-Pro 意图识别与对话架构设计.md`
> - `00-系统设计/SSA-Pro 工具体系规划方案(团队讨论稿).md`v3.1 融合方案)
> - `00-系统设计/SSA-Pro 四层七工具实现机制详解.md`v1.1 三层架构 + 对话层 LLM
> **前置计划:** `04-开发计划/10-QPER架构开发计划-智能化主线.md`Phase E+/Q/P/R 已完成)
> **目标:** 将 SSA 从"统计分析执行器"升级为"数据感知的统计顾问"
---
## 1. 文档概要
### 1.1 背景
QPER 主线Phase E+ → Q → P → R已完成闭环系统具备了完整的"接单→规划→执行→结论"能力。但当前系统存在两个核心问题:
1. **无对话能力** — 用户每条消息都被当作分析请求,无法自由探索数据、咨询方法
2. **工具体系单一** — 仅有 R 执行工具,缺少数据查看、方法咨询、用户交互等非执行类工具
本计划基于已定型的两份设计文档,制定从设计到代码落地的具体开发任务。
### 1.2 与 QPER 主线计划的关系
```
QPER 主线计划10-QPER架构开发计划
├── Phase E+ ✅ 已完成
├── Phase Q ✅ 已完成
├── Phase P ✅ 已完成
├── Phase R ✅ 已完成
├── Phase Deploy 🔶 R 层完成12 工具),前端/部署待收尾 ← 前置条件已满足
└── Phase Q+ 📋 → 吸收进本计划 Phase IDataContext + 变量字典)
本计划11-智能对话与工具体系开发计划)
├── Phase I Session 黑板 + READ 层工具 ✅ 已完成2026-02-22
├── Phase II 意图路由器 + 统一对话入口 ✅ 已完成2026-02-22
├── Phase III method_consult + ask_user 标准化 ✅ 已完成2026-02-22E2E 13/13+4skip
├── Phase IV 对话驱动分析 + QPER 集成 ✅ 已完成2026-02-22E2E 25/25
├── Phase V 反思编排 + 高级特性
└── Phase VI 集成测试 + 可观测性
```
**关键决策:**
- Phase Deploy R 工具层已完成2026-02-22工具 7→12前置条件已满足。前端增强/决策表补齐/部署上线暂缓,不阻塞本计划
- Phase Q+(变量字典 + 变量选择面板)**吸收进**本计划 Phase I因为变量字典是 DataContext 的 Layer 3
- QPER 透明化Pipeline 可观测性)**部分融入**本计划 Phase VI
### 1.3 核心原则(贯穿全计划)
| # | 原则 | 约束 |
|---|------|------|
| 1 | **领域知识可配置化** | 所有 Prompt、决策表、流程模板、工具注册表、叙事模板均由 JSON/数据库驱动,不写死在 TypeScript 中 |
| 2 | **QPER 不动** | QPER 四层的底层 Service 保持不变,新工具封装为 Tool 接口调用已有 Service |
| 3 | **渐进式改造** | 每个 Phase 独立可交付、可验收,不依赖后续 Phase |
| 4 | **安全梯度** | READ 层随时调用ACT 层需确认,降低 LLM 决策风险 |
| 5 | **Token 敏感** | Session 黑板注入 LLM 前做裁剪R 原始输出不入 LLM |
---
## 2. 现有资产盘点
### 2.1 可直接复用(改造程度:低)
| 现有组件 | 对应新工具/模块 | 复用方式 |
|----------|----------------|---------|
| `DataProfileService`Python | `get_data_overview` | 封装为 Tool 接口,追加 PICO 推断字段 |
| `ClarificationCard`(前端) | `ask_user` | 标准化后端输入/输出接口 |
| `WorkflowExecutorService` | `run_step` | 已是傻瓜式执行器,直接封装 |
| `ConfigLoader` + Zod Schema | 新工具注册表 | 扩展工具描述字段 |
| `SSE 基础设施` | 全链路事件推送 | 扩展事件类型 |
| `ssaStore.ts`Zustand | 前端状态扩展 | 扩展 DataContext 和意图状态 |
### 2.2 需要扩展(改造程度:中)
| 现有组件 | 改造内容 |
|----------|---------|
| `DataProfileService` | 新增单列查询 API`get_variable_detail` |
| `DecisionTableService` | 封装为 `method_consult` Tool 接口,追加 LLM 推理补充 |
| `FlowTemplateService` + `QueryService` | 合并封装为 `analysis_plan` Tool |
| `ReflectionService` | 新增 `interpret` 模式(结果解读) |
| `workflow.routes.ts` | 新增统一对话入口 `/api/ssa/chat` |
### 2.3 需要新建
| 新组件 | 位置 | 职责 |
|--------|------|------|
| `SessionBlackboardService` | `backend/services/` | Session 黑板生命周期管理 |
| `IntentRouterService` | `backend/services/` | 意图分类(规则 + LLM 混合) |
| `ChatService` | `backend/services/` | 非 analyze 意图的 LLM 对话处理 |
| `ToolRegistryService` | `backend/services/` | 7 工具注册 + 阶段性可见性控制 |
| `tool_definitions.json` | `backend/config/` | 7 工具的 LLM 描述JSON 驱动) |
| `intent_rules.json` | `backend/config/` | 意图识别规则JSON 驱动) |
### 2.4 已有违规项(需在开发中修正)
| 违规 | 位置 | 修正计划 |
|------|------|---------|
| ~~`AVAILABLE_TOOLS` 硬编码常量~~ | `WorkflowPlannerService.ts` | ✅ Phase IV 已改为 `toolRegistryService.getToolName()` |
---
## 3. 开发计划总览
```
Phase Deploy前置37h / 5.5 天)
┌────────────────────────────────────┐
│ R 工具补齐 11 个 + 部署上线 │
└────────────────┬───────────────────┘
│ 完成后启动
┌──────────────────────────────────────────────────────────────────┐
│ 本计划开发阶段 │
│ │
│ Phase I ──→ Phase II ────→ Phase III ──→ Phase IV ──→ Phase V │
│ Session黑板 对话层LLM核心 方法咨询 THINK+ACT 反思编排 │
│ + READ层 + 意图路由器 + ask_user 工具封装 + 高级特性│
│ (30h/5天) + 统一对话入口 (20h/3天) (21h/3天) (18h/3天) │
│ (35h/5.5天) │
│ ──→ Phase VI集成测试, 10h/2天
└──────────────────────────────────────────────────────────────────┘
总工时(不含 Phase Deploy134h ≈ 22 天
含 Phase Deploy171h ≈ 27.5 天
```
---
## 4. Phase I — Session 黑板 + READ 层30h / 5 天)✅ 已完成
> **目标:让系统能"看懂数据"并陪用户聊天,即使不能跑分析,用户也能感受到 AI 的价值。**
> **产出:** `get_data_overview` + `get_variable_detail` + Session 黑板 + DataContext 前端展示
> **吸收:** 原 QPER 计划的 Phase Q+(变量字典 + 变量选择面板20h
> **完成日期:** 2026-02-225 批次开发 + E2E 测试 31/31 通过)
### 任务清单
| # | 任务 | 工时 | 产出 | 状态 |
|---|------|------|------|------|
| I-1 | **SessionBlackboardService 设计与实现** | 5h | Session 黑板 CRUD + CacheFactoryPostgres-Only+ 互斥锁 patchH1 | ✅ 完成 |
| I-2 | **SessionBlackboard 类型定义** | 1.5h | `SessionBlackboard` interface + Zod SchemaPicoInference 允许 nullH3 | ✅ 完成 |
| I-3 | **get_data_overview 工具实现** | 5h | 封装 DataProfileService + 正态性检验 + 完整病例数 + 五段式报告 + 写入 Session 黑板 | ✅ 完成 |
| I-4 | **get_variable_detail 工具实现** | 4h | Python variable-detail 端点 + bins<=30H2+ Q-Q 点数限制 + Tool 接口 | ✅ 完成 |
| I-5 | **DataContext 前端状态扩展** | 3h | ssaStore dataContext 字段 + DataContextCard 五段式报告组件 | ✅ 完成 |
| I-6 | **PICO 推断 Prompt + PicoInferenceService** | 2h | seed-ssa-pico-prompt.ts 已入库 + LLM 推断 + Zod 校验 + jsonrepair + 重试 | ✅ 完成 |
| I-7 | **变量字典前端面板** | 4h | VariableDictionaryPanel搜索/筛选/类型编辑/标签编辑)+ VariableDetailPanel | ✅ 完成 |
| I-8 | **数据上传后自动触发 + SSE** | 2h | session.routes.ts 异步 fire-and-forget + GET /data-context/stream SSE 端点 | ✅ 完成 |
| I-9 | **TokenTruncationService** | 2h | aggressive/balanced/minimal 策略 + estimateTokens + toPromptString | ✅ 完成 |
| I-10 | **Phase I E2E 测试** | 1.5h | test-phase-i-e2e.cjs: Python 端点 + 数据结构 + H2/H3 防护31/31 通过 | ✅ 完成 |
### 配置化要求
| 配置项 | 文件 | 方法学团队可编辑 |
|--------|------|:---:|
| PICO 推断 Prompt | `pico_inference_prompt.json` 或 DB Prompt 表 | ✅ |
| 变量类型推断规则 | `variable_inference_rules.json` | ✅ |
| Token 裁剪阈值 | `session_config.json`(变量数阈值、滑动窗口大小) | ✅ |
### 验收标准(已全部达成)
```
✅ 上传 CSV 后自动触发 data_overview + PICO 推断(异步 fire-and-forget + SSE 实时进度)
✅ DataContextCard 展示五段式报告(基本特征/缺失/类型/异常值/正态性)
✅ 点击任意变量 → VariableDetailPanel 展示描述统计/直方图/Q-Q/正态性/分类分布
✅ PICO 推断支持观察性研究intervention/comparison 允许 nullH3
✅ 变量字典支持搜索/筛选/修改 confirmedType/label修改通过 PATCH 写回 Session 黑板
✅ SessionBlackboard patch() 使用 sessionId 互斥锁防止并发覆盖H1
✅ Python histogram bins <= 30H2Q-Q 点数有上限,防止前端 Payload 爆炸
✅ E2E 测试 31/31 通过Python 端点 + 数据结构 + H2/H3 验证)
```
---
## 5. Phase II — 对话层 LLM + 意图路由器 + 统一对话入口35h / 5.5 天)✅ 已完成
> **目标:构建对话层 LLM 基础设施 + 意图路由,让系统具备多轮连贯对话能力。**
> **产出:** 对话层 LLM 核心System Prompt + 对话历史 + 上下文组装)+ `IntentRouterService` + `/api/ssa/chat` 统一入口 + `ChatHandlerService`
> **核心认知:对话层 LLM 是系统的大脑和嘴巴(详见《四层七工具实现机制详解》第 1-4 章),不是简单的"调一次 LLM API"。**
> **完成日期:** 2026-02-224 批次开发 + E2E 测试 38/38 通过 + 团队反馈 H1-H4 全部落地)
### 任务清单
| # | 任务 | 工时 | 产出 | 状态 |
|---|------|------|------|------|
| **对话层 LLM 基础设施** | | | | |
| II-1 | **ConversationService 核心实现** | 5h | 对话持久化(复用 AIA conversations/messages 表)+ LLM 流式调用 + 5s 心跳保活H1+ Placeholder 占位H3 | ✅ 完成 |
| II-2 | **对话历史管理** | 3h | 吸收进 ConversationService滑动窗口 MAX=20 + generating 消息过滤 + 消息计数 | ✅ 完成 |
| II-3 | **System Prompt 架构实现** | 4h | SystemPromptService 六段式组装 + H2 Lost-in-the-Middle 修正(意图指令放最后)+ Token 预算裁剪 | ✅ 完成 |
| II-4 | **System Prompt 模板(全意图)** | 3h | seed-ssa-phase2-prompts.ts8 个 PromptSSA_BASE_SYSTEM + 6 意图指令 + SSA_INTENT_ROUTER | ✅ 完成 |
| **意图路由器** | | | | |
| II-5 | **意图识别规则引擎** | 3h | `intent_rules.json`5 条规则 + excludeKeywords + contextGuards + defaultIntent | ✅ 完成 |
| II-6 | **IntentRouterService 实现** | 4h | 规则优先 + LLM 兜底 + 上下文守卫C5+ parseLLMResponse 安全解析 | ✅ 完成 |
| II-7 | **Intent Router Prompt 模板** | 1.5h | SSA_INTENT_ROUTER Prompt 已入 seed 脚本(含 Few-Shot 表格) | ✅ 完成 |
| **统一对话入口 + 基础意图处理** | | | | |
| II-8 | **统一对话 API `/api/ssa/chat`** | 3h | chat.routes.tsPOST /:id/chatSSE+ GET /:id/chat/history + GET /:id/chat/conversation | ✅ 完成 |
| II-9 | **ChatHandlerService — chat 意图处理** | 2h | handleChat()ConversationService(DataContext) → 对话层 LLM 直接回复 | ✅ 完成 |
| II-10 | **ChatHandlerService — explore 意图处理** | 2.5h | handleExplore():读黑板 → TokenTruncation 裁剪 → 工具输出注入 → 对话层 LLM 生成数据解读 | ✅ 完成 |
| II-11 | **前端对话入口统一** | 2h | useSSAChat hook + SSAChatPane 改造SSE 流式 + ThinkingBlock + 意图标签 + H3 输入锁 + 中断按钮) | ✅ 完成 |
| II-12 | **Phase II 联调测试** | 2h | test-ssa-phase2-e2e.ts11 组测试 38/38 通过6 意图分类 + SSE 流式 + 对话历史 + 上下文守卫) | ✅ 完成 |
### 意图分发逻辑
```
/api/ssa/chat 收到消息
→ IntentRouterService.classify(message, sessionContext)
→ chat → ChatService.handleChat() → 直接 LLM 回复
→ explore → ChatService.handleExplore() → DataProfile + LLM 解读
→ consult → Phase III: method_consult 路径
→ analyze → 转发到现有 /api/ssa/workflow/planQPER 入口)
→ discuss → Phase V: write_report(interpret) 路径
→ feedback → Phase V: 反思编排路径
```
### ConversationService 核心架构
```
每次对话请求的处理流程:
用户消息
→ IntentRouterService.classify() → 意图分类
→ ConversationService.buildContext():
├── 加载 base_system Prompt固定角色
├── 注入 DataContext从 Session 黑板,带 Token 裁剪)
├── 注入意图指令段(按 intent 选择对应 Prompt 段)
├── 注入工具输出(如有工具调用,结构化 JSON 作为上下文)
├── 注入分析结果discuss/feedback 时,从 Session 黑板取 stepResults 摘要)
└── 加载对话历史滑动窗口5-10 轮)
→ LLM.call(assembledPrompt)
→ 回复返回前端 + 消息存入对话历史
```
### 配置化要求
| 配置项 | 文件 | 方法学团队可编辑 |
|--------|------|:---:|
| 意图识别规则(关键词 + 上下文条件) | `intent_rules.json` | ✅ |
| Intent Router Prompt | `intent_router_prompt.json` 或 DB Prompt 表 | ✅ |
| 基础角色 System Prompt | DB Prompt 表 `base_system` | ✅ |
| 6 个意图指令段 | DB Prompt 表 `chat_instruction` / `explore_instruction` / `consult_instruction` / `analyze_instruction` / `discuss_instruction` / `feedback_instruction` | ✅ |
| 意图→可见工具映射 | `intent_tool_visibility.json` | ✅ |
| 对话历史窗口配置 | `session_config.json`窗口大小、Token 上限) | IT 团队 |
### 验收标准(已全部达成)
```
✅ "BMI 的正常范围是多少?" → chat → 对话层 LLM 带 DataContext 直接回复E2E Test 4
✅ "帮我看看各组的样本分布" → explore → 黑板数据注入 → 对话层 LLM 生成数据解读E2E Test 5
✅ "对 BMI 和血压做相关分析" → analyze → LLM 生成方案摘要E2E Test 6
✅ "应该用什么方法比较两组差异" → consult → LLM 方法推荐回复E2E Test 7
✅ "这个 p 值说明什么" → discuss 被守卫降级为 chat无分析结果时E2E Test 8
✅ LLM 不可用时 → 规则引擎兜底 → 正确识别明确意图IntentRouterService try/catch
✅ 无法判断时 → 默认 chat最安全的兜底confidence=0.5
✅ 对话历史持久化 → 消息有 intent 标记 + 无残留 generating 状态E2E Test 9
✅ SSE 心跳保活 5sH1+ Placeholder 占位H3+ 意图指令放最后H2
✅ 前端 useSSAChat hook + SSAChatPane 流式渲染 + ThinkingBlock + 意图标签 + 输入锁
```
### 团队反馈落地H1-H4
| 编号 | 问题 | 修正 | 实现文件 |
|------|------|------|---------|
| H1 | SSE 超时/网关断开 | 5s 心跳 keep-alive + 标准化错误事件 | ConversationService.ts |
| H2 | Lost in the Middle | 意图指令放 Prompt 最后,工具输出放中间 | SystemPromptService.ts |
| H3 | 对话历史竞态条件 | DB Placeholder 占位 + 前端 isGenerating 输入锁 | ConversationService.ts + useSSAChat.ts |
| H4 | 前端渐进迁移 | 直接原地改造(开发阶段无需灰度) | SSAChatPane.tsx |
---
## 6. Phase III — method_consult + ask_user 标准化20h / 3 天)✅ 已完成
> **目标:系统能给用户推荐分析方法(不执行),并在不确定时主动提问。**
> **产出:** `MethodConsultService` + `AskUserService` + `ToolRegistryService`H2 仓储模式)+ `AskUserCard` + consult 意图完整链路
> **完成日期:** 2026-02-225 批次代码开发完成,待数据库启动后运行 seed + E2E 测试)
### 任务清单
| # | 任务 | 工时 | 产出 | 状态 |
|---|------|------|------|------|
| III-1 | **method_consult Tool 实现** | 5h | MethodConsultService: PICO→ParsedQuery 映射 + DecisionTable 匹配 + ToolRegistry 工具详情 + formatForLLM | ✅ 完成 |
| III-2 | **method_consult Prompt 模板** | 2h | seed-ssa-phase3-prompts.ts: SSA_METHOD_CONSULTP1 结论先行+结构化列表约束) | ✅ 完成(待 seed |
| III-3 | **ask_user 后端接口标准化** | 4h | AskUserService: createQuestion + parseResponse + clearPending + 黑板持久化 + H1 全局打断判定 | ✅ 完成 |
| III-4 | **ask_user 前端组件增强** | 3h | AskUserCard.tsx: 4 种 inputTypesingle_select/multi_select/free_text/confirm+ H1 跳过按钮 + H3 统一替代 ClarificationCard | ✅ 完成 |
| III-5 | **consult 意图完整链路** | 3h | ChatHandlerService.handleConsultmethod_consult→LLM 推荐→ask_user 确认)+ handleAskUserResponseconfirm/skip/change | ✅ 完成 |
| III-6 | **ToolRegistryService** | 2h | H2 仓储模式: IToolRepository 接口 + JsonToolRepository + formatForLLM/formatToolDetail + QueryService 替换 | ✅ 完成 |
| III-7 | **Phase III 联调测试** | 1h | test-ssa-phase3-e2e.ts: 8 组测试consult + ask_user confirm/skip + H1 全局打断 + 对话历史) | ✅ 完成13 pass / 4 skip |
### 配置化要求
| 配置项 | 文件 | 方法学团队可编辑 |
|--------|------|:---:|
| 方法推荐 Prompt | DB Prompt 表 SSA_METHOD_CONSULT | ✅ |
| 工具定义(名称、描述、参数) | `tools_registry.json` | ✅ |
| 决策表(四维匹配规则) | `decision_tables.json` | ✅ |
### 验收标准
```
✅ "我想比较两组差异" → consult → MethodConsultService → DecisionTable 匹配 T 检验
✅ LLM 输出 P1 格式(结论先行 + 理由/前提/替代列表)
✅ method_consult 不触发执行,推送 ask_user confirm 卡片
✅ 用户确认 → 可转 analyze用户跳过 → 友好回复
✅ H1: 用户无视卡片直接打字 → 自动 clearPending + 按新意图路由
✅ H2: ToolRegistryService 通过 IToolRepository 隔离数据源
✅ H3: AskUserCard 统一替代 ClarificationCard旧组件保留 deprecated
✅ 工具注册表可通过热更新 API 重载
```
### 团队审查修正落地
| 编号 | 盲区 | 修正 | 实现文件 |
|------|------|------|---------|
| H1 | 状态死锁/意图强行打断 | 前端跳过按钮 + 后端全局打断判定chat.routes 入口 pendingAskUser 检测) | chat.routes.ts, AskUserCard.tsx |
| H2 | ToolRegistry 绑死 JSON | IToolRepository 接口 + JsonToolRepository 实现 | ToolRegistryService.ts |
| H3 | Clarification vs AskUser 概念冲突 | 统一 AskUser 领域模型,新建 AskUserCard | AskUserService.ts, AskUserCard.tsx |
| P1 | Prompt 输出格式 | 结论先行 + 结构化列表约束 | seed-ssa-phase3-prompts.ts |
---
## 7. Phase IV — 对话驱动分析 + QPER 集成14h / 2.5 天)✅ 已完成
> **目标:打通对话层与 QPER 执行层的断裂,让 analyze 意图在对话流中完成全链路。**
> **产出:** ToolOrchestratorService + handleAnalyze 重写 + AVAILABLE_TOOLS 配置化 + 前端事件协调 + E2E
> **完成日期:** 2026-02-225 批次开发 + E2E 测试 25/25 通过 + 团队审查 H1-H3+B1-B2 全部落地)
### 现状诊断
Phase II 的 `handleAnalyze()` 是一个占位符 — 只生成 1-3 句 LLM 摘要就结束QPER 计划生成和执行需要前端单独调用 `/workflow/plan` + `/workflow/{id}/stream`。对话层与执行层完全断裂。
### 核心架构决策
| # | 决策 | 选择 | 理由 |
|---|------|------|------|
| D1 | 执行通道 | **保留独立 workflow SSE** | R 引擎每步 20-40sworkflow SSE 已有心跳/重连/进度机制Workspace 已完美适配 |
| D2 | 计划传递 | **chat SSE 推送 `analysis_plan` 事件** | 前端不再单独调 POST /workflow/plan计划生成在对话流中完成 |
| D3 | 确认方式 | **双通道** | ask_user 卡片 + Workspace "执行"按钮,两者都触发同一个 executeWorkflow() |
| D4 | 工具封装 | **ToolOrchestratorService 薄层** | 不创建独立 Tool 类(当前阶段过度设计),一个 Service 统一封装 plan/execute/report |
| D5 | PICO 角色 | **可选 hint非必要条件** | 用户直接表述优先于系统推断PICO 存在时作为 LLM 附加上下文,不存在时退化为纯 LLM + DataProfile 解析 |
### 团队审查修正记录
| # | 盲区 | 审查结论 | 落地方案 |
|---|------|---------|---------|
| H1 | **planWorkflow 上下文失忆** — plan() 仅传 userMessage丢失 PICO/变量字典等黄金上下文 | ✅ 接受核心洞察,实现方式优化 | ToolOrchestratorService.plan() 读取黑板PICO 作为可选 hint 注入 LLM prompt非强依赖 |
| H2 | **幽灵卡片竞态** — Workspace 触发执行后Chat 区 ask_user 卡片仍可点击 | ✅ 接受,简化实现 | 任一侧触发执行时同步清除 pendingQuestion + clearPending卡片消失而非仅禁用 |
| H3 | **SSE 事件乱序** — 建议 analysis_plan → LLM → ask_user 之间加 delay(500) | ❌ 拒绝 delay 方案 | SSE 协议保证顺序TCPJS 单线程保证处理顺序;保持严格串行 await 即可 |
| B1 | **修改建议循环** — 用户在 ask_user 自由文本中要求换方法,应走重新规划 | ✅ 接受 | handleAskUserResponse 识别 change_method → 重新调 handleAnalyze() |
| B2 | **旧 API 向后兼容** — /workflow/plan 仍需可用 | ✅ 接受 | 改调用方不改被调用方E2E 显式验证旧 API |
### PICO 三层降级策略D5 详解)
```
用户上传数据后直接说"对BMI做T检验" → 场景 B最常见~50%
用户经历完整探索/PICO推断后再分析 → 场景 A~30%
用户说"帮我分析一下"很模糊 → 场景 C~20%
ToolOrchestratorService.plan(sessionId, userMessage):
1. 读 SessionBlackboardPICO 可能有也可能没有)
2. 判断路径:
┌─ 用户消息明确(提到变量+目标)→ planWorkflow()LLM 解析PICO 不参与)
├─ 用户消息模糊 + PICO 存在 → PICO 作为 hint 注入 LLM prompt提高准确率
└─ 用户消息模糊 + 无 PICO → 纯 LLM + DataProfile 推断confidence<0.7 则追问
3. 无论哪条路径 → ParsedQuery → DecisionTable → FlowTemplate → WorkflowPlan
核心原则: PICO 锦上添花,不是必要条件。用户直接表述永远优先于系统推断。
```
### 核心数据流
```mermaid
sequenceDiagram
participant U as 用户
participant FE as ChatPane
participant WS as Workspace
participant Chat as "/chat SSE"
participant TO as ToolOrchestratorService
participant WP as WorkflowPlannerService
participant WE as WorkflowExecutorService
U->>FE: "对BMI和血压做相关分析"
FE->>Chat: POST /chat
Chat->>TO: plan(sessionId, userMessage)
Note over TO: 读黑板, PICO作为可选hint
TO->>WP: planWorkflow()
WP-->>TO: WorkflowPlan
TO-->>Chat: return plan
Chat-->>FE: SSE: analysis_plan事件
FE->>WS: 自动创建Record+打开Workspace
Chat-->>FE: SSE: LLM流式方案说明
Chat-->>FE: SSE: ask_user确认卡片
U->>FE: 点"确认执行"
Note over FE: 清除pendingQuestion(H2)
FE->>WS: executeWorkflow(workflowId)
WS->>WE: GET /workflow/id/stream
WE-->>WS: SSE: 步骤进度+结果
WS->>WS: 显示分析结果+结论
```
### 任务清单(修订后)
| # | 任务 | 工时 | 产出 | 状态 |
|---|------|------|------|------|
| IV-1 | **AVAILABLE_TOOLS 配置化** | 2h | WorkflowPlannerService 删除硬编码常量11 处引用),改为 toolRegistryService.getToolName(); ToolCode 改为 string 类型 | ✅ 完成 |
| IV-2 | **工具可见性实现** | 1h | ToolRegistryService 新增 getVisibleTools(intent) 按意图过滤工具列表 | ✅ 完成 |
| IV-3 | **ToolOrchestratorService** | 2h | 新建 Service: plan()(含 PICO hint 三层降级 D5+ formatPlanForLLM() + buildPicoHint() | ✅ 完成 |
| IV-4 | **handleAnalyze 重写** | 3h | 多阶段编排: 调 orchestrator.plan → 推 analysis_plan SSE → LLM 流式方案说明 → 推 ask_user 确认(含 confirm_plan/change_method 选项) | ✅ 完成 |
| IV-5 | **handleAskUserResponse 扩展** | 1h | 新增 confirm_plan 路由(推 plan_confirmed SSE; change_method 走重新规划循环(B1); 执行触发时 clearPending(H2) | ✅ 完成 |
| IV-6 | **前端对接** | 3h | useSSAChat 增加 analysis_plan SSE → ssaStore.addRecord + setWorkspaceOpen; plan_confirmed SSE → pendingPlanConfirm 触发 executeWorkflow; SSAChatPane 渲染 AskUserCard + 幽灵卡片清除(H2) | ✅ 完成 |
| IV-7 | **Prompt 种子** | 1h | seed-ssa-phase4-prompts.ts: SSA_ANALYZE_PLAN指导 LLM 解释分析方案 + 步骤/理由/注意事项格式约束)已入库 | ✅ 完成 |
| IV-8 | **E2E 测试** | 1h | test-ssa-phase4-e2e.ts: 7 组测试 25/25 通过analyze 意图→analysis_plan→ask_user 确认→旧 API 兼容 B2→AVAILABLE_TOOLS 配置化→对话历史) | ✅ 完成 |
> **总工时: 14h原计划 21h → 精简 7h因不创建独立 Tool 类)**
### data_source 自动注入流程
```
executeWorkflow() 被前端触发
→ GET /workflow/{id}/stream
→ WorkflowExecutorService.resolveDataSource() 自动注入(已有逻辑,不改)
→ POST 给 R 服务
→ LLM 和 ToolOrchestratorService 全程不感知 data_source
```
### 验收标准(已全部达成)
```
✅ "请执行分析比较两组患者的BMI差异" → analyze → plan 生成 3 步骤(对话内)→ ask_user 确认卡片E2E Test 3
✅ analysis_plan 通过 chat SSE 推送,前端自动创建 AnalysisRecord 并打开 WorkspaceE2E Test 3
✅ 无 PICO 时链路完全可用 — E2E 测试数据无完整 PICOplanWorkflow 仍成功生成方案E2E Test 6
✅ 有 PICO 时作为 hint 注入ToolOrchestratorService.buildPicoHint不覆盖用户显式指令
✅ ask_user 确认卡片包含 confirm_plan确认执行和 change_method修改方案选项E2E Test 4
✅ confirm_plan 响应 → 推 plan_confirmed SSE → 前端 pendingPlanConfirm → executeWorkflowH2 幽灵卡片修正)
✅ change_method 响应 → handleAskUserResponse 重新调 handleAnalyzeB1 修改建议循环)
✅ WorkflowPlannerService.AVAILABLE_TOOLS 已删除11 处引用全部改为 toolRegistryService.getToolName()E2E Test 6
✅ ToolRegistryService.getVisibleTools(intent) 按意图过滤工具列表
✅ 旧 /workflow/plan API 仍可正常调用,返回 WorkflowPlan 含 workflow_id + 步骤E2E Test 5, B2 向后兼容)
✅ 对话历史中有 analyze 意图消息记录,无残留 generating 状态E2E Test 7
✅ LLM 流式方案说明 >200 字符,使用 SSA_ANALYZE_PLAN Prompt 指导输出E2E Test 3
```
---
## 8. Phase V — 反思编排 + 高级特性18h / 3 天)
> **目标:系统具备自修复能力和结果深度解读能力。**
> **产出:** 双轨反思机制 + write_report(interpret) + discuss 意图处理 + feedback 意图处理
### 任务清单
| # | 任务 | 工时 | 产出 | 依赖 |
|---|------|------|------|------|
| V-1 | **错误分类器实现** | 3h | run_step 返回 error → 分类为"可自愈"(参数级) 或"不可自愈"(方法级) | Phase IV |
| V-2 | **自动反思(静默重试)** | 3h | 可自愈错误 → 注入错误日志 + DataContext → LLM 修正参数 → 重试MAX 2 次) | V-1 |
| V-3 | **手动反思(用户驱动)** | 3h | feedback 意图 → 注入完整 qperTrace → LLM 分析 → 新 analysis_plan → 重新执行 | V-1, Phase IV |
| V-4 | **write_report interpret 模式** | 3h | ReflectionService 扩展:接收用户问题 + 已有结果 → LLM 深度解读 | Phase IV |
| V-5 | **discuss 意图处理(对话层 LLM 集成)** | 2h | 检测最近有分析结果 → 分析结果注入 ConversationService → 对话层 LLM 深度解读 | V-4, Phase II |
| V-6 | **反思 Prompt 模板** | 2h | `reflection_prompt.json`(自动修正 + 手动反思两套 Prompt | 无 |
| V-7 | **Phase V 联调测试** | 2h | 自动重试场景 + 用户不满意场景 + 结果解读场景 | 全部 |
### 双轨反思流程
```
触发路径 1 — 自动(用户无感知):
run_step → error("Column 'BP' not found")
→ 错误分类器 → 可自愈(列名拼写)
→ 注入 {error, dataOverview.columns} → LLM 修正 → 重试
→ 成功 → 用户看到正常结果
触发路径 2 — 手动(用户驱动):
用户: "结果不对p 值不应该这么大"
→ IntentRouter → feedback
→ 注入 qperTrace(最近 3 条,摘要压缩) → LLM 分析原因
→ ask_user("建议1)换非参数 2)排除极值 3)合并亚组")
→ 用户选择 → 新 analysis_plan → run_step → write_report
```
### 配置化要求
| 配置项 | 文件 | 方法学团队可编辑 |
|--------|------|:---:|
| 错误分类映射R 报错关键词 → 分类) | `error_classification.json` | ✅ |
| 自动修正 Prompt | `auto_fix_prompt.json` 或 DB Prompt 表 | ✅ |
| 手动反思 Prompt | `manual_reflection_prompt.json` 或 DB Prompt 表 | ✅ |
| 结果解读 Prompt | `interpret_prompt.json` 或 DB Prompt 表 | ✅ |
### 验收标准
```
✅ run_step 列名错误 → 自动修正并重试 → 用户无感知看到正常结果
✅ 超过 2 次重试 → 停止重试 → 报告用户并建议替代方案
✅ 用户说"结果不对" → feedback 意图 → 注入 QPER 记录 → 新方案 → 重新执行
✅ 用户说"p 值说明什么" → discuss 意图 → 带分析结果的深度解读
✅ interpret 模式不重新跑分析,只解读已有结果
```
---
## 9. Phase VI — 集成测试 + 可观测性10h / 2 天)
> **目标:全链路验证 + 开发者调试支持 + 文档更新。**
> **产出:** 端到端测试脚本 + QPER 透明化面板 + 文档更新
### 任务清单
| # | 任务 | 工时 | 产出 | 依赖 |
|---|------|------|------|------|
| VI-1 | **端到端测试脚本** | 3h | 覆盖 6 种意图的自动化测试 + 7 工具调用链验证 | Phase V |
| VI-2 | **QPER + Tool 可观测性面板** | 4h | 开发者面板意图分类日志、工具调用链、Session 黑板状态、LLM Prompt/Response 可查看 | Phase V |
| VI-3 | **文档更新** | 2h | 更新模块状态文档 + README + API 文档 | Phase V |
| VI-4 | **回归测试** | 1h | 确认原有 QPER 流程未被破坏 | 全部 |
### 验收标准
```
✅ 6 种意图场景全部自动化验证通过
✅ 7 个工具调用链(典型调用链场景 1-5端到端通过
✅ 开发者面板可查看IntentRouter 分类结果 + 工具调用序列 + Session 黑板快照
✅ 原有 QPER 直接调用路径(/api/ssa/workflow/plan仍然可用
```
---
## 10. 工时与里程碑
### 10.1 工时汇总
| Phase | 名称 | 工时 | 日历天 | 里程碑 | v1.1 变更 |
|-------|------|------|--------|--------|----------|
| **前置** | **Phase DeployR 工具补齐)** | **37h** | **5.5 天** | R 工具 7→11生产环境可用 | 不变 |
| **I** | **Session 黑板 + READ 层** | **30h** | **5 天** | 系统能看懂数据 | 不变 |
| **II** | **对话层 LLM + 意图路由器 + 统一对话入口** | **35h** | **5.5 天** | 系统能连贯对话 + 区分意图 | **+11h**:新增 ConversationService(5h) + 对话历史管理(3h) + System Prompt 架构(4h) + 全意图 Prompt 模板(3h)chat/explore 工时因依赖 ConversationService 而减少 |
| **III** | **method_consult + ask_user** | **20h** | **3 天** | 系统能推荐方法、主动提问 | 不变consult 对话层集成已含在 III-5 |
| **IV** | **对话驱动分析 + QPER 集成** | **14h** | **2.5 天** | analyze 意图打通对话→计划→执行→结果 | **v1.7 修订**:不创建独立 Tool 类ToolOrchestratorService 薄层封装21h→14h含 H1-H3+B1-B2 团队审查修正 |
| **V** | **反思编排 + 高级特性** | **18h** | **3 天** | 自修复 + 结果解读 | 不变 |
| **VI** | **集成测试 + 可观测性** | **10h** | **2 天** | 全链路验证 + 开发者调试 | 不变 |
| | **本计划合计** | **127h** | **~20.5 天** | **智能对话 + 工具体系上线** | v1.7: Phase IV 21h→14h(-7h) |
| | **含 Phase Deploy 总计** | **164h** | **~26 天** | **完整系统升级** | v1.7: -7h |
### 10.2 里程碑时间线
```
Week 1 ──────────────────────────────────
Day 1-5.5: Phase DeployR 工具补齐 + 部署)
✅ 里程碑 0R 工具 11 个全部上线
Week 2 ──────────────────────────────────
Day 6-10: Phase ISession 黑板 + READ 层 + DataContext 前端)
✅ 里程碑 1数据上传后展示 DataContext 全貌 + 变量字典
Week 3 ──────────────────────────────────
Day 11-15.5: Phase II对话层 LLM 基础设施 + 意图路由器 + chat/explore
✅ 里程碑 2A多轮连贯对话能力上线对话层 LLM + System Prompt + 对话历史)
Week 4 ──────────────────────────────────
Day 16-18: Phase IIImethod_consult + ask_user 标准化)
Day 19-21: Phase IVTHINK + ACT 工具封装 + analyze 完整链路)
✅ 里程碑 2B系统能区分 6 种意图,支持自由对话 + 方法咨询 + 完整分析链路
Week 5 ──────────────────────────────────
Day 22-24: Phase V反思编排 + discuss + feedback
✅ 里程碑 37 工具 + 4 层架构 + 对话层 LLM 完整上线
Week 5-6 ──────────────────────────────
Day 25-26: Phase VI集成测试 + 可观测性 + 文档)
✅ 里程碑 4全系统验收完成
Week 6 后 ──────────────────────────────
收集用户反馈,评估意图识别准确率 + 对话连贯性
评估是否需要 RAG 增强 method_consult
评估 LLM Function Calling 模式预研Phase 4+ 方向)
```
### 10.3 里程碑验收条件
| 里程碑 | 核心验收 | 用户可感知变化 |
|--------|---------|---------------|
| **M0** | 11 个 R 工具全部通过单元测试 | 更多分析类型可用 |
| **M1** | 上传数据 → 自动展示数据全貌 + PICO 推断 + 变量字典 | "系统读懂了我的数据" |
| **M2A** | 多轮对话连贯 + 对话层 LLM System Prompt 完整 + 意图识别准确 | "像和一个记住之前聊过什么的统计专家对话" |
| **M2B** | 自由对话 + 数据探索 + 方法咨询 + 主动提问 + 完整分析链路 | "全流程 AI 陪伴" |
| **M3** | 完整分析旅程:探索→咨询→确认→执行→报告→解读→反思 | "结果不满意可以反思重来" |
| **M4** | 自动化测试通过 + 开发者面板可用 + 文档齐全 | 团队可维护和扩展 |
---
## 11. 新增配置文件清单
> **约束:一切业务逻辑靠读 JSON/数据库驱动,绝不写死在 TypeScript 的 if-else 和常量对象中。**
### 11.1 新增 JSON 配置文件
| 文件 | 位置 | 用途 | Owner | Phase |
|------|------|------|-------|-------|
| `tool_definitions.json` | `backend/config/` | 7 工具的 LLM 描述(名称、参数 Schema、触发说明 | 方法学团队 | III |
| `intent_rules.json` | `backend/config/` | 意图识别规则(关键词、上下文条件、优先级) | 方法学团队 | II |
| `intent_tool_visibility.json` | `backend/config/` | 意图→可见工具映射 | 方法学团队 | II |
| `session_config.json` | `backend/config/` | Token 控制阈值(变量数裁剪、滑动窗口大小、摘要长度) | IT 团队 | I |
| `error_classification.json` | `backend/config/` | R 报错关键词→错误分类映射 | 方法学团队 | V |
| `variable_inference_rules.json` | `backend/config/` | 变量类型/角色推断规则(列名模式、数据特征) | 方法学团队 | I |
### 11.2 新增/更新 Prompt 模板DB 管理)
| Prompt | 用途 | Seed 脚本 | Phase |
|--------|------|-----------|-------|
| `pico_inference` | PICO 推断 | `seed-ssa-pico-prompt.ts` | I |
| `intent_router` | 意图分类 | `seed-ssa-intent-router-prompt.ts` | II |
| `base_system` | 对话层 LLM 基础角色(固定段) | `seed-ssa-conversation-prompts.ts` | II |
| `chat_instruction` | chat 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `explore_instruction` | explore 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `consult_instruction` | consult 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `analyze_instruction` | analyze 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `discuss_instruction` | discuss 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `feedback_instruction` | feedback 意图指令段 | `seed-ssa-conversation-prompts.ts` | II |
| `method_consult` | 方法推荐 | `seed-ssa-method-consult-prompt.ts` | III |
| `auto_fix` | 自动错误修正 | `seed-ssa-auto-fix-prompt.ts` | V |
| `manual_reflection` | 手动反思 | `seed-ssa-reflection-prompt.ts`(扩展) | V |
| `interpret` | 结果解读 | `seed-ssa-interpret-prompt.ts` | V |
### 11.3 Zod Schema 校验
每个 JSON 配置文件都必须有对应的 Zod Schema`ConfigLoader.load()` 时严格校验。参考已有的 `config/schemas.ts` 模式扩展。
---
## 12. 新增代码目录规划
```
backend/src/modules/ssa/
├── services/
│ ├── SessionBlackboardService.ts # 🆕 Phase ISession 黑板管理
│ ├── ConversationService.ts # 🆕 Phase II对话层 LLM 核心System Prompt 组装 + LLM 调用)
│ ├── ConversationHistoryService.ts # 🆕 Phase II对话历史管理存储 + 滑动窗口裁剪)
│ ├── IntentRouterService.ts # 🆕 Phase II意图分类
│ ├── ChatService.ts # 🆕 Phase II非 analyze 意图的对话处理(依赖 ConversationService
│ ├── ToolRegistryService.ts # 🆕 Phase III工具注册 + 阶段性可见性
│ ├── ToolOrchestratorService.ts # 🆕 Phase IV工具编排data_source 注入等)
│ ├── ErrorClassifierService.ts # 🆕 Phase V错误分类
│ ├── QueryService.ts # 已有,不变
│ ├── DecisionTableService.ts # 已有Phase III 封装为 method_consult
│ ├── FlowTemplateService.ts # 已有Phase IV 封装为 analysis_plan 内部
│ ├── WorkflowPlannerService.ts # 已有Phase IV 修正 AVAILABLE_TOOLS
│ ├── WorkflowExecutorService.ts # 已有Phase IV 封装为 run_step
│ ├── ReflectionService.ts # 已有Phase V 新增 interpret 模式
│ ├── ConclusionGeneratorService.ts # 已有,不变
│ ├── DataProfileService.ts # 已有Phase I 新增单列查询
│ └── DataParserService.ts # 已有,不变
├── config/
│ ├── ConfigLoader.ts # 已有,扩展加载新配置
│ ├── schemas.ts # 已有,扩展新 Schema
│ ├── tools_registry.json # 已有R 工具注册表)
│ ├── decision_tables.json # 已有
│ ├── flow_templates.json # 已有
│ ├── tool_definitions.json # 🆕 Phase III7 个 Agent 工具定义
│ ├── intent_rules.json # 🆕 Phase II意图识别规则
│ ├── intent_tool_visibility.json # 🆕 Phase II意图→工具映射
│ ├── session_config.json # 🆕 Phase IToken 控制配置
│ ├── error_classification.json # 🆕 Phase V错误分类映射
│ └── variable_inference_rules.json # 🆕 Phase I变量推断规则
├── routes/
│ ├── chat.routes.ts # 🆕 Phase II统一对话入口
│ ├── workflow.routes.ts # 已有,保持兼容
│ ├── config.routes.ts # 已有,扩展热更新范围
│ └── ...
└── types/
├── tool.types.ts # 🆕 Phase ITool 接口定义
├── session.types.ts # 🆕 Phase ISessionBlackboard 类型
├── intent.types.ts # 🆕 Phase II意图类型定义
├── query.types.ts # 已有
└── reflection.types.ts # 已有
frontend-v2/src/modules/ssa/
├── components/
│ ├── DataContextCard.tsx # 🆕 Phase I数据全貌展示卡片
│ ├── VariableDictionaryPanel.tsx # 🆕 Phase I变量字典面板
│ ├── AnalysisPlanReview.tsx # 🆕 Phase IV分析方案审查面板
│ ├── DevPanel.tsx # 🆕 Phase VI开发者调试面板
│ ├── ClarificationCard.tsx # 已有Phase III 标准化增强
│ └── ...
├── stores/
│ └── ssaStore.ts # 已有Phase I 扩展 dataContext 字段
└── types/
└── index.ts # 已有,扩展新类型
```
---
## 13. 风险管理
| 风险 | 概率 | 影响 | 应对 |
|------|------|------|------|
| 意图识别准确率不足 | 中 | 高 | 混合路由(规则 + LLM+ 默认兜底为 chat最安全收集误分类日志持续优化规则 |
| Session 黑板内存泄漏 | 中 | 中 | 使用 `CacheFactory`Postgres-Only参见 §16.4+ TTL 过期策略(默认 2h监控内存占用 |
| Token 成本过高 | 中 | 中 | Token 控制三原则stepResults 清旧、qperTrace 滑窗、R 原始输出不入 LLM |
| DataContext 注入导致 LLM 上下文过长 | 低 | 中 | 变量字典裁剪策略≤20 全注入、>20 只注入 confirmed、>50 只注入 PICO 相关) |
| 新旧 API 并存导致混乱 | 中 | 低 | `/api/ssa/chat` 为新统一入口;`/api/ssa/workflow/plan` 保留为内部调用;前端统一走新入口 |
| Phase Deploy 延期影响本计划启动 | 低 | 高 | Phase I 不依赖 Phase Deploy只需已有 7 个 R 工具),可并行启动 |
| PICO 推断准确率不足 | 中 | 中 | 始终标记为"AI 推断",必须经 ask_user 确认才生效;错误推断不影响系统可用性 |
### 回退策略
| 层级 | 正常路径 | 降级路径 | 触发条件 |
|------|---------|---------|---------|
| **意图路由** | LLM 分类 | 规则引擎兜底 | LLM 超时/不可用 |
| **chat/explore** | LLM(DataContext) 对话 | 返回 DataContext 结构化摘要(无 LLM 解读) | LLM 超时/不可用 |
| **method_consult** | 决策表 + LLM 推理 | 仅决策表匹配结果(无 LLM 补充推理) | LLM 超时/不可用 |
| **analysis_plan** | 正常规划 | 回退到 WorkflowPlannerService 硬编码逻辑 | 决策表 + 模板均无匹配 |
| **反思(自动)** | LLM 修正参数 | 直接报告错误给用户 | 重试 2 次仍失败 |
| **Session 黑板** | CacheFactoryPostgres/Memory | 每次从 DataProfileService 重新生成(慢但可用) | 缓存过期或丢失 |
---
## 14. 验收场景总览
### 场景 1完整分析旅程覆盖 7 工具 + 6 意图)
```
用户上传数据
→ [自动] get_data_overview → DataContext 卡片展示
用户: "这个数据有什么特点?"
→ [chat] LLM(DataContext) → "您的数据有 200 行 15 列..."
用户: "帮我看看 BMI 这个变量"
→ [explore] get_variable_detail("bmi") → 分布图 + 统计量
用户: "你觉得结局变量是什么?"
→ [explore] LLM 推断 PICO → ask_user 确认 → 写入 Session
用户: "我想比较两组差异,应该用什么方法?"
→ [consult] method_consult → 推荐 T 检验 + 理由 + 前提
用户: "好的,按这个方案执行"
→ [analyze] analysis_plan → 用户确认 → run_step ×N → write_report
用户: "p 值 0.03 说明什么?"
→ [discuss] write_report(interpret) → 深度解读
用户: "能不能换个方法试试?"
→ [feedback] 反思编排 → 新方案 → 重新执行
```
### 场景 2纯数据探索不做分析
```
用户上传数据 → DataContext 展示
用户: "有多少缺失值?" → [chat] 回答
用户: "age 的分布?" → [explore] 变量详情
用户: "哪些变量可能是混杂因素?" → [chat] LLM 基于 DataContext 推理
用户: "谢谢,我先了解这些" → [chat] 结束
```
### 场景 3LLM 不可用降级
```
用户: "比较两组血压差异"
→ IntentRouter LLM 不可用 → 规则引擎识别 "比较" → analyze
→ 转入 QPERQ 层有自己的 LLM 降级到正则)
→ 系统功能不中断,退化为 QPER 主线水平
```
---
## 15. 与 QPER 主线计划的关系映射
| QPER 主线计划内容 | 本计划处理方式 | Phase |
|-------------------|---------------|-------|
| Phase DeployR 工具补齐 37h | **前置条件,先于本计划执行** | 前置 |
| Phase Q+(变量字典 + 变量选择面板 20h | **吸收进 Phase I**DataContext + 变量字典面板) | I |
| QPER 透明化Pipeline 可观测性) | **部分融入 Phase VI**(开发者面板) | VI |
| 核心原则"领域知识可配置化" | **贯穿全计划**,每个 Phase 有配置化要求 | 全部 |
| 会话状态机 ExecutionStatus | **扩展**:新增意图路由相关状态 | II |
| QPER 级 SSE 事件类型 | **扩展**新增意图分类、DataContext 就绪等事件 | I, II |
| 回退策略表 | **扩展**新增意图路由、Session 黑板等降级路径 | 全部 |
---
## 16. 实现规范与约束v1.2 新增)
> **来源:** 架构审查 6 条建议3 预警 + 3 盲区),经逐条验证和裁定后形成以下实现规范。
> **强制性:** ✅ 必须遵守,开发阶段代码审查时检查。
> **核心背景:** 平台为 **Postgres-Only** 架构(无 Redis缓存统一使用 `CacheFactory``memory` / `postgres`),参见 `docs/04-开发规范/08-云原生开发规范.md`。
### 16.1 预警 W1禁止向对话层 LLM 传递 Function Calling tools 参数
**状态:** ✅ 完全接受
**问题:** 如果在调用对话层 LLM 时传入 `tools`OpenAI Function Calling 格式LLM 将绕过 Node.js 编排层自行决定调用哪个工具,与 Node.js 集中编排的架构冲突。
**规范:**
```typescript
// ✅ 正确Node.js 编排层决定工具调用LLM 只负责语言生成
const response = await llm.chat(messages, {
// 不传 tools / function_call 参数
});
// ❌ 禁止:让 LLM 自行决定工具调用
const response = await llm.chat(messages, {
tools: toolDefinitions, // ← 禁止!
tool_choice: 'auto', // ← 禁止!
});
```
**影响范围:** `ConversationService``ChatService`、所有调用对话层 LLM 的代码
**检查时机:** Phase II 代码审查
**例外:** `IntentRouterService` 的 LLM 兜底分类可以使用 `response_format: { type: 'json_object' }` 约束输出格式,但不使用 `tools`
### 16.2 预警 W2System Prompt 膨胀控制
**状态:** ⚠️ 接受(需精细化)
**问题:** 六段式 System Promptbase_system + DataContext + 意图指令 + 工具输出 + 分析结果 + 对话历史)可能超出 Token 上限,导致 LLM 质量下降或请求失败。
**规范:**
| 控制策略 | 阈值(可配置) | 实现位置 |
|---------|--------------|---------|
| DataContext 裁剪 | 变量 ≤20 全注入;>20 只注入 confirmed>50 只注入 PICO 相关 | `session_config.json` |
| 对话历史滑动窗口 | 默认 5-10 轮(按 Token 预算动态调整,非固定轮数) | `session_config.json` |
| 工具输出摘要 | 单次工具输出 ≤500 Token超出自动截取 top-N 关键字段 | `session_config.json` |
| 分析结果注入 | 仅 discuss/feedback 时注入,且只取 stepResults 摘要(不含 R 原始输出) | 硬规则 |
| **总 Token 预算** | System Prompt ≤ 4000 Token可配置上限超出按优先级裁剪对话历史 > 工具输出 > DataContext | `session_config.json` |
| **位置优化** | 关键指令放在 System Prompt 开头和结尾LLM 注意力 U 型分布) | `ConversationService` |
**配置项扩展(`session_config.json`**
```json
{
"systemPromptTokenBudget": 4000,
"dataContextTruncation": {
"fullInjectThreshold": 20,
"confirmedOnlyThreshold": 50
},
"conversationWindowSize": { "min": 3, "max": 10 },
"toolOutputMaxTokens": 500,
"truncationPriority": ["conversationHistory", "toolOutput", "dataContext"]
}
```
**影响范围:** `ConversationService.buildContext()``session_config.json`
**检查时机:** Phase II 任务 II-3System Prompt 架构实现)
### 16.3 预警 W3对话层 LLM 必须使用流式输出
**状态:** ✅ 完全接受
**问题:** 对话层 LLM 的回复可能较长(方法推荐、结果解读等场景),非流式模式下用户等待 5-15 秒无反馈,体验差。
**规范:**
- `ConversationService` 默认使用 `LLMAdapter.chatStream()` 而非 `chat()`
- 通过现有 SSE 基础设施实时推送 LLM 输出 chunk 到前端
- 前端 `SSAChatPane` 使用已有的 `AIStreamChat` 组件渲染流式回复
**实现要点:**
```typescript
// ConversationService 核心调用方式
async *generateReply(context: ConversationContext): AsyncGenerator<StreamChunk> {
const messages = this.buildMessages(context);
yield* this.llmAdapter.chatStream(messages, { /* options */ });
}
```
**平台支持:** `LLMAdapter.chatStream()` 已就绪(`backend/src/common/llm/adapters/types.ts`),前端 `AIStreamChat` 已支持流式渲染。
**影响范围:** `ConversationService``ChatService`、前端 `SSAChatPane`
**检查时机:** Phase II 任务 II-1ConversationService 核心实现)
### 16.4 盲区 B1Session 黑板必须使用 Postgres 缓存Postgres-Only 架构)
**状态:** ⚠️ 部分接受(修正:无 Redis使用 Postgres
**问题:** Session 黑板如果使用纯内存 `Map` 存储,多实例部署时数据不共享,容器重启后丢失。
**重要修正:** 平台为 **Postgres-Only** 架构(参见 `docs/04-开发规范/08-云原生开发规范.md`**无 Redis**。缓存统一通过 `CacheFactory` 管理,支持 `memory`(本地开发)和 `postgres`(生产环境)。
**规范:**
```typescript
// ✅ 正确:使用平台 CacheFactory遵循云原生开发规范
import { CacheFactory } from '@/common/cache/CacheFactory';
export class SessionBlackboardService {
private cache = CacheFactory.getInstance(); // 自动选择 memory / postgres
async get(sessionId: string): Promise<SessionBlackboard | null> {
return this.cache.get(`ssa:session:${sessionId}`);
}
async set(sessionId: string, data: SessionBlackboard, ttl?: number): Promise<void> {
await this.cache.set(`ssa:session:${sessionId}`, data, ttl ?? 7200); // 默认 2h TTL
}
}
// ❌ 禁止:自建内存 Map违反云原生规范 §2 "内存缓存 ❌"
const sessionCache = new Map<string, SessionBlackboard>(); // ← 禁止!
```
**环境切换:**
| 环境 | `CACHE_TYPE` | 实际存储 |
|------|-------------|---------|
| 本地开发 | `memory`(默认) | 内存 Map单实例足够 |
| 生产部署 | `postgres` | `platform_schema.app_cache` 表 |
**注意:** 无需新建任务Phase I 任务 I-1SessionBlackboardService 设计与实现)按此规范使用 `CacheFactory` 即可。
**影响范围:** `SessionBlackboardService`
**检查时机:** Phase I 代码审查
### 16.5 盲区 B2数据依赖意图必须有上下文守卫
**状态:** ✅ 完全接受
**问题:** `explore``analyze``discuss``feedback` 四个意图依赖已上传的数据DataContext但用户可能在未上传数据时就发出这些意图的消息如"帮我分析一下"),此时系统不应崩溃或给出空结果。
**规范:**
```typescript
// IntentRouterService 中的上下文守卫
const DATA_DEPENDENT_INTENTS = ['explore', 'analyze', 'discuss', 'feedback'] as const;
function applyContextGuard(intent: Intent, session: SessionBlackboard | null): Intent {
if (DATA_DEPENDENT_INTENTS.includes(intent) && !session?.dataOverview) {
return {
type: 'chat',
metadata: {
guardTriggered: true,
originalIntent: intent,
guidanceMessage: 'need_data_upload' // 触发引导语
}
};
}
return { type: intent };
}
```
**用户体验:** 当守卫触发时,对话层 LLM 收到 `guidanceMessage: 'need_data_upload'`,自然回复:"您还没有上传数据,上传 CSV/Excel 后我就能帮您分析了。您也可以先问我统计方法相关的问题。"
**配置化:** 守卫映射(哪些意图需要哪些上下文前置条件)放入 `intent_rules.json`
```json
{
"contextGuards": {
"explore": { "requires": ["dataOverview"] },
"analyze": { "requires": ["dataOverview"] },
"discuss": { "requires": ["dataOverview", "latestStepResults"] },
"feedback": { "requires": ["dataOverview", "latestStepResults"] }
}
}
```
**影响范围:** `IntentRouterService``intent_rules.json`
**检查时机:** Phase II 任务 II-6IntentRouterService 实现)
### 16.6 盲区 B3LLM 输出 Zod 动态校验模式扩展
**状态:** ⚠️ 部分接受Q 层已有,需扩展到其他 LLM 输出点)
**问题:** LLM 可能生成不存在的列名、不合法的统计方法等幻觉参数,需要用 Zod 校验拦截。
**现状:** Q 层 `QueryService` 已有 `createDynamicIntentSchema(validColumns)`,用 `z.enum` 动态校验列名。
**规范 — 需要新增 Zod 校验的 LLM 输出点:**
| LLM 输出点 | 校验内容 | Phase |
|-----------|---------|-------|
| Q 层 `QueryService` | 列名 `z.enum(validColumns)` | ✅ 已有 |
| `IntentRouterService` LLM 兜底 | 意图类型 `z.enum(['chat','explore','consult','analyze','discuss','feedback'])` | II |
| `method_consult` LLM 补充推理 | 方法名 `z.enum(registeredMethods)` — 从 `decision_tables.json` 动态提取 | III |
| `ConversationService`(自动修正)| 修正后的参数列名 `z.enum(validColumns)` | V |
**不需要 Zod 校验的工具(模板驱动):**
| 工具 | 原因 |
|-----|------|
| `analysis_plan` | 输出来自 `FlowTemplateService` 模板填充,非 LLM 自由生成 |
| `run_step` | 参数来自 `analysis_plan` 输出,傻瓜式转发 |
| `write_report` | 输出为自然语言报告,无结构化参数需校验 |
**实现模式:** 复用 Q 层的动态 Schema 工厂模式:
```typescript
// 通用模式:从运行时数据构建 Zod Schema
function createDynamicSchema<T>(validValues: T[]) {
return z.enum(validValues as [T, ...T[]]);
}
```
**影响范围:** `IntentRouterService``method_consult` Tool、`ConversationService`(自动修正)
**检查时机:** Phase II / III / V 各自代码审查
---
## 17. 附录:架构约束速查表
> **开发时快速参考,无需回查全文。**
| # | 约束 | 违反后果 | 检查阶段 |
|---|------|---------|---------|
| C1 | 对话层 LLM **禁止** 传入 `tools` / `function_call` 参数 | LLM 绕过编排层自行调用工具,失控 | Phase II |
| C2 | System Prompt 总 Token ≤ 4000可配置超出按优先级裁剪 | LLM 注意力稀释,回复质量下降 | Phase II |
| C3 | 对话层 LLM 默认使用 `chatStream()` 流式输出 | 用户等待 5-15 秒无反馈,体验差 | Phase II |
| C4 | Session 黑板使用 `CacheFactory`**Postgres-Only**,无 Redis | 多实例数据不共享 / 违反云原生规范 | Phase I |
| C5 | 数据依赖意图explore/analyze/discuss/feedback必须有上下文守卫 | 未上传数据时系统崩溃或空结果 | Phase II |
| C6 | LLM 输出涉及枚举值(列名、方法名、意图类型)必须 Zod 动态校验 | LLM 幻觉参数导致下游工具失败 | Phase II/III/V |
| C7 | **Postgres-Only 架构**:禁止引入 Redis 等外部缓存依赖 | 增加运维复杂度,违反平台规范 | 全 Phase |
| C8 | R 原始输出 **不入** LLM 上下文 | Token 浪费,可能触发上下文超限 | Phase IV/V |
---
**文档维护者:** SSA 架构团队
**创建日期:** 2026-02-21
**最后更新:** 2026-02-22v1.8 — Phase IV 开发完成E2E 25/25 通过)
**下一步行动:**
1. 执行 Phase V反思编排 + 高级特性18h / 3 天)
2. Phase Deploy 剩余收尾可与 Phase V 并行
### 变更日志
| 版本 | 日期 | 变更内容 |
|------|------|---------|
| v1.0 | 2026-02-21 | 初版6 Phase 开发计划122h/20 天 |
| v1.1 | 2026-02-21 | **新增对话层 LLM 基础设施**:① Phase II 新增 ConversationService 核心实现(5h) + 对话历史管理(3h) + System Prompt 架构实现(4h) + 全意图 Prompt 模板(3h);② Phase II 名称改为"对话层 LLM + 意图路由器 + 统一对话入口"24h→35h③ Phase IV analyze 链路增加对话层 LLM 进展播报(+1h);④ Prompt 模板清单从 7 个扩展为 13 个(新增 base_system + 6 个意图指令段);⑤ 新增 ConversationService.ts + ConversationHistoryService.ts⑥ 总工时 122h→134h27.5 天含 Deploy |
| v1.2 | 2026-02-22 | **新增实现规范与约束§16-§17**:① 6 条架构审查建议3 预警 W1-W3 + 3 盲区 B1-B3转化为实现规范② 修正 Session 黑板缓存策略为 Postgres-Only无 Redis遵循平台云原生规范③ 新增架构约束速查表8 条 C1-C8④ 无新增工时(规范融入已有任务) |
| v1.3 | 2026-02-22 | **Phase I 开发完成**:① 5 批次全部交付18 个文件新增/修改);② 实现 4 项隐患修正H1 互斥锁/H2 bins 限制/H3 观察性研究 null/H4 Mock 先行);③ E2E 测试 31/31 通过;④ 新增文件SessionBlackboardService、PicoInferenceService、TokenTruncationService、GetDataOverviewTool、GetVariableDetailTool、blackboard.routes、seed-ssa-pico-prompt、DataContextCard、VariableDictionaryPanel、VariableDetailPanel、test-phase-i-e2e.cjs⑤ Python 扩展:正态性检验 + variable-detail 端点 |
| v1.4 | 2026-02-22 | **Phase II 开发完成**:① 4 批次全部交付9 个文件新增 + 3 个文件修改);② 落地团队反馈 H1-H4SSE 心跳/Lost-in-the-Middle/竞态保护/前端直接改造);③ E2E 测试 38/38 通过11 组测试6 意图分类 + SSE 流式 + 对话历史 + 上下文守卫);④ 新增后端SystemPromptService、ConversationService、IntentRouterService、ChatHandlerService、chat.routes、intent_rules.json、seed-ssa-phase2-prompts8 Prompt⑤ 新增前端useSSAChat hook⑥ 修改前端SSAChatPanehandleSend 走 /chat SSE + ThinkingBlock + 意图标签 + H3 输入锁);⑦ 修复 bugfinalizeAssistantMessage metadata 合并(保留 intent 字段) |
| v1.5 | 2026-02-22 | **Phase III 代码完成**:① 5 批次代码交付7 个文件新增 + 5 个文件修改);② 落地团队审查 H1-H3+P1状态死锁防护/仓储模式/概念统一/Prompt 格式约束);③ 新增后端ToolRegistryServiceIToolRepository+JsonToolRepository、MethodConsultServicePICO→ParsedQuery→DecisionTable、AskUserServicecreateQuestion/parseResponse/clearPending、seed-ssa-phase3-prompts、test-ssa-phase3-e2e④ 新增前端AskUserCard4 inputType + H1 跳过按钮);⑤ 修改后端ChatHandlerServicehandleConsult+handleAskUserResponse、chat.routesH1 全局打断判定、session-blackboard.typespendingAskUser 字段);⑥ 修改前端useSSAChatpendingQuestion+respondToQuestion+skipQuestion⑦ QueryService 替换 AVAILABLE_TOOLS 为 toolRegistryService.formatForLLM() |
| v1.6 | 2026-02-22 | **Phase III 完成**:① SSA_METHOD_CONSULT Prompt seed 成功入库id=28② E2E 测试 13 passed / 0 failed / 4 skipped跳过原因测试数据 PICO 推断不完整,未触发 ask_user 确认卡片,属预期行为);③ 修复 seed 脚本(从 raw SQL 改为 Prisma model 调用,适配 capability_schema |
| v1.7 | 2026-02-22 | **Phase IV 设计方案确定**:① 重新定位为"对话驱动分析 + QPER 集成"(原"THINK + ACT 层工具封装");② 5 项架构决策D1 保留独立 workflow SSE / D2 chat SSE 推 analysis_plan / D3 双通道确认 / D4 ToolOrchestratorService 薄层封装 / D5 PICO 可选 hint 非必要条件);③ 团队审查 5 条反馈H1 上下文失忆→接受优化为 PICO hint 注入 / H2 幽灵卡片→接受简化为清除 pendingQuestion / H3 SSE 乱序 delay→拒绝 / B1 修改建议循环→接受 / B2 旧 API 兼容→接受);④ PICO 三层降级策略用户显式指令优先→PICO hint 辅助→纯 LLM+DataProfile 推断);⑤ 工时从 21h 精简为 14h不创建独立 Tool 类);⑥ 8 个任务 5 个 Batch |
| v1.8 | 2026-02-22 | **Phase IV 开发完成**:① 5 批次全部交付4 个文件新增 + 7 个文件修改);② 落地团队审查 H1-H3+B1-B2PICO hint 注入/幽灵卡片清除/SSE 严格串行/修改建议循环/旧 API 兼容);③ E2E 测试 25/25 通过7 组登录→Session 创建+数据概览→analyze 意图 analysis_plan 3 步骤→ask_user 确认卡片→旧 /workflow/plan B2 兼容→AVAILABLE_TOOLS 配置化→对话历史);④ 新增后端ToolOrchestratorServiceplan+formatPlanForLLM+buildPicoHint、seed-ssa-phase4-promptsSSA_ANALYZE_PLAN 入库、test-ssa-phase4-e2e⑤ 修改后端WorkflowPlannerService删除 AVAILABLE_TOOLS 常量11 处改 toolRegistryService、ToolRegistryService+getVisibleTools、ChatHandlerServicehandleAnalyze 重写+handleAskUserResponse 扩展 confirm_plan/change_method、AskUserService+metadata、QueryService/WorkflowExecutorService清理未用导入⑥ 修改前端useSSAChatanalysis_plan+plan_confirmed SSE 处理+pendingPlanConfirm、SSAChatPaneAskUserCard 渲染+executeWorkflow 触发) |