# 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[]` 文件路径为主 - 不适合直接承载“选区级写作编辑器状态” - `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 右侧编辑器结构 建议右侧拆分为以下区域: 1. 文档头部区 - 文档标题 - 文档状态 - 可能的保存提示 2. 主工具栏 - 正文 - 一级标题 - 二级标题 - 三级标题 - 有序列表 - 无序列表 - 引用 - 代码块 - 加粗 - 斜体 - 下划线 - 删除线 3. 编辑正文区 - 基于 Tiptap 的可编辑正文 4. 选区浮层 - AI 改写 - 加粗 - 斜体 - 标题 - 复制 5. AI 改写动作菜单 - 润色 - 扩写 - 缩写 - 改语气 6. 改写结果预览区 - 预览文本 - 替换 - 插入 - 重试 - 取消 ### 7.3 目标交互闭环 1. 用户在左侧发起写作任务 2. 右侧生成初稿或打开写作画布 3. 用户在右侧直接编辑 4. 用户选中一句或多段 5. 弹出浮层 6. 点击 `AI 改写` 7. 选择 `润色 / 扩写 / 缩写 / 改语气` 8. 看到候选结果 9. 选择 `替换` 或 `插入` 10. 继续写、继续改、继续和左侧聊天协同 --- ## 8. 核心能力详细定义 ## 8.1 能力一:选区浮层 ### 目标 用户在右侧选中文本后,出现跟随选区的浮层工具条。 ### 首版必须包含的按钮 - AI 改写 - 加粗 - 斜体 - 标题 - 复制 ### 行为要求 - 只有在有效文本选区存在时显示 - 选区取消后自动消失 - 滚动时位置跟随更新 - 只对右侧编辑器正文区域生效 - 对跨多个段落的纯文本选区生效 ### 首版限制 - 首版只处理文本选区 - 不处理跨复杂嵌套节点的高级结构变更 ### 验收标准 - 选中单段文本时能稳定出现 - 选中连续多段文本时能稳定出现 - 不遮挡正文主要阅读区域 --- ## 8.2 能力二:AI 改写动作 ### 目标 用户选中内容后,可快速对该内容发起 AI 重写。 ### 一级动作 - 润色 - 扩写 - 缩写 - 改语气 ### 改语气二级选项 - 更专业 - 更口语化 - 更易读 - 更学术 - 更有文采 ### 行为要求 - 改写动作基于当前选区触发 - 支持单段落与多段落 - 支持带少量前后文一起发给后端 - 改写期间有明显 loading 态 - 改写失败要有失败提示和重试入口 ### 提示词策略 首版不开放自定义 prompt,只提供预设动作。 ### 验收标准 - 四类一级动作可正常使用 - 改语气二级菜单可正常展开和触发 - 多段落改写不会破坏原文结构边界 --- ## 8.3 能力三:替换 / 插入 ### 目标 AI 返回候选内容后,不直接覆盖原文,而是先让用户决策如何应用。 ### 两种应用方式 - 替换:用候选结果替换当前选区 - 插入:把候选结果插入到选区后面,保留原文 ### 行为要求 - AI 返回结果后先展示预览 - 默认不自动落文档 - 支持重试 - 支持取消 - 应用动作完成后,编辑器内容与光标位置要合理 ### 首版简化 - 不做复杂 diff 对比 - 先做“原文 + 候选文”的简单预览卡片 ### 验收标准 - 替换位置准确 - 插入位置准确 - 应用后编辑器不丢焦点或出现异常闪动 --- ## 8.4 能力四:主工具栏 ### 目标 让右侧不再只是 AI 输出区,而是正式写作编辑器。 ### 首版必须支持的结构 - 正文 - 一级标题 - 二级标题 - 三级标题 - 有序列表 - 无序列表 - 引用 - 代码块 ### 首版必须支持的行内样式 - 加粗 - 斜体 - 下划线 - 删除线 ### 行为要求 - 工具条按钮有选中态 - 光标所在块能正确反映当前结构 - 对选区和当前块的作用逻辑明确 - 工具栏与选区浮层不打架 ### 验收标准 - 标题和正文可互相切换 - 列表、引用、代码块可稳定切换 - 行内样式不影响 AI 选区改写链路 --- ## 9. 编辑器数据模型 ### 9.1 前端主状态 建议前端编辑器使用 Tiptap JSON 作为内部主状态。 建议定义: ```ts type WritingDocumentState = { documentId?: string; title: string; markdown: string; editorJson?: Record; updatedAt?: string; }; ``` ### 9.2 选区状态 ```ts type WritingSelectionState = { from: number; to: number; text: string; isCollapsed: boolean; blockTypes?: string[]; }; ``` ### 9.3 改写动作 ```ts type RewriteAction = | "polish" | "expand" | "shorten" | "tone"; ``` ### 9.4 改语气风格 ```ts type RewriteTone = | "professional" | "casual" | "readable" | "academic" | "expressive"; ``` ### 9.5 改写请求 ```ts 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 改写响应 ```ts 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` 下新增独立模块目录: ```text 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.tsx` - `frontend-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.tsx` - `TiptapExtensions.ts` - 基础编辑器容器样式 ### 依赖关系 - 无前置依赖,可先开工 ### 验收标准 - 右侧可以像普通文档编辑器一样输入和编辑内容 ## 13.2 模块 B:主工具栏 ### 目标 补齐写作编辑基础能力。 ### 任务 - 实现标题切换 - 实现列表切换 - 实现引用切换 - 实现代码块切换 - 实现加粗 / 斜体 / 下划线 / 删除线 - 工具按钮高亮与禁用态 - 光标所在块状态识别 ### 输出物 - `WritingToolbar.tsx` - `useWritingToolbar.ts` ### 依赖关系 - 依赖模块 A ### 验收标准 - 常用写作结构和行内样式均可稳定切换 ## 13.3 模块 C:选区浮层 ### 目标 选中文本后出现轻量化操作浮层。 ### 任务 - 监听 Tiptap selection - 接入 BubbleMenu - 处理显示 / 隐藏逻辑 - 布局 AI 改写、加粗、斜体、标题、复制 - 处理滚动与定位稳定性 ### 输出物 - `WritingBubbleMenu.tsx` - `useWritingSelection.ts` - `selection.ts` ### 依赖关系 - 依赖模块 A ### 验收标准 - 选区浮层在单段和多段文本上都稳定可用 ## 13.4 模块 D:AI 改写菜单 ### 目标 把 AI 改写入口真正挂进选区工作流。 ### 任务 - 实现 `AI 改写` 一级入口 - 实现动作菜单 - 实现改语气二级菜单 - 封装改写请求 API - 建立 loading / success / error 状态管理 ### 输出物 - `WritingAiMenu.tsx` - `useWritingRewrite.ts` - `api/rewrite.ts` ### 依赖关系 - 依赖模块 C - 与后端接口联调 ### 验收标准 - 四类改写动作都能从选区直接触发 ## 13.5 模块 E:候选结果预览与应用 ### 目标 将 AI 改写从“直接灌入文本”升级为“预览后应用”。 ### 任务 - 设计候选结果展示卡 - 展示原文选区与候选结果 - 提供: - 替换 - 插入 - 重试 - 取消 - 将候选内容通过 Tiptap transaction 应用到文档 ### 输出物 - `WritingRewritePreview.tsx` - `apply-rewrite.ts` ### 依赖关系 - 依赖模块 D ### 验收标准 - 替换和插入都能准确写回编辑器 ## 13.6 模块 F:页面美化 ### 目标 把页面从“工程面板”升级为“成熟产品页面”。 ### 任务 - 调整双栏比例和留白 - 优化右侧容器背景、阴影、边框、圆角 - 优化标题层级、正文字号、行高、段距 - 优化浮层和工具条视觉层级 - 优化 loading、hover、active 动效 - 对移动端和窄屏做降级策略 ### 输出物 - `WritingShell.tsx` - `WritingHeader.tsx` - `WritingStatusBar.tsx` - 相关样式变量 ### 依赖关系 - 可与其他模块并行推进 ### 验收标准 - 整体视觉明显接近正式写作产品 --- ## 14. 后端实施拆解 ## 14.1 总原则 后端保留现有 LangGraph 和线程架构,本轮只增加“选区改写型接口 / 节点 / 工具”,不重构整套后端。 ## 14.2 后端最小职责 后端负责: - 接收选区文本 - 接收动作类型 - 补足必要上下文 - 调用模型完成改写 - 返回候选文本 后端首版不负责: - 直接操作 Tiptap JSON - 直接做文档 patch - 直接做复杂结构变换 ## 14.3 推荐新增能力 - `rewrite_selection` - `expand_selection` - `shorten_selection` - `change_tone` ### 统一接口建议 更推荐做成一个统一接口: ```text POST /api/writing/rewrite ``` 由请求体中的 `action` 和 `tone` 控制行为。 ### 请求建议 - `threadId` - `documentId` - `selection.text` - `selection.from` - `selection.to` - `action` - `tone` - `surroundingContext.before` - `surroundingContext.after` ### 返回建议 - `output` - `metadata.action` - `metadata.tone` - `metadata.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 的成熟交互 只要按照本文档分阶段推进,这个需求虽然大,但完全可以拆成多组并行、逐步验收、持续落地的工程任务,而不是一次性大爆炸改造。