Files
AIclinicalresearch/docs/03-业务模块/AIA-AI智能问答/04-开发计划/07-Protocol-Agent-2.0-开发计划.md
HaHafeng 2030ebe28f feat(iit): Complete V3.1 QC engine + GCP business reports + AI timeline + bug fixes
V3.1 QC Engine:
- QcExecutor unified entry + D1-D7 dimension engines + three-level aggregation
- HealthScoreEngine + CompletenessEngine + ProtocolDeviationEngine + QcAggregator
- B4 flexible cron scheduling (project-level cronExpression + pg-boss dispatcher)
- Prisma migrations for qc_field_status, event_status, project_stats

GCP Business Reports (Phase A - 4 reports):
- D1 Eligibility: record_summary full list + qc_field_status D1 overlay
- D2 Completeness: data entry rate and missing rate aggregation
- D3/D4 Query Tracking: severity distribution from qc_field_status
- D6 Protocol Deviation: D6 dimension filtering
- 4 frontend table components + ReportsPage 5-tab restructure

AI Timeline Enhancement:
- SkillRunner outputs totalRules (33 actual rules vs 1 skill)
- iitQcCockpitController severity mapping fix (critical->red, warning->yellow)
- AiStreamPage expandable issue detail table with Chinese labels
- Event label localization (eventLabel from backend)

Business-side One-click Batch QC:
- DashboardPage batch QC button with SyncOutlined icon
- Auto-refresh QcReport cache after batch execution

Bug Fixes:
- dimension_code -> rule_category in 4 SQL queries
- D1 eligibility data source: record_summary full + qc_field_status overlay
- Timezone UTC -> Asia/Shanghai (QcReportService toBeijingTime helper)
- Pass rate calculation: passed/totalEvents instead of passed/totalRecords

Docs:
- Update IIT module status with GCP reports and bug fix milestones
- Update system status doc v6.6 with IIT progress

Tested: Backend compiles, frontend linter clean, batch QC verified
Made-with: Cursor
2026-03-01 22:49:49 +08:00

53 KiB
Raw Blame History

Protocol Agent 2.0 开发计划 — 工作流驱动的智能对话 Agent

版本: v2.0
日期: 2026-03-01
核心定位: 将 6 个验证过的子 Agent 聚合为一个工作流驱动的研究方案制定智能体
架构模式: 智能拼图板(工作流编排层 + 对话智能层 双层融合)
前置文档:

  • 00-模块当前状态与开发指南.mdAIA 模块全貌)
  • 04-Protocol_Agent开发计划/V1.0 MVP 设计)
  • 06-开发记录/2026-01-24-Protocol_Agent_MVP开发完成.md
  • 06-开发记录/2026-01-25-Protocol_Agent_MVP完整交付.md

1. 为什么需要 2.0

1.1 V1.0 MVP 的测试反馈11 个问题)

# 问题 根因
0 段落序号全为 "1." Markdown 渲染 Bug
1 说了队列研究,同步时还是显示 RCT 上下文未注入已确认数据
2 未确认参数就可以同步,内容是 AI 编造的 同步按钮触发逻辑依赖关键词匹配
3 已确认的信息被重复讨论 历史消息注入方式低效
4 观察指标阶段 AI 又绕回样本量 阶段控制完全依赖 Prompt 约束
5 不联系对话上下文PICO 阶段说过的数据收集时间点在研究设计又问) 阶段间上下文未传递
6 发送参数后又要求重复提供 take: 20 历史消息截断关键信息
7 完成样本量计算后仍然说"正式进入样本量计算阶段" LLM 无视 system prompt 的阶段指令
8 纠正后能回到正确方向,下一条消息又回退 LLM 无法可靠维持阶段状态
9 正在进行观察指标设计,又回到样本量计算 同上Prompt 约束不可靠
10 同步到右侧的内容与对话讨论内容不一致 condenseStageData 二次 LLM 调用改变了数据

1.2 V1.0 架构的 5 个根本缺陷

  1. 编排器被绕过ProtocolAgentController.sendMessage 直接调用 LLM未经过 BaseAgentOrchestratorAgent 框架形同虚设
  2. 阶段管理 100% 靠 PromptbuildSystemPrompt 用"禁止事项"约束 LLMLLM 经常违反
  3. <extracted_data> 机制脆弱:依赖 LLM 在对话中输出 XML 标签,前端解析后触发同步
  4. 历史消息注入低效take: 20 原始消息不分阶段全部注入,浪费 Token 且丢失关键上下文
  5. 未复用已验证的子 Agent 提示词:用一个通用 buildSystemPrompt 取代了 6 个经过专家验证的提示词

1.3 核心设计理念

