Day 2 Development (2026-01-24): Backend Enhancements: - Implement SSE streaming in ProtocolAgentController using createStreamingService - Add data condensation via LLM in ProtocolOrchestrator.handleProtocolSync - Support stage editing without resetting progress - Add explicit JSON output format for each stage in system prompt - Create independent seed script for Protocol Agent (seed-protocol-agent.ts) Frontend Improvements: - Integrate useAIStream hook for typewriter effect in ChatArea - Add MarkdownContent component for basic Markdown rendering - Implement StageEditModal for editing stage data (scientific question, PICO, etc.) - Add edit button to StageCard (visible on hover) - Fix routing paths from /aia to /ai-qa - Enhance CSS with full-screen layout and Markdown styles New Documentation: - One-click protocol generation development plan (v1.1) - Editor selection evaluation (Novel vs BlockNote vs Tiptap) - Novel fork strategy for AI-native editing Technical Decisions: - Choose Novel (Fork) as protocol editor for AI-first design - Two-stage progressive generation: summary in chat, full protocol in editor - 10-day development plan for protocol generation feature Code Stats: - Backend: 3 files modified, 1 new file - Frontend: 9 files modified, 2 new files - Docs: 3 new files Status: Streaming and editable features working, protocol generation pending
119 lines
6.1 KiB
Markdown
119 lines
6.1 KiB
Markdown
# **临床研究方案编辑器选型评估与落地建议**
|
||
|
||
**评估对象**: BlockNote vs. Tiptap vs. Others
|
||
|
||
**业务场景**: AI 驱动的一键生成临床研究方案 (Protocol)
|
||
|
||
**技术栈**: React 19, TypeScript, Ant Design X
|
||
|
||
## **1\. 为什么 BlockNote (Tiptap Wrapper) 是最佳选择?**
|
||
|
||
在 "AI \+ 文档编辑器" 领域,目前业界的主流标准其实就是 **Tiptap**。
|
||
|
||
* **Vercel AI SDK** 的官方示例使用的是 Tiptap (Novel)。
|
||
* **Notion** 风格的开源实现大多基于 Tiptap。
|
||
|
||
### **✅ BlockNote 的核心优势(针对你们的项目)**
|
||
|
||
1. **结构化数据 (JSON)**: BlockNote 默认保存为 JSON Blocks。这对于后端解析、存储、甚至未来做 "结构化数据提取"(比如从方案中提取入排标准存入数据库)非常有利。
|
||
* *对比*: 纯 Markdown 编辑器(Milkdown)在处理复杂嵌套结构时,解析成本较高。
|
||
2. **Slash Command (/命令)**: 开箱即用的 "/" 菜单,非常适合集成 "AI 续写"、"插入统计公式"、"插入 CRF 表格" 等医疗特有指令。
|
||
3. **React 19 兼容性**: 它是专为 React 设计的,集成到你们现在的 frontend-v2 没有任何阻碍。
|
||
|
||
## **2\. 医疗科研场景的特殊挑战 (Risk Assessment)**
|
||
|
||
虽然 BlockNote 很棒,但在**临床研究方案**这个垂直场景下,有两个潜在的大坑,你需要提前规划:
|
||
|
||
### **🚨 挑战 A:复杂的医学表格 (Schedule of Events)**
|
||
|
||
临床方案中必须包含 **"访视排期表" (Schedule of Events)**,这是一个极其复杂的二维表格(行是检查项目,列是访视时间点,中间是 X)。
|
||
|
||
* **BlockNote 现状**: 表格支持相对基础。
|
||
* **Tiptap 能力**: Tiptap 拥有非常强大的 Table 扩展(支持合并单元格、列宽调整)。
|
||
* **建议**: 如果 BlockNote 的表格无法满足需求,你需要利用它 "基于 Tiptap" 的特性,**混入 Tiptap 原生的 Table 插件**,或者开发一个自定义的 React Component Block 来渲染复杂的访视表。
|
||
|
||
### **🚨 挑战 B:参考文献管理 (Citations)**
|
||
|
||
研究方案必须引用文献(如 \[1\], \[2\]),且文末要有参考文献列表。
|
||
|
||
* **现状**: 通用编辑器通常不自带引用管理。
|
||
* **建议**: 这需要自定义开发。利用 BlockNote 的 Inline Content 扩展能力,创建一个 Citation 节点。点击 \[1\] 时,侧边栏(利用 Ant Design X)显示文献详情(从 PKB 知识库获取)。
|
||
|
||
## **3\. 推荐的 AI 集成架构 (Streaming Architecture)**
|
||
|
||
不要只把编辑器当文本框。在 React 19 \+ AI 场景下,建议采用以下模式:
|
||
|
||
### **3.1 影子文档模式 (Shadow Document)**
|
||
|
||
当 AI 在生成方案时,不要直接操作用户的编辑器实例(会导致光标跳动、冲突)。
|
||
|
||
* **方案**: 使用一个不可见的 "Shadow Editor" 接收流式数据,或者在当前编辑器中插入一个 "Ghost Block"(幽灵块,灰色文字),流式结束后转为正式内容。
|
||
|
||
### **3.2 交互式 AI 块 (Interactive AI Blocks)**
|
||
|
||
利用 BlockNote 的自定义 Block 能力,不仅仅生成文本,而是生成**交互组件**。
|
||
|
||
* *场景*: AI 觉得样本量太小,不仅生成文字建议,还生成一个 **"样本量重算按钮"** 插入到文档中。点击按钮,弹窗调用你们的 **SSA (统计分析)** 模块。
|
||
|
||
## **4\. 最终选型结论与 Roadmap**
|
||
|
||
### **🏆 最终推荐:BlockNote (Phase 1\) \-\> Tiptap Custom (Phase 2\)**
|
||
|
||
这个路线是完全可行的,因为 BlockNote 就是 Tiptap 的一层优美的皮肤。
|
||
|
||
| 阶段 | 技术选型 | 关键任务 |
|
||
| :---- | :---- | :---- |
|
||
| **Phase 1 (快速上线)** | **BlockNote** (标准版) | 1\. 快速实现文档读写 2\. 实现 /ai 命令调用你们的 Protocol Agent 3\. 实现 Markdown/Word 导出 |
|
||
| **Phase 2 (专业增强)** | **BlockNote \+ 自定义 React Blocks** | 1\. 开发 CitationBlock (关联 PKB 模块) 2\. 开发 ScheduleTableBlock (复杂表格) 3\. 开发 ReviewComment (批注功能,复用 RVW 模块逻辑) |
|
||
| **Phase 3 (极致定制)** | **Tiptap Headless** (如果 BlockNote 限制太大) | 如果 BlockNote 的交互逻辑(如拖拽)严重干扰了医学文档的严谨性,此时可以剥离 BlockNote UI,回退到 Tiptap 核心重写 UI,**数据模型无需迁移**。 |
|
||
|
||
### **💡 另外一个强有力的竞争者:Novel (novel.sh)**
|
||
|
||
* **简介**: Novel 是一个开源的、基于 Tiptap 的、类似 Notion 的编辑器,专门为 AI 写作设计。
|
||
* **优势**: 它已经把 "AI 自动补全" (Vercel AI SDK) 集成得非常好了。
|
||
* **建议**: 你们可以看一眼 [Novel 的源码](https://github.com/steven-tey/novel)。如果觉得 BlockNote 封装太深,可以直接 Fork Novel 进行修改。Novel 的代码结构可能更适合做深度定制。
|
||
|
||
### **5\. 代码落地示例 (React 19 \+ BlockNote \+ AI Stream)**
|
||
|
||
// components/ProtocolEditor/index.tsx
|
||
import { useCreateBlockNote } from "@blocknote/react";
|
||
import { BlockNoteView } from "@blocknote/mantine";
|
||
import "@blocknote/mantine/style.css";
|
||
|
||
export default function ProtocolEditor({ aiStreamContent }) {
|
||
// 1\. 初始化编辑器
|
||
const editor \= useCreateBlockNote({
|
||
initialContent: \[
|
||
{ type: "heading", content: "1. 研究背景" },
|
||
{ type: "paragraph", content: "在此输入背景..." }
|
||
\],
|
||
});
|
||
|
||
// 2\. 监听 AI 流式输出 (Hooks)
|
||
useEffect(() \=\> {
|
||
if (aiStreamContent) {
|
||
// 实时将 AI 的内容插入到当前光标位置或指定 Block
|
||
editor.insertBlocks(
|
||
\[{ type: "paragraph", content: aiStreamContent }\],
|
||
editor.getTextCursorPosition().block,
|
||
"after"
|
||
);
|
||
}
|
||
}, \[aiStreamContent\]);
|
||
|
||
// 3\. 自定义渲染 (集成 Ant Design X 风格)
|
||
return (
|
||
\<div className="protocol-editor-container bg-white min-h-screen"\>
|
||
\<BlockNoteView
|
||
editor={editor}
|
||
theme="light"
|
||
// 可以在这里覆盖默认的 Slash Menu,集成你们的 Protocol Agent
|
||
slashMenu={false}
|
||
\>
|
||
{/\* 自定义 Slash Menu 组件 \*/}
|
||
\<MyCustomSlashMenu editor={editor} /\>
|
||
\</BlockNoteView\>
|
||
\</div\>
|
||
);
|
||
}
|