diff --git a/docs/00-系统总体设计/00-系统当前状态与开发指南.md b/docs/00-系统总体设计/00-系统当前状态与开发指南.md index 30729028..32e29dee 100644 --- a/docs/00-系统总体设计/00-系统当前状态与开发指南.md +++ b/docs/00-系统总体设计/00-系统当前状态与开发指南.md @@ -1,11 +1,12 @@ # AIclinicalresearch 系统当前状态与开发指南 -> **文档版本:** v5.7 +> **文档版本:** v5.8 > **创建日期:** 2025-11-28 > **维护者:** 开发团队 -> **最后更新:** 2026-02-21 +> **最后更新:** 2026-02-22 > **🎉 重大里程碑:** -> - **🆕 2026-02-21:SSA QPER 智能化主线闭环完成!** Q→P→E→R 四层架构全部开发完成,端到端 40/40 测试通过 +> - **🆕 2026-02-22:SSA 智能对话与工具体系架构设计完成!** 四层七工具 + 对话层 LLM + 6 Phase 开发计划 v1.2 定稿(134h/22天) +> - **2026-02-21:SSA QPER 智能化主线闭环完成!** Q→P→E→R 四层架构全部开发完成,端到端 40/40 测试通过 > - **2026-02-20:SSA Phase 2A 前端集成完成!** 多步骤工作流端到端 + V11 UI联调 + Block-based 架构共识 > - **2026-02-19:SSA T 检验端到端测试通过!** 完整流程验证 + 9 个 Bug 修复 + Phase 1 核心完成 85% > - **2026-02-19:SSA Week 1 开发完成!** R Docker 镜像构建成功 + 后端/前端骨架 + 规范对齐 @@ -24,13 +25,11 @@ > - **2026-01-24:Protocol Agent 框架完成!** 可复用Agent框架+5阶段对话流程 > - **2026-01-22:OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层 > -> **🆕 最新进展(SSA QPER 智能化主线闭环 2026-02-21):** -> - ✅ **🎉 QPER 四层架构主线闭环** — Phase E+/Q/P/R 全部完成(93.5h),端到端 40/40 测试通过 -> - ✅ **Q 层 LLM 意图理解** — 自然语言→四维信息提取 + Zod 动态防幻觉 + 追问卡片 -> - ✅ **P 层配置化决策表** — JSON 驱动四维匹配 + 流程模板 + PlannedTrace + 热更新 API -> - ✅ **R 层 LLM 论文级结论** — 6 要素结论 + 统计量槽位注入 + Zod 校验 + 敏感性冲突准则 -> - ✅ **四层降级体系** — Q→正则, P→硬编码, E→错误分类, R→规则引擎,LLM 不可用时系统不中断 -> - ✅ **Block-based 标准化** — 7 个 R 工具输出 report_blocks,前端动态渲染 + Word 导出 +> **🆕 最新进展(SSA 智能对话与工具体系架构设计 2026-02-22):** +> - ✅ **🎉 智能对话与工具体系架构设计完成** — 四层七工具(READ/INTERACT/THINK/ACT)+ 对话层 LLM + 意图路由器 +> - ✅ **开发计划 v1.2 定稿** — 6 Phase / 134h / 22 天,含 8 条架构约束(Postgres-Only 缓存、Function Calling 禁止、流式输出等) +> - ✅ **3 份系统设计文档** — 意图识别架构设计 + 工具体系融合方案 + 四层七工具实现机制详解 +> - ✅ **6 条架构审查建议裁定** — 3 预警 + 3 盲区,转化为 8 条强制性实现约束(C1-C8) > > **部署状态:** ✅ 生产环境运行中 | 公网地址:http://8.140.53.236/ > **REDCap 状态:** ✅ 生产环境运行中 | 地址:https://redcap.xunzhengyixue.com/ @@ -71,7 +70,7 @@ | **ASL** | AI智能文献 | 文献筛选、Meta分析、证据图谱 | ⭐⭐⭐⭐⭐ | 🎉 **智能检索MVP完成(60%)** - DeepSearch集成 | **P0** | | **DC** | 数据清洗整理 | ETL + 医学NER(百万行级数据) | ⭐⭐⭐⭐⭐ | ✅ **Tool B完成 + Tool C 99%(异步架构+性能优化-99%+多指标转换+7大功能)** | **P0** | | **IIT** | IIT Manager Agent | AI驱动IIT研究助手 - 双脑架构+REDCap集成 | ⭐⭐⭐⭐⭐ | 🎉 **事件级质控V3.1完成(设计100%,代码60%)** | **P0** | -| **SSA** | 智能统计分析 | **QPER架构** + LLM意图理解 + 配置化决策表 + LLM论文结论 | ⭐⭐⭐⭐⭐ | 🎉 **QPER主线闭环(E+/Q/P/R 100%)** - 40/40端到端通过,Phase Deploy待启动 | **P1** | +| **SSA** | 智能统计分析 | **QPER架构** + 四层七工具 + 对话层LLM + 意图路由器 | ⭐⭐⭐⭐⭐ | 🎉 **QPER主线闭环 + 智能对话架构设计完成** - 6 Phase 开发计划 v1.2 定稿(134h),Phase Deploy待启动 | **P1** | | **ST** | 统计分析工具 | 100+轻量化统计工具 | ⭐⭐⭐⭐ | 📋 规划中 | P2 | | **RVW** | 稿件审查系统 | 方法学评估 + 🆕数据侦探(L1/L2/L2.5验证)+ Skills架构 + Word导出 | ⭐⭐⭐⭐ | 🚀 **V2.0 Week3完成(85%)** - 统计验证扩展+负号归一化+文件格式提示+用户体验优化 | P1 | | **ADMIN** | 运营管理端 | Prompt管理、租户管理、用户管理、运营监控、系统知识库 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 4.6完成(88%)** - Prompt知识库集成+动态注入 | **P0** | @@ -156,9 +155,32 @@ --- -## 🚀 当前开发状态(2026-02-21) +## 🚀 当前开发状态(2026-02-22) -### 🎉 最新进展:SSA QPER 智能化主线闭环完成(2026-02-21) +### 🎉 最新进展:SSA 智能对话与工具体系架构设计完成(2026-02-22) + +#### ✅ SSA 智能对话架构设计完成(2026-02-22) + +**重大里程碑:从"统计分析执行器"到"数据感知的统计顾问"的架构升级设计全部完成!** + +| 设计产出 | 核心内容 | 状态 | +|---------|---------|------| +| 意图识别与对话架构设计 | Intent Router(规则+LLM混合)+ DataContext + 6 种意图分类 | ✅ | +| 工具体系规划方案(融合方案) | 四层七工具(READ/INTERACT/THINK/ACT)+ Session 黑板 + Token 控制 | ✅ | +| 四层七工具实现机制详解 | 三层架构(Node.js 编排 + 对话层 LLM + 工具层)+ System Prompt 架构 | ✅ | +| 开发计划 v1.2 | 6 Phase / 134h / 22 天 + 8 条架构约束(C1-C8) | ✅ | + +**架构关键决策**: +- ✅ **对话层 LLM**:六段式 System Prompt 动态组装 + 流式输出(禁止 Function Calling) +- ✅ **Postgres-Only 缓存**:Session 黑板使用 CacheFactory(无 Redis,遵循云原生规范) +- ✅ **上下文守卫**:数据依赖意图(explore/analyze/discuss/feedback)在无数据时自动降级为 chat +- ✅ **Zod 动态校验**:LLM 输出的列名、方法名、意图类型等枚举值均动态校验 + +**下一步**:Phase Deploy(R 工具补齐 37h)→ Phase I(Session 黑板 + READ 层 30h)→ Phase II(对话层 LLM + 意图路由器 35h) + +**相关文档**: +- 开发计划:`docs/03-业务模块/SSA-智能统计分析/04-开发计划/11-智能对话与工具体系开发计划.md` +- 系统设计:`docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 四层七工具实现机制详解.md` #### ✅ SSA QPER 四层架构全部完成(2026-02-21) @@ -176,8 +198,6 @@ - ✅ **配置化驱动**:决策表/模板/工具注册表为 JSON,`POST /reload` 热更新 - ✅ **统计量槽位注入**:LLM 被剥夺生成数值权限,所有数值来自 R 引擎 -**下一步**:Phase Deploy(工具补齐 + 部署)→ Phase Q+(人机协同增强) - **相关文档**: - 开发计划:`docs/03-业务模块/SSA-智能统计分析/04-开发计划/10-QPER架构开发计划-智能化主线.md` - 开发总结:`docs/03-业务模块/SSA-智能统计分析/06-开发记录/SSA-QPER架构开发总结-2026-02-21.md` @@ -1435,7 +1455,7 @@ npm run dev # http://localhost:3000 ### 模块完成度 - ✅ **已完成**:AIA V2.0(85%,核心功能完成)、平台基础层(100%)、RVW(95%)、通用能力层升级(100%)、**PKB(95%,Dify已替换)** 🎉 -- 🚧 **开发中**:ASL(80%)、DC(Tool C 98%,Tool B后端100%,Tool B前端0%)、IIT(60%,Phase 1.5完成)、**SSA(95%,Phase 2A完成,Block-based重构待执行)** 🎉 +- 🚧 **开发中**:ASL(80%)、DC(Tool C 98%,Tool B后端100%,Tool B前端0%)、IIT(60%,Phase 1.5完成)、**SSA(QPER主线100% + 智能对话架构设计完成,Phase Deploy待启动)** 🎉 - 📋 **未开始**:ST ### 部署完成度 diff --git a/docs/03-业务模块/SSA-智能统计分析/00-模块当前状态与开发指南.md b/docs/03-业务模块/SSA-智能统计分析/00-模块当前状态与开发指南.md index edacaf56..4d32a6d2 100644 --- a/docs/03-业务模块/SSA-智能统计分析/00-模块当前状态与开发指南.md +++ b/docs/03-业务模块/SSA-智能统计分析/00-模块当前状态与开发指南.md @@ -1,13 +1,19 @@ # SSA智能统计分析模块 - 当前状态与开发指南 -> **文档版本:** v2.1 +> **文档版本:** v3.0 > **创建日期:** 2026-02-18 -> **最后更新:** 2026-02-21 +> **最后更新:** 2026-02-22 > **维护者:** 开发团队 -> **当前状态:** 🎉 **QPER 主线闭环 + 集成测试通过 + 统一状态管理重构完成** +> **当前状态:** 🎉 **QPER 主线闭环 + 智能对话与工具体系架构设计完成** > **文档目的:** 快速了解SSA模块状态,为新AI助手提供上下文 > -> **最新进展(2026-02-21 晚):** +> **最新进展(2026-02-22):** +> - ✅ **智能对话与工具体系架构设计完成** — 四层七工具 + 对话层 LLM + 意图路由器 +> - ✅ **开发计划 v1.2 定稿** — 6 Phase / 134h / 22 天(含 8 条架构约束 + Postgres-Only 缓存规范) +> - ✅ **3 份系统设计文档** — 意图识别架构、工具体系规划方案、四层七工具实现机制详解 +> - ✅ **6 条架构审查建议已裁定** — 3 预警(Function Calling 冲突、System Prompt 膨胀、流式输出)+ 3 盲区(Postgres-Only 缓存、上下文守卫、Zod 动态校验) +> +> **此前进展(2026-02-21):** > - ✅ **前后端集成测试** — 7 个 Bug 全部修复(R 引擎防御、意图识别、前端状态) > - ✅ **统一状态管理重构** — 消除 isWorkflowMode 双轨逻辑,AnalysisRecord 成为唯一数据源 > - ✅ **多任务切换** — 点击不同卡片正确显示各自的分析计划和结果 @@ -22,12 +28,12 @@ | 项目 | 信息 | |------|------| | **模块名称** | SSA - 智能统计分析 (Smart Statistical Analysis) | -| **模块定位** | AI驱动的"白盒"统计分析系统 | -| **架构模式** | **QPER — Query → Planner → Execute → Reflection** | +| **模块定位** | AI驱动的"白盒"统计分析系统 → 升级为"数据感知的统计顾问" | +| **架构模式** | **QPER(执行层)** + **四层七工具 + 对话层 LLM(智能对话层)** | | **前端状态模型** | **Unified Record Architecture — 一次分析 = 一个 Record = N 个 Steps** | | **商业价值** | ⭐⭐⭐⭐⭐ 极高 | | **目标用户** | 临床研究人员、生物统计师 | -| **开发状态** | 🎉 **QPER 主线闭环 + 集成测试通过,Phase Deploy 待启动** | +| **开发状态** | 🎉 **QPER 主线闭环 + 智能对话架构设计完成,Phase Deploy 待启动** | ### 核心目标 @@ -123,9 +129,14 @@ AnalysisRecord { | **Phase P** | **决策表 + 流程模板** | **23h** | ✅ **已完成** | 2026-02-21 | | **Phase R** | **LLM 论文级结论** | **22h** | ✅ **已完成** | 2026-02-21 | | **集成测试** | **Bug 修复 + 统一状态管理重构** | **~4h** | ✅ **已完成** | 2026-02-21 | +| **架构设计** | **智能对话与工具体系架构设计** | **~8h** | ✅ **已完成** | 2026-02-22 | | Phase Deploy | 工具补齐 + 部署上线 | 37h | 📋 待开始 | - | -| Phase Q+ | 人机协同增强 | 20h | 📋 待开始 | - | -| **QPER 透明化** | **Pipeline 可观测性增强** | TBD | 📋 待开始 | - | +| **Phase I** | **Session 黑板 + READ 层** | **30h** | 📋 待开始(吸收 Phase Q+) | - | +| **Phase II** | **对话层 LLM + 意图路由器 + 统一对话入口** | **35h** | 📋 待开始 | - | +| **Phase III** | **method_consult + ask_user 标准化** | **20h** | 📋 待开始 | - | +| **Phase IV** | **THINK + ACT 工具封装** | **21h** | 📋 待开始 | - | +| **Phase V** | **反思编排 + 高级特性** | **18h** | 📋 待开始 | - | +| **Phase VI** | **集成测试 + 可观测性** | **10h** | 📋 待开始 | - | ### 已完成核心功能 @@ -236,10 +247,14 @@ npx tsx scripts/seed-ssa-reflection-prompt.ts | 文档 | 路径 | |------|------| | **QPER 开发计划(主线)** | `04-开发计划/10-QPER架构开发计划-智能化主线.md` | +| **🆕 智能对话与工具体系开发计划** | `04-开发计划/11-智能对话与工具体系开发计划.md` | +| **🆕 意图识别与对话架构设计** | `00-系统设计/SSA-Pro 意图识别与对话架构设计.md` | +| **🆕 工具体系规划方案(融合方案)** | `00-系统设计/SSA-Pro 工具体系规划方案(团队讨论稿).md` | +| **🆕 四层七工具实现机制详解** | `00-系统设计/SSA-Pro 四层七工具实现机制详解.md` | | **QPER 开发总结** | `06-开发记录/SSA-QPER架构开发总结-2026-02-21.md` | | **集成测试 Bug 修复** | `06-开发记录/2026-02-21-集成测试Bug修复与统一状态管理重构.md` | | **智能化愿景设计** | `00-系统设计/SSA-Pro 理想状态与智能化愿景设计.md` | -| **PRD** | `00-系统设计/PRD SSA-Pro 严谨型智能统计分析模块.md` | +| **PRD** | `00-系统设计/PRA SSA-Pro 严谨型智能统计分析模块.md` | | **架构设计 V4** | `00-系统设计/SSA-Pro 严谨型智能统计分析架构设计方案V4.md` | --- @@ -248,23 +263,76 @@ npx tsx scripts/seed-ssa-reflection-prompt.ts ### 近期(优先级高) -1. **QPER 透明化(Pipeline 可观测性)** - - Q 层:展示 LLM 解析结果(goal、变量、置信度)和降级原因 - - P 层:展示决策表匹配过程和流程模板填充参数 - - E 层:实时展示步骤输入参数 + R 返回摘要;开发模式显示 R 原始错误 - - R 层:展示槽位注入内容和 Zod 校验状态 - - 开发者面板:持久化 trace_log + LLM prompt/response 可查看 +1. **Phase Deploy(37h / 5.5 天)** — 补齐 R 工具 7→11 + 生产环境部署上线 -2. **Phase Deploy(37h)** — 补齐 ANOVA / Fisher / Wilcoxon / 线性回归 + 复合工具 ST_BASELINE_TABLE + 部署上线 +2. **Phase I — Session 黑板 + READ 层(30h / 5 天)** — 已吸收 Phase Q+ + - SessionBlackboardService(CacheFactory / Postgres-Only 架构) + - `get_data_overview` + `get_variable_detail` 工具 + - DataContext 前端展示 + 变量字典面板 + - PICO 推断 + 用户确认流程 + +3. **Phase II — 对话层 LLM + 意图路由器 + 统一对话入口(35h / 5.5 天)** + - ConversationService 核心(六段式 System Prompt 动态组装) + - IntentRouterService(规则 + LLM 混合路由 + 上下文守卫) + - 统一对话 API `/api/ssa/chat` + - chat/explore 意图处理 ### 中期 -3. **Phase Q+(20h)** — 变量数据字典(AI 先猜用户微调)+ 变量选择确认面板(AI 推荐医生确认) -4. **前端 UI 细节打磨** — 执行计划格式美化、错误状态视觉增强 +4. **Phase III(20h)** — method_consult + ask_user 标准化 +5. **Phase IV(21h)** — THINK + ACT 工具封装 + analyze 完整链路 +6. **Phase V(18h)** — 反思编排 + discuss + feedback + +### 后期 + +7. **Phase VI(10h)** — 集成测试 + 可观测性(含 QPER 透明化) + +**详细计划:** `04-开发计划/11-智能对话与工具体系开发计划.md`(v1.2,含 8 条架构约束 C1-C8) --- -**文档版本:** v2.1 -**最后更新:** 2026-02-21 -**当前状态:** 🎉 QPER 主线闭环 + 集成测试通过 + 统一状态管理重构完成 -**下一步:** QPER 透明化 → Phase Deploy 工具补齐 + 部署上线 +## 🏗️ 智能对话架构概览(四层七工具 + 对话层 LLM) + +> **设计目标:** 从"统计分析执行器"升级为"数据感知的统计顾问" + +``` +用户消息 + │ + ▼ +┌─ Intent Router ──────────────────────────────────────┐ +│ 规则引擎优先 + LLM 兜底 + 上下文守卫(§16.5) │ +│ → chat / explore / consult / analyze / discuss / feedback │ +└─────────────────────┬────────────────────────────────┘ + ▼ +┌─ Conversation Layer LLM ─────────────────────────────┐ +│ 六段式 System Prompt + DataContext 注入 + 流式输出 │ +│ Token 预算 ≤4000(§16.2)+ 禁止 Function Calling(§16.1)│ +└─────────────────────┬────────────────────────────────┘ + ▼ +┌─ 四层七工具 ─────────────────────────────────────────┐ +│ READ: get_data_overview | get_variable_detail | method_consult │ +│ INTERACT: ask_user │ +│ THINK: analysis_plan │ +│ ACT: run_step | write_report │ +└─────────────────────┬────────────────────────────────┘ + ▼ +┌─ QPER 执行层(已有) ────────────────────────────────┐ +│ Q → P → E → R(四层降级体系,不动) │ +└──────────────────────────────────────────────────────┘ +``` + +**关键架构约束(详见开发计划 §16-§17):** + +| # | 约束 | +|---|------| +| C1 | 对话层 LLM 禁止 Function Calling tools 参数 | +| C4 | Session 黑板使用 CacheFactory(Postgres-Only,无 Redis) | +| C5 | 数据依赖意图必须有上下文守卫 | +| C6 | LLM 枚举输出必须 Zod 动态校验 | + +--- + +**文档版本:** v3.0 +**最后更新:** 2026-02-22 +**当前状态:** 🎉 QPER 主线闭环 + 智能对话与工具体系架构设计完成 +**下一步:** Phase Deploy(工具补齐)→ Phase I(Session 黑板 + READ 层) diff --git a/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 四层七工具实现机制详解.md b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 四层七工具实现机制详解.md new file mode 100644 index 00000000..27547acd --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 四层七工具实现机制详解.md @@ -0,0 +1,875 @@ +# SSA-Pro 四层七工具实现机制详解 + +> **文档版本:** v1.1 +> **创建日期:** 2026-02-21 +> **最后更新:** 2026-02-21(v1.1 — 新增对话层 LLM 架构说明) +> **文档类型:** 架构说明 (Architecture Reference) +> **目标读者:** 开发团队 +> **前置文档:** `SSA-Pro 工具体系规划方案(团队讨论稿).md`(定义了"做什么"),本文档说明"怎么做" +> **核心问题:** 每个工具的内部实现机制是什么?哪些依赖 LLM?哪些依赖规则引擎?哪些是纯计算?**对话层 LLM 如何保证多轮对话的连贯性?** + +--- + +## 1. 三层架构全貌:对话层 LLM 是核心大脑 + +### 1.1 架构中的三个层次 + +系统不是简单的"Node.js 调工具",而是三层协同: + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ │ +│ 第一层:Node.js 编排层(交通指挥) │ +│ ──────────────────────────────── │ +│ 职责:意图路由 → 工具调度 → 流程控制 → Session 黑板读写 │ +│ 特点:确定性、无 LLM、零 Token 成本 │ +│ 类比:交通警察,决定车(工具)往哪走,但不理解乘客(用户)在说什么 │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ 第二层:对话层 LLM(全局大脑) ← 这是架构的核心 │ +│ ──────────────────────────── │ +│ 职责:理解用户意图 → 组织工具输出 → 生成连贯自然语言回复 │ +│ 特点:全局状态感知、多轮对话记忆、知识推理 │ +│ 类比:统计顾问本人,读过你的数据,记得之前聊了什么,知道什么时候该问 │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ 第三层:工具层(专业手脚) │ +│ ──────────────────────── │ +│ 职责:执行具体任务(统计计算、规则匹配、R 脚本执行) │ +│ 特点:无状态函数,输入→输出,不关心对话上下文 │ +│ 类比:实验室设备,按按钮出结果,但不知道实验的完整背景 │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 1.2 一次完整交互的真实流程 + +以用户说 **"帮我看看各组的样本分布"** 为例: + +``` +用户消息: "帮我看看各组的样本分布" + │ + ▼ + ┌─ 第一层:Node.js 编排 ──────────────────────────────────────────┐ + │ IntentRouter 分类 → explore │ + │ 决定调用 get_data_overview(若缓存未命中) │ + └──────────────┬──────────────────────────────────────────────────┘ + │ 工具调用 + ▼ + ┌─ 第三层:工具层 ────────────────────────────────────────────────┐ + │ get_data_overview → DataProfileService(Python) 返回结构化 JSON │ + │ { total_rows: 200, categorical_vars: [...], ... } │ + └──────────────┬──────────────────────────────────────────────────┘ + │ 结构化输出 + ▼ + ┌─ 第二层:对话层 LLM ────────────────────────────────────────────┐ + │ │ + │ System Prompt: │ + │ "你是 SSA-Pro 智能统计分析助手... │ + │ 用户数据全貌: {DataContext} │ + │ 请基于数据摘要为用户解读数据特征。" │ + │ │ + │ 对话历史: │ + │ [user] 上传了数据 xxx.csv │ + │ [assistant] 您的数据已上传成功... │ + │ [user] 帮我看看各组的样本分布 ← 当前消息 │ + │ │ + │ 工具输出(注入为上下文): │ + │ get_data_overview 返回: { ... } │ + │ │ + │ → LLM 生成连贯的自然语言回复: │ + │ "您的数据共 200 例,分为 treatment 组(103 例)和 │ + │ control 组(97 例)。各组分布如下: │ + │ - treatment 组平均年龄 54.3 岁(SD=11.2)... │ + │ 需要我进一步看某个具体变量吗?" │ + │ │ + └──────────────────────────────────────────────────────────────────┘ +``` + +**关键点:工具返回的是结构化 JSON,但用户看到的是自然语言。中间的翻译者就是对话层 LLM。** + +### 1.3 对话层 LLM 的六大职责 + +| # | 职责 | 靠 Node.js 能做到吗? | 说明 | +|---|------|:---:|------| +| 1 | **自然语言生成** | ❌ | 把结构化 JSON 变成"像人说的话" | +| 2 | **多轮对话记忆** | ❌ | "刚才那个变量"→ 理解指的是上一轮讨论的 BMI | +| 3 | **上下文推理** | ❌ | 用户说"有没有效"→ 结合 DataContext 推理出想比较什么 | +| 4 | **主动引导** | ❌ | 分析完主动问"需要做敏感性分析吗?" | +| 5 | **知识融合** | ❌ | 结合统计学知识解释"为什么选 T 检验而不是 ANOVA" | +| 6 | **语气和策略** | ❌ | 对医生用临床语言,对统计师用技术语言 | + +> **结论:Node.js 编排层绝对不够。对话层 LLM 是不可或缺的核心大脑。Node.js 管"做什么",LLM 管"怎么说"和"怎么想"。** + +--- + +## 2. 对话层 LLM 的技术实现 + +### 2.1 System Prompt 架构 + +对话层 LLM 有一个持久的 System Prompt,在整个会话生命周期内持续生效,并根据意图和状态动态组装: + +``` +┌─ System Prompt(始终存在)────────────────────────────────────────┐ +│ │ +│ [基础角色](固定) │ +│ 你是 SSA-Pro 智能统计分析助手,专注于临床研究统计分析。 │ +│ 你了解用户上传的数据,可以回答关于数据的问题,推荐分析方法, │ +│ 解读分析结果。你的风格是专业但易懂的统计顾问。 │ +│ │ +│ [数据全貌](上传数据后始终注入,~200 Token) │ +│ 用户上传了一份数据集: │ +│ {DataContext.summary — 行数/列数/缺失率/类型/结构} │ +│ │ +│ [PICO 分类](推断后注入,~150 Token) │ +│ 根据数据特征,推断/确认的 PICO 分类如下: │ +│ {DataContext.pico — population/intervention/outcome} │ +│ │ +│ [变量字典](逐步丰富,~50 Token/变量,裁剪后注入) │ +│ 各变量的定义和角色: │ +│ {DataContext.variableDictionary — 裁剪策略控制} │ +│ │ +│ [意图特定指令](每次请求动态切换) │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ chat: 请基于统计知识和用户数据回答。不要主动建议分析。│ │ +│ │ explore: 请基于数据摘要解读数据特征。可以推断 PICO。 │ │ +│ │ consult: 请推荐分析方法,给出理由和前提。不要执行。 │ │ +│ │ analyze: 以下是工具执行结果,请向用户说明进展。 │ │ +│ │ discuss: 以下是分析结果: {结果}。请帮助用户解读。 │ │ +│ │ feedback: 以下是完整 QPER 记录: {trace}。请分析问题。 │ │ +│ └──────────────────────────────────────────────────┘ │ +│ │ +│ [工具输出](本轮工具调用的结果,动态注入) │ +│ {get_data_overview / method_consult / run_step 等的结构化输出} │ +│ │ +│ [分析结果](discuss/feedback 时注入,~500 Token/步骤) │ +│ {最近的 AnalysisRecord 摘要} │ +│ │ +└────────────────────────────────────────────────────────────────────┘ + +┌─ 对话历史(最近 N 轮,滑动窗口)─────────────────────────────────────┐ +│ [user] 上传了 clinical_trial.csv │ +│ [assistant] 您的数据已上传,共 200 行 15 列... │ +│ [user] 帮我看看各组的样本分布 │ +│ [assistant] treatment 组 103 例,control 组 97 例... │ +│ [user] BMI 的分布怎样? │ +│ [assistant] BMI 均值 25.3,标准差 4.1... │ +│ [user] 这两组 BMI 有差异吗?应该怎么分析? ← 当前消息 │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +### 2.2 对话层 LLM 在每种意图中的角色 + +| 意图 | Node.js 编排做了什么 | 对话层 LLM 做了什么 | +|------|---------------------|-------------------| +| **chat** | 几乎不介入(不调工具) | **完全主导**:纯 LLM 对话,基于 DataContext + 统计知识回答 | +| **explore** | 调用 get_data_overview 或 get_variable_detail | **翻译 + 解读**:把结构化 JSON 变成易懂的数据解读 | +| **consult** | 调用 method_consult(决策表匹配) | **融合 + 解释**:把匹配结果变成完整的方法推荐(带理由、前提、替代) | +| **analyze** | 调用 analysis_plan → run_step ×N → write_report | **进度播报 + 过渡衔接**:每步执行后生成进展说明,衔接步骤间的上下文 | +| **discuss** | 提取最近的 AnalysisRecord | **深度解读**:回答"p 值说明什么""置信区间为什么宽"等统计学问题 | +| **feedback** | 注入 qperTrace 到 LLM | **问题诊断**:分析完整记录,找出问题根因,建议新方案 | + +### 2.3 对话连贯性保障机制 + +``` +┌─ 保障机制 1:对话历史注入 ────────────────────────────────────────┐ +│ │ +│ 每次 LLM 调用都携带最近 N 轮对话历史(滑动窗口) │ +│ → 用户说"刚才那个变量" → LLM 从历史中知道指的是 BMI │ +│ → 用户说"按你说的方案执行" → LLM 从历史中知道之前推荐了 T 检验 │ +│ │ +│ 窗口大小:根据 Token 预算动态调整 │ +│ - 简单对话:保留最近 10 轮 │ +│ - 长对话(含分析结果):保留最近 5 轮 + 关键事件摘要 │ +│ │ +└────────────────────────────────────────────────────────────────────┘ + +┌─ 保障机制 2:Session 黑板持久化 ──────────────────────────────────┐ +│ │ +│ 对话历史有滑动窗口(会丢失早期内容),但关键决策结果不会丢失: │ +│ - PICO 确认结果 → 写入 blackboard.confirmedPico → 始终可用 │ +│ - 变量角色确认 → 写入 blackboard.variableDictionary → 始终可用 │ +│ - 分析方案 → 写入 blackboard.currentPlan → 始终可用 │ +│ - 执行结果 → 写入 blackboard.stepResults → 始终可用 │ +│ │ +│ → 即使对话历史中早期的讨论被裁剪,结论仍在 Session 黑板中 │ +│ → LLM 通过 DataContext 注入随时可以引用这些结论 │ +│ │ +└────────────────────────────────────────────────────────────────────┘ + +┌─ 保障机制 3:意图切换时的上下文衔接 ──────────────────────────────┐ +│ │ +│ 用户从 consult 转到 analyze 时: │ +│ │ +│ [consult 阶段对话] │ +│ user: "我想比较两组血压差异,用什么方法?" │ +│ assistant: "建议独立样本 T 检验,理由是..." │ +│ user: "好的,按这个方案执行" │ +│ │ +│ → IntentRouter 识别为 analyze │ +│ → Node.js 编排层从 Session 黑板读取 consult 阶段的结论 │ +│ → 对话层 LLM 收到完整上下文: │ +│ System Prompt(含 DataContext + "用户已确认 T 检验方案") │ +│ + 对话历史(包含 consult 阶段的讨论) │ +│ + 意图特定指令("正在执行分析,请向用户说明进展") │ +│ → LLM 生成衔接回复: │ +│ "好的,我来按之前讨论的方案执行。分析计划如下: │ +│ 步骤 1: 描述统计(两组基线特征) │ +│ 步骤 2: 独立样本 T 检验(比较血压差异) │ +│ 确认开始执行吗?" │ +│ │ +└────────────────────────────────────────────────────────────────────┘ +``` + +### 2.4 对话层 LLM 的技术参数 + +| 参数 | 值 | 说明 | +|------|---|------| +| 模型 | deepseek-v3 | 全系统统一模型 | +| Temperature | 0.7(对话)/ 0.3(报告生成) | 对话允许自然变化,报告追求稳定 | +| System Prompt | 持久注入 | 整个会话生命周期内持续生效 | +| 对话历史 | 滑动窗口(5-10 轮) | Token 预算内尽量多保留 | +| DataContext | 始终注入 | 通过 Session 黑板注入,保证数据感知 | +| Prompt 管理 | DB 存储 + Seed 脚本 | 方法学团队可编辑,不写死在代码中 | + +--- + +## 3. 编排层 vs 对话层的职责划分 + +### 3.1 什么事 Node.js 编排层做 + +| 职责 | 说明 | 举例 | +|------|------|------| +| **意图路由** | 决定这条消息走哪个处理路径 | "比较两组" → analyze | +| **工具调度** | 决定调用哪些工具、什么顺序 | analyze → plan → run_step ×N → report | +| **Session 黑板读写** | 工具输出写入黑板,工具输入从黑板读 | PICO 写入 → plan 读取 | +| **Token 控制** | 注入 LLM 前裁剪上下文 | 变量字典 >20 → 只注入已确认的 | +| **data_source 注入** | R 引擎调用前自动注入数据源 | OSS 预签名 URL | +| **错误分类** | run_step 出错后决定重试还是报告 | "Column not found" → 可自愈 | +| **流程控制** | ask_user 中断/恢复、重试计数 | MAX 2 次 → 停止重试 | + +### 3.2 什么事对话层 LLM 做 + +| 职责 | 说明 | 举例 | +|------|------|------| +| **自然语言生成** | 把结构化输出变成人话 | JSON → "您的数据共 200 例..." | +| **多轮对话连贯** | 理解指代、省略、上下文引用 | "刚才那个" → BMI | +| **知识推理** | 基于统计学知识回答专业问题 | "为什么选 T 检验?" | +| **PICO 推断** | 基于临床知识推断数据角色 | 推断 outcome 可能是 bp_change | +| **方法解释** | 解释决策表的匹配结果 | "选 T 检验是因为..." | +| **结果解读** | 深度解释统计结果的含义 | "p=0.03 说明..." | +| **主动引导** | 在合适时机引导用户下一步 | "需要做敏感性分析吗?" | +| **反思分析** | 分析 QPER 全记录找问题根因 | "样本量不足导致检验效能低" | + +### 3.3 协作模型 + +``` +Node.js 编排层 对话层 LLM +───────────── ────────── + +"这条消息是 explore 意图" → + +"调用 get_data_overview" → + +"工具返回了 JSON 结果" → "把 JSON + DataContext + 对话历史 + 组装成 Prompt,生成自然语言解读" + + ← "您的数据共 200 例,分为..." + +"把回复返回给前端" → + +─── 下一轮 ─── + +"这条消息是 consult 意图" → + +"调用 method_consult → + (DecisionTable 匹配)" + +"匹配结果: T 检验" → "把匹配结果 + DataContext + 对话历史 + 组装成 Prompt,生成方法推荐 + 理由" + + ← "建议独立样本 T 检验,因为..." +``` + +**核心原则:Node.js 决定"做什么",LLM 决定"怎么说"和"怎么想"。两者缺一不可。** + +--- + +## 4. 意图 → 编排流程 → LLM 角色映射 + +| 意图 | Node.js 编排流程 | 对话层 LLM 角色 | +|------|-----------------|----------------| +| **chat** | 几乎不介入 | **完全主导**:直接回答,DataContext 保证数据感知 | +| **explore** | 调用 READ 层工具 | **翻译+解读**:JSON → 自然语言数据解读 | +| **consult** | 调用 method_consult | **融合+解释**:决策表结果 → 完整方法推荐 | +| **analyze** | 调用 THINK+ACT 全链路 | **播报+衔接**:步骤进展说明,上下文衔接 | +| **discuss** | 提取分析结果 | **深度解读**:统计学问题的专业解答 | +| **feedback** | 注入 QPER 记录 | **诊断+建议**:问题根因分析,新方案建议 | + +--- + +## 5. 四层七工具实现机制总览 + +### 5.1 四层七工具实现机制一览 + +| 层 | 工具 | 实现机制 | LLM 参与 | 核心引擎 | 风险/成本 | +|----|------|---------|:---:|---------|----------| +| **READ** | `get_data_overview` | Python 计算 + LLM 推断 | ✅ 部分 | DataProfileService (Python) | 零风险 | +| **READ** | `get_variable_detail` | 纯 Python 计算 | ❌ | DataProfileService (Python) | 零风险 | +| **READ** | `method_consult` | 匹配引擎 + LLM 补充 | ✅ 部分 | DecisionTableService (规则) | 零风险 | +| **INTERACT** | `ask_user` | 纯系统机制 | ❌ | Node.js → 前端 → 用户 | 零风险 | +| **THINK** | `analysis_plan` | 匹配引擎 + 模板填充 | ❌ | DecisionTable + FlowTemplate | 低风险 | +| **ACT** | `run_step` | 纯 R 引擎执行 | ❌ | WorkflowExecutor → R Plumber | 有计算成本 | +| **ACT** | `write_report` | LLM 生成 + 槽位注入 | ✅ 核心 | ReflectionService (LLM) | 有 Token 成本 | + +### 5.2 辅助机制 + +| 机制 | 实现方式 | LLM 参与 | +|------|---------|:---:| +| **意图路由器** | 规则引擎优先 + LLM 兜底(混合路由) | ✅ 部分 | +| **反思 — 自动重试** | 错误分类器(规则) + LLM 修正参数 | ✅ 部分 | +| **反思 — 手动触发** | LLM 分析完整 QPER 记录 → 新方案 | ✅ 核心 | +| **Session 黑板** | Node.js 内存缓存 | ❌ | +| **Token 控制** | 代码裁剪函数 | ❌ | +| **data_source 注入** | Node.js 编排层自动注入 | ❌ | + +--- + +## 6. READ 层 — 只读,零风险 + +### 6.1 get_data_overview + +> **实现机制:Python 统计计算 + LLM PICO 推断(两步串联)** + +``` + ┌──────────────────────────────────┐ + session_id ──→ │ Step 1: DataProfileService │ ← 纯 Python 计算 + │ (Python pandas 统计分析) │ 无 LLM + │ 输出:行数/列数/缺失率/类型/分布 │ + └──────────────┬───────────────────┘ + │ 结构化 JSON + ▼ + ┌──────────────────────────────────┐ + │ Step 2: LLM PICO 推断 │ ← LLM Prompt + │ 输入:统计摘要 + 临床知识 │ 纯推理,无工具调用 + │ 输出:population / intervention / │ + │ outcome 候选 + 置信度 │ + └──────────────┬───────────────────┘ + │ 合并 + ▼ + 写入 Session 黑板 +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| 统计摘要生成 | **Python(pandas)** | 调用已有 `DataProfileService`,返回结构化 JSON | +| PICO 推断 | **LLM Prompt** | 将统计摘要注入 Prompt,LLM 基于临床知识推断 PICO 分类 | +| 结果缓存 | **Node.js 内存** | 写入 Session 黑板,后续工具直接读缓存 | + +**关键约束:** +- Step 1(统计计算)和 LLM 完全无关,是确定性结果 +- Step 2(PICO 推断)标记为 `inference`,必须经 `ask_user` 确认后才变为 `confirmed` +- 已有实现基础:`DataProfileService` 已能生成统计摘要并缓存 + +--- + +### 6.2 get_variable_detail + +> **实现机制:纯 Python 计算(零 LLM)** + +``` + session_id + variable_name + │ + ▼ + ┌────────────────────────────────┐ + │ DataProfileService │ ← 纯 Python 计算 + │ 按需查询单列 │ 无 LLM + │ 输出:分布/直方图/异常值/样本值 │ 确定性结果 + └────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| 单列统计分析 | **Python(pandas)** | 计算分布、异常值、直方图分箱等 | + +**关键约束:** +- 整个工具内部没有 LLM 参与,完全是 Python 数值计算 +- 是 `get_data_overview` 的按需 drill-down,解决大数据集 Token 爆炸问题 +- 需要在 Python 侧新增"单列查询" API(当前 `DataProfileService` 只有全量 profile) + +--- + +### 6.3 method_consult + +> **实现机制:决策表四维匹配 + LLM 推理补充(双引擎)** + +``` + research_question + outcome_var + predictors + DataContext + │ + ├──→ ┌─────────────────────────────────────────┐ + │ │ 引擎 A: DecisionTableService │ ← 规则匹配引擎 + │ │ 四维匹配 Goal × OutcomeType × │ 无 LLM + │ │ PredictorType × Design │ 确定性结果 + │ │ 输出:primaryTool + fallbackTool │ + │ └──────────────┬──────────────────────────┘ + │ │ 匹配结果 + │ ▼ + └──→ ┌─────────────────────────────────────────┐ + │ 引擎 B: LLM 推理补充 │ ← LLM Prompt + │ 输入:匹配结果 + DataContext + 统计知识 │ 纯推理 + │ 输出: │ + │ rationale(选择理由) │ + │ prerequisites(前提条件) │ + │ limitations(局限性) │ + │ alternatives(替代方案 + 适用场景) │ + └─────────────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| 方法选择(选什么) | **DecisionTableService** | 四维规则匹配,JSON 驱动,确定性、可审计 | +| 解释说明(为什么选) | **LLM Prompt** | 利用 LLM 统计学知识生成自然语言解释 | + +**关键约束:** +- 核心决策(选什么方法)由规则引擎决定,不由 LLM 决定 — 确保可审计、可配置 +- LLM 只负责"润色"和"补充" — 生成人类可读的理由和替代方案说明 +- 决策表当前 ~10 条规则,覆盖 7 个 R 工具,JSON 驱动,方法学团队可编辑 +- 未来工具扩展到 30+ 时,可在决策表前加一层 RAG Top-K 检索 +- 已有实现基础:`DecisionTableService.match()` 已实现四维匹配 + +--- + +## 7. INTERACT 层 — 人机交互,零风险 + +### 7.1 ask_user + +> **实现机制:纯系统机制(Node.js 请求-响应模式,零 LLM)** + +``` + Node.js 编排层决定需要提问 + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 1: Node.js 生成 ClarificationCard JSON │ ← 无 LLM + │ (question + options + context) │ Node.js 代码构造 + └──────────────┬───────────────────────────────────┘ + │ SSE 推送 / HTTP Response + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 2: 前端 ClarificationCard 组件渲染 │ ← 前端 React + │ 用户看到选择卡片 → 点击选择 → 提交 │ + └──────────────┬───────────────────────────────────┘ + │ HTTP POST(用户选择结果) + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 3: Node.js 从 Session 黑板恢复上下文 │ ← 无 LLM + │ 将用户选择写入黑板 → 继续后续流程 │ + └──────────────────────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| 卡片生成 | **Node.js 代码** | 根据当前流程上下文构造问题和选项 | +| 卡片渲染 | **前端 React** | `ClarificationCard` 组件,支持单选/多选/自由文本 | +| 上下文恢复 | **Session 黑板** | 用户响应后,从黑板恢复上下文继续流程 | + +**关键约束:** +- 工具本身完全不涉及 LLM — 它是一个"人机交互通道" +- 但"什么时候问、问什么"是由 Node.js 编排层决定的 +- 当前实现为"请求-响应模式":Node.js 发送卡片 → 中断等待 → 下一次 HTTP 请求恢复 +- 不是 LLM Function Calling 挂起模式(那是 Phase 4+ 的预研方向) +- 已有实现基础:`QueryService.generateClarificationCards()` + `ClarificationCard` 前端组件 + +--- + +## 8. THINK 层 — 生成方案,低风险 + +### 8.1 analysis_plan + +> **实现机制:决策表匹配 + 流程模板填充(确定性引擎,零 LLM)** + +``` + confirmed_question + confirmed_methods + variable_mapping + DataContext + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 1: DecisionTableService.match() │ ← 规则匹配引擎 + │ 四维匹配 → 命中规则 → 得到 templateId │ 无 LLM + └──────────────┬───────────────────────────────────┘ + │ matchResult { templateId, primaryTool, fallbackTool } + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 2: FlowTemplateService.fill() │ ← 模板引擎 + │ 选择模板 → 填充参数 → EPV 防护 → 有序步骤列表 │ 无 LLM + │ 输出:[{order, tool_code, params, depends_on}] │ 确定性结果 + └──────────────────────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| 规则匹配 | **DecisionTableService** | 四维匹配(Goal × OutcomeType × PredictorType × Design) | +| 模板填充 | **FlowTemplateService** | 从 `flow_templates.json` 加载模板,填入变量名和参数 | +| EPV 防护 | **FlowTemplateService** | 检查事件数/自变量比,超限自动截断并生成免责声明 | + +**关键约束:** +- 整个工具内部没有 LLM 参与 — 完全是规则匹配 + 模板填充的确定性计算 +- 方法选择在 `method_consult` 阶段已完成并经用户确认,`analysis_plan` 只负责"编排顺序 + 填充参数" +- 输出包含确定的 `tool_code` + 完整 `params`,`run_step` 只需傻瓜式执行 +- 生成后展示给用户审查,用户确认后才进入 ACT 层 +- 已有实现基础:`FlowTemplateService.fill()` + `decision_tables.json` + `flow_templates.json` + +--- + +## 9. ACT 层 — 执行,有成本 + +### 9.1 run_step + +> **实现机制:纯 R 引擎执行(傻瓜式 API 转发,零 LLM)** + +``` + step_definition { tool_code, params } + session_id + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Node.js 编排层:自动注入 data_source │ ← 无 LLM + │ 从 Session 黑板取 dataOssKey → 生成预签名 URL │ 系统机制 + │ 注入 params.data_source = { type:'oss', oss_url } │ + └──────────────┬───────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ WorkflowExecutorService → RClientService │ + │ HTTP POST 给 R Plumber API │ ← 无 LLM + │ R 脚本执行统计分析 │ 纯 R 引擎计算 + │ 返回 ReportBlock[] + figures + r_code │ + └──────────────────────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| data_source 注入 | **Node.js 编排层** | 从 Session 黑板取 `dataOssKey`,生成预签名 URL 自动注入 | +| R 脚本执行 | **R Plumber API** | 接收 tool_code + params → 执行统计计算 → 返回结构化结果 | +| 结果标准化 | **R Block Helpers** | R 端输出标准化为 `ReportBlock[]` 格式 | + +**关键约束:** +- 整个工具内部没有 LLM 参与 — 纯粹的 HTTP 转发 + R 引擎执行 +- 是"傻瓜式 API 转发器",不做任何方法选择决策 +- `data_source` 由 Node.js 编排层自动注入,LLM 和 `analysis_plan` 全程不感知数据文件位置 +- 错误处理由编排层接管(双轨反思机制) +- 已有实现基础:`WorkflowExecutorService` + `RClientService` + `resolveDataSource()` 全部已实现 + +--- + +### 9.2 write_report + +> **实现机制:LLM 生成叙述 + 统计量槽位注入 + Zod 校验(LLM 为核心引擎)** + +#### generate 模式(论文级报告) + +``` + step_results + DataContext + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 1: 提取 Key Findings │ ← 无 LLM + │ 从 stepResults 中提取 p 值、置信区间、效应量等 │ 纯代码提取 + │ 生成 {{ slot }} 映射表 │ + └──────────────┬───────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 2: LLM 生成叙述框架 │ ← LLM 核心 + │ Prompt: "根据以下统计结果,生成论文级结论" │ 生成自然语言叙述 + │ LLM 输出包含 {{ slot }} 占位符 │ + │ LLM 被禁止生成任何数值(反幻觉机制) │ + └──────────────┬───────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ Step 3: jsonrepair + Zod 校验 + 槽位渲染 │ ← 无 LLM + │ 校验 LLM 输出结构完整性 │ 确定性后处理 + │ 用真实统计数值替换 {{ slot }} 占位符 │ + │ 校验失败 → 降级到 ConclusionGeneratorService │ + └──────────────────────────────────────────────────┘ +``` + +#### interpret 模式(结果解读) + +``` + user_question + step_results + DataContext + │ + ▼ + ┌──────────────────────────────────────────────────┐ + │ LLM 深度解读 │ ← LLM 核心 + │ Prompt: DataContext + 分析结果 + 用户具体问题 │ 纯推理 + │ 输出:针对用户问题的统计学解读 │ + └──────────────────────────────────────────────────┘ +``` + +**实现细节:** + +| 环节 | 引擎 | 说明 | +|------|------|------| +| Key Findings 提取 | **Node.js 代码** | 从 R 输出中提取关键统计量,构建槽位映射表 | +| 叙述框架生成 | **LLM (deepseek-v3)** | 生成论文级叙述,用 `{{ slot }}` 占位符替代数值 | +| 输出校验 | **jsonrepair + Zod** | 修复 JSON 格式 → Schema 强校验 → 确保结构完整 | +| 槽位渲染 | **Node.js 代码** | 用真实统计数值替换占位符 | +| 降级兜底 | **ConclusionGeneratorService** | Zod 校验失败时,规则拼接生成基础结论 | + +**关键约束:** +- 这是 7 个工具中 LLM 参与度最高的,LLM 是核心引擎 +- 但 LLM 不是"裸奔"的:统计量通过槽位注入从 R 输出渲染,LLM 被禁止生成数值(反幻觉) +- 三层防御:`jsonrepair` → `Zod Schema` → `ConclusionGeneratorService`(规则拼接兜底) +- 已有实现基础:`ReflectionService` + `ConclusionGeneratorService` 全部已实现 + +--- + +## 10. 辅助机制详解 + +### 10.1 意图路由器(IntentRouterService) + +> **实现机制:规则引擎优先 + LLM 兜底(混合路由)** + +``` + 用户消息 + Session 上下文 + │ + ▼ + ┌──────────────────────────────────────┐ + │ Step 1: 规则匹配器 │ ← 无 LLM + │ 关键词匹配 + 上下文状态推断 │ 确定性、零延迟 + │ "执行""分析一下" → analyze │ + │ "应该用什么方法" → consult │ + │ "帮我看看" → explore │ + │ "p 值说明什么"(有结果) → discuss │ + └──────────────┬───────────────────────┘ + │ + ├── 命中 → 直接返回意图(不调 LLM) + │ + └── 未命中 ──→ ┌──────────────────────────┐ + │ Step 2: LLM 轻量分类 │ ← LLM Prompt + │ 仅做分类,不生成长文 │ 低 Token 成本 + │ 输出:intent + confidence │ + └──────────────┬───────────┘ + │ + ├── confidence 足够 → 返回 + └── confidence 不足 → 默认 chat +``` + +**关键约束:** +- 规则优先:明确场景走规则,零延迟、零 Token 成本 +- LLM 兜底:模糊场景走轻量级 LLM 分类(仅输出 intent + confidence,不生成长文) +- 默认安全:无法判断时 → chat(最安全的兜底,不触发任何流水线) + +### 10.2 反思机制(编排层逻辑,非工具) + +#### 自动反思(静默重试) + +``` + run_step 返回 error + │ + ▼ + ┌──────────────────────────────────────┐ + │ 错误分类器 │ ← 无 LLM + │ 读取 error_classification.json │ 规则匹配 + │ R 报错关键词 → 分类 │ + └──────────┬──────────┬────────────────┘ + │ │ + 可自愈(参数级) 不可自愈(方法级) + │ │ + ▼ ▼ + ┌──────────────┐ ┌──────────────────────────┐ + │ LLM 修正参数 │ │ 报告用户 + 建议替代方案 │ + │ 注入错误日志 │ │ 不重试 │ + │ + DataContext │ └──────────────────────────┘ + │ → 重试(MAX 2) │ + └──────────────┘ + ← LLM Prompt +``` + +#### 手动反思(用户驱动) + +``` + 用户: "结果不对" / "换个方法试试" + │ + ▼ + IntentRouter → feedback 意图 + │ + ▼ + ┌──────────────────────────────────────┐ + │ LLM 分析完整 QPER 记录 │ ← LLM 核心 + │ 注入 qperTrace(滑动窗口摘要) │ 深度推理 + │ 分析问题根因 → 生成新方案建议 │ + └──────────────┬───────────────────────┘ + │ + ▼ + ask_user → 新 analysis_plan → run_step → write_report +``` + +### 10.3 Session 黑板(纯系统基础设施) + +``` +┌─ Session Blackboard ─────────────────────────────────────┐ +│ sessionId │ +│ dataOverview ← get_data_overview 写入 │ +│ confirmedPico ← ask_user 确认后写入 │ +│ variableDictionary ← 对话中逐步丰富 │ +│ dataOssKey ← 上传时写入(run_step 自动注入用) │ +│ currentPlan ← analysis_plan 写入 │ +│ stepResults ← run_step 每步追加 │ +│ report ← write_report 写入 │ +│ qperTrace ← 所有工具调用记录(反思用) │ +└──────────────────────────────────────────────────────────┘ + +实现:纯 Node.js 内存缓存,无 LLM 参与 +Token 控制:注入 LLM 前的裁剪函数(纯代码逻辑) +``` + +--- + +## 11. LLM 在架构中的准确定位 + +### 11.1 三层分类 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 完全不用 LLM 的 │ +│ │ +│ get_variable_detail — 纯 Python 计算 │ +│ ask_user — 纯系统机制(Node.js → 前端 → 用户) │ +│ analysis_plan — 纯规则匹配 + 模板填充 │ +│ run_step — 纯 R 引擎执行 │ +│ Session 黑板 / Token 控制 / data_source 注入 │ +│ │ +│ → 这些是"管道和基础设施",确定性、可审计、零 Token 成本 │ +├─────────────────────────────────────────────────────────────┤ +│ 部分使用 LLM 的 │ +│ │ +│ get_data_overview — Python 计算(主) + LLM PICO 推断(辅) │ +│ method_consult — 决策表匹配(选什么) + LLM(解释为什么选) │ +│ 意图路由器 — 规则优先(确定性) + LLM 兜底(模糊场景) │ +│ 反思-自动重试 — 规则分类错误 + LLM 修正参数 │ +│ │ +│ → 这些是"引擎 + LLM 增强",核心决策不依赖 LLM │ +├─────────────────────────────────────────────────────────────┤ +│ LLM 为核心的 │ +│ │ +│ write_report(generate) — LLM 生成叙述(但槽位注入防幻觉) │ +│ write_report(interpret) — LLM 深度解读用户问题 │ +│ 反思-手动触发 — LLM 分析完整 QPER 记录 │ +│ chat / explore 对话 — LLM(DataContext) 直接回复 │ +│ │ +│ → 这些是"LLM 的主场",充分发挥 LLM 知识和推理能力 │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 11.2 LLM 调用点清单 + +| 调用点 | LLM 角色 | 模型 | 防护机制 | +|--------|---------|------|---------| +| PICO 推断 | 临床知识推理 | deepseek-v3 | ask_user 人工确认 | +| method_consult 补充 | 统计学知识解释 | deepseek-v3 | 决策表为主,LLM 只补充说明 | +| 意图路由 LLM 兜底 | 意图分类 | deepseek-v3 | 规则优先,LLM 只处理模糊场景 | +| write_report(generate) | 论文级叙述生成 | deepseek-v3 | 槽位注入 + Zod 校验 + 规则拼接兜底 | +| write_report(interpret) | 结果深度解读 | deepseek-v3 | DataContext 约束回答范围 | +| 反思-自动修正 | 参数级错误修复 | deepseek-v3 | MAX 2 次重试限制 | +| 反思-手动分析 | QPER 全记录分析 | deepseek-v3 | ask_user 确认新方案 | +| chat/explore 对话 | 自由知识对话 | deepseek-v3 | DataContext 注入提供约束 | + +--- + +## 12. 架构哲学总结 + +### 12.1 核心协作模型 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ │ +│ Node.js 编排层(交通指挥) │ +│ ┌────────────────────────┐ │ +│ │ 意图路由 → 工具调度 │ │ +│ │ Session 黑板读写 │ │ +│ │ Token 控制 + 流程控制 │ │ +│ └──┬──────────────┬──────┘ │ +│ │ │ │ +│ ┌──────────┘ └──────────┐ │ +│ ▼ ▼ │ +│ ┌────────────────┐ ┌────────────────┐ │ +│ │ 工具层(手脚) │ │ 用户 │ │ +│ │ │ 结构化输出 │ │ │ +│ │ Python 计算 │ ──────────────→ │ ask_user │ │ +│ │ DecisionTable │ │ PICO 确认 │ │ +│ │ FlowTemplate │ │ 方案审查 │ │ +│ │ R 引擎 │ │ 反思决策 │ │ +│ │ ErrorClassify │ └────────────────┘ │ +│ └────────┬───────┘ │ +│ │ 结构化输出 │ +│ ▼ │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ 对话层 LLM(全局大脑) │ │ +│ │ │ │ +│ │ System Prompt(角色 + DataContext + 意图指令) │ │ +│ │ + 对话历史(滑动窗口) │ │ +│ │ + 工具输出(结构化 JSON) │ │ +│ │ │ │ +│ │ → 自然语言生成 → 多轮对话连贯 │ │ +│ │ → 知识推理 → 主动引导 │ │ +│ │ → PICO 推断 → 结果解读 │ │ +│ │ → 方法解释 → 反思分析 │ │ +│ └────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 自然语言回复 → 前端展示 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 12.2 一句话总结 + +> **确定性的事交给规则引擎**(决策表、模板、R 脚本、Python 计算) +> **需要知识和推理的事交给对话层 LLM**(理解意图、组织回复、知识推理、结果解读) +> **需要判断和确认的事交给用户**(PICO 确认、方法选择、方案审查) +> **三者通过 Node.js 编排层和 Session 黑板协同工作** + +### 12.3 角色定位 + +| 层 | 角色类比 | 核心职责 | Token 成本 | +|----|---------|---------|-----------| +| **Node.js 编排层** | 交通指挥 | 决定做什么、走哪条路 | 零 | +| **对话层 LLM** | 统计顾问本人 | 理解、推理、表达、引导 | 有(核心开销) | +| **工具层** | 实验室设备 | 计算、匹配、执行 | 零(除 write_report) | +| **用户** | 最终决策者 | 确认、修正、决定方向 | 零 | + +**对话层 LLM 是系统的大脑和嘴巴** — 它理解用户在说什么,知道该怎么回答,把工具的结构化输出变成人类能理解的对话。没有它,系统只是一堆互不关联的 API 调用。 + +--- + +--- + +**文档维护者:** SSA 架构团队 +**创建日期:** 2026-02-21 +**最后更新:** 2026-02-21(v1.1 — 新增对话层 LLM 架构说明,明确三层架构模型) +**关联文档:** +- `SSA-Pro 工具体系规划方案(团队讨论稿).md` — 工具定义(做什么) +- `SSA-Pro 意图识别与对话架构设计.md` — 意图路由 + System Prompt 策略 +- `04-开发计划/11-智能对话与工具体系开发计划.md` — 开发落地计划 + +### 变更日志 + +| 版本 | 日期 | 变更内容 | +|------|------|---------| +| v1.0 | 2026-02-21 | 初版:四层七工具的内部实现机制 | +| v1.1 | 2026-02-21 | **新增对话层 LLM 架构**:① 明确三层架构(编排层 + 对话层 LLM + 工具层);② 新增 System Prompt 架构(基础角色 + DataContext 注入 + 意图指令 + 对话历史);③ 新增对话连贯性三大保障机制(对话历史注入 + Session 黑板持久化 + 意图切换上下文衔接);④ 新增编排层 vs 对话层职责划分表 | diff --git a/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 工具体系规划方案(团队讨论稿).md b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 工具体系规划方案(团队讨论稿).md new file mode 100644 index 00000000..1bc4056c --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 工具体系规划方案(团队讨论稿).md @@ -0,0 +1,675 @@ +# SSA-Pro 工具体系规划方案 + +> **日期:** 2026-02-21 +> **版本:** v3.1(融合方案 + 工程补强) +> **议题:** SSA 智能统计分析助手的工具定义与规划 +> **背景:** 当前 100 个 R 执行工具是基础能力,但工具体系过于单一。需要规划更完整的工具层,让 LLM Agent 能够在分析的全生命周期中为用户服务。 +> **结论:** 经过多轮讨论和团队评审,确定融合方案(四层 7 工具 + 反思编排 + Session 黑板 + Token 控制 + data_source 自动注入) + +--- + +## 一、当前问题 + +**现状**:系统只有 R 执行工具(约 100 个),用户发消息 → 系统直接匹配统计方法 → 执行 R 脚本。 + +**问题**: +- 用户无法与系统自由对话(每条消息都被当作分析请求) +- LLM 面对 100 个 R 工具会决策瘫痪(工具过载) +- 缺少"看数据""选方法""解读结果"等非执行类工具 +- 分析全过程对用户不透明 + +--- + +## 二、工具设计原则 + +| 原则 | 含义 | +|------|------| +| **正交性** | 每个工具有唯一职责,不重叠 | +| **清晰触发** | LLM 看到工具名就知道何时该用 | +| **组合性** | 工具可按不同顺序组合,下游只依赖上游输出而非特定调用链 | +| **粒度适中** | 太粗=黑箱,太细=决策负担;5-8 个工具是 LLM 的甜区 | +| **安全分级** | 只读工具随时调用,执行工具需确认 | +| **最小暴露** | 每个阶段只暴露完成当前任务所必需的工具子集 | +| **工具 vs 智能体** | 需要外部信息或改变外部世界 → 工具;纯 LLM 推理 → Prompt 职责,不封装为工具 | + +--- + +## 三、融合方案总览 + +### 3.1 四层架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ LLM Agent 决策层 │ +│ 根据对话上下文 + 当前阶段,选择调用哪个工具 │ +└──┬─────────────┬──────────────┬──────────────┬──────────────┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + READ 层 INTERACT 层 THINK 层 ACT 层 + 只读,零风险 人机交互 生成方案 执行,有成本 + 随时可调用 零风险 需用户审查 需用户确认 +``` + +### 3.2 工具清单(7 个) + +| 层 | # | 工具名 | 类型 | 一句话职责 | +|----|---|--------|------|-----------| +| **READ** | 1 | **get_data_overview** | 只读 | 数据全貌:统计摘要 + 缺失 + 变量分类 + PICO 自动推断 | +| **READ** | 2 | **get_variable_detail** | 只读 | 单变量深入:分布 + 异常值 + 唯一值(按需查看,控制 Token) | +| **READ** | 3 | **method_consult** | 只读 | 方法咨询:推荐统计方法 + 理由 + 前提 + 替代方案 | +| **INTERACT** | 4 | **ask_user** | 交互 | 向用户提问/确认:渲染为选择卡片,用于 PICO 确认、方案审查 | +| **THINK** | 5 | **analysis_plan** | 生成 | 分析规划:有序步骤 + 参数 + 依赖(输出确定的 tool_code + params) | +| **ACT** | 6 | **run_step** | 执行 | 傻瓜式 R 执行:接收 tool_code + params,转发 R 引擎,返回结果 | +| **ACT** | 7 | **write_report** | 生成 | 论文级报告 / 结果解读(双模式:generate + interpret) | + +### 3.3 反思机制(不是工具,是编排层逻辑) + +反思不定义为独立工具,而是系统编排机制,采用**双轨触发**: + +**自动触发(静默重试)**:当 `run_step` 返回硬性错误(Column not found、NaN produced 等参数级错误),系统自动将错误日志注入 LLM 上下文,LLM 修正参数后静默重试,最多 2 次。用户无感知。 + +**手动触发(用户驱动)**:当执行成功但用户不满意("能不能换个方法""把极值删了再跑一次"),意图路由器识别为 feedback 意图,将完整 QPER 记录注入 LLM,LLM 分析问题后生成新的 `analysis_plan`。 + +``` +run_step 返回 error + → 错误分类器 + → 可自愈(参数拼写、列名错误) → 自动修正 → 重试(最多 2 次) + → 不可自愈(方法不适用、数据不足) → 报告用户 + 建议替代方案 + +用户表达不满 + → 意图路由器 → feedback 意图 + → 注入完整 QPER 记录 → LLM 分析原因 → 新的 analysis_plan → 重新执行 +``` + +### 3.4 PICO 需求梳理(不是工具,是 Prompt 职责) + +PICO 梳理在对话过程中自然完成,不需要专门的工具: + +``` +1. LLM 调用 get_data_overview → 返回中包含 AI 自动推断的 PICO 分类(置信度标记) +2. LLM 基于推断结果 + 临床知识 + System Prompt 组织 PICO 描述 +3. LLM 调用 ask_user → 让用户确认/修正 PICO 分类 +4. 确认后的 PICO 写入 Session 黑板,后续所有工具调用都携带 +``` + +--- + +## 四、各工具详细定义 + +### 工具 1: get_data_overview + +``` +名称: get_data_overview +层级: READ(只读,零风险) +触发时机: 数据上传后自动调用 / 用户询问数据概况时 +底层实现: DataProfileService(Python) + +输入: { + session_id: string +} + +输出: { + total_rows: number, + total_columns: number, + missing_overview: { + overall_rate: number, + columns_with_missing: [{ name, rate }] + }, + categorical_vars: [{ name, levels_count, top_levels }], + continuous_vars: [{ name, mean, sd, min, max }], + id_like_vars: [string], + data_structure: "cross-sectional" | "longitudinal" | "repeated-measures" | "unknown", + sample_size_warning: string | null, + + // PICO 自动推断(AI 猜测,需用户通过 ask_user 确认后才生效) + pico_inference: { + population: string | null, + intervention_var: string | null, + intervention_levels: [string], + outcome_candidates: [{ var, type, confidence }], + design_guess: string | null, + confidence: number // 整体推断置信度 + } +} +``` + +**设计要点**: +- 输出一次性包含"下游需要的一切只读信息",满足组合性原则 +- PICO 推断标记为 inference(推断),不是 confirmed(确认),后续必须经过 ask_user 确认 +- 输出写入 Session 黑板缓存,后续工具直接读缓存,不重复调用 + +### 工具 2: get_variable_detail + +``` +名称: get_variable_detail +层级: READ(只读,零风险) +触发时机: LLM 需要深入了解某个变量时(按需 drill-down) +底层实现: DataProfileService(Python),按需查询单列 + +输入: { + session_id: string, + variable_name: string +} + +输出: { + name: string, + type: "continuous" | "categorical" | "ordinal" | "datetime" | "id", + missing_rate: number, + unique_values: number, + distribution: { + // 连续型: { mean, median, sd, q1, q3, min, max, histogram_bins } + // 分类型: { levels: [{ value, count, percentage }] } + }, + outliers: { count, threshold }, + sample_values: [...] +} +``` + +**设计要点**: +- 解决大数据集 Token 爆炸 — LLM 先看 overview 概览,再按需 drill-down 单列 +- 多次调用查看不同变量,每次只增加一列的 Token 消耗 + +### 工具 3: method_consult + +``` +名称: method_consult +层级: READ(只读,零风险) +触发时机: 用户询问"应该用什么方法" / LLM 需要方法推荐时 +底层实现: DecisionTableService 四维匹配 + LLM 推理补充 + +输入: { + research_question: string, + outcome_var: string, + predictor_vars: [string], + data_context: DataContext // 从 Session 黑板读取 +} + +输出: { + recommended_method: { + name: string, // "Independent Samples T-Test" + tool_code: string, // "ST_T_TEST_IND" + rationale: string, + prerequisites: [string], // ["正态性", "方差齐性"] + limitations: [string] + }, + alternatives: [{ + name, tool_code, when_to_use // 何时该用替代方案 + }], + warnings: [string] +} +``` + +**设计要点**: +- 当前 R 工具数量 7 个,决策表四维匹配(Goal × OutcomeType × PredictorType × Design)已足够精准 +- 未来工具扩展到 30+ 时,可在此处引入 RAG Top-K 检索替代/增强决策表 +- 只返回推荐,不执行。用户通过 ask_user 确认后才进入 THINK 层 + +### 工具 4: ask_user + +``` +名称: ask_user +层级: INTERACT(人机交互,零风险) +触发时机: LLM 需要用户确认或澄清时 +前端渲染: 选择卡片(单选/多选)或输入框,嵌入对话流 + +输入: { + question: string, + context: string, + options: [{ + id: string, + label: string, + description?: string + }], + allow_multiple: boolean, + allow_free_text: boolean +} + +输出: { + selected_options: [string], + free_text: string | null +} +``` + +**设计要点**: +- 强制 LLM 在不确定时向用户提问,而非自行猜测 +- 贯穿全流程:PICO 确认、变量角色确认、方法选择确认、方案审查 +- 前端已有 ClarificationCard 组件基础,需要标准化接口 + +**实现方式(请求-响应模式,非 Function Calling 挂起)**: +- 当前架构是 Node.js 编排层控制流程,不是 LLM 自主调用链 +- ask_user 不需要"挂起 LLM 推理线程":Node.js 生成卡片 → 返回前端 → 用户点击 → 前端 POST 新请求 → Node.js 从 Session 黑板恢复上下文 → 继续流程 +- 已有实现基础:`QueryService.generateClarificationCards()` + `/workflow/clarify` 路由 +- 未来若演进为 LLM Function Calling 模式(LLM 自主编排),需引入 Session 状态机 + 消息历史持久化(Phase 4 预研) + +### 工具 5: analysis_plan + +``` +名称: analysis_plan +层级: THINK(生成方案,需用户审查) +触发时机: 用户确认需求和方法后 +底层实现: FlowTemplateService 模板填充 + DecisionTableService 匹配 + +输入: { + confirmed_question: string, + confirmed_methods: [string], // 用户确认的 tool_code 列表 + variable_mapping: { + outcome: string, + predictors: [string], + confounders?: [string], + group_var?: string + }, + data_context: DataContext // 从 Session 黑板读取 +} + +输出: { + plan_id: string, + title: string, + steps: [{ + step_id: string, + order: number, + tool_code: string, // 确定的 R 工具代码,如 "ST_T_TEST_IND" + tool_name: string, + description: string, + params: { ... }, // 已填好的参数,run_step 直接透传 + depends_on: [step_id], + expected_output: string + }], + estimated_duration: string, + notes: [string] +} +``` + +**设计要点**: +- 输出包含确定的 `tool_code` 和完整 `params`,`run_step` 只需要傻瓜式执行 +- 方法选择由 `method_consult`(决策表)+ 用户确认完成,`analysis_plan` 只负责编排顺序和填充参数 +- 生成后展示给用户审查,用户确认后才进入 ACT 层 + +### 工具 6: run_step + +``` +名称: run_step +层级: ACT(执行,有计算成本) +触发时机: 用户确认分析计划后,逐步执行 +底层实现: WorkflowExecutorService → RClientService → R Plumber API + +输入: { + step_definition: { // 直接来自 analysis_plan 输出的某一步 + step_id: string, + tool_code: string, // 如 "ST_T_TEST_IND" + params: { ... } + }, + session_id: string +} + +输出: { + status: "success" | "warning" | "error", + result: { + blocks: ReportBlock[], + figures: [{ type, data, title }], + raw_output: { ... } + }, + r_code: string, + warnings: [string], + error_message: string | null +} +``` + +**设计要点**: +- **傻瓜式 API 转发器** — 不做任何方法选择决策,只接收 tool_code + params → 调用 R → 返回结果 +- **data_source 自动注入** — LLM 和 analysis_plan 都不需要关心数据文件位置。Node.js 编排层自动从 Session 黑板取出 `dataOssKey`,生成预签名 URL,注入 `{ type: 'oss', oss_url: signedUrl }` 后再 POST 给 R 服务(代码已实现:`WorkflowExecutorService.resolveDataSource()`) +- 错误处理由编排层接管(双轨反思机制) +- warning 状态的结果正常展示(R 引擎的 ggplot2 废弃警告等不影响结果) + +### 工具 7: write_report + +``` +名称: write_report +层级: ACT(生成,有 LLM Token 成本) +触发时机: 步骤全部执行完成后 / 用户要求解读结果时 +底层实现: ReflectionService(LLM 结论生成)+ 槽位注入 + Zod 校验 + +输入: { + mode: "generate" | "interpret", + step_results: [StepResult], // generate 模式:全部步骤结果 + data_context: DataContext, + user_question?: string // interpret 模式:用户的具体问题 +} + +输出: { + conclusion: { + summary: string, + detailed: string, + clinical_significance: string, + limitations: [string], + recommendations: [string] + }, + export_formats: ["word", "markdown"] +} +``` + +**设计要点**: +- **双模式**:`generate` 生成完整论文级报告(QPER R 层),`interpret` 解读已有结果(新增能力,支持 discuss 意图) +- generate 模式在全部 run_step 完成后自动触发 +- interpret 模式在用户追问结果时触发("p 值说明什么""为什么置信区间这么宽") + +--- + +## 五、Session 黑板(状态管理) + +### 5.1 为什么需要 Session 黑板 + +7 个工具本身是无状态函数。要让它们协同工作,需要一个后端"会话黑板"(Session Context Blackboard)在工具之间传递上下文。 + +**核心规则:切勿让 LLM 反复重新生成上下文。** `get_data_overview` 的输出缓存到 Session,后续 `analysis_plan` / `run_step` / `write_report` 直接从 Session 读取,不重新调用。 + +### 5.2 Session 黑板结构 + +```typescript +interface SessionBlackboard { + sessionId: string; + uploadedAt: string; + + // get_data_overview 的缓存输出 + dataOverview: DataOverviewResult | null; + + // 用户确认的 PICO(经过 ask_user 确认后写入) + confirmedPico: { + population: string; + intervention: { var: string; levels: string[] }; + outcomes: [{ var: string; type: string; role: string }]; + confirmed: boolean; + } | null; + + // 变量字典(对话中逐步丰富) + variableDictionary: Array<{ + name: string; + label: string; + type: string; + role: string; + confirmed: boolean; + }>; + + // 当前分析计划(analysis_plan 输出后写入) + currentPlan: AnalysisPlanResult | null; + + // 数据文件信息(上传时写入,run_step 自动注入 data_source 用) + dataOssKey: string | null; + + // 执行结果(run_step 每完成一步追加) + // ⚠️ Token 控制:只保留当前生效计划的结果,废弃试错结果 + stepResults: StepResult[]; + + // 结论报告(write_report 输出后写入) + report: ReportResult | null; + + // QPER 执行记录(反思机制需要) + // ⚠️ Token 控制:注入 LLM 前只保留最近 3 次关键事件,做摘要压缩 + qperTrace: Array<{ + timestamp: string; + tool: string; + input: any; + output: any; + }>; +} +``` + +### 5.3 Token 控制策略 + +Session 黑板会随着对话和试错不断膨胀。如果全量注入 LLM,会导致 Token 爆炸和注意力涣散。 + +**规则 1:stepResults 只保留当前生效计划的结果** +- 用户确认新的 analysis_plan 后,清空旧的 stepResults +- 反思迭代产生新方案时,旧方案的结果标记为 `deprecated`,不注入 LLM + +**规则 2:qperTrace 滑动窗口** +- 注入 LLM 前,只保留最近 3 次关键事件(tool 调用 + 错误 + 修复动作) +- 早期的 trace 条目压缩为一行摘要(如"第 1 轮:T 检验成功") + +**规则 3:R 引擎原始输出不入 LLM** +- stepResults 中的 `raw_output` 只存储在黑板中供前端展示 +- 注入 LLM 时只提取结构化摘要(关键数值、p 值、置信区间),不灌入完整日志 + +### 5.4 数据流 + +``` +get_data_overview + → 输出写入 blackboard.dataOverview + → LLM 基于输出推断 PICO + +ask_user(确认 PICO) + → 用户选择写入 blackboard.confirmedPico + +method_consult + → 读取 blackboard.dataOverview + confirmedPico + → 返回推荐方法(不写入 blackboard,只是对话中的回复) + +analysis_plan + → 读取 blackboard 全部上下文 + → 输出写入 blackboard.currentPlan + +run_step ×N + → 读取 blackboard.currentPlan 中的 step 定义 + → 每步输出追加到 blackboard.stepResults + +write_report + → 读取 blackboard.stepResults + dataOverview + → 输出写入 blackboard.report + +反思(自动/手动) + → 读取 blackboard.qperTrace(完整记录) + → 生成新的 analysis_plan → 覆盖 blackboard.currentPlan +``` + +### 5.5 持久化策略 + +| 层级 | 策略 | 理由 | +|------|------|------| +| 内存缓存 | 当前会话有效,进程重启丢失 | 快速读写,满足当前需求 | +| 数据库持久化 | 跨会话保留,支持历史回溯 | 后续扩展,用于分析记录和审计 | +| 当前实现 | 先用内存缓存(已有 DataProfileService 缓存机制) | 快速落地 | + +--- + +## 六、安全梯度与阶段性工具可见性 + +### 6.1 安全梯度 + +``` +READ 层: get_data_overview / get_variable_detail / method_consult + → 零风险,调用 100 次也无副作用 + → 对话阶段主要使用,支持自由探索 + → LLM 不确定时的安全默认选择 + +INTERACT 层: ask_user + → 零风险,让用户参与决策 + → 贯穿全流程:PICO 确认、方案审查、结果追问 + +THINK 层: analysis_plan + → 低风险,只生成方案不执行 + → 用户审查确认后才进入 ACT 层 + +ACT 层: run_step / write_report + → 有成本(R 计算资源、LLM Token) + → 产生真实结果,但可重新执行 +``` + +### 6.2 阶段性工具可见性 + +不同阶段向 LLM 暴露不同的工具子集: + +| 阶段 | 可见工具 | 隐藏工具 | +|------|---------|---------| +| **数据探索** | get_data_overview, get_variable_detail, ask_user | method_consult, analysis_plan, run_step, write_report | +| **需求梳理** | 全部 READ + ask_user | analysis_plan, run_step, write_report | +| **方案规划** | method_consult, ask_user, analysis_plan | run_step, write_report | +| **分析执行** | run_step, ask_user | 其他 | +| **报告生成** | write_report, ask_user | 其他 | +| **自由对话** | 全部 READ + INTERACT | THINK + ACT | + +--- + +## 七、典型调用链 + +### 场景 1:完整分析旅程 + +``` +用户上传数据 + → get_data_overview [自动] → 写入 Session 黑板 + → "您的数据有 200 行 15 列,推断为横截面..." [LLM 回复] + → 用户: "帮我看看 BMI 这个变量" + → get_variable_detail("bmi") [LLM 调用] + → ask_user("推断结局变量为 bp_change, [LLM 调用] + 分组变量为 group,是否正确?") + → 用户确认 → 写入 Session 黑板 confirmedPico + → 用户: "帮我比较两组血压差异" + → method_consult(...) [LLM 调用,从 Session 读上下文] + → "建议独立样本 T 检验,理由..." [LLM 回复] + → ask_user("确认使用 T 检验分析?") [LLM 调用] + → 用户确认 + → analysis_plan(...) [LLM 调用] → 写入 Session 黑板 + → "分析计划:步骤1 描述统计 → 步骤2 T 检验" [展示给用户] + → 用户: "确认,开始执行" + → run_step(step_1) [逐步执行] → 追加到 Session + → run_step(step_2) [逐步执行] → 追加到 Session + → write_report(mode: "generate") [生成报告] → 写入 Session +``` + +### 场景 2:用户只是了解数据 + +``` +用户: "这个数据有什么特点?" + → get_data_overview [LLM 调用] + → "您的数据包含 200 例患者,15 个变量..." [LLM 基于缓存回复] + +用户: "age 的分布怎样?" + → get_variable_detail("age") [LLM 调用] + +用户: "哪些变量缺失比较严重?" + → [LLM 从 Session 黑板缓存直接回答,无需再调工具] +``` + +### 场景 3:方法咨询 + +``` +用户: "BMI 和血压有关系吗?应该怎么分析?" + → method_consult(...) [LLM 调用] + → "建议 Pearson 相关分析,因为两个变量均为连续型..." + → ask_user("是否需要控制混杂因素?", + options: ["不需要", "控制年龄", "控制年龄和性别"]) + → 用户选择后 LLM 更新建议 +``` + +### 场景 4:结果不满意,反思迭代 + +``` +用户: "结果不对,p 值不应该这么大" + → [编排层] 注入完整 qperTrace 到 LLM 上下文 + → LLM: "可能原因:样本量不足导致检验效能低..." + → ask_user("建议:1)换用非参数检验 2)排除极值后重新分析 3)合并亚组") + → 用户选择 "换用非参数检验" + → analysis_plan(...) [生成新方案] + → run_step(...) [重新执行] + → write_report(mode: "generate") [新报告] +``` + +### 场景 5:执行出错,自动修正 + +``` + → run_step(step_2) [执行] + → R 返回 error: "Column 'Blood_Pressure' not found" + → [编排层] 错误分类 → 可自愈(列名拼写) + → [编排层] 自动注入错误 + 数据概览 → LLM 修正参数(bp_change) + → run_step(step_2, 修正后参数) [静默重试] + → 成功 → 用户无感知 +``` + +--- + +## 八、R 工具路由策略 + +### 当前方案:决策表四维匹配 + +100 个 R 脚本通过 `run_step` 调用时,方法选择在 `method_consult` / `analysis_plan` 阶段已确定: + +``` +用户需求 → method_consult 调用 DecisionTableService + → 四维匹配(Goal × OutcomeType × PredictorType × Design) + → 命中规则:primaryTool = ST_T_TEST_IND, fallbackTool = ST_MANN_WHITNEY + → 用户确认 → analysis_plan 填充参数 → run_step 傻瓜式执行 +``` + +决策表(`decision_tables.json`)当前有 ~10 条规则,覆盖 7 个 R 工具。规则驱动的确定性匹配比语义检索更精准、更可控。 + +### 未来扩展:RAG 增强 + +当 R 工具扩展到 30+ 且四维规则无法穷举时,可在 `method_consult` 内部增加 RAG 层: + +``` +method_consult 内部路由: + 1. 先走决策表匹配 → 命中则直接返回 + 2. 未命中 → pgvector 语义检索 Top-5 工具 → LLM 从中选择 → 返回推荐 +``` + +当前阶段不需要实现 RAG,决策表已足够。 + +--- + +## 九、与意图识别架构的关系 + +工具体系与意图路由器(详见《SSA-Pro 意图识别与对话架构设计》)配套工作: + +``` +意图路由器输出 可见工具 典型调用 +───────────── ────────── ──────── +chat(自由对话) → READ + INTERACT data_overview / variable_detail +explore(数据探索) → READ + INTERACT data_overview / variable_detail / ask_user +consult(方法咨询) → READ + INTERACT method_consult / ask_user +analyze(分析执行) → THINK + ACT + INTERACT analysis_plan → run_step → write_report +discuss(结果讨论) → ACT(write_report) + READ write_report(interpret) +feedback(不满意) → 反思编排 → THINK + ACT analysis_plan → run_step → write_report +``` + +**两个设计合在一起**: +- **意图路由器**决定"用户想干什么"→ 控制工具可见性 +- **工具体系**决定"系统能干什么"→ 提供能力边界 +- **Session 黑板**贯穿全流程 → 所有工具共享上下文,避免重复生成 + +--- + +## 十、与现有 QPER 代码的映射 + +| 工具 | 现有组件 | 改造程度 | +|------|---------|---------| +| get_data_overview | DataProfileService(已有) | **低** — 封装为 Tool 接口 + 新增 PICO 推断字段 | +| get_variable_detail | DataProfileService(需扩展) | **中** — 新增单列查询 API | +| method_consult | DecisionTableService(已有) | **中** — 封装为 Tool 接口 + LLM 推理补充 | +| ask_user | ClarificationCard 前端组件(已有) | **低** — 标准化后端接口 | +| analysis_plan | Q 层 + P 层(FlowTemplateService 已有) | **低** — 封装为 Tool 接口 | +| run_step | E 层 WorkflowExecutorService(已有) | **已有** — 当前就是傻瓜式执行 | +| write_report | R 层 ReflectionService(已有) | **中** — 新增 interpret 模式 | +| Session 黑板 | DataProfileService 缓存(部分已有) | **中** — 扩展为完整 Blackboard | +| 反思编排 | 无 | **新增** — 错误分类器 + 自动重试 + 手动触发 | + +**核心结论:QPER 四层的底层实现基本可复用,主要工作是封装 Tool 接口 + 新增 READ/INTERACT 层 + Session 黑板 + 意图路由。** + +--- + +## 十一、落地路线 + +| Phase | 工作内容 | 依赖现有组件 | 核心产出 | +|-------|---------|-------------|---------| +| **Phase 1** | **READ + INTERACT 层** | DataProfileService | get_data_overview + get_variable_detail + ask_user + Session 黑板 | +| | 目标:让系统能陪用户聊天,能看懂数据 | | 即使不能跑分析,用户也能感受到 AI 的价值 | +| **Phase 2** | **意图路由器 + method_consult** | DecisionTableService | 意图分类 + 方法咨询 + 阶段性工具可见性 | +| | 目标:系统能区分对话/探索/咨询/分析意图 | | | +| **Phase 3** | **THINK + ACT 对接** | QPER 全链路 | analysis_plan + run_step + write_report 封装为 Tool 接口 | +| | 目标:把已有 QPER 挂载到新工具体系上 | | | +| **Phase 4** | **反思编排 + 高级特性** | 全部 | 双轨反思 + write_report interpret 模式 + 持久化 | + +--- + +**附:参考文档** +- `00-系统设计/SSA-Pro 意图识别与对话架构设计.md` — 意图路由器设计 +- `00-系统设计/SSA-Pro 严谨型智能统计分析架构设计方案V4.md` — QPER 架构 +- `00-系统设计/SSA-Pro 理想状态与智能化愿景设计.md` — 智能化愿景 +- `06-开发记录/J技术报告审核评估与建议/SSA-Pro 智能体边界与工具生态规划报告.md` — 团队架构评审 diff --git a/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 意图识别与对话架构设计.md b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 意图识别与对话架构设计.md new file mode 100644 index 00000000..977b6422 --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/00-系统设计/SSA-Pro 意图识别与对话架构设计.md @@ -0,0 +1,628 @@ +# 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 }; + 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** | "这个数据有多少样本?"
"BMI 一般正常范围是多少?"
"临床试验中 P 值多少算显著?" | 直接 LLM 对话 | DataContext | +| **explore** | "帮我看看各组的样本分布"
"哪些变量缺失比较严重?"
"能推断出结局指标是哪些吗?" | DataProfile 增强探索 | DataContext + 统计摘要 | +| **consult** | "我想比较两组差异,应该用什么方法?"
"这个数据适合做什么分析?"
"帮我制定一个分析计划" | LLM 给出分析建议(不执行) | DataContext + 统计知识 | +| **analyze** | "对 BMI 和血压做相关分析"
"比较治疗组和对照组的血压差异"
"执行之前建议的分析方案" | 进入 QPER 流水线 | DataContext → Q 层 | +| **discuss** | "这个 p 值说明什么?"
"结果和我预期不一样,为什么?"
"需要做哪些敏感性分析?" | 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 +**下一步:** 评审确认后制定详细开发计划 diff --git a/docs/03-业务模块/SSA-智能统计分析/04-开发计划/11-智能对话与工具体系开发计划.md b/docs/03-业务模块/SSA-智能统计分析/04-开发计划/11-智能对话与工具体系开发计划.md new file mode 100644 index 00000000..65c46482 --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/04-开发计划/11-智能对话与工具体系开发计划.md @@ -0,0 +1,911 @@ +# SSA-Pro 智能对话与工具体系开发计划 + +> **文档版本:** v1.2 +> **创建日期:** 2026-02-21 +> **最后更新:** 2026-02-22(v1.2 — 新增实现规范与约束:6 条审查建议 + Postgres-Only 缓存修正) +> **文档类型:** 开发计划 (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 📋 待启动 ← 本计划的前置条件 +└── Phase Q+ 📋 → 吸收进本计划 Phase I(DataContext + 变量字典) + +本计划(11-智能对话与工具体系开发计划) +├── Phase I Session 黑板 + READ 层工具 +├── Phase II 意图路由器 + 统一对话入口 +├── Phase III method_consult + ask_user 标准化 +├── Phase IV THINK + ACT 层工具封装 +├── Phase V 反思编排 + 高级特性 +└── Phase VI 集成测试 + 可观测性 +``` + +**关键决策:** +- Phase Deploy **必须先于**本计划启动,因为 R 工具数量从 7 扩展到 11 是 method_consult 和 analysis_plan 的基础 +- 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 中改为读取 `tools_registry.json` | + +--- + +## 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 Deploy):134h ≈ 22 天 +含 Phase Deploy:171h ≈ 27.5 天 +``` + +--- + +## 4. Phase I — Session 黑板 + READ 层(30h / 5 天) + +> **目标:让系统能"看懂数据"并陪用户聊天,即使不能跑分析,用户也能感受到 AI 的价值。** +> **产出:** `get_data_overview` + `get_variable_detail` + Session 黑板 + DataContext 前端展示 +> **吸收:** 原 QPER 计划的 Phase Q+(变量字典 + 变量选择面板,20h) + +### 任务清单 + +| # | 任务 | 工时 | 产出 | 依赖 | +|---|------|------|------|------| +| I-1 | **SessionBlackboardService 设计与实现** | 5h | Session 黑板 CRUD + CacheFactory(Postgres-Only,参见 §16.4)+ sessionId 索引 + TTL 过期 | 无 | +| I-2 | **SessionBlackboard 类型定义** | 1.5h | `SessionBlackboard` interface + Zod Schema 校验 | 无 | +| I-3 | **get_data_overview 工具实现** | 5h | 封装 DataProfileService + PICO 推断字段 + 写入 Session 黑板 | I-1, I-2 | +| I-4 | **get_variable_detail 工具实现** | 4h | DataProfileService 单列查询 API(Python 侧新增)+ Tool 接口 | I-1 | +| I-5 | **DataContext 前端状态扩展** | 3h | ssaStore 新增 dataContext 字段 + DataContextCard 组件 | I-3 | +| I-6 | **PICO 推断 Prompt 模板** | 2h | `pico_inference_prompt.json` + Few-Shot 示例 + Seed 脚本 | I-3 | +| I-7 | **变量字典前端面板** | 4h | VariableDictionaryPanel 组件(AI 推断 + 用户编辑/确认) | I-3, I-5 | +| I-8 | **数据上传后自动触发 get_data_overview** | 2h | 上传回调中调用 + SSE 推送 DataContext 就绪事件 | I-3 | +| I-9 | **Token 控制策略实现** | 2h | Session 黑板注入 LLM 前的裁剪函数(变量字典裁剪、qperTrace 滑动窗口) | I-1 | +| I-10 | **Phase I 联调测试** | 1.5h | 上传数据 → DataContext 自动生成 → 前端展示数据全貌 + 变量字典 | 全部 | + +### 配置化要求 + +| 配置项 | 文件 | 方法学团队可编辑 | +|--------|------|:---:| +| PICO 推断 Prompt | `pico_inference_prompt.json` 或 DB Prompt 表 | ✅ | +| 变量类型推断规则 | `variable_inference_rules.json` | ✅ | +| Token 裁剪阈值 | `session_config.json`(变量数阈值、滑动窗口大小) | ✅ | + +### 验收标准 + +``` +✅ 上传 CSV 后 3 秒内,前端展示 DataContext 卡片(统计摘要 + PICO 推断 + 变量列表) +✅ 点击任意变量 → 展示单变量详情(分布图 + 统计量 + 异常值) +✅ PICO 推断标记为 "AI 推断",用户可编辑确认后标记为 "已确认" +✅ 变量字典支持用户修改 label、type、role,修改后写回 Session 黑板 +✅ Session 黑板数据在同一会话内持久有效,刷新页面后可恢复(CacheFactory,生产环境 Postgres 持久化) +``` + +--- + +## 5. Phase II — 对话层 LLM + 意图路由器 + 统一对话入口(35h / 5.5 天) + +> **目标:构建对话层 LLM 基础设施 + 意图路由,让系统具备多轮连贯对话能力。** +> **产出:** 对话层 LLM 核心(System Prompt + 对话历史 + 上下文组装)+ `IntentRouterService` + `/api/ssa/chat` 统一入口 + `ChatService` +> **核心认知:对话层 LLM 是系统的大脑和嘴巴(详见《四层七工具实现机制详解》第 1-4 章),不是简单的"调一次 LLM API"。** + +### 任务清单 + +| # | 任务 | 工时 | 产出 | 依赖 | +|---|------|------|------|------| +| **对话层 LLM 基础设施** | | | | | +| II-1 | **ConversationService 核心实现** | 5h | 对话层 LLM 的核心服务:System Prompt 动态组装 + DataContext 注入 + 工具输出注入 + LLM 调用 + 流式/完整回复 | Phase I | +| II-2 | **对话历史管理** | 3h | 消息历史存储(内存/DB) + 滑动窗口裁剪(根据 Token 预算动态调整窗口大小) + 关键事件摘要压缩 | Phase I | +| II-3 | **System Prompt 架构实现** | 4h | 基础角色(固定) + DataContext 注入(动态) + 意图指令(按意图切换) + 工具输出注入(按需) + 分析结果注入(discuss 时) — 六段式动态组装 | II-1 | +| II-4 | **System Prompt 模板(全意图)** | 3h | DB Prompt 表:`base_system`(基础角色)+ `chat_instruction` / `explore_instruction` / `consult_instruction` / `analyze_instruction` / `discuss_instruction` / `feedback_instruction`(6 个意图指令段)+ Seed 脚本 | 无 | +| **意图路由器** | | | | | +| II-5 | **意图识别规则引擎** | 3h | `intent_rules.json` 规则定义 + 规则匹配器(关键词 + 上下文状态) | Phase I | +| II-6 | **IntentRouterService 实现** | 4h | 混合路由(规则优先 + LLM 兜底)+ 意图分类输出 | II-5 | +| II-7 | **Intent Router Prompt 模板** | 1.5h | `intent_router_prompt.json` + Few-Shot 示例 + Seed 脚本 | 无 | +| **统一对话入口 + 基础意图处理** | | | | | +| II-8 | **统一对话 API `/api/ssa/chat`** | 3h | 新路由:接收消息 → IntentRouter 分类 → ConversationService 组装上下文 → 分发到对应 Handler → 对话层 LLM 生成回复 | II-1, II-6 | +| II-9 | **ChatService — chat 意图处理** | 2h | ConversationService(DataContext) → 对话层 LLM 直接回复 | II-8 | +| II-10 | **ChatService — explore 意图处理** | 2.5h | 调用 READ 工具获取数据 → 工具输出注入 ConversationService → 对话层 LLM 生成数据解读 | II-8 | +| II-11 | **前端对话入口统一** | 2h | SSAChatPane 消息统一走 `/api/ssa/chat`,按意图渲染不同回复类型 | II-8 | +| II-12 | **Phase II 联调测试** | 2h | 多轮对话连贯性验证 + 各意图场景验证 + 降级验证(LLM 不可用时规则兜底) | 全部 | + +### 意图分发逻辑 + +``` +/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/plan(QPER 入口) + → 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 团队 | + +### 验收标准 + +``` +✅ "这个数据有多少样本?" → 识别为 chat → 对话层 LLM 带 DataContext 直接回复 +✅ "帮我看看各组的样本分布" → 识别为 explore → 工具输出注入 → 对话层 LLM 生成数据解读 +✅ "对 BMI 和血压做相关分析" → 识别为 analyze → 转入 QPER 流水线 +✅ LLM 不可用时 → 规则引擎兜底 → 正确识别明确意图 +✅ 无法判断时 → 默认 chat(最安全的兜底) +✅ 多轮对话连贯性:用户说"刚才那个变量" → LLM 从对话历史正确解析为 BMI +✅ 意图切换衔接:consult → analyze 时,LLM 自然衔接"好的,我来按之前讨论的方案执行" +``` + +--- + +## 6. Phase III — method_consult + ask_user 标准化(20h / 3 天) + +> **目标:系统能给用户推荐分析方法(不执行),并在不确定时主动提问。** +> **产出:** `method_consult` 工具 + `ask_user` 标准化接口 + consult 意图处理 + +### 任务清单 + +| # | 任务 | 工时 | 产出 | 依赖 | +|---|------|------|------|------| +| III-1 | **method_consult Tool 实现** | 5h | 封装 DecisionTableService 四维匹配 + LLM 推理补充 + 返回推荐/替代/前提 | Phase I | +| III-2 | **method_consult Prompt 模板** | 2h | `method_consult_prompt.json` + 方法推荐 Few-Shot | 无 | +| III-3 | **ask_user 后端接口标准化** | 4h | 统一输入/输出 Schema + 请求-响应模式(Node.js 生成卡片 → 前端渲染 → 用户选择 → 恢复流程) | Phase I | +| III-4 | **ask_user 前端组件增强** | 3h | ClarificationCard 升级:支持单选/多选/自由文本、上下文说明、标准化样式 | III-3 | +| III-5 | **consult 意图处理(对话层 LLM 集成)** | 3h | method_consult 返回匹配结果 → 注入 ConversationService → 对话层 LLM 生成完整方法推荐(理由+前提+替代) → ask_user 确认 → 可转入 analyze | III-1, III-3, Phase II | +| III-6 | **ToolRegistryService 骨架** | 2h | 7 工具注册表 + `tool_definitions.json` + 阶段性可见性查询 API | 无 | +| III-7 | **Phase III 联调测试** | 1h | consult 场景端到端 + ask_user 确认流程 | 全部 | + +### 配置化要求 + +| 配置项 | 文件 | 方法学团队可编辑 | +|--------|------|:---:| +| 方法推荐 Prompt | `method_consult_prompt.json` 或 DB Prompt 表 | ✅ | +| 工具定义(名称、描述、层级、参数) | `tool_definitions.json` | ✅ | +| 意图→工具可见性映射 | `intent_tool_visibility.json` | ✅ | + +### 验收标准 + +``` +✅ "我想比较两组差异,应该用什么方法?" → method_consult → 推荐 T 检验 + 理由 + 前提 + 替代方案 +✅ method_consult 输出不触发执行,用户确认后才转入 analyze +✅ ask_user 渲染为标准化选择卡片(单选/多选/自由文本) +✅ PICO 确认流程:get_data_overview → LLM 推断 → ask_user 确认 → 写入 Session 黑板 +✅ 工具注册表可通过热更新 API 重载 +``` + +--- + +## 7. Phase IV — THINK + ACT 层工具封装(21h / 3 天) + +> **目标:将已有 QPER 底层 Service 封装为标准 Tool 接口,挂载到新工具体系上。** +> **产出:** `analysis_plan` + `run_step` + `write_report`(generate) 工具封装 + AVAILABLE_TOOLS 配置化修正 + +### 任务清单 + +| # | 任务 | 工时 | 产出 | 依赖 | +|---|------|------|------|------| +| IV-1 | **analysis_plan Tool 封装** | 4h | 封装 Q 层参数提取 + P 层 FlowTemplate 填充 → 输出有序步骤列表 | Phase I, Phase III | +| IV-2 | **run_step Tool 封装** | 3h | 封装 WorkflowExecutorService + data_source 自动注入(从 Session 黑板取 dataOssKey) | Phase I | +| IV-3 | **write_report Tool 封装(generate 模式)** | 3h | 封装 ReflectionService → 论文级报告生成 | Phase I | +| IV-4 | **analyze 意图完整链路对接(对话层 LLM 集成)** | 4h | IntentRouter(analyze) → analysis_plan → 对话层 LLM 生成方案说明 → ask_user(确认方案) → run_step ×N(每步对话层 LLM 播报进展) → write_report → 对话层 LLM 生成总结 | IV-1, IV-2, IV-3, Phase II | +| IV-5 | **AVAILABLE_TOOLS 配置化修正** | 2h | WorkflowPlannerService 中的硬编码常量改为读取 tools_registry.json | 无 | +| IV-6 | **阶段性工具可见性实现** | 2h | ToolRegistryService 根据当前意图/阶段过滤可用工具列表,注入 LLM 上下文 | III-6 | +| IV-7 | **analysis_plan 前端审查面板** | 2h | 展示分析方案 → 用户确认/修改 → 确认后触发执行 | IV-1, IV-4 | +| IV-8 | **Phase IV 联调测试** | 1h | analyze 意图完整旅程验证 | 全部 | + +### data_source 自动注入流程 + +``` +run_step 被调用 + → ToolOrchestrator 拦截 + → 从 SessionBlackboard 取出 dataOssKey + → 生成预签名 URL + → 注入 params.data_source = { type: 'oss', oss_url: signedUrl } + → POST 给 R 服务 + → LLM 和 analysis_plan 全程不感知 data_source +``` + +> 注:`WorkflowExecutorService.resolveDataSource()` 已有此逻辑,run_step 封装时直接复用。 + +### 验收标准 + +``` +✅ "对 BMI 和血压做相关分析" → analyze → analysis_plan → 用户确认 → run_step → write_report +✅ analysis_plan 输出确定的 tool_code + params,run_step 傻瓜式转发 +✅ data_source 由 Session 黑板自动注入,LLM 上下文中不出现文件路径 +✅ WorkflowPlannerService.AVAILABLE_TOOLS 读取 JSON,不再硬编码 +✅ 不同阶段 LLM 看到的工具列表不同(数据探索阶段看不到 run_step) +``` + +--- + +## 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 Deploy(R 工具补齐)** | **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** | **THINK + ACT 工具封装** | **21h** | **3 天** | 新工具体系挂载 QPER | **+1h**:IV-4 analyze 链路增加对话层 LLM 进展播报 | +| **V** | **反思编排 + 高级特性** | **18h** | **3 天** | 自修复 + 结果解读 | 不变 | +| **VI** | **集成测试 + 可观测性** | **10h** | **2 天** | 全链路验证 + 开发者调试 | 不变 | +| | **本计划合计** | **134h** | **~22 天** | **智能对话 + 工具体系上线** | **+12h** | +| | **含 Phase Deploy 总计** | **171h** | **~27.5 天** | **完整系统升级** | **+12h** | + +### 10.2 里程碑时间线 + +``` +Week 1 ────────────────────────────────── + Day 1-5.5: Phase Deploy(R 工具补齐 + 部署) + ✅ 里程碑 0:R 工具 11 个全部上线 + +Week 2 ────────────────────────────────── + Day 6-10: Phase I(Session 黑板 + 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 III(method_consult + ask_user 标准化) + Day 19-21: Phase IV(THINK + ACT 工具封装 + analyze 完整链路) + ✅ 里程碑 2B:系统能区分 6 种意图,支持自由对话 + 方法咨询 + 完整分析链路 + +Week 5 ────────────────────────────────── + Day 22-24: Phase V(反思编排 + discuss + feedback) + ✅ 里程碑 3:7 工具 + 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 I:Session 黑板管理 +│ ├── 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 III:7 个 Agent 工具定义 +│ ├── intent_rules.json # 🆕 Phase II:意图识别规则 +│ ├── intent_tool_visibility.json # 🆕 Phase II:意图→工具映射 +│ ├── session_config.json # 🆕 Phase I:Token 控制配置 +│ ├── 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 I:Tool 接口定义 + ├── session.types.ts # 🆕 Phase I:SessionBlackboard 类型 + ├── 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 黑板** | CacheFactory(Postgres/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] 结束 +``` + +### 场景 3:LLM 不可用降级 + +``` +用户: "比较两组血压差异" + → IntentRouter LLM 不可用 → 规则引擎识别 "比较" → analyze + → 转入 QPER(Q 层有自己的 LLM 降级到正则) + → 系统功能不中断,退化为 QPER 主线水平 +``` + +--- + +## 15. 与 QPER 主线计划的关系映射 + +| QPER 主线计划内容 | 本计划处理方式 | Phase | +|-------------------|---------------|-------| +| Phase Deploy(R 工具补齐 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 预警 W2:System Prompt 膨胀控制 + +**状态:** ⚠️ 接受(需精细化) + +**问题:** 六段式 System Prompt(base_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-3(System Prompt 架构实现) + +### 16.3 预警 W3:对话层 LLM 必须使用流式输出 + +**状态:** ✅ 完全接受 + +**问题:** 对话层 LLM 的回复可能较长(方法推荐、结果解读等场景),非流式模式下用户等待 5-15 秒无反馈,体验差。 + +**规范:** + +- `ConversationService` 默认使用 `LLMAdapter.chatStream()` 而非 `chat()` +- 通过现有 SSE 基础设施实时推送 LLM 输出 chunk 到前端 +- 前端 `SSAChatPane` 使用已有的 `AIStreamChat` 组件渲染流式回复 + +**实现要点:** + +```typescript +// ConversationService 核心调用方式 +async *generateReply(context: ConversationContext): AsyncGenerator { + 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-1(ConversationService 核心实现) + +### 16.4 盲区 B1:Session 黑板必须使用 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 { + return this.cache.get(`ssa:session:${sessionId}`); + } + + async set(sessionId: string, data: SessionBlackboard, ttl?: number): Promise { + await this.cache.set(`ssa:session:${sessionId}`, data, ttl ?? 7200); // 默认 2h TTL + } +} + +// ❌ 禁止:自建内存 Map(违反云原生规范 §2 "内存缓存 ❌") +const sessionCache = new Map(); // ← 禁止! +``` + +**环境切换:** + +| 环境 | `CACHE_TYPE` | 实际存储 | +|------|-------------|---------| +| 本地开发 | `memory`(默认) | 内存 Map,单实例足够 | +| 生产部署 | `postgres` | `platform_schema.app_cache` 表 | + +**注意:** 无需新建任务,Phase I 任务 I-1(SessionBlackboardService 设计与实现)按此规范使用 `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-6(IntentRouterService 实现) + +### 16.6 盲区 B3:LLM 输出 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(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-22(v1.2 — 新增实现规范与约束:6 条审查建议 + Postgres-Only 缓存修正) +**下一步行动:** +1. Phase Deploy 启动(R 工具补齐,5.5 天) +2. Phase Deploy 完成后立即启动 Phase I(Session 黑板 + READ 层) +3. Phase I 和 Phase Deploy 可考虑部分并行(Phase I 不依赖新 R 工具) + +### 变更日志 + +| 版本 | 日期 | 变更内容 | +|------|------|---------| +| 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→134h,27.5 天含 Deploy | +| v1.2 | 2026-02-22 | **新增实现规范与约束(§16-§17)**:① 6 条架构审查建议(3 预警 W1-W3 + 3 盲区 B1-B3)转化为实现规范;② 修正 Session 黑板缓存策略为 Postgres-Only(无 Redis,遵循平台云原生规范);③ 新增架构约束速查表(8 条 C1-C8);④ 无新增工时(规范融入已有任务) | diff --git a/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 工具体系 V3.0 终极审查与补强报告.md b/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 工具体系 V3.0 终极审查与补强报告.md new file mode 100644 index 00000000..c610818f --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 工具体系 V3.0 终极审查与补强报告.md @@ -0,0 +1,75 @@ +# **架构委员会审查报告:SSA-Pro 工具体系 (V3.0 融合方案)** + +**审查对象:** 《SSA-Pro 工具体系规划方案 v3.0(融合方案定稿)》 + +**审查时间:** 2026-02-21 + +**总体评级:** 🌟 **S++ 级 (Agent 架构设计的行业教科书)** + +**核心裁决:** 完全通过!方案在逻辑自洽、职责边界、性能考量上均达到了企业级 SaaS 的最高标准。只需在工程实现(特别是异步流转)上打几个“补丁”即可完美落地。 + +## **一、 值得全行业学习的 3 大神级设计 (Highlights)** + +我必须对团队在 V3.0 中做出的以下三个决策给予最高赞誉: + +### **1\. 拨乱反正:“把 PICO 和反思移出工具箱”** + +* **精妙之处**:很多新手团队会把“PICO 梳理”和“反思”写成让 LLM 调用的 tool。你们准确地认识到,它们本质上是 **“Prompt 的职责”** 和 **“系统的编排机制 (Orchestrator Loop)”**。这彻底避免了 LLM “左脚踩右脚”的死循环逻辑。 + +### **2\. 引入 Session 黑板 (Blackboard Pattern)** + +* **精妙之处**:这是整个方案的灵魂!LLM 是无状态的,如果每次调用 run\_step 都要重新把 10MB 的数据描述再生成一遍,系统会慢得令人发指。利用 Node.js 内存建立统一的 Blackboard,工具之间通过它隐式传参,这是高级 Multi-Agent 系统的标准范式。 + +### **3\. get\_variable\_detail 的“按需下钻”设计** + +* **精妙之处**:没有把 100 列的特征全塞给 get\_data\_overview,而是采用“总-分”结构。这是解决医疗宽表(特征极多)导致 Token Context 爆炸的唯一正确解法。 + +## **二、 架构师的“挑刺”与补强建议 (Critical Enhancements)** + +方案在理论上已经无懈可击,但在实际用 Node.js 结合 OpenAI/DeepSeek 的 API 落地时,你们会遇到以下三个工程硬伤。请在代码设计时提前防范: + +### **🚨 盲区 1:ask\_user 工具的“异步挂起”难题 (The Suspend/Resume Problem)** + +* **纸面逻辑**:LLM 调用 ask\_user \-\> 用户回复 \-\> LLM 继续。 +* **物理现实**:在标准的 LLM Function Calling 中,当模型决定调用 ask\_user 时,它的推理线程**必须停止**。在 Web 架构中,Node.js 会向前端发送卡片并结束本次 HTTP 请求(或暂停 SSE 流)。**系统如何知道用户明天点完卡片后,该从哪里恢复?** +* **补强方案**: + 必须将 ask\_user 与之前定义的 ExecutionStatus 状态机强绑定。 + 1. LLM 发出 ask\_user(question, options) 工具调用指令。 + 2. Node.js 拦截该调用,将 Session 状态改为 CLARIFYING,把当前 LLM 的 messages 历史(包含刚才的 tool\_call)存入数据库/Redis。 + 3. 前端展示卡片,用户点击。 + 4. 前端发起新的 HTTP POST,Node.js 提取保存的 messages,追加一条 role: "tool", content: "用户选择了 A",然后**再次请求 LLM**,恢复流转。 + +### **🚨 盲区 2:Session 黑板的历史记录 (Token 爆炸)** + +* **纸面逻辑**:stepResults 和 qperTrace 完整保存在 Session 黑板中,反思或生成报告时一起喂给 LLM。 +* **物理现实**:如果用户在这个 Session 里反复试错了 10 次,stepResults 会积累大量冗长的 R 引擎日志。如果把它们全量注入,不仅极度浪费 Token,还会让大模型“注意力涣散”,找不到最新的结果。 +* **补强方案**: + 引入 **"滑动窗口 (Sliding Window)"** 或 **"摘要压缩 (Trace Truncation)"**。 + 在将 Session 黑板的内容组装进 Prompt 前: + * stepResults 只保留当前最终采用的计划所对应的结果。废弃试错结果。 + * qperTrace 只保留最近 3 次的关键错误和修复动作。 + +### **🚨 盲区 3:run\_step 的数据流向缺失 (The Data Payload)** + +* **纸面逻辑**:输入包含 tool\_code 和 params。 +* **物理现实**:在你们前两天的决议中,我们规定了 R 引擎必须接收 data\_source: { type: 'oss', oss\_url: '...' }。但目前的 run\_step 定义里遗漏了这一点。 +* **补强方案**: + 不需要大模型(LLM)去生成 data\_source。在 Node.js 执行 run\_step 的真实逻辑时,**必须拦截指令**,自动从 Session 黑板中取出 ossKey,生成预签名 URL,然后强行混入 params 中,再 POST 给 R 服务。 + +## **三、 对“典型调用链”的效率优化 (Fast Track Optimization)** + +你们在第七章设计的“典型调用链”逻辑非常严密,但在“用户目标极度明确”的情况下,显得有些啰嗦。 + +* **优化前**:用户说“直接做T检验” \-\> method\_consult \-\> ask\_user 确认 \-\> analysis\_plan \-\> run\_step。 +* **优化后 (增加 Fast Track 快速通道)**: + 如果意图路由器 (Intent Router) 判断用户的信心度极高且方法明确(如:“我要做 T 检验比较性别和身高的差异”),**允许 LLM 跳过 method\_consult 和 ask\_user**,直接并行调用 get\_data\_overview 和 analysis\_plan。 + *这能为用户节省至少 5 秒钟的 AI 生成和等待确认时间。* + +## **四、 最终执行发令** + +这份 V3.0 的工具体系规划,与 Q-P-E-R 四层架构、V13 动态前端原型、以及 OSS 混合协议**形成了完美的完美拼图**。 + +1. **同意按此方案全面进入 API 封装和 Prompt 编写阶段。** +2. 请后端同学重点关注 **Session Blackboard 的 Redis/DB 结构设计**,这是本周最核心的基础设施。 + +你们正在打造一个极具壁垒的“医疗级数据分析系统”,放手去干吧! \ No newline at end of file diff --git a/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 智能体边界与工具生态规划报告.md b/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 智能体边界与工具生态规划报告.md new file mode 100644 index 00000000..d13b9183 --- /dev/null +++ b/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro 智能体边界与工具生态规划报告.md @@ -0,0 +1,88 @@ +# **架构委员会独立审查报告:SSA-Pro 智能体边界与工具生态规划** + +**审查对象:** SSA-Pro 核心工具的定义与扩展规划 + +**审查时间:** 2026-02-21 + +**核心洞察:** 区分“认知节点 (Cognitive Nodes)”与“物理工具 (Physical Tools)”,避免让大模型陷入“左脚踩右脚”的逻辑死锁。 + +## **一、 核心诊断:你给出的 7 个定义,到底是“工具”还是“智能体”?** + +你提出的 7 个维度非常完整地覆盖了统计分析的全生命周期。但我对这 7 个定义的架构定性如下: + +| 用户提出的名称 | 架构师的定性 | 为什么?(底层逻辑) | +| :---- | :---- | :---- | +| (1) PICO 需求梳理 | 🧠 **智能体 (Agent/Prompt)** | 这不需要调用外部系统,纯靠 LLM 内置知识和特定的 Prompt 引导用户对话即可完成。 | +| (2) 数据总览与变量 | 🛠️ **物理工具 (Tool)** | LLM 算不出缺失率,它必须通过调用 get\_data\_profile() API(即 Python Tool C)来获取真实数据特征。 | +| (3) 高水平分析计划 | 🧠 **智能体 (Agent/Prompt)** | 这是纯逻辑推理,是 Planner Agent 的核心输出物。 | +| (4) 统计方法匹配规划 | 🧠 **智能体 \+ 规则引擎** | 这是大模型基于数据特征去匹配配置表(决策树)的过程。 | +| (5) 分析执行 (调用R) | 🛠️ **物理工具 (Tool)** | 这是最经典的动作,LLM 调用 run\_r\_script(params) 来改变外部世界。 | +| (6) 报告生成与解读 | 🧠 **智能体 (Agent/Prompt)** | 这是 Critic Agent 拿到数字后进行的文本翻译工作。 | +| (7) 反思与重执行 | 🔄 **系统编排机制 (Workflow)** | 这是一个系统级的 while 循环,将 Error Log 喂给 LLM 重新生成参数,而不是一个具体的“工具”。 | + +**💡 架构师的黄金法则:** + +* **工具 (Tools)** 是 LLM 的\*\*“手和眼睛”\*\*。只有当 LLM 需要获取外部信息(看数据)、或改变外部世界(跑代码)时,才定义为 Tool。 +* **智能体 (Agents)** 是 LLM 的\*\*“大脑”\*\*。思考、规划、写文章、做匹配,这些都是靠切换 System Prompt 就能完成的,绝对不要把它们封装成所谓的“推理工具”让 LLM 自己调自己,这会浪费极大的上下文并导致不可控。 + +## **二、 重新梳理:3 种工具规划与定义范式 (供团队讨论)** + +基于上述理念,如果你想“精心规划工具的选择和使用”,我们在架构上有以下 3 种范式可供讨论。我强烈建议采用 **范式 C**。 + +### **❌ 范式 A:“上帝工具”模式 (The Monolithic Tool)** + +* **设计思路**:给 LLM 提供一个巨大的工具 run\_full\_statistics(goal, data\_id, x\_vars, y\_vars, need\_baseline, need\_plot...)。 +* **优点**:LLM 只需要调用一次工具。 +* **致命缺点**:大模型的“注意力分散”。让 LLM 一次性填对包含几十个参数的巨型 JSON 几乎是不可能的。中间一旦报错,完全无法定位是哪一步错了,直接黑盒。 + +### **🟡 范式 B:“原子工具箱”模式 (The Micro-Tools Box)** + +* **设计思路**:我们手里有 100 个 R 脚本,就直接注册 100 个工具(如 t\_test, anova, km\_curve, cox\_regression)。 +* **优点**:颗粒度极细,非常灵活。 +* **致命缺点**:大模型选错工具的概率激增。你很难通过 System Prompt 讲清楚这 100 个工具的区别。同时,大模型不擅长做复杂的代码控制流(比如:如果正态,调用工具 A;如果不正态,调用工具 B),这会导致极高的 Token 消耗和幻觉。 + +### **🌟 范式 C:“宏观指令与物理探针”模式 (The Macro & Probe Paradigm) \-\> 推荐!** + +**这是最符合你“精心规划”理念的架构,也是我们 SSA-Pro QPER 的最佳实践。** 我们把交给 LLM 的工具极度压缩为**三类**(甚至少于 5 个具体的 Function): + +#### **1\. 探针类工具 (Probe Tools) \- 充当 LLM 的眼睛** + +当 LLM 处于 Q 层(需求梳理期)时,它只有这两个工具可用: + +* get\_data\_schema(file\_id): 获取表头和列类型。 +* get\_column\_details(file\_id, column\_name): 深入查看某一列的具体分布(解决大文件 Token 爆炸的问题,按需查看)。 + +#### **2\. 交互类工具 (Human-in-the-loop Tools) \- 充当 LLM 的嘴巴** + +当 LLM 觉得需求模糊时,**不要让它自己瞎猜**,强迫它调用交互工具: + +* ask\_user\_clarification(question, options\_array): LLM 调用此工具后,前端会渲染出一个漂亮的“单选卡片”让用户点击,而不是一串干巴巴的文字。 + +#### **3\. 宏观调度工具 (Macro-Execution Tools) \- 充当 LLM 的手** + +当进入 E 层(执行期)时,LLM **不直接调用具体的 100 个原子工具**。它只调用一个统一的超级路由器: + +* execute\_statistical\_pipeline(pipeline\_id, parameter\_map) +* **说明**:pipeline\_id 就是我们配置中心的“套餐 ID”(如:经典队列研究套餐)。LLM 的工作是“根据用户的需求,把正确的变量名(X, Y, Confounders)塞进这个套餐的插槽里”。具体的“T检验还是秩和检验”,是由后台 R 脚本内部的护栏去动态决定的。 + +## **三、 对你的三个问题的直接回答与行动建议** + +**(1) 如何规划好工具,你有什么想法?** + +* **减法思维**:限制 LLM 能看到的工具数量。不要把 100 个 R 脚本同时暴露给 LLM,这会引发选择困难症。 +* **使用 RAG 进行工具检索**:如果非要暴露 100 个工具,请在 LLM 规划前,先用 pgvector(向量库)根据用户的对话,**检索出最相关的 Top-5 工具**。然后只把这 5 个工具的 JSON Schema 塞进 LLM 的上下文。这是目前解决“工具过载”唯一成熟的工业方案。 + +**(2) 对于你给出的工具规划和定义有什么建议?** + +* 你的分类是对\*\*“产品功能矩阵”\*\*的完美分类,可以直接拿来画产品架构图和商业 BP。 +* 但在写代码时,请一定要把它们转化为 **Agent (专门的 Prompt) \+ Workflow (Node.js 编排) \+ API (真实的 Tool)** 三者的结合体。 + +**(3) 梳理后的下一步行动建议** + +按照 **范式 C**,我们在代码层面需要做的其实是“分身术(Multi-Agent)”: + +1. **建立 咨询 Agent**:它只有看数据的工具,没有执行计算的工具。它专心做 PICO 梳理和 SAP 计划生成。 +2. **建立 执行 Agent**:它只能看到 Top-5 的候选工具,职责极其单一,就是把变量名填到这些工具的参数里。 +3. **建立 反思 Agent**:它不调用任何工具,它只接收 R 报错的字符串,输出修正后的参数 JSON。 + +**总结:** 精心规划工具的最高境界,不是造很多工具,而是**在不同的阶段,向不同的 Agent,只暴露其完成当前任务所必需的最小工具集。** \ No newline at end of file diff --git a/frontend-v2/src/modules/aia/styles/chat-workspace.css b/frontend-v2/src/modules/aia/styles/chat-workspace.css index 33023890..401db75c 100644 --- a/frontend-v2/src/modules/aia/styles/chat-workspace.css +++ b/frontend-v2/src/modules/aia/styles/chat-workspace.css @@ -1020,4 +1020,4 @@ border-radius: 4px; font-family: 'Monaco', 'Consolas', 'Courier New', monospace; font-size: 0.9em; -} +} \ No newline at end of file