feat(aia): Protocol Agent streaming + editable state panel + protocol generation plan
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
This commit is contained in:
351
docs/03-业务模块/AIA-AI智能问答/04-开发计划/05-一键生成研究方案开发计划.md
Normal file
351
docs/03-业务模块/AIA-AI智能问答/04-开发计划/05-一键生成研究方案开发计划.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# 一键生成研究方案 - 开发计划
|
||||
|
||||
> **版本**: v1.1
|
||||
> **创建日期**: 2026-01-24
|
||||
> **最后更新**: 2026-01-24
|
||||
> **负责人**: AI Assistant
|
||||
> **状态**: 待开发
|
||||
|
||||
---
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
### 目标
|
||||
基于 Protocol Agent 收集的 5 个核心要素,一键生成完整的临床研究方案文档,支持在线编辑和 Word 导出。
|
||||
|
||||
### 核心价值
|
||||
- 将 5-10 小时的方案撰写工作缩短至 30 分钟
|
||||
- AI 生成 + 人工编辑,保证专业性和个性化
|
||||
- 输出符合伦理委员会审查要求的标准文档
|
||||
|
||||
---
|
||||
|
||||
## 二、交互设计:两阶段渐进式生成
|
||||
|
||||
### 第一阶段:对话框生成摘要
|
||||
|
||||
```
|
||||
用户点击"一键生成研究方案"
|
||||
↓
|
||||
AI 在对话框中流式输出研究方案摘要(约500字)
|
||||
↓
|
||||
用户确认摘要 → 进入第二阶段
|
||||
用户不满意 → 在对话中继续调整要素
|
||||
```
|
||||
|
||||
**摘要内容**:
|
||||
- 研究题目
|
||||
- 研究目的(主要/次要)
|
||||
- 研究设计概述
|
||||
- 样本量结论
|
||||
- 主要结局指标
|
||||
|
||||
### 第二阶段:方案编辑器生成完整方案
|
||||
|
||||
```
|
||||
用户点击"生成完整方案"
|
||||
↓
|
||||
跳转到方案编辑器页面
|
||||
↓
|
||||
流式生成完整研究方案(5000-8000字)
|
||||
↓
|
||||
用户在线编辑 / AI协作润色
|
||||
↓
|
||||
导出 Word 文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、研究方案结构
|
||||
|
||||
```markdown
|
||||
# 临床研究方案
|
||||
|
||||
## 1. 研究题目
|
||||
## 2. 研究背景与立题依据
|
||||
## 3. 研究目的
|
||||
## 4. 研究设计
|
||||
## 5. 研究对象(纳入/排除标准)
|
||||
## 6. 样本量估算
|
||||
## 7. 研究实施步骤与技术路线
|
||||
## 8. 观察指标
|
||||
## 9. 数据管理与质量控制
|
||||
## 10. 安全性评价
|
||||
## 11. 统计分析计划
|
||||
## 12. 伦理与知情同意
|
||||
## 13. 研究时间表
|
||||
## 14. 参考文献
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、方案编辑器设计
|
||||
|
||||
### 布局结构
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ ← 返回 📄 研究方案编辑器 [自动保存✓] [导出Word] [发布] │
|
||||
├──────────┬─────────────────────────────────────┬───────────────┤
|
||||
│ 📑 大纲 │ 📝 编辑区 │ 🤖 AI助手 │
|
||||
│ │ │ │
|
||||
│ 可点击 │ Notion 风格分块编辑 │ 选中文本后: │
|
||||
│ 快速跳转 │ 支持 Markdown + 富文本 │ - /ai 润色 │
|
||||
│ │ Slash 命令 (/) │ - /ai 扩写 │
|
||||
│ │ 拖拽排序章节 │ - /ai 精简 │
|
||||
└──────────┴─────────────────────────────────────┴───────────────┘
|
||||
```
|
||||
|
||||
### 核心功能
|
||||
|
||||
| 功能 | 说明 | 优先级 |
|
||||
|------|------|--------|
|
||||
| **Slash 命令** | 输入 / 唤起菜单,支持 /ai 调用生成 | P0 |
|
||||
| **分块编辑** | 每个章节独立编辑,支持拖拽排序 | P0 |
|
||||
| **大纲导航** | 左侧目录,点击跳转 | P0 |
|
||||
| **自动保存** | 每30秒 + 失焦时保存 | P0 |
|
||||
| **导出Word** | Tiptap JSON → docx | P0 |
|
||||
| **AI润色** | 选中文本,/ai polish 优化 | P1 |
|
||||
| **AI扩写** | 选中章节,/ai expand 补充 | P1 |
|
||||
| **Ghost Text** | AI 生成时显示幽灵文字预览 | P1 |
|
||||
| **版本历史** | 查看修改记录,回滚 | P2 |
|
||||
|
||||
---
|
||||
|
||||
## 五、技术方案
|
||||
|
||||
### 技术选型:Novel (Fork)
|
||||
|
||||
**选型结论**:Fork [Novel](https://github.com/steven-tey/novel) 源码,而非 npm 包引入。
|
||||
|
||||
**选择 Novel 的理由**:
|
||||
|
||||
| 因素 | Novel 优势 |
|
||||
|------|-----------|
|
||||
| **AI 原生** | 专为 AI 写作设计,已处理流式生成的 UX 细节(Ghost Text、光标锁定) |
|
||||
| **标准 Tiptap** | 直接暴露 Tiptap 配置,可插入交互组件(样本量计算器、引用卡片) |
|
||||
| **可控性** | 源码在手,100% 可定制 UI 和逻辑 |
|
||||
| **对接成本** | 替换 useCompletion → useAIStream 即可对接现有后端 |
|
||||
|
||||
**Fork 策略**:
|
||||
|
||||
```
|
||||
不要 npm install novel
|
||||
|
||||
将 novel/packages/core/src 复制到:
|
||||
frontend-v2/src/shared/components/ProtocolEditor/
|
||||
|
||||
目录结构:
|
||||
├── index.tsx # 主组件
|
||||
├── extensions/ # Tiptap 扩展
|
||||
│ ├── ai-autocomplete.ts # 替换为 useAIStream
|
||||
│ ├── slash-command.tsx # 保留 Slash 菜单
|
||||
│ ├── citation.ts # Phase 2: 文献引用
|
||||
│ └── medical-table.ts # Phase 2: 复杂表格
|
||||
├── components/ # UI 组件
|
||||
│ ├── EditorContent.tsx
|
||||
│ ├── SlashMenu.tsx
|
||||
│ └── BubbleMenu.tsx
|
||||
└── styles/ # 样式(处理 Tailwind 冲突)
|
||||
└── editor.css
|
||||
```
|
||||
|
||||
**Tailwind CSS 冲突处理**:
|
||||
|
||||
```css
|
||||
/* 方案:CSS 命名空间隔离 */
|
||||
.novel-editor-scope {
|
||||
/* Novel 的 Tailwind 样式限制在此作用域 */
|
||||
}
|
||||
```
|
||||
|
||||
### 技术栈总览
|
||||
|
||||
```
|
||||
前端编辑器:Novel (Fork) - 基于 Tiptap/ProseMirror
|
||||
├── 优点:AI 原生、Notion 风格、源码可控
|
||||
├── 核心:Slash 命令、Ghost Text、拖拽排序
|
||||
│
|
||||
AI 调用:复用现有 useAIStream Hook
|
||||
├── 替换 Novel 的 useCompletion (Vercel AI SDK)
|
||||
├── 对接 /api/v1/aia/protocol-agent/generate
|
||||
│
|
||||
文档导出:docx.js 或 @tiptap-pro/extension-export-docx
|
||||
│
|
||||
数据存储:PostgreSQL (protocol_generations 表)
|
||||
```
|
||||
|
||||
### 数据模型
|
||||
|
||||
```sql
|
||||
-- 方案生成记录表
|
||||
CREATE TABLE protocol_generations (
|
||||
id UUID PRIMARY KEY,
|
||||
conversation_id UUID REFERENCES conversations(id),
|
||||
user_id UUID REFERENCES users(id),
|
||||
|
||||
-- 内容
|
||||
summary TEXT, -- 摘要(第一阶段)
|
||||
full_content JSONB, -- 完整方案(Tiptap JSON,标准格式)
|
||||
|
||||
-- 状态
|
||||
status VARCHAR(20), -- draft | generating | completed
|
||||
version INT DEFAULT 1,
|
||||
|
||||
-- 元数据
|
||||
word_file_url TEXT, -- 导出的Word文件URL
|
||||
created_at TIMESTAMP,
|
||||
updated_at TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### API 设计
|
||||
|
||||
```typescript
|
||||
// 第一阶段:生成摘要(流式)
|
||||
POST /api/v1/aia/protocol-agent/generate/summary
|
||||
Request: { conversationId: string }
|
||||
Response: SSE 流式输出摘要
|
||||
|
||||
// 第二阶段:生成完整方案(流式)
|
||||
POST /api/v1/aia/protocol-agent/generate/full
|
||||
Request: { conversationId: string }
|
||||
Response: SSE 流式输出完整方案
|
||||
|
||||
// 保存编辑
|
||||
PUT /api/v1/aia/protocol-agent/generation/:id
|
||||
Request: { content: TiptapJSON }
|
||||
|
||||
// 导出Word
|
||||
POST /api/v1/aia/protocol-agent/generation/:id/export
|
||||
Response: { downloadUrl: string }
|
||||
|
||||
// AI编辑(润色/扩写)
|
||||
POST /api/v1/aia/protocol-agent/generation/:id/ai-edit
|
||||
Request: {
|
||||
action: 'polish' | 'expand' | 'simplify',
|
||||
selectedText: string,
|
||||
context: string
|
||||
}
|
||||
Response: SSE 流式输出
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、开发计划
|
||||
|
||||
### Phase 1:Fork Novel + 对接后端(3天)
|
||||
|
||||
**目标**:3天内跑通"编辑器 + AI 流式生成"
|
||||
|
||||
| 天数 | 任务 | 交付物 |
|
||||
|------|------|--------|
|
||||
| Day 1 | Fork Novel 源码 + 项目集成 | 编辑器基础渲染、Slash 菜单可用 |
|
||||
| Day 2 | 替换 AI 调用 → useAIStream | /ai 命令可调用后端生成 |
|
||||
| Day 3 | 摘要生成 API + 编辑器页面路由 | 完整的"对话→摘要→编辑器"流程 |
|
||||
|
||||
**Phase 1 交付**:
|
||||
- ✅ Notion 风格编辑器可用
|
||||
- ✅ /ai 命令可调用 Protocol Agent
|
||||
- ✅ 支持 Markdown 导出
|
||||
|
||||
### Phase 2:完整方案生成 + Word 导出(3天)
|
||||
|
||||
| 天数 | 任务 | 交付物 |
|
||||
|------|------|--------|
|
||||
| Day 4 | 完整方案生成 API(流式) | 编辑器中流式显示完整方案 |
|
||||
| Day 5 | 自动保存 + 版本管理 | 数据库存储、草稿恢复 |
|
||||
| Day 6 | Word 导出功能 | docx 文件下载 |
|
||||
|
||||
**Phase 2 交付**:
|
||||
- ✅ 完整方案流式生成
|
||||
- ✅ 自动保存
|
||||
- ✅ Word 导出
|
||||
|
||||
### Phase 3:医疗特性增强(4天)
|
||||
|
||||
| 天数 | 任务 | 交付物 |
|
||||
|------|------|--------|
|
||||
| Day 7 | 集成 Tiptap Table 扩展 | 复杂表格支持(访视排期表) |
|
||||
| Day 8 | 开发 CitationBlock | 文献引用组件(对接 PKB) |
|
||||
| Day 9 | AI 润色/扩写优化 | 选中文本 AI 编辑体验 |
|
||||
| Day 10 | 测试 + UI 美化 | 完整功能测试 |
|
||||
|
||||
**Phase 3 交付**:
|
||||
- ✅ 复杂表格支持
|
||||
- ✅ 文献引用功能
|
||||
- ✅ AI 协作编辑完善
|
||||
|
||||
---
|
||||
|
||||
## 七、风险与依赖
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| Tailwind CSS 冲突 | 样式混乱 | CSS 命名空间隔离 |
|
||||
| Novel 源码维护成本 | 后续升级困难 | 代码量小(~2000行),可独立维护 |
|
||||
| LLM 生成质量不稳定 | 方案内容不专业 | 优化 Prompt + 人工模板 |
|
||||
| 长文本生成超时 | 用户等待过久 | 分章节流式生成 |
|
||||
| Word 导出格式问题 | 格式错乱 | 预设 Word 模板 |
|
||||
|
||||
### 依赖项
|
||||
|
||||
- [x] Protocol Agent 5阶段数据收集(已完成)
|
||||
- [x] StreamingService 流式输出(已完成)
|
||||
- [x] useAIStream Hook(已完成)
|
||||
- [ ] Novel 源码 Fork(待执行)
|
||||
- [ ] docx.js 导出功能(待开发)
|
||||
|
||||
### 兜底方案
|
||||
|
||||
如果 Fork 的 Novel 代码难以维护:
|
||||
- 可回退到 **Tiptap Headless**
|
||||
- 用 Ant Design 重写 UI
|
||||
- **数据模型 (Tiptap JSON) 完全兼容**,用户数据不丢失
|
||||
|
||||
---
|
||||
|
||||
## 八、验收标准
|
||||
|
||||
### 功能验收
|
||||
|
||||
- [ ] 点击"一键生成",对话框流式输出摘要
|
||||
- [ ] 点击"生成完整方案",跳转编辑器并流式生成
|
||||
- [ ] 编辑器支持 Slash 命令 (/)
|
||||
- [ ] 编辑器支持章节拖拽排序
|
||||
- [ ] 选中文本可调用 AI 润色/扩写
|
||||
- [ ] 可导出标准格式的 Word 文档
|
||||
- [ ] 支持复杂表格编辑
|
||||
|
||||
### 性能指标
|
||||
|
||||
| 指标 | 目标 |
|
||||
|------|------|
|
||||
| 摘要生成时间 | < 30秒 |
|
||||
| 完整方案生成时间 | < 3分钟 |
|
||||
| 自动保存延迟 | < 1秒 |
|
||||
| Word导出时间 | < 5秒 |
|
||||
|
||||
---
|
||||
|
||||
## 九、后续迭代
|
||||
|
||||
- **v1.1**: 方案模板库(不同研究类型)
|
||||
- **v1.2**: 多人协作编辑
|
||||
- **v1.3**: 方案审核流程
|
||||
- **v1.4**: 与伦理系统对接
|
||||
|
||||
---
|
||||
|
||||
## 十、参考文档
|
||||
|
||||
- [Novel GitHub](https://github.com/steven-tey/novel)
|
||||
- [Tiptap 官方文档](https://tiptap.dev/)
|
||||
- [编辑器选型深度评估](./编辑器选型深度评估与落地建议.md)
|
||||
- [Novel vs BlockNote 对比分析](./Novel_vs_BlockNote_深度对比分析.md)
|
||||
|
||||
---
|
||||
|
||||
**文档更新记录**:
|
||||
- 2026-01-24 v1.0: 初始版本(技术选型:Tiptap/BlockNote)
|
||||
- 2026-01-24 v1.1: 技术选型改为 **Novel (Fork)**,更新开发计划
|
||||
150
docs/03-业务模块/AIA-AI智能问答/04-开发计划/Novel_vs_BlockNote_深度对比分析.md
Normal file
150
docs/03-业务模块/AIA-AI智能问答/04-开发计划/Novel_vs_BlockNote_深度对比分析.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# **深度选型报告:Novel vs. BlockNote**
|
||||
|
||||
**评估对象**: Novel (Fork源码方案) vs. BlockNote (npm包方案)
|
||||
|
||||
**业务场景**: AI 驱动的临床研究方案生成编辑器
|
||||
|
||||
**核心结论**: **推荐 Novel (Fork)**。虽然初期成本略高,但在 AI 集成和 UI 定制上拥有绝对的主动权。
|
||||
|
||||
## **1\. 核心架构对比 (The Architecture)**
|
||||
|
||||
两者底层都是 **Tiptap (ProseMirror)**,但封装哲学完全不同。
|
||||
|
||||
| 维度 | BlockNote | Novel |
|
||||
| :---- | :---- | :---- |
|
||||
| **封装程度** | **极高**。它试图隐藏 Tiptap 的复杂性,创造了一套自己的 Schema (BlockNote Schema)。 | **中等**。它本质上只是 Tiptap 的一个 React Wrapper,直接暴露 Tiptap 的配置。 |
|
||||
| **数据结构** | **自定义 JSON Blocks**。它把 Tiptap 的 Document 转换成了自己的 Block 数组。 | **标准 Tiptap JSON**。完全遵循 ProseMirror 标准结构。 |
|
||||
| **UI 耦合度** | **高**。Slash Menu 和 Side Menu 是硬编码在库里的,很难改样式。 | **低 (Fork后)**。所有 UI 组件(Menu, Bubble)都是 React 代码,你可以随意魔改。 |
|
||||
| **React 亲和度** | ⭐⭐⭐⭐⭐ (专为 React 设计) | ⭐⭐⭐⭐⭐ (专为 React/Next.js 设计) |
|
||||
|
||||
**🧐 分析**:
|
||||
|
||||
* 如果您只是想做一个简单的笔记应用,BlockNote 完胜。
|
||||
* 但您要做的是 **"AI Protocol Editor"**,需要插入复杂的 **"样本量计算器按钮"**、**"引用卡片"**。BlockNote 的自定义 Schema 可能会成为绊脚石,而 Novel 直接操作 Tiptap,灵活性无限。
|
||||
|
||||
## **2\. AI 集成维度 (The AI Factor)**
|
||||
|
||||
这是您最关心的部分:如何与你们自研的 StreamingService 对接。
|
||||
|
||||
### **BlockNote 的表现**
|
||||
|
||||
* **现状**: 它没有内置 AI 自动补全逻辑。
|
||||
* **实现路径**: 您需要自己监听后端流式数据,然后手动调用 editor.insertBlocks()。
|
||||
* **痛点**: 处理“流式打字机效果”时,BlockNote 的 Block 更新机制可能会导致光标跳动或性能问题。
|
||||
|
||||
### **Novel 的表现**
|
||||
|
||||
* **现状**: 它是**为 AI 而生**的。它内置了 useCompletion (Vercel SDK) 的完整逻辑。
|
||||
* **优势**: 它已经处理好了 "AI 生成时的 Ghost Text (幽灵文字)"、"生成后的 Markdown 解析"、"生成中的光标锁定" 等细节。
|
||||
* **实现路径 (Fork)**: 您只需要把 useCompletion 替换为你们的 useAIStream,剩下的 UI 交互(如 /ai 唤起生成框)都是现成的。
|
||||
|
||||
**🏆 胜出者**: **Novel**。它在 AI 交互体验上已经帮您踩平了坑。
|
||||
|
||||
## **3\. 医疗特性扩展性 (Medical Features)**
|
||||
|
||||
### **场景 A:访视排期表 (复杂表格)**
|
||||
|
||||
* **BlockNote**: 对表格支持较弱,很难实现合并单元格。
|
||||
* **Novel**: 可以直接引入 @tiptap/extension-table。虽然 Novel 默认表格也不强,但您可以直接修改源码,引入更强的表格插件。
|
||||
|
||||
### **场景 B:文献引用 (Citation)**
|
||||
|
||||
* **BlockNote**: 需要学习它的 Custom Schema API 来定义一个 Inline Content。文档相对较少。
|
||||
* **Novel**: 直接写一个标准的 Tiptap NodeView (React 组件)。网上的 Tiptap 教程都能用。
|
||||
|
||||
### **场景 C:导出 Word**
|
||||
|
||||
* **BlockNote**: 它的 JSON 结构是非标准的,您需要先转成 Markdown/HTML,再转 Word。
|
||||
* **Novel**: 它的 JSON 是 Tiptap 标准的。社区里有现成的 tiptap-to-docx 转换库,或者直接用 pandoc。
|
||||
|
||||
**🏆 胜出者**: **Novel**。标准的 Tiptap 生态远比 BlockNote 的私有生态强大。
|
||||
|
||||
## **4\. 潜在风险与成本 (The "Gotchas")**
|
||||
|
||||
### **🔴 Novel (Fork) 的风险**
|
||||
|
||||
1. **代码维护成本**: 您 Copy 了几千行代码进项目,以后 Novel 官方更新了,您得手动同步(或者不仅同步,直接断开维护)。
|
||||
2. **样式污染**: Novel 使用 Tailwind CSS,类名可能会与您的 Ant Design 冲突。需要小心处理 CSS 作用域。
|
||||
3. **学习曲线**: 您的团队需要懂一点 Tiptap 的底层原理(Node, Mark, Extension)。
|
||||
|
||||
### **🔴 BlockNote 的风险**
|
||||
|
||||
1. **天花板效应**: 开发到第 2 个月,产品经理说“我要在编辑器里画一个甘特图”,BlockNote 可能直接做不到。
|
||||
2. **黑盒**: 作为一个 npm 包,如果它有 Bug,您只能等官方修,或者发 Patch。
|
||||
|
||||
## **5\. 最终决策建议**
|
||||
|
||||
**如果您满足以下条件,请坚决选择 Novel (Fork):**
|
||||
|
||||
1. 您的团队有能力读懂并修改 React 源码。
|
||||
2. 您不仅需要“写文字”,还需要在文档里插入“交互式组件”(如计算器、图表)。
|
||||
3. 您对 UI 的精细度要求很高(必须符合 Ant Design X 风格)。
|
||||
|
||||
**如果您满足以下条件,才退而求其次选择 BlockNote:**
|
||||
|
||||
1. 您的团队只有 1 个前端,且不熟悉富文本原理。
|
||||
2. 您只需要一个“能打字的 Notion”,不需要太复杂的 AI 交互。
|
||||
|
||||
### **🚀 您的选择确认**
|
||||
|
||||
您之前的 **Phase 1 (Fork Novel)** 计划是非常明智的。
|
||||
|
||||
**不要纠结了,Fork Novel 是正确的路。** BlockNote 看起来简单,但在深度 AI 集成场景下,它是\*\*“先甜后苦”**;而 Novel 是**“先苦后甜”\*\*,一旦您掌握了源码,天空才是极限。
|
||||
|
||||
鉴于 Novel 的代码质量很高(基于 Tiptap + React),完全放弃它太可惜。
|
||||
|
||||
我的最终建议是:不要作为 npm 包引入 Novel,而是将其源码 Copy 到项目中作为起点 (Fork & Own)。
|
||||
|
||||
这样既利用了它现成的 UI (Slash Menu, Drag Handle),又拥有了 100% 的控制权,可以随意修改 AI 逻辑和组件。
|
||||
|
||||
🗺️ 推荐落地路线图 (Phase 1-3)
|
||||
这个路线图将确保你们在 Phase 1 快速上线,同时为 Phase 2 的医疗特性预留空间。
|
||||
|
||||
Phase 1: Fork Novel + 对接你们的 StreamingService (快速上线)
|
||||
目标:3天内 跑通“编辑器 + AI 流式生成”。
|
||||
|
||||
Action 1: 源码引入
|
||||
|
||||
不要 npm install novel。
|
||||
|
||||
去 GitHub 把 novel/packages/core/src 下的核心代码复制到 frontend-v2/src/shared/components/Editor。
|
||||
|
||||
Action 2: 剥离 Vercel SDK,对接自研后端
|
||||
|
||||
找到 useCompletion 或 AI 调用的 hook。
|
||||
|
||||
替换为 你们现有的 useAIStream Hook (来自 shared/components/Chat/hooks/useAIStream.ts)。
|
||||
|
||||
修改 API 路径:指向 /api/v1/aia/protocol-agent/generate。
|
||||
|
||||
Action 3: 保留核心交互
|
||||
|
||||
保留 Slash 命令 (/) 和 拖拽手柄 (DragHandle)。这些是 Notion 体验的灵魂,自己写很费劲。
|
||||
|
||||
交付物:一个长得像 Notion、实际上调用的你们 Fastify 后端的编辑器。支持 Markdown 导出。
|
||||
|
||||
Phase 2: 医疗特性增强 (差异化竞争)
|
||||
目标:解决“表格”和“引用”这两个痛点。
|
||||
|
||||
Action 1: 集成 Tiptap Table 扩展
|
||||
|
||||
Novel 默认可能对表格支持较弱。
|
||||
|
||||
引入 @tiptap/extension-table,并定制渲染组件,支持合并单元格(访视排期表刚需)。
|
||||
|
||||
Action 2: 开发 CitationBlock (对接 PKB)
|
||||
|
||||
这是 Novel 没有的功能。
|
||||
|
||||
基于 Tiptap 的 NodeView,开发一个 React 组件:<Citation id="123" title="阿司匹林..." />。
|
||||
|
||||
点击时,右侧弹窗显示 PKB 中的文献详情。
|
||||
|
||||
Action 3: 导出 Word
|
||||
|
||||
使用 docx.js 或 pandoc (后端服务),将 Tiptap JSON 转换为 .docx。注意:表格的转换是难点,需预留时间调试。
|
||||
|
||||
Phase 3: 如需更深定制 (兜底方案)
|
||||
如果发现 Fork 来的代码太乱,难以维护。
|
||||
|
||||
回退策略:此时你们已经熟悉了 Tiptap 的 API。可以丢弃 Novel 的 UI 代码,仅保留 Tiptap 核心,用 Ant Design X 重写工具栏。数据模型 (JSON) 是完全兼容的,用户数据不会丢。
|
||||
118
docs/03-业务模块/AIA-AI智能问答/04-开发计划/编辑器选型深度评估与落地建议.md
Normal file
118
docs/03-业务模块/AIA-AI智能问答/04-开发计划/编辑器选型深度评估与落地建议.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# **临床研究方案编辑器选型评估与落地建议**
|
||||
|
||||
**评估对象**: 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\>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user