22 KiB
AI 写作助手右侧编辑器升级需求文档
1. 文档目标
本文档用于指导 DeerFlow 当前 AI 写作助手的第二阶段升级。
本次升级不推翻现有整体架构,不重做左侧聊天,不替换 LangGraph 后端,而是在现有 DeerFlow 基础上,把右侧编辑区升级为更接近豆包 AI 写作助手、Novel、open-canvas 风格的 AI 原生写作编辑器。
本次需求聚焦四类核心能力:
- 选区浮层
- 润色 / 扩写 / 缩写 / 改语气
- 替换 / 插入
- 标题 / 列表 / 引用 / 代码块工具条
本次交付目标不是“补几个按钮”,而是把右侧从“结果预览面板”升级成“可直接写、可选区改、可连续编辑、可 AI 辅助重写”的正式写作工作区。
2. 总体结论
2.1 保留不动的部分
- 保留现有左侧聊天区
- 保留现有线程体系
- 保留现有 LangGraph 后端
- 保留现有模型配置与模型选择体系
- 保留现有消息流与线程上下文
- 保留现有“写作模式”总入口
2.2 本次替换和新增的部分
- 将右侧简易 Artifact 文本查看 / 编辑区升级为
Tiptap富文本编辑器 - 在右侧新增面向写作场景的 AI 选区改写工作流
- 为右侧补齐写作工具栏、选区浮层、结果预览、替换 / 插入动作
- 将当前“生成后查看”的体验改造成“生成、选中、局部重写、继续编辑”的闭环
2.3 技术选型结论
本次默认采用 Tiptap 作为右侧编辑器内核。
原因:
- 更适合做选区级 AI 操作
- 更适合做浮动菜单和块结构格式工具栏
- 更适合多段落选区与结构化文本编辑
- 更适合后续扩展 slash menu、批注、修订记录、评论等能力
- 与 Novel 和 open-canvas 的交互借鉴路径更贴近
Plate 作为 UI 参考和交互参考保留,不作为本轮主内核。
3. 参考产品与参考源码
3.1 交互参考
- 豆包 AI 写作助手
- Novel
- open-canvas
3.2 借鉴重点
- 豆包:选区浮层、AI 改写入口、替换 / 插入、轻量化写作工具条、页面留白和排版气质
- Novel:文档编辑器产品感、工具条组织、编辑容器、页面视觉层级
- open-canvas:AI 改写流程、候选内容应用流程、编辑器与聊天协同思路
3.3 明确不直接照搬的部分
- 不直接复制 open-canvas 的 Next.js 页面结构
- 不直接复制 Novel 的服务端实现
- 不直接引入整套 Plate 生态替代现有编辑区
4. 当前系统现状
结合当前代码结构,和本需求直接相关的现状如下:
4.1 已有接入点
-
frontend-web/src/pages/PageRoutes.tsx- 当前已引入
@/open-canvas/routes/OpenCanvasRoutes - 说明项目已经有独立 Canvas 路由接入能力
- 当前已引入
-
frontend-web/src/components/workspace/chats/chat-box.tsx- 当前左聊天 + 右 Artifact 面板是双栏布局
- 当前右侧仍然偏 Artifact 文件查看 / 编辑
-
frontend-web/src/components/workspace/artifacts/context.tsx- 当前 Artifact 上下文仍以
string[]文件路径为主 - 不适合直接承载“选区级写作编辑器状态”
- 当前 Artifact 上下文仍以
-
frontend-web/src/components/workspace/input-box.tsx- 已经存在
writing_mode - 可以作为本次写作助手模式切换的入口保留
- 已经存在
4.2 当前不足
- 右侧编辑区更像文件预览器,不像完整写作编辑器
- 缺少选区工具条
- 缺少多段落改写能力
- 缺少 AI 改写候选应用工作流
- 缺少标题 / 列表 / 引用 / 代码块等正式文档工具
- 页面视觉上仍偏“工程面板”,产品完成度不足
5. 本次需求范围
5.1 本次必须实现
- 基于
Tiptap的右侧富文本编辑器 - 选区浮层
- AI 改写动作菜单
- 润色 / 扩写 / 缩写 / 改语气
- 改语气二级选项
- 改写结果预览
- 替换 / 插入
- 标题 / 列表 / 引用 / 代码块工具条
- UI 美化与交互统一
- 多段落选区改写
5.2 本次不做
- 多人协作
- 评论系统
- 修订模式
- 文档历史对比
- 图片、表格、附件编辑器
- 复杂导入导出
- 全量 Notion 式块拖拽系统
- slash command
5.3 下阶段可扩展
- slash command
- 改写历史
- 修订轨迹
- 边写边建议
- 文风模板
- 批注与审阅
6. 产品目标
升级完成后,用户应获得以下体验:
- 在左侧继续正常聊天
- 在右侧像正式文档编辑器一样直接书写和改写
- 选中一句、一段、多段内容后,能立即触发 AI 改写
- AI 返回结果后,用户能决定“替换原文”还是“插入到后面”
- 页面视觉上明显从“开发态”升级为“产品态”
- 对长文写作、改稿、润色、扩写更友好
7. 页面与交互结构
7.1 整体布局
继续保留双栏布局:
- 左侧:聊天区
- 右侧:AI 写作编辑器
7.2 右侧编辑器结构
建议右侧拆分为以下区域:
-
文档头部区
- 文档标题
- 文档状态
- 可能的保存提示
-
主工具栏
- 正文
- 一级标题
- 二级标题
- 三级标题
- 有序列表
- 无序列表
- 引用
- 代码块
- 加粗
- 斜体
- 下划线
- 删除线
-
编辑正文区
- 基于 Tiptap 的可编辑正文
-
选区浮层
- AI 改写
- 加粗
- 斜体
- 标题
- 复制
-
AI 改写动作菜单
- 润色
- 扩写
- 缩写
- 改语气
-
改写结果预览区
- 预览文本
- 替换
- 插入
- 重试
- 取消
7.3 目标交互闭环
- 用户在左侧发起写作任务
- 右侧生成初稿或打开写作画布
- 用户在右侧直接编辑
- 用户选中一句或多段
- 弹出浮层
- 点击
AI 改写 - 选择
润色 / 扩写 / 缩写 / 改语气 - 看到候选结果
- 选择
替换或插入 - 继续写、继续改、继续和左侧聊天协同
8. 核心能力详细定义
8.1 能力一:选区浮层
目标
用户在右侧选中文本后,出现跟随选区的浮层工具条。
首版必须包含的按钮
- AI 改写
- 加粗
- 斜体
- 标题
- 复制
行为要求
- 只有在有效文本选区存在时显示
- 选区取消后自动消失
- 滚动时位置跟随更新
- 只对右侧编辑器正文区域生效
- 对跨多个段落的纯文本选区生效
首版限制
- 首版只处理文本选区
- 不处理跨复杂嵌套节点的高级结构变更
验收标准
- 选中单段文本时能稳定出现
- 选中连续多段文本时能稳定出现
- 不遮挡正文主要阅读区域
8.2 能力二:AI 改写动作
目标
用户选中内容后,可快速对该内容发起 AI 重写。
一级动作
- 润色
- 扩写
- 缩写
- 改语气
改语气二级选项
- 更专业
- 更口语化
- 更易读
- 更学术
- 更有文采
行为要求
- 改写动作基于当前选区触发
- 支持单段落与多段落
- 支持带少量前后文一起发给后端
- 改写期间有明显 loading 态
- 改写失败要有失败提示和重试入口
提示词策略
首版不开放自定义 prompt,只提供预设动作。
验收标准
- 四类一级动作可正常使用
- 改语气二级菜单可正常展开和触发
- 多段落改写不会破坏原文结构边界
8.3 能力三:替换 / 插入
目标
AI 返回候选内容后,不直接覆盖原文,而是先让用户决策如何应用。
两种应用方式
- 替换:用候选结果替换当前选区
- 插入:把候选结果插入到选区后面,保留原文
行为要求
- AI 返回结果后先展示预览
- 默认不自动落文档
- 支持重试
- 支持取消
- 应用动作完成后,编辑器内容与光标位置要合理
首版简化
- 不做复杂 diff 对比
- 先做“原文 + 候选文”的简单预览卡片
验收标准
- 替换位置准确
- 插入位置准确
- 应用后编辑器不丢焦点或出现异常闪动
8.4 能力四:主工具栏
目标
让右侧不再只是 AI 输出区,而是正式写作编辑器。
首版必须支持的结构
- 正文
- 一级标题
- 二级标题
- 三级标题
- 有序列表
- 无序列表
- 引用
- 代码块
首版必须支持的行内样式
- 加粗
- 斜体
- 下划线
- 删除线
行为要求
- 工具条按钮有选中态
- 光标所在块能正确反映当前结构
- 对选区和当前块的作用逻辑明确
- 工具栏与选区浮层不打架
验收标准
- 标题和正文可互相切换
- 列表、引用、代码块可稳定切换
- 行内样式不影响 AI 选区改写链路
9. 编辑器数据模型
9.1 前端主状态
建议前端编辑器使用 Tiptap JSON 作为内部主状态。
建议定义:
type WritingDocumentState = {
documentId?: string;
title: string;
markdown: string;
editorJson?: Record<string, unknown>;
updatedAt?: string;
};
9.2 选区状态
type WritingSelectionState = {
from: number;
to: number;
text: string;
isCollapsed: boolean;
blockTypes?: string[];
};
9.3 改写动作
type RewriteAction =
| "polish"
| "expand"
| "shorten"
| "tone";
9.4 改语气风格
type RewriteTone =
| "professional"
| "casual"
| "readable"
| "academic"
| "expressive";
9.5 改写请求
type RewriteRequest = {
threadId: string;
documentId?: string;
selection: {
from: number;
to: number;
text: string;
};
action: RewriteAction;
tone?: RewriteTone;
mode?: "preview";
surroundingContext?: {
before?: string;
after?: string;
};
};
9.6 改写响应
type RewriteResponse = {
output: string;
originalSelection: {
from: number;
to: number;
text: string;
};
metadata?: {
action: RewriteAction;
tone?: RewriteTone;
model?: string;
};
};
10. 与现有 DeerFlow 代码结构的对应关系
10.1 需要保留并对接的现有模块
-
frontend-web/src/pages/PageRoutes.tsx- 保留现有路由接入方式
-
frontend-web/src/components/workspace/chats/chat-box.tsx- 保留左右布局思路
- 需要改造右侧内容承载能力
-
frontend-web/src/components/workspace/input-box.tsx- 保留
writing_mode - 后续可作为进入写作编辑区的重要入口
- 保留
-
frontend-web/src/components/workspace/artifacts/context.tsx- 现有结构不够承载写作编辑器状态
- 可保留给原文件型 artifact
- 新写作画布建议单独维护自己的 context
10.2 不建议继续复用的方式
- 不建议把 Tiptap 状态直接塞进现有
string[] artifacts - 不建议继续把右侧主体验建立在“文件详情页”上
- 不建议把 AI 改写做成单纯聊天消息回传后人工复制
11. 前端目录建议
建议在 frontend-web/src 下新增独立模块目录:
src/open-canvas-writing/
routes/
WritingRoutes.tsx
pages/
WritingWorkspacePage.tsx
components/
WritingShell.tsx
WritingHeader.tsx
WritingToolbar.tsx
WritingEditorPane.tsx
WritingBubbleMenu.tsx
WritingAiMenu.tsx
WritingRewritePreview.tsx
WritingStatusBar.tsx
editor/
TiptapEditor.tsx
TiptapExtensions.ts
commands.ts
selection.ts
context/
WritingEditorContext.tsx
hooks/
useWritingEditor.ts
useWritingSelection.ts
useWritingRewrite.ts
useWritingToolbar.ts
api/
rewrite.ts
documents.ts
types/
document.ts
rewrite.ts
utils/
markdown.ts
apply-rewrite.ts
editor-style.ts
12. 路由与页面接入要求
12.1 路由策略
建议在现有 PageRoutes 体系下增加独立写作工作区页面,而不是塞进已有普通 artifact 面板。
12.2 接入方式
建议新增:
frontend-web/src/open-canvas-writing/routes/WritingRoutes.tsxfrontend-web/src/open-canvas-writing/pages/WritingWorkspacePage.tsx
然后在:
frontend-web/src/pages/PageRoutes.tsx
中引入新的写作助手路由,例如:
page/writing/*- 或合并到现有
page/canvas/*下的子路由
12.3 路由设计建议
推荐:
-
page/writing- 新建写作工作区
-
page/writing/:threadId- 进入某个线程对应写作工作区
如果你们已经有 open-canvas 路由,则建议不要把“豆包式写作编辑器”塞进原实验性画布页面里,而是作为独立子模式接入,避免后续页面职责混乱。
13. 前端实施拆解
13.1 模块 A:编辑器内核接入
目标
让右侧拥有正式可编辑文档能力。
任务
- 安装 Tiptap 基础依赖
- 接入
StarterKit - 接入
Underline - 配置支持:
- paragraph
- heading
- bulletList
- orderedList
- blockquote
- codeBlock
- bold
- italic
- underline
- strike
- code
- 建立受控 / 半受控编辑器状态
- 实现 Markdown 与 Tiptap JSON 的最小同步策略
输出物
TiptapEditor.tsxTiptapExtensions.ts- 基础编辑器容器样式
依赖关系
- 无前置依赖,可先开工
验收标准
- 右侧可以像普通文档编辑器一样输入和编辑内容
13.2 模块 B:主工具栏
目标
补齐写作编辑基础能力。
任务
- 实现标题切换
- 实现列表切换
- 实现引用切换
- 实现代码块切换
- 实现加粗 / 斜体 / 下划线 / 删除线
- 工具按钮高亮与禁用态
- 光标所在块状态识别
输出物
WritingToolbar.tsxuseWritingToolbar.ts
依赖关系
- 依赖模块 A
验收标准
- 常用写作结构和行内样式均可稳定切换
13.3 模块 C:选区浮层
目标
选中文本后出现轻量化操作浮层。
任务
- 监听 Tiptap selection
- 接入 BubbleMenu
- 处理显示 / 隐藏逻辑
- 布局 AI 改写、加粗、斜体、标题、复制
- 处理滚动与定位稳定性
输出物
WritingBubbleMenu.tsxuseWritingSelection.tsselection.ts
依赖关系
- 依赖模块 A
验收标准
- 选区浮层在单段和多段文本上都稳定可用
13.4 模块 D:AI 改写菜单
目标
把 AI 改写入口真正挂进选区工作流。
任务
- 实现
AI 改写一级入口 - 实现动作菜单
- 实现改语气二级菜单
- 封装改写请求 API
- 建立 loading / success / error 状态管理
输出物
WritingAiMenu.tsxuseWritingRewrite.tsapi/rewrite.ts
依赖关系
- 依赖模块 C
- 与后端接口联调
验收标准
- 四类改写动作都能从选区直接触发
13.5 模块 E:候选结果预览与应用
目标
将 AI 改写从“直接灌入文本”升级为“预览后应用”。
任务
- 设计候选结果展示卡
- 展示原文选区与候选结果
- 提供:
- 替换
- 插入
- 重试
- 取消
- 将候选内容通过 Tiptap transaction 应用到文档
输出物
WritingRewritePreview.tsxapply-rewrite.ts
依赖关系
- 依赖模块 D
验收标准
- 替换和插入都能准确写回编辑器
13.6 模块 F:页面美化
目标
把页面从“工程面板”升级为“成熟产品页面”。
任务
- 调整双栏比例和留白
- 优化右侧容器背景、阴影、边框、圆角
- 优化标题层级、正文字号、行高、段距
- 优化浮层和工具条视觉层级
- 优化 loading、hover、active 动效
- 对移动端和窄屏做降级策略
输出物
WritingShell.tsxWritingHeader.tsxWritingStatusBar.tsx- 相关样式变量
依赖关系
- 可与其他模块并行推进
验收标准
- 整体视觉明显接近正式写作产品
14. 后端实施拆解
14.1 总原则
后端保留现有 LangGraph 和线程架构,本轮只增加“选区改写型接口 / 节点 / 工具”,不重构整套后端。
14.2 后端最小职责
后端负责:
- 接收选区文本
- 接收动作类型
- 补足必要上下文
- 调用模型完成改写
- 返回候选文本
后端首版不负责:
- 直接操作 Tiptap JSON
- 直接做文档 patch
- 直接做复杂结构变换
14.3 推荐新增能力
rewrite_selectionexpand_selectionshorten_selectionchange_tone
统一接口建议
更推荐做成一个统一接口:
POST /api/writing/rewrite
由请求体中的 action 和 tone 控制行为。
请求建议
threadIddocumentIdselection.textselection.fromselection.toactiontonesurroundingContext.beforesurroundingContext.after
返回建议
outputmetadata.actionmetadata.tonemetadata.model
14.4 后端提示词策略
首版建议固定模板:
- 润色:保持原意,提高表达质量
- 扩写:在不偏离主题的前提下扩展细节
- 缩写:压缩表达但保留关键信息
- 改语气:保持事实不变,调整语言风格
统一要求:
- 尽量不要引入原文没有的新事实
- 不输出解释性前缀
- 直接返回可落文档的正文
14.5 后端验收标准
- 单段落改写稳定
- 多段落改写稳定
- 返回结果不夹带解释性废话
- 失败时能返回可识别错误
15. 前后端协议约束
15.1 首版协议原则
- 前端负责编辑器结构和最终写回
- 后端负责文本重写
- 前后端暂时通过“纯文本选区 + 上下文”交互
15.2 为什么不直接传富文本 JSON
因为首版最大的目标是稳定闭环,而不是复杂结构编辑。
如果一开始就让后端理解完整 Tiptap JSON,会显著增加:
- 协议复杂度
- 结构错位风险
- 测试成本
- 联调成本
因此首版推荐:
- 编辑器内部状态:Tiptap JSON
- 改写协议:纯文本 + 前后文
- 最终应用:前端 transaction
16. 分阶段实施计划
阶段 1:编辑器底座
目标
让右侧具备正式写作编辑能力。
包含内容
- Tiptap 接入
- 标题 / 列表 / 引用 / 代码块
- 行内样式
- 初步页面容器
验收
- 右侧能独立承担写作编辑
阶段 2:选区浮层
目标
把“选中文本后操作”打通。
包含内容
- BubbleMenu
- AI 改写入口
- 基础样式按钮
验收
- 单段和多段选区都可稳定触发
阶段 3:AI 改写
目标
把改写请求与后端串起来。
包含内容
- 润色
- 扩写
- 缩写
- 改语气
验收
- 四类动作都能返回结果
阶段 4:替换 / 插入
目标
把候选结果稳定应用到文档。
包含内容
- 结果预览
- 替换
- 插入
- 重试
- 取消
验收
- 改写结果可控落文档
阶段 5:UI 打磨
目标
让右侧从“能用”升级到“成熟产品感”。
包含内容
- 容器和留白
- 工具栏设计
- 浮层风格
- 字体和排版
- 动效
验收
- 视觉上明显接近豆包 / Novel 风格
17. 可并行分工建议
17.1 前端 A 组:编辑器底座
负责:
- Tiptap 接入
- 主工具栏
- 结构节点与 marks
对应阶段:
- 阶段 1
17.2 前端 B 组:选区交互
负责:
- 选区监听
- BubbleMenu
- AI 改写入口
对应阶段:
- 阶段 2
17.3 前端 C 组:候选结果与体验层
负责:
- 改写结果预览
- 替换 / 插入
- loading / error / retry
- UI 打磨
对应阶段:
- 阶段 4
- 阶段 5
17.4 后端 D 组:改写服务
负责:
- 统一改写接口
- LangGraph 节点或工具
- 提示词
- 上下文拼接
对应阶段:
- 阶段 3
17.5 联调负责人
负责:
- 协议定稿
- 错误码和异常约定
- 多段落选区联调
- 光标位置 / 替换位置问题兜底
18. UI 设计要求
18.1 风格关键词
- 轻
- 干净
- 编辑器优先
- AI 能力明显但不喧宾夺主
- 有留白
- 有产品感
18.2 页面视觉要求
- 右侧阅读宽度适中,不可过宽
- 主文内容器有明确层级
- 正文行高偏舒展
- 标题有清晰层级
- 工具栏不应过厚重
- 浮层必须轻、准、快
18.3 动效要求
- 浮层出现和消失有轻微过渡
- AI 改写请求有反馈
- 替换 / 插入确认有轻量状态切换
18.4 参考视觉方向
- 布局参考 Novel
- 选区和改写交互参考豆包
- AI 工作流节奏参考 open-canvas
19. 风险与规避方案
19.1 风险一:现有 Artifact 架构不适合承载写作编辑器
规避
- 不强塞到
string[] artifacts - 新建独立写作模块和上下文
19.2 风险二:富文本与 Markdown 同步复杂
规避
- 首版以 Tiptap 内部状态为准
- 对外只做最小 Markdown 输出
19.3 风险三:多段落改写后替换位置错乱
规避
- 前端记录稳定选区范围
- 候选结果应用时使用 Tiptap transaction
- 首版优先支持连续纯文本段落
19.4 风险四:AI 返回啰嗦解释文本
规避
- 后端提示词严格约束只返回正文
- 前端必要时做轻量清洗
19.5 风险五:UI 做成“功能堆砌”
规避
- 首版只上最核心 4 类能力
- 不把太多低频按钮塞进第一层工具栏
20. 验收标准
20.1 功能验收
- 右侧可直接编辑文档
- 支持标题 / 列表 / 引用 / 代码块
- 选中内容后有浮层
- 支持润色 / 扩写 / 缩写 / 改语气
- 支持替换 / 插入
- 支持多段落选区改写
20.2 交互验收
- 浮层位置稳定
- AI 改写链路顺畅
- 替换 / 插入后位置正确
- 不影响左侧聊天流
20.3 体验验收
- 右侧明显比当前版本更成熟
- 页面更适合长文阅读和改稿
- 整体交互接近豆包 AI 写作助手
21. 首版最小可交付范围
如果需要控制风险,建议首版只交付:
- Tiptap 接入
- 主工具栏
- 选区浮层
- 润色 / 扩写 / 缩写 / 改语气
- 替换 / 插入
- 基础 UI 美化
以下能力不要强行塞进首版:
- 自定义提示词
- slash command
- 修订模式
- 评论系统
- 复杂 diff 对比
- 文档历史版本
22. 实施优先级
P0
- Tiptap 接入
- 主工具栏
- 选区浮层
- AI 改写接口
- 替换 / 插入
P1
- 页面整体美化
- 改语气二级菜单
- 多段落改写稳定性
- 错误态 / 重试态
P2
- 文档状态提示
- 轻量空态
- 细节动画
- 交互易用性优化
23. 结论
这次升级最合理的路线,不是继续在现有右侧 Artifact 详情页上小修小补,而是正式引入一层写作编辑器能力。
最稳妥的做法是:
- 保留左侧聊天和现有 LangGraph 后端
- 在右侧引入
Tiptap - 先把四个核心能力做深做稳
- UI 借鉴豆包、Novel、open-canvas 的成熟交互
只要按照本文档分阶段推进,这个需求虽然大,但完全可以拆成多组并行、逐步验收、持续落地的工程任务,而不是一次性大爆炸改造。