一句话定义: Protocol Agent 2.0 = 工作流驱动的智能对话 Agent

  • 工作流层(智能拼图板)定义 6 块必须完成的"拼图",但不强制填充顺序,用户可以从任意话题切入
  • 对话智能层保证用户交互的自然性和灵活性(来自 SSA 模式的核心思想:用户驱动对话流,系统智能填补空白)
  • 验证过的提示词保证每个阶段的专业深度(复用已有 6 个子 Agent
  • 双层依赖模型保证方法学严谨性(软依赖允许开始聊,硬依赖守卫最终同步)

核心隐喻6 块拼图可以任意顺序完成,但每块拼图内部由经过专家验证的 AI 专家坐诊。


2. 架构设计

2.1 智能拼图板架构

┌─────────────────────────────────────────────────────────────────────┐
│  Layer 1: 工作流编排层 — 智能拼图板 (WorkflowOrchestrator)           │
│                                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                          │
│  │ ① 科学问题│  │ ② PICO  │  │ ③ 选题评价│   第一阶:定问题         │
│  │ ██░░ 40% │  │ ████ 85%│  │ ░░░░  0% │                          │
│  └──────────┘  └──────────┘  └──────────┘                          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                          │
│  │ ④ 研究设计│  │ ⑤ 观察指标│  │ ⑥ 样本量 │   第二阶:做设计         │
│  │ ██░░ 50% │  │ ░░░░  0% │  │ ░░░░  0% │                          │
│  └──────────┘  └──────────┘  └──────────┘                          │
│                                                                      │
│  SmartFocus: 当前聚焦 → ② PICO建议非强制                      │
│  用户可随时切换到任意阶段讨论                                        │
│                                                                      │
│  依赖关系(软约束):                                                 │
│  科学问题 ─soft→ PICO ─soft→ 选题评价                               │
│                    │                                                 │
│                    └─soft→ 研究设计 ─soft→ 观察指标 ─soft→ 样本量    │
│                                                                      │
│  同步守卫(硬约束):                                                 │
│  同步样本量 ←hard─ 研究设计已确认 + 主要指标已确认                   │
└──────────────────────┬──────────────────────────────────────────────┘
                       │ 每次对话
                       ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Layer 2: 对话智能层 (ConversationIntelligence)                      │
│                                                                      │
│  ┌────────────┐  ┌───────────────────┐  ┌──────────────────┐       │
│  │ Opening    │  │  Intent           │  │  Prompt          │       │
│  │ Analyzer   │→ │  Router           │→ │  Selector        │       │
│  │ (首条消息)  │  │ (7 种意图)         │  │ (依赖感知选择)    │       │
│  └────────────┘  └───────────────────┘  └────────┬─────────┘       │
│                                                   │                  │
│                                                   ▼                  │
│  ┌───────────────────┐  ┌────────────────────────────────────┐     │
│  │  Conversation     │  │  Post-Process Pipeline              │     │
│  │  Service          │→ │  GlobalExtract → CheckProgress      │     │
│  │ (验证提示词 +     │  │  → SmartFocus → SyncGuard?          │     │
│  │  黑板上下文注入)   │  └────────────────────────────────────┘     │
│  └───────────────────┘                                              │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  ProtocolBlackboard (Session 黑板 — 单一真相源)               │   │
│  │  科学问题 ██░░ 40%   PICO ████ 85% 🔄   选题评价 ░░░░ 0%   │   │
│  │  研究设计 ██░░ 50%   观察指标 ░░░░ 0%    样本量 ░░░░ 0%     │   │
│  └──────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

2.2 核心组件职责

组件 层级 职责 复用来源
WorkflowOrchestrator 工作流层 管理 6 阶段拼图板、依赖关系(软/硬、SmartFocus 推荐 新建
StageRegistry 工作流层 注册 6 个阶段的提示词、输出 Schema、完成标准、软硬依赖 新建(消费已有 Prompt
OpeningAnalyzer 对话智能层 首条消息分析,判定开场模式(新手/有经验/跳阶段),初始化黑板 新建
IntentRouter 对话智能层 轻量级意图分类7 种意图) 参考 SSA IntentRouterService
PromptSelector 对话智能层 根据 focusStage + 前提条件选择 Prompt 策略(完整模式/依赖感知模式) 新建
ConversationService 对话智能层 组装 system prompt + 黑板上下文 + 对话历史 → LLM 流式生成 参考 SSA ConversationService
ProtocolBlackboard 对话智能层 统一存储所有阶段的结构化数据(单一真相源) 参考 SSA SessionBlackboard
GlobalExtractTool 对话智能层 每次 AI 回复后全域提取(可同时更新多个阶段黑板) 新建
CheckProgressTool 对话智能层 评估各阶段完整度 + 硬依赖守卫 新建
SyncElementTool 对话智能层 用户确认后同步数据到方案(含硬依赖校验) 重构现有 sync

2.3 阶段定义与验证提示词映射

# 阶段 Prompt Code 输出 Schema 完成标准
1 科学问题梳理 AIA_SCIENTIFIC_QUESTION { content: string } content 非空且 ≥30 字
2 PICO 梳理 AIA_PICO_ANALYSIS { population, intervention, comparison, outcome } 4 字段均非空
3 选题评价 AIA_TOPIC_EVALUATION { feasibility, novelty, significance, summary } summary 非空
4 研究设计 新建 PA_STUDY_DESIGN(基于验证提示词适配) { studyType, designFeatures[], details } studyType 非空
5 观察指标设计 AIA_OUTCOME_DESIGN { outcomes: { primary[], secondary[], safety[] }, confounders[] } primary 至少 1 项
6 样本量计算 AIA_SAMPLE_SIZE { sampleSize, calculation: { alpha, power, effectSize }, rationale } sampleSize > 0

关键原则:验证过的提示词从 capability_schema.prompt_templates 数据库加载(通过 PromptService),不硬编码在 TypeScript 中。进入方式变了(拼图板而非流水线),但阶段内部仍加载对应的验证提示词。

2.4 意图分类7 种)

意图 触发示例 处理方式
chat "队列研究和 RCT 有什么区别" focusStage 提示词 + 黑板上下文 → LLM 直接回答
provide_info "研究人群是 45-75 岁冠心病患者" LLM 回复 + 全域提取 → 更新黑板
multi_stage_input "做老年冠心病队列研究,看出血事件发生率" LLM 回复 + 全域提取(多阶段同时更新)→ SmartFocus 推荐聚焦
ask_guidance "下一步该讨论什么" / "还缺什么" check_progress → LLM 引导回复
confirm_sync "确认" / 点击同步按钮 sync_element含硬依赖守卫→ SmartFocus 切换
generate "帮我生成完整方案" 校验全局完整度 → 生成全文
revise "PICO 的人群描述要改一下" 定位目标阶段和要素 → 更新黑板 → LLM 确认

意图识别采用规则优先 + LLM 兜底策略(与 SSA 一致),规则配置放在 intent_rules.json

multi_stage_inputprovide_info 的区别:前者的用户消息涉及多个阶段的信息(通过规则或 LLM 判断消息中包含多个阶段关键词),全域提取会扫描所有阶段 Schema后者只涉及当前 focusStage。

2.5 核心对话流程(全域提取 + 智能聚焦)

用户发送消息
  │
  ▼
┌─────────────────────────────────────────────────────────────┐
│  1. IntentRouter.classify(message, blackboard)               │
│     → chat / provide_info / multi_stage_input /              │
│       ask_guidance / confirm_sync / generate / revise        │
│                                                              │
│  如果是会话首条消息 → 先经过 OpeningAnalyzer见 2.8 节)    │
└──────────┬──────────────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│  2. PromptSelector.select(focusStage, blackboard)            │
│                                                              │
│  检查 focusStage 的软依赖是否满足:                           │
│                                                              │
│  情况 A — 前提充足(软依赖满足):                             │
│    mode = 'full_stage'                                       │
│    → 直接加载 focusStage 的验证提示词                        │
│    → 如 AIA_SAMPLE_SIZE                                      │
│                                                              │
│  情况 B — 前提不足(软依赖缺失):                             │
│    mode = 'dependency_aware'                                 │
│    → 加载 focusStage 的验证提示词作为专业知识参考            │
│    → 额外注入依赖感知指令:                                   │
│      "用户希望讨论样本量计算。以下前提信息尚未收集:           │
│       - 研究设计类型 - 主要观察指标                          │
│       围绕用户目标,自然地引导收集上述信息。"                 │
│                                                              │
│  随着对话推进、黑板填充,情况 B 自然过渡到情况 A用户无感知│
└──────────┬──────────────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│  3. ConversationService.buildMessages()                      │
│                                                              │
│  system = PromptSelector 选择的提示词组合                    │
│         + 全黑板状态摘要(每个阶段一两句话,自然语言)       │
│         + focusStage 阶段内已收集的数据                      │
│                                                              │
│  history = focusStage 阶段内的对话历史                       │
│           (滑动窗口 ≤15 轮,不含其他阶段的对话)            │
│                                                              │
│  user = 用户消息                                             │
└──────────┬──────────────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│  4. LLM 流式生成回复createStreamingService               │
│     使用通用 StreamingServiceOpenAI Compatible            │
└──────────┬──────────────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│  5. 后处理管线(流式完成后执行)                              │
│                                                              │
│  a. GlobalExtractTool.extract(                               │
│       recentMessages,                                        │
│       allStageSchemas  ← 全域扫描,非仅 focusStage           │
│     )                                                        │
│     → 独立 LLM 调用temperature=0.1, Zod 校验)            │
│     → 一次提取,多阶段黑板同时更新                           │
│     → 例:用户说"做队列研究看出血事件"                       │
│       → study_design.data.studyType = "队列研究"             │
│       → endpoints.data.primary = ["出血事件发生率"]           │
│                                                              │
│  b. CheckProgressTool.check(blackboard)                      │
│     → 纯规则计算(确定性逻辑,无 LLM                      │
│     → 返回:每个阶段的 completeness%, readyToSync            │
│     → readyToSync 需同时满足:                               │
│       ✅ 本阶段完整度达标completionRules                 │
│       ✅ 硬依赖的前序阶段已 confirmed                        │
│                                                              │
│  c. SmartFocus.recommend(blackboard, userMessage)            │
│     → 计算下一步建议聚焦的阶段(见 2.6 节)                 │
│                                                              │
│  d. 如果某阶段 readyToSync == true                           │
│     → 前端显示该阶段的同步按钮(含预览数据,可编辑)         │
│                                                              │
│  e. 保存 AI 回复到 messages 表metadata 含 stageCode      │
│  f. 更新 conversation.updatedAt                              │
└─────────────────────────────────────────────────────────────┘

2.6 SmartFocus 智能聚焦机制

SmartFocus 替代了 V1.0 的固定 advanceStage,它建议聚焦阶段但不强制

SmartFocus.recommend(blackboard, userMessage)
  │
  ▼
┌─────────────────────────────────────────────────────────────┐
│  优先级规则(从高到低):                                     │
│                                                              │
│  P0: 用户明确要求的阶段                                      │
│      "我们聊聊样本量" → focusStage = sample_size             │
│      "PICO 的人群描述要改" → focusStage = pico               │
│                                                              │
│  P1: 用户刚同步完的阶段的下一个推荐阶段                      │
│      刚同步完 PICO → 推荐 topic_evaluation 或 study_design   │
│                                                              │
│  P2: 完整度最低的、且软依赖已满足的阶段                      │
│      科学问题 40% + PICO 85% → 推荐先补完科学问题            │
│                                                              │
│  P3: 完整度已高但未确认的阶段(建议确认同步)                │
│      PICO 85% 且未 confirmed → "PICO 信息已较完整,          │
│      建议确认后同步到方案"                                   │
│                                                              │
│  → 输出: suggestedFocusStage + reason                        │
│  → 以系统提示的方式告知用户(非强制切换)                    │
│  → 用户下一条消息可以接受建议,也可以继续聊其他话题          │
└─────────────────────────────────────────────────────────────┘

focusStage 切换时机

场景 切换行为
用户对话内容明确指向某阶段 自动切换IntentRouter 识别)
用户点击同步按钮 同步完成后SmartFocus 推荐下一个
用户说"继续"/"下一步" SmartFocus 自动推荐
用户持续在当前阶段对话 不切换

