# AI 写作助手源码与实现映射表 ## 1. 文档目标 本文档用于把以下几类信息对应起来: - 豆包 AI 写作助手里要借鉴的交互 - Novel / open-canvas / Tiptap 中可参考的实现思路 - DeerFlow 当前项目里已经存在的落点 - 本次新建模块应该落到哪里 这份文档不是源码复制文档,而是开发时的“对照表”和“导航图”。 --- ## 2. 使用方式 开发时建议按以下顺序看: 1. 先看“目标能力” 2. 再看“参考来源” 3. 再看“DeerFlow 当前落点” 4. 最后看“本次目标文件” 这样可以避免出现两种常见问题: - 直接照搬外部项目结构,结果和你们现有架构冲突 - 只看自己项目,不知道成熟产品交互应该怎么落 --- ## 3. 总体映射 | 目标能力 | 产品参考 | 外部参考实现 | DeerFlow 当前落点 | 本次目标文件 | | --- | --- | --- | --- | --- | | 写作工作区路由 | open-canvas 独立页面 | open-canvas 路由组织思路 | `frontend-web/src/pages/PageRoutes.tsx` | `frontend-web/src/open-canvas-writing/routes/WritingRoutes.tsx` | | 左右双栏工作区 | 豆包写作页 / open-canvas | open-canvas 页面壳思路 | `frontend-web/src/components/workspace/chats/chat-box.tsx` | `frontend-web/src/open-canvas-writing/pages/WritingWorkspacePage.tsx`、`WritingShell.tsx` | | 富文本正文编辑 | Novel | Tiptap 官方编辑器模式 | 当前无正式富文本正文编辑器 | `frontend-web/src/open-canvas-writing/editor/TiptapEditor.tsx` | | 文档工具栏 | 豆包 / Novel | Tiptap Toolbar 组合思路 | 当前右侧无正式工具栏 | `frontend-web/src/open-canvas-writing/components/WritingToolbar.tsx` | | 选区浮层 | 豆包 | Tiptap BubbleMenu | 当前右侧无选区浮层 | `frontend-web/src/open-canvas-writing/components/WritingBubbleMenu.tsx` | | AI 改写菜单 | 豆包 | 自定义菜单 + BubbleMenu 挂接 | 当前无 | `frontend-web/src/open-canvas-writing/components/WritingAiMenu.tsx` | | 候选结果预览 | 豆包 / open-canvas | open-canvas 候选应用思路 | 当前无 | `frontend-web/src/open-canvas-writing/components/WritingRewritePreview.tsx` | | 替换 / 插入 | 豆包 | Tiptap transaction 应用 | 当前无 | `frontend-web/src/open-canvas-writing/utils/apply-rewrite.ts` | | 写作模式总入口 | 当前 DeerFlow | 现有 `writing_mode` 开关 | `frontend-web/src/components/workspace/input-box.tsx` | 保留现有入口并接新页面 | | 线程与模型协同 | 当前 DeerFlow | 现有线程 / 模型体系 | 现有 `core/threads`、`core/models` | 继续复用,新增 `api/rewrite.ts` | --- ## 4. 豆包功能到 DeerFlow 的映射 ## 4.1 滑词 / 选区浮层 ### 豆包里的体验 - 选中文本后出现轻量浮层 - 浮层里有: - AI 改写 - 文本样式 - 复制 ### DeerFlow 当前状态 - 右侧还没有正式的选区级工具层 ### 本次实现方式 - 使用 Tiptap 的 `BubbleMenu` - 再叠加自定义菜单逻辑 ### 本次落点 - `frontend-web/src/open-canvas-writing/components/WritingBubbleMenu.tsx` - `frontend-web/src/open-canvas-writing/hooks/useWritingSelection.ts` - `frontend-web/src/open-canvas-writing/editor/selection.ts` --- ## 4.2 多段落改写 ### 豆包里的体验 - 不是只改单句 - 能对连续几段一起润色、扩写、缩写、改语气 ### DeerFlow 当前状态 - 现有右侧编辑区没有正式的多段落选区改写模型 ### 本次实现方式 - 前端提取连续选区纯文本 - 前端附带前后文 - 后端返回候选纯文本 - 前端决定替换或插入 ### 本次落点 - `frontend-web/src/open-canvas-writing/hooks/useWritingSelection.ts` - `frontend-web/src/open-canvas-writing/hooks/useWritingRewrite.ts` - `frontend-web/src/open-canvas-writing/api/rewrite.ts` --- ## 4.3 替换 / 插入 ### 豆包里的体验 - 改写结果不是直接覆盖原文 - 用户可选择: - 替换 - 插入 ### DeerFlow 当前状态 - 当前没有候选文本应用层 ### 本次实现方式 - 建立候选结果预览区 - 基于 Tiptap transaction 应用文本 ### 本次落点 - `frontend-web/src/open-canvas-writing/components/WritingRewritePreview.tsx` - `frontend-web/src/open-canvas-writing/utils/apply-rewrite.ts` --- ## 4.4 标题 / 列表 / 引用 / 代码块工具条 ### 豆包里的体验 - 右侧本身就是正式文档编辑器 - 可以快速切换文档结构 ### DeerFlow 当前状态 - 当前右侧偏预览,不是正式写作编辑器 ### 本次实现方式 - 使用 Tiptap 节点和命令 - 在主工具栏中集中承载 ### 本次落点 - `frontend-web/src/open-canvas-writing/components/WritingToolbar.tsx` - `frontend-web/src/open-canvas-writing/hooks/useWritingToolbar.ts` - `frontend-web/src/open-canvas-writing/editor/commands.ts` - `frontend-web/src/open-canvas-writing/editor/TiptapExtensions.ts` --- ## 5. Novel 参考映射 ## 5.1 最值得借鉴的不是“代码整搬”,而是这三件事 - 编辑器主容器的产品感 - 工具栏和空态的组织方式 - 正文阅读宽度、排版、留白 ## 5.2 对应到 DeerFlow 的实现位置 - 页面壳:`WritingShell.tsx` - 顶部文档区:`WritingHeader.tsx` - 编辑容器:`TiptapEditor.tsx` - 工具栏:`WritingToolbar.tsx` - 空态:`WritingEmptyState.tsx` ## 5.3 不建议直接照搬的部分 - Next.js 页面结构 - 依赖其服务端 AI 调用方式 - 与 Vercel AI SDK 深绑定的部分 --- ## 6. open-canvas 参考映射 ## 6.1 主要借鉴对象 open-canvas 这次最值得借鉴的不是页面外观,而是: - AI 工作流组织方式 - 改写结果应用节奏 - 编辑器和聊天协作的模式 ## 6.2 借鉴重点 ### 借鉴 1:独立工作区思想 不要把写作体验塞进一个零散的弹窗或文件详情页,要有独立工作区。 对应 DeerFlow: - `frontend-web/src/open-canvas-writing/pages/WritingWorkspacePage.tsx` ### 借鉴 2:画布状态独立维护 不要让写作状态完全依附聊天消息渲染结果,要独立维护文档和候选状态。 对应 DeerFlow: - `frontend-web/src/open-canvas-writing/context/WritingEditorContext.tsx` ### 借鉴 3:AI 输出先预览,再应用 对应 DeerFlow: - `frontend-web/src/open-canvas-writing/components/WritingRewritePreview.tsx` --- ## 7. Tiptap 参考映射 ## 7.1 Tiptap 在本项目中的职责 - 作为右侧正式富文本编辑器内核 - 提供结构节点与 marks - 提供 BubbleMenu 能力 - 提供 transaction 应用能力 ## 7.2 建议直接参考的实现点 - `EditorContent` 的封装模式 - `BubbleMenu` 的接入方式 - heading / list / blockquote / codeBlock 扩展配置 - `editor.chain().focus()` 命令调用模式 - selection 变化监听 ## 7.3 DeerFlow 本次落点 - `frontend-web/src/open-canvas-writing/editor/TiptapEditor.tsx` - `frontend-web/src/open-canvas-writing/editor/TiptapExtensions.ts` - `frontend-web/src/open-canvas-writing/editor/commands.ts` - `frontend-web/src/open-canvas-writing/components/WritingBubbleMenu.tsx` --- ## 8. DeerFlow 现有文件到新模块的映射 ## 8.1 `frontend-web/src/pages/PageRoutes.tsx` ### 当前职责 - 汇总页面路由 ### 本次作用 - 挂入新的写作助手路由 ### 后续动作 - 引入 `WritingRoutes` - 增加 `page/writing/*` --- ## 8.2 `frontend-web/src/components/workspace/chats/chat-box.tsx` ### 当前职责 - 左聊天 + 右 Artifact 双栏布局 ### 本次作用 - 提供双栏工作区组织思路 - 可复用布局比例和 panel 交互经验 ### 不建议直接复用的部分 - 不要继续让右侧核心能力挂在 ArtifactFileDetail 上 ### 本次目标替代 - `WritingWorkspacePage.tsx` - `WritingShell.tsx` --- ## 8.3 `frontend-web/src/components/workspace/artifacts/context.tsx` ### 当前职责 - 管理文件型 artifact 列表、选中项和开关状态 ### 本次作用 - 仅作为旧 Artifact 模块保留 ### 本次目标替代 - `WritingEditorContext.tsx` ### 原因 - 写作编辑器需要的不是文件路径状态 - 而是文档状态、选区状态、候选结果状态、工具层状态 --- ## 8.4 `frontend-web/src/components/workspace/input-box.tsx` ### 当前职责 - 聊天输入区 - 已有 `writing_mode` 入口 ### 本次作用 - 保留为用户进入写作模式的现有入口 ### 本次改造建议 - 写作模式打开时,跳转或唤起新的写作工作区 - 不再只停留在“生成 Markdown 文件”这个层面 --- ## 9. 新模块间的依赖关系 ## 9.1 页面层 - `WritingRoutes.tsx` - `WritingWorkspacePage.tsx` - `WritingShell.tsx` 职责: - 页面路由 - 双栏或工作区布局 - 上下文装配 ## 9.2 编辑器层 - `TiptapEditor.tsx` - `TiptapExtensions.ts` - `commands.ts` - `selection.ts` 职责: - 编辑器内核 - 节点和 marks - 基础命令 - 选区抽取 ## 9.3 交互层 - `WritingToolbar.tsx` - `WritingBubbleMenu.tsx` - `WritingAiMenu.tsx` - `WritingRewritePreview.tsx` 职责: - 工具栏 - 浮层 - AI 菜单 - 候选内容应用 ## 9.4 状态层 - `WritingEditorContext.tsx` - `useWritingEditor.ts` - `useWritingSelection.ts` - `useWritingRewrite.ts` - `useWritingToolbar.ts` 职责: - 主状态 - 选区状态 - 改写状态 - 工具栏状态 ## 9.5 API 层 - `api/rewrite.ts` - `api/documents.ts` 职责: - 对接后端写作改写接口 - 对接文档加载与保存接口 --- ## 10. 能力到文件的精确映射 | 能力 | 新文件 | 说明 | | --- | --- | --- | | 新写作页面 | `frontend-web/src/open-canvas-writing/pages/WritingWorkspacePage.tsx` | 承载整个新模式 | | 写作路由 | `frontend-web/src/open-canvas-writing/routes/WritingRoutes.tsx` | 统一路由入口 | | 页面外壳 | `frontend-web/src/open-canvas-writing/components/WritingShell.tsx` | 页面布局与容器 | | 文档头部 | `frontend-web/src/open-canvas-writing/components/WritingHeader.tsx` | 标题、状态 | | 主工具栏 | `frontend-web/src/open-canvas-writing/components/WritingToolbar.tsx` | 文档结构与格式工具 | | 正文编辑器 | `frontend-web/src/open-canvas-writing/editor/TiptapEditor.tsx` | Tiptap 核心封装 | | 扩展配置 | `frontend-web/src/open-canvas-writing/editor/TiptapExtensions.ts` | 节点和 marks | | 选区浮层 | `frontend-web/src/open-canvas-writing/components/WritingBubbleMenu.tsx` | 选区出现的悬浮条 | | AI 菜单 | `frontend-web/src/open-canvas-writing/components/WritingAiMenu.tsx` | 润色、扩写等动作 | | 改写预览 | `frontend-web/src/open-canvas-writing/components/WritingRewritePreview.tsx` | 候选内容展示与应用 | | 替换 / 插入 | `frontend-web/src/open-canvas-writing/utils/apply-rewrite.ts` | 应用候选结果 | | 编辑器状态 | `frontend-web/src/open-canvas-writing/context/WritingEditorContext.tsx` | 独立上下文 | | 改写请求 | `frontend-web/src/open-canvas-writing/api/rewrite.ts` | 调后端接口 | --- ## 11. 开发时的参考顺序 建议开发顺序如下: 1. 先看 `PageRoutes.tsx`,确定路由接法 2. 再看 `chat-box.tsx`,理解当前左右布局 3. 然后起 `WritingWorkspacePage.tsx` 和 `WritingShell.tsx` 4. 再接 `TiptapEditor.tsx` 5. 再做 `WritingToolbar.tsx` 6. 再做 `WritingBubbleMenu.tsx` 7. 再做 `WritingAiMenu.tsx` 8. 最后做 `WritingRewritePreview.tsx` 这样可以让每一层都有稳定承载,不会出现“先做了 AI 菜单,但页面还没落点”的混乱情况。 --- ## 12. 明确哪些是“参考”,哪些是“目标” ### 12.1 参考 - 豆包:交互体验参考 - Novel:页面和编辑器质感参考 - open-canvas:AI 工作流参考 - Tiptap:编辑器技术实现参考 ### 12.2 目标 目标不是复刻任何一个外部项目,而是: - 在 DeerFlow 现有架构中 - 用 React + Vite + 现有线程体系 - 做出一个更成熟的 AI 写作编辑器模式 --- ## 13. 结论 这份映射表的核心作用,是避免团队在开发时迷路。 真正推荐的姿势是: - 用豆包定义目标体验 - 用 Novel 定义页面质感 - 用 open-canvas 定义 AI 工作流 - 用 Tiptap 作为编辑器内核 - 用 DeerFlow 现有路由、线程、模型体系做宿主 这样推进,既不会脱离你们现有工程,也能尽量快地把右侧编辑区拉到更接近成熟产品的水平。