2.7 阶段同步与回溯机制

用户点击"同步到方案"
  │
  ▼
┌─────────────────────────────────────────────────────────────┐
│  SyncElementTool.sync(stageCode, confirmedData)              │
│                                                              │
│  1. 硬依赖守卫 canSync():                                    │
│     检查该阶段的硬依赖是否全部满足                           │
│                                                              │
│     ❌ 不满足 → 返回友好提示 + 快捷操作:                    │
│     "样本量计算结果同步前,需先确认研究设计和主要观察指标。   │
│      [快速确认研究设计] [快速确认观察指标]"                   │
│                                                              │
│     ✅ 满足 → 继续:                                         │
│  2. 将数据写入 ProtocolBlackboard标记 confirmed          │
│  3. 写入 protocol_contexts 表持久化                          │
│  4. SmartFocus.recommend() → 推荐下一个聚焦阶段              │
│  5. 前端更新 StatePanel 进度                                 │
└─────────────────────────────────────────────────────────────┘

回溯机制(与原方案一致):

用户修改已确认的阶段数据(通过 StatePanel 编辑按钮或对话中 revise 意图)
  │
  ▼
┌─────────────────────────────────────────────────────────────┐
│  WorkflowOrchestrator.handleRevision(targetStage)            │
│                                                              │
│  策略 A小修改不影响后续阶段:                            │
│    → 直接更新黑板对应字段                                    │
│    → 不切换 focusStage                                       │
│    → LLM 回复确认修改                                        │
│                                                              │
│  策略 B大修改影响后续阶段的依赖:                        │
│    → 更新黑板                                                │
│    → 将受影响的后续阶段标记为 needs_review                   │
│    → 提示用户: "人群范围的变化可能影响研究设计,              │
│      建议重新确认研究设计。"                                  │
│    → 不强制回溯,由用户决定                                  │
└─────────────────────────────────────────────────────────────┘

2.8 开场模式自适应OpeningAnalyzer

用户的第一条消息由 OpeningAnalyzer 分析,自适应三种开场模式:

用户首条消息
  │
  ▼
┌─────────────────────────────────────────────────────────────┐
│  OpeningAnalyzer.analyze(firstMessage)                        │
│                                                              │
│  模式 A: 新手 / 空白开场                                     │
│  触发: "我想做一个研究" / "你好" / 消息 < 20 字且无专业术语  │
│  处理:                                                       │
│    → focusStage = scientific_question                        │
│    → 引导式对话: "请先告诉我你想研究什么问题?"              │
│                                                              │
│  模式 B: 有经验 / 信息丰富开场                               │
│  触发: "做老年冠心病患者队列研究,看出血事件发生率"           │
│        消息含多个阶段的关键信息                               │
│  处理:                                                       │
│    → GlobalExtract 全域提取 → 多阶段黑板同时填充             │
│    → focusStage = 最需要补充的阶段                           │
│    → "我已记录到您的研究主题和设计方向。                      │
│       目前 PICO 中的对照组还未明确,我们来确认一下?"        │
│                                                              │
│  模式 C: 明确跳阶段                                         │
│  触发: "科学问题和 PICO 已确定,直接做研究设计"              │
│        明确表示跳过某些阶段                                  │
│  处理:                                                       │
│    → 在 StatePanel 显示待确认项(快速录入界面)              │
│    → focusStage = 用户指定的阶段                             │
│    → 对于已跳过的阶段,提示"可在 StatePanel 中补充"          │
└─────────────────────────────────────────────────────────────┘

2.9 双层依赖模型

核心洞察:方法学上的依赖关系有两种强度,不能一刀切。

软依赖Soft Dependency— 可以开始聊

阶段 软依赖 含义
科学问题 任何时候都可以聊
PICO 有大致研究方向 知道"大概要研究什么"就能开始
选题评价 有科学问题 需要评价的对象
研究设计 有大致 P 和 O 知道"人群和结局"就能聊设计
观察指标 有研究设计方向 知道"什么研究类型"就能聊指标
样本量 有研究类型和指标方向 知道"做什么研究、看什么"就能开始聊

软依赖不满足时:不阻止用户,而是进入"依赖感知对话模式"(见 2.5 节 PromptSelector 情况 B通过对话自然收集缺失的前提信息。

类比:研究者说"老师我想算样本量",方法学专家不会说"请先写好 PICO 再来",而是说"好的,你打算做什么类型的研究?主要看什么指标?"——在讨论样本量的过程中自然收集前提。

硬依赖Hard Dependency— 不能最终同步

阶段 硬依赖(同步守卫) 含义
科学问题 随时可同步
PICO 随时可同步
选题评价 PICO 已 confirmed 评价必须基于确认的 PICO
研究设计 PICO 已 confirmed 设计必须基于确认的人群和结局
观察指标 研究设计已 confirmed 指标必须匹配确认的设计
样本量 研究设计 + 主要指标已 confirmed 计算必须基于确认的设计和指标

硬依赖不满足时:同步按钮不出现,或点击后返回友好提示 + 快捷操作按钮(如"快速确认研究设计")。

Prompt 选择策略伪代码

function selectPromptStrategy(
  focusStage: ProtocolStageCode,
  blackboard: ProtocolBlackboard
): PromptStrategy {

  const softDeps = stageRegistry[focusStage].softDependencies;
  const missingDeps = softDeps.filter(
    dep => !hasSufficientData(blackboard.stages[dep.stage], dep.minimumFields)
  );

  if (missingDeps.length === 0) {
    // 前提充足 → 直接用该阶段的验证提示词深度对话
    return {
      mode: 'full_stage',
      promptCode: stageRegistry[focusStage].promptCode,
      context: buildBlackboardSummary(blackboard),
    };
  } else {
    // 前提不足 → 依赖感知模式(目标导向收集前提)
    return {
      mode: 'dependency_aware',
      primaryPromptCode: stageRegistry[focusStage].promptCode,
      missingPrerequisites: missingDeps.map(formatMissing),
      guidanceInstruction: '围绕用户目标,自然地引导收集上述前提信息',
      context: buildBlackboardSummary(blackboard),
    };
  }
}

关键点:随着对话推进、全域提取不断填充黑板,missingDeps 逐渐清零,系统从"依赖感知模式"自然过渡到"完整验证提示词模式",用户完全无感知。

2.10 ProtocolBlackboard 数据结构

interface ProtocolBlackboard {
  sessionId: string;
  userId: string;
  conversationId: string;

  // 当前工作流状态
  focusStage: ProtocolStageCode;     // 建议聚焦的阶段(非强制锁定)
  stageHistory: Array<{ stage: string; enteredAt: Date; completedAt?: Date }>;

  // 6 个阶段的数据(每个阶段独立管理)
  stages: {
    scientific_question: StageData<{
      content: string;
    }>;
    pico: StageData<{
      population: string;
      intervention: string;
      comparison: string;
      outcome: string;
    }>;
    topic_evaluation: StageData<{
      feasibility: string;
      novelty: string;
      significance: string;
      summary: string;
    }>;
    study_design: StageData<{
      studyType: string;
      designFeatures: string[];
      details: string;
    }>;
    endpoints: StageData<{
      outcomes: {
        primary: string[];
        secondary: string[];
        safety: string[];
      };
      confounders: string[];
      followUp: string;
    }>;
    sample_size: StageData<{
      sampleSize: number;
      calculation: {
        alpha: number;
        power: number;
        effectSize: string;
      };
      rationale: string;
      dropoutRate: string;
    }>;
  };

  // 每个阶段的对话历史 ID用于加载阶段内历史
  stageConversationRanges: Record<string, { startMessageId: string; endMessageId?: string }>;
}

interface StageData<T> {
  status: 'pending' | 'in_progress' | 'completed' | 'needs_review';
  data: Partial<T>;               // 已收集的数据(可能不完整)
  confirmedData?: T;              // 用户确认后的完整数据
  completeness: number;           // 0-100
  confirmedAt?: Date;
  lastExtractedAt?: Date;
}

持久化策略ProtocolBlackboard 写入 protocol_contexts 表(已存在),使用 JSONB 字段存储。每次 GlobalExtractsync_element 后更新。


3. 与 V1.0 的关键差异

维度 V1.0 MVP V2.0
架构模型 顺序流水线(必须按 1→2→3→4→5 走) 智能拼图板6 块拼图任意顺序SmartFocus 引导)
提示词 1 个通用 buildSystemPrompt(手写,未验证) 6 个验证过的提示词(从 PromptService 加载)
阶段控制 Prompt 中写"禁止讨论其他阶段" 代码控制WorkflowOrchestrator + SmartFocus
依赖关系 隐含在顺序中(硬编码) 双层依赖模型(软依赖可聊,硬依赖守卫同步)
上下文管理 take: 20 原始消息 + JSON.stringify 注入 ProtocolBlackboard + 阶段内对话隔离 + 自然语言摘要注入
数据提取 LLM 在对话中输出 <extracted_data> 标签 GlobalExtractTool(独立 LLM全域扫描多阶段Zod 校验)
同步按钮 关键词匹配 / 前端解析 XML 标签 CheckProgressTool 规则计算 + 硬依赖守卫(双重校验)
编排器 BaseAgentOrchestrator 被绕过 WorkflowOrchestrator 统一入口
意图识别 IntentRouter7 种意图,规则 + LLM 兜底)
开场方式 强制从科学问题开始 OpeningAnalyzer 三模式自适应(新手/有经验/跳阶段)
跨阶段修改 不支持 回溯机制(小修改直接更新,大修改提示用户)

4. 工具定义5 个)

4.1 Tool 1: global_extract(自动触发)

{
  name: "global_extract",
  trigger: "auto_after_response",
  description: "从最近对话中全域提取结构化数据,可同时更新多个阶段黑板",
  input: {
    recentMessages: "最近 3 轮对话",
    allStageSchemas: "所有 6 个阶段的 Zod Schema",
    currentBlackboard: "黑板当前状态"
  },
  output: {
    updates: "Record<StageCode, { updatedFields, confidence }>",
    rationale: "提取依据"
  },
  implementation: "独立 LLM 调用非对话层temperature=0.1Zod 校验jsonrepair 容错"
}

与 V1.0 的区别

  • V1.0 要求对话 LLM 在回复中输出 <extracted_data> 标签(不可靠)
  • V2.0 用独立的 LLM 调用专门做提取(可靠),且是全域扫描而非仅 focusStage

全域提取示例

用户: "做老年冠心病患者的队列研究,主要看 6 个月后的出血事件发生率"

GlobalExtract 输出:
  scientific_question → { content: "老年冠心病患者...出血事件..." }
  pico              → { population: "老年冠心病患者", outcome: "出血事件发生率" }
  study_design      → { studyType: "前瞻性队列研究" }
  endpoints         → { primary: ["出血事件发生率"], followUp: "6个月" }

4.2 Tool 2: check_progress(自动触发 + 按需)

{
  name: "check_progress",
  trigger: "auto_after_extract | on_demand",
  description: "评估各阶段完整度 + 硬依赖校验",
  input: {},
  output: {
    stageProgress: "Record<StageCode, { completeness, missingFields, readyToSync }>",
    globalCompleteness: "number 0-100",
    suggestion: "string下一步建议"
  },
  implementation: "纯规则计算,无 LLM 调用"
}

完成标准规则示例

const COMPLETION_RULES: Record<ProtocolStageCode, (data: any) => CompletionResult> = {
  pico: (data) => {
    const fields = ['population', 'intervention', 'comparison', 'outcome'];
    const filled = fields.filter(f => data[f] && data[f].length >= 5);
    return {
      completeness: Math.round((filled.length / fields.length) * 100),
      missingFields: fields.filter(f => !filled.includes(f)),
    };
  },
  // ...其他阶段
};

readyToSync 判定(含硬依赖守卫)

function isReadyToSync(stageCode: ProtocolStageCode, blackboard: ProtocolBlackboard): boolean {
  const completion = COMPLETION_RULES[stageCode](blackboard.stages[stageCode].data);
  if (!completion.readyToSync) return false;

  const hardDeps = stageRegistry[stageCode].hardDependencies;
  return hardDeps.every(
    dep => blackboard.stages[dep.stage].status === 'completed'
  );
}

4.3 Tool 3: search_methodology(按需)

{
  name: "search_methodology",
  trigger: "on_demand",
  description: "在方法学知识库中检索",
  input: { question: "string", topic: "string" },
  output: { chunks: "RetrievalResult[]", summary: "string" },
  implementation: "复用平台 RAG 引擎pgvector"
}

Phase 1 不实现预留接口。Phase 2 接入知识库后启用。

4.4 Tool 4: compute_sample_size(按需)

{
  name: "compute_sample_size",
  trigger: "on_demand样本量阶段参数就绪后",
  description: "调用统计引擎计算样本量",
  input: { design, outcomeType, alpha, power, effectSize, dropoutRate },
  output: { sampleSize, formula, sensitivityTable },
  implementation: "复用 SSA 的 RClientService 或内置公式"
}

Phase 1 不实现预留接口。Phase 2 接入 R 统计引擎后启用。

4.5 Tool 5: sync_element(用户确认触发)

{
  name: "sync_element",
  trigger: "user_explicit_action",
  description: "将确认的数据同步到方案(含硬依赖守卫)",
  input: { stageCode, data, source: "extracted | edited" },
  output: { success, updatedBlackboard, nextSuggestion },
  guards: {
    canSync: "硬依赖校验,不满足时返回友好提示 + 快捷操作按钮"
  },
  implementation: "硬依赖校验 → 写入 protocol_contexts → 更新黑板 → SmartFocus 推荐"
}

硬依赖守卫伪代码

function canSync(stageCode: ProtocolStageCode, blackboard: ProtocolBlackboard): SyncGuardResult {
  const hardDeps = stageRegistry[stageCode].hardDependencies;
  const unmet = hardDeps.filter(
    dep => blackboard.stages[dep.stage].status !== 'completed'
  );

  if (unmet.length > 0) {
    return {
      allowed: false,
      reason: `同步前需先确认: ${unmet.map(d => d.label).join('、')}`,
      quickActions: unmet.map(d => ({
        label: `确认${d.label}`,
        action: `sync_stage:${d.stage}`,
      })),
    };
  }
  return { allowed: true };
}

5. 开发计划

5.1 Phase 概览

Phase 0: 基础设施搭建3 天)
  → ProtocolBlackboard + WorkflowOrchestrator + StageRegistry含双层依赖配置

Phase 1: 对话智能层核心5 天)
  → OpeningAnalyzer + IntentRouter + PromptSelector + ConversationService 改造
  → GlobalExtractTool + CheckProgressTool + SyncElementTool

Phase 2: 前端重构3 天)
  → ChatArea 改造 + StatePanel 改造 + 同步按钮重构

Phase 3: 联调测试 + 迁移2 天)
  → 端到端测试 + V1.0 数据兼容

合计:~13 天

5.2 Phase 0基础设施搭建3 天)

# 任务 工时 产出
0-1 ProtocolBlackboard 设计与实现 4h ProtocolBlackboardServiceCRUD + 增量 patch + 完整度计算。使用 protocol_contexts 表 JSONB 字段持久化
0-2 StageRegistry 阶段注册表 4h 6 个阶段的配置promptCode、outputSchemaZod、completionRules、softDependencies、hardDependencies。JSON 配置 + Zod 校验
0-3 WorkflowOrchestrator 实现 5h 拼图板状态机:SmartFocus.recommend() / handleRevision() / canSync()。双层依赖校验
0-4 阶段配置 JSON + Seed 3h protocol_stages.json6 阶段定义(含软硬依赖配置)。seed-protocol-stages.ts:写入数据库或加载到内存
0-5 类型定义 2h ProtocolBlackboardStageDataCompletionResultStageConfigSoftDependencyHardDependency 等接口

验收标准

  • ProtocolBlackboardService 可以 get/patch/reset
  • SmartFocus.recommend() 可以根据黑板状态推荐聚焦阶段
  • canSync() 正确拒绝硬依赖不满足的同步请求
  • 每个阶段能加载对应的 Prompt Code

5.3 Phase 1对话智能层核心5 天)

# 任务 工时 产出
1-1 IntentRouter 实现 4h 规则引擎(关键词 + 上下文守卫)+ LLM 兜底。7 种意图(含 multi_stage_input)。intent_rules.json 配置
1-2 OpeningAnalyzer 实现 3h 首条消息分析,三模式判定(新手/有经验/跳阶段),初始化 focusStage
1-3 PromptSelector 实现 4h 根据 focusStage + 软依赖状态选择 Prompt 策略full_stage / dependency_aware。依赖感知 Prompt 模板设计
1-4 ConversationService 改造 5h 核心改造:① 从 PromptService 加载验证提示词;② PromptSelector 策略组装;③ 注入全黑板摘要(自然语言);④ 阶段内对话历史隔离
1-5 GlobalExtractTool 实现 6h 独立 LLM 调用 + 全域扫描所有阶段 Schema + Zod 校验 + jsonrepair + 增量 patch 黑板。每个阶段有专属提取 Prompt
1-6 CheckProgressTool 实现 3h 纯规则计算 + 硬依赖守卫。返回每个阶段的 completeness + missingFields + readyToSync
1-7 SyncElementTool 重构 3h 替代现有 handleProtocolSync。canSync 硬依赖守卫 → 写入黑板confirmed→ SmartFocus 推荐
1-8 ProtocolAgentController 重写 5h sendMessage 走新架构OpeningAnalyzer(首条) → IntentRouter → PromptSelector → ConversationService → 流式生成 → 后处理管线
1-9 提取 Prompt 设计 + Seed 3h 全域提取 Prompt 模板 + 6 个阶段的字段映射。写入 prompt_templates

验收标准

  • 新手开场:"你好" → 引导到科学问题
  • 信息丰富开场:"做队列研究看出血事件" → 全域提取填充多个阶段,推荐最需要补充的阶段
  • 跳阶段:"直接聊样本量" → 进入依赖感知模式,自然引导收集前提
  • check_progress 在 PICO 四字段填满后返回 readyToSync: true
  • 同步样本量时,如果研究设计未确认 → canSync 返回拒绝 + 快捷操作

5.4 Phase 2前端重构3 天)

# 任务 工时 产出
2-1 ChatArea 改造 5h ① 移除 parseExtractedData XML 解析逻辑;② 同步按钮改为由后端 readyToSync 控制显示;③ 同步前显示数据预览(可编辑);④ 硬依赖不满足时显示快捷操作按钮
2-2 StatePanel 增强 3h ① 显示 6 阶段拼图板(非线性展示);② 每个阶段显示完整度百分比;③ 已确认阶段支持查看和编辑;④ focusStage 高亮;⑤ 点击任意阶段可切换 focusStage
2-3 阶段过渡 UI 3h ① SmartFocus 推荐提示(系统消息,用户可接受或忽略);② 进度条更新;③ 依赖关系可视化提示
2-4 回溯编辑 UI 2h ① StatePanel 已确认阶段的编辑按钮;② 编辑弹窗;③ 编辑后触发 handleRevision
2-5 Markdown 渲染修复 1h 修复段落序号全为 "1." 的问题Issue #0

验收标准

  • 同步按钮只在 readyToSync(含硬依赖满足)时出现
  • 硬依赖不满足时显示友好提示和快捷操作
  • 同步前可以预览和编辑提取的数据
  • StatePanel 点击阶段可切换聚焦
  • 已确认阶段可以查看详情和编辑

5.5 Phase 3联调测试 + 迁移2 天)

# 任务 工时 产出
3-1 端到端测试脚本 4h 覆盖 11 个 V1.0 反馈问题的回归测试 + 3 种开场模式测试
3-2 V1.0 数据兼容 2h 已有的 protocol_contexts 数据迁移到新的 blackboard 格式
3-3 Prompt 调优 3h 根据测试结果微调阶段内指令、提取 Prompt、依赖感知指令
3-4 文档更新 2h 更新模块状态文档 + API 文档

6. 数据库变更

6.1 无需新建表

V2.0 复用现有表:

Schema 用途 变更
protocol_contexts protocol_schema ProtocolBlackboard 持久化 扩展 JSONB 字段结构
conversations aia_schema 对话管理 无变更
messages aia_schema 消息存储 新增 metadata.stageCode 字段JSONB 内)
prompt_templates capability_schema 提示词管理 新增 6 个提取 Prompt + 依赖感知 Prompt 模板
agent_sessions agent_schema Agent 会话 无变更

6.2 protocol_contexts 字段扩展

现有的 protocol_contexts 表已包含 scientific_questionpicostudy_designsample_sizeendpoints 等 JSONB 字段。V2.0 在这些字段内增加 statuscompletenessconfirmedAt 等元数据,向后兼容。


7. 配置文件清单

文件 位置 用途 维护者
protocol_stages.json backend/src/modules/agent/protocol/config/ 6 阶段定义promptCode、schema、completionRules、softDependencies、hardDependencies 方法学团队
intent_rules.json backend/src/modules/agent/protocol/config/ 意图识别规则7 种意图,关键词 + 上下文守卫) IT 团队
extraction_prompts/ PromptService 数据库 6 个阶段的数据提取 Prompt + 全域提取模板 方法学团队

8. 保留什么(不动的部分)

组件 理由
ProtocolContextService(大部分) CRUD 逻辑复用,增加 blackboard 适配层
ProtocolExportService Word 导出,不变
protocolGenerationPrompts.ts 全文生成 Prompt不变
前端 DocumentPanel 方案预览和 A4 展示,不变
前端 useProtocolGeneration 一键生成逻辑,不变
前端 useProtocolConversations 对话管理,不变
6 个验证过的 Prompt数据库中 核心资产,阶段进入方式变了但阶段内仍加载验证提示词

9. 废弃什么

组件 替代
ProtocolAgentController.buildSystemPrompt() → PromptSelector + ConversationService从 PromptService 加载)
ProtocolAgentController.buildMessagesWithContext() → ConversationService黑板上下文 + 阶段内历史)
ProtocolAgentController.getStageOutputFormat() → StageRegistryZod Schema 定义)
ProtocolAgentController.getStageInstructions() → StageRegistry阶段内指令
ProtocolOrchestrator.buildSyncButton()(关键词匹配) → CheckProgressTool规则计算 + 硬依赖守卫)
ProtocolOrchestrator.extractDataFromResponse()XML 解析) → GlobalExtractTool独立 LLM全域扫描
前端 parseExtractedData()XML 解析) → 后端推送 readyToSync 信号
固定 advanceStage() 顺序推进 → SmartFocus 智能推荐

10. V1.0 问题解决映射

# 问题 V2.0 解决机制
0 段落序号全为 "1." Phase 2 Markdown 渲染修复
1 不结合上下文(说了队列还显示 RCT ProtocolBlackboard + 全黑板摘要注入 + GlobalExtract 全域提取
2 未确认就可同步 AI 编造内容 CheckProgressTool completionRules + 硬依赖守卫 canSync
3 重复讨论已确认信息 阶段内对话历史隔离 + 已确认数据以摘要形式注入
4 观察指标阶段又讨论样本量 SmartFocus 代码控制聚焦 + 每阶段专属验证提示词
5 不联系对话过程中的上下文 ProtocolBlackboard 统一存储 + GlobalExtract 跨阶段收集
6 发送参数后不联系上下文 阶段内对话历史不截断(窗口 ≤15 轮,非全局 20 条)
7 阶段未正确推进 SmartFocus.recommend() 智能推荐 + 同步后自动切换
8 纠正后又回退 ProtocolBlackboard 为单一真相源,不受 LLM 遗忘影响
9 反复回到已完成话题 SmartFocus + 每阶段专属验证提示词 + 阶段内历史隔离
10 同步内容与讨论不一致 GlobalExtractTool 独立提取 + 同步前预览可编辑

11. 风险管理

风险 概率 影响 应对
GlobalExtractTool 全域提取准确率不足 Zod 校验 + 置信度阈值(<0.5 不更新黑板)+ 同步前人工确认
全域提取误将信息归入错误阶段 阶段 Schema 设计有区分度 + 同步前预览可编辑
验证提示词不适配对话场景 原提示词设计为一问一答,需增加阶段内指令适配多轮对话
依赖感知模式 Prompt 收集效果不好 依赖感知指令模板迭代优化 + 前提收集完成后自然切换到完整模式
后处理管线增加延迟 GlobalExtract 异步执行,不阻塞 UI先显示 AI 回复,提取结果后续更新
拼图板自由度导致用户迷失 SmartFocus 始终给出建议 + StatePanel 可视化进度
V1.0 数据迁移 Blackboard 结构向后兼容,旧数据可平滑映射

回退策略

层级 正常路径 降级路径 触发条件
验证提示词加载 PromptService 从数据库加载 内置兜底 Prompt 数据库不可用
OpeningAnalyzer 三模式分析 默认新手模式(最安全) 分析异常
IntentRouter 规则引擎 + LLM 兜底 默认为 provide_info(最安全) LLM 不可用
PromptSelector full_stage / dependency_aware 切换 始终 full_stage降级为只用当前阶段提示词 依赖分析异常
GlobalExtractTool 全域扫描 + Zod 校验 仅提取 focusStage降级为单阶段提取 LLM 不可用或全域提取超时
CheckProgressTool 规则计算 + 硬依赖守卫 不显示同步按钮,等待人工确认 规则异常

12. 工时与里程碑

Phase 名称 工时 日历天 里程碑
0 基础设施搭建 18h 3 天 Blackboard + Orchestrator + StageRegistry含双层依赖可用
1 对话智能层核心 36h 5 天 三种开场模式、全域提取、依赖感知对话、硬依赖守卫全部可用
2 前端重构 14h 3 天 完整用户体验(拼图板 StatePanel + 同步守卫 UI
3 联调测试 + 迁移 11h 2 天 11 个问题 + 3 种开场模式全部验证通过
合计 79h ~13 天 Protocol Agent 2.0 上线

里程碑时间线

Week 1 ──────────────────────────────────
  Day 1-3:   Phase 0基础设施 + 双层依赖配置)
  Day 4-5:   Phase 1 前半OpeningAnalyzer + IntentRouter + PromptSelector

Week 2 ──────────────────────────────────
  Day 6-8:   Phase 1 后半GlobalExtract + CheckProgress + SyncElement + Controller 重写)
  Day 9-11:  Phase 2前端重构

Week 3 ──────────────────────────────────
  Day 12-13: Phase 3联调测试 + 迁移)
  ✅ Protocol Agent 2.0 上线

13. 未来扩展Phase 2+

功能 说明 何时做
RAG 知识库接入 search_methodology 工具接入方法学知识库 V2.0 上线 + 知识库就绪后
样本量计算器 compute_sample_size 工具接入 R 统计引擎 V2.0 上线 + R 引擎就绪后
方法学评审 第 7 个阶段,方案生成后自动评审 V2.1
多会话支持 跨天/跨设备继续协作 V2.1
协作功能 多人协同编辑方案 V3.0

14. 关键决策记录

决策 选择 理由
架构模型 智能拼图板(非顺序流水线) 真正融合 SSA 模式的核心思想:用户驱动对话流,系统智能填补空白
依赖关系 双层模型(软依赖 + 硬依赖) 软依赖保证灵活性(可以聊),硬依赖保证严谨性(不能乱同步)
阶段聚焦 SmartFocus 建议,非强制锁定 用户可以从任意话题切入,系统推荐但不阻止
开场方式 OpeningAnalyzer 三模式自适应 新手得到引导,有经验的用户不被束缚
前提信息收集 依赖感知对话模式(自然引导) 像真正的方法学专家一样,在讨论目标话题时自然收集前提
提示词来源 复用 6 个验证过的子 Agent 提示词 不重复造轮子,验证过的是核心资产。进入方式变了,阶段内提示词不变
数据提取 GlobalExtract 全域提取(非仅当前阶段) 一次对话可能涉及多个阶段信息,全域扫描不遗漏
同步判断 代码规则计算 + 硬依赖守卫 确定性逻辑 > 概率性判断,方法学约束代码化
阶段内对话 自由对话 + 验证提示词引导 用户体验自然,专业深度有保证
历史消息 阶段内隔离 + 全黑板摘要注入 避免跨阶段干扰,保留跨阶段上下文
Session 黑板 protocol_contexts 表 JSONB 复用现有表,无需新建
IntentRouter 规则优先 + LLM 兜底7 种意图) 与 SSA 模式一致,已验证有效。新增 multi_stage_input 处理跨阶段输入

一句话总结Protocol Agent 2.0 = 智能拼图板6 块拼图任意顺序完成)+ 验证过的 AI 专家(每块拼图由专家坐诊)+ 双层依赖守卫(聊天自由,同步严谨),让用户像和方法学专家自由聊天一样完成研究方案制定。