From b34219ce865f212de524d0fbabc16873b1ae9fbb Mon Sep 17 00:00:00 2001 From: fengxiangdebaozi <10845145+fengxiangdebaozi@user.noreply.gitee.com> Date: Sat, 16 May 2026 09:07:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/ai-writing-assistant-backend-api.md | 726 ++++++++++ ...ai-writing-assistant-frontend-checklist.md | 703 ++++++++++ .../docs/ai-writing-assistant-source-map.md | 457 +++++++ .../docs/ai-writing-assistant-upgrade.md | 1191 +++++++++++++++++ 4 files changed, 3077 insertions(+) create mode 100644 frontend-web/docs/ai-writing-assistant-backend-api.md create mode 100644 frontend-web/docs/ai-writing-assistant-frontend-checklist.md create mode 100644 frontend-web/docs/ai-writing-assistant-source-map.md create mode 100644 frontend-web/docs/ai-writing-assistant-upgrade.md diff --git a/frontend-web/docs/ai-writing-assistant-backend-api.md b/frontend-web/docs/ai-writing-assistant-backend-api.md new file mode 100644 index 00000000..4f8e00c8 --- /dev/null +++ b/frontend-web/docs/ai-writing-assistant-backend-api.md @@ -0,0 +1,726 @@ +# AI 写作助手后端接口与 Prompt 协议文档 + +## 1. 文档目标 + +本文档用于指导 AI 写作助手第二阶段升级中的后端开发、接口设计、提示词设计和联调约束。 + +本轮后端目标不是重做 DeerFlow 的整体架构,而是在保留现有 Python + LangGraph + 线程体系的基础上,新增一套稳定的“选区改写型能力”,服务前端的 Tiptap 写作编辑器。 + +--- + +## 2. 本轮后端职责 + +后端负责: + +- 接收当前线程信息 +- 接收用户选区文本 +- 接收改写动作 +- 选取必要上下文 +- 调用模型生成候选改写结果 +- 返回纯净候选文本 + +后端本轮不负责: + +- 直接编辑 Tiptap JSON +- 直接操作前端编辑器选区 +- 直接替换前端文档内容 +- 做复杂富文本 patch +- 做 tracked changes + +--- + +## 3. 设计原则 + +### 3.1 纯文本协议优先 + +首版只让后端处理: + +- 选区文本 +- 前后文文本 +- 动作类型 +- 风格参数 + +不让后端直接理解完整富文本 JSON。 + +### 3.2 前端负责应用,后端负责生成 + +- 前端负责选区获取 +- 前端负责候选结果展示 +- 前端负责替换 / 插入 +- 后端只负责“给出候选文本” + +### 3.3 结果必须可直接落文档 + +后端输出必须尽量是可直接放回编辑器的正文,不应带解释性前缀,例如: + +- “当然可以,以下是润色版本:” +- “我帮你改写如下:” +- “下面是优化后的内容:” + +这类内容必须禁止。 + +--- + +## 4. 推荐接口设计 + +## 4.1 主接口 + +推荐新增统一接口: + +```text +POST /api/writing/rewrite +``` + +由 `action` 决定具体重写类型。 + +## 4.2 为什么推荐统一接口 + +因为前端交互是一套统一浮层和统一预览面板,拆成多个接口会导致: + +- 前端判断分支增多 +- 埋点与异常处理分散 +- 后续新增动作不方便扩展 + +统一接口更适合本轮需求。 + +--- + +## 5. 请求体定义 + +建议请求体如下: + +```json +{ + "threadId": "string", + "documentId": "string", + "selection": { + "from": 120, + "to": 260, + "text": "待改写文本" + }, + "action": "polish", + "tone": "professional", + "surroundingContext": { + "before": "选区前文", + "after": "选区后文" + } +} +``` + +--- + +## 6. 字段说明 + +### 6.1 `threadId` + +用途: + +- 关联当前 DeerFlow 线程 +- 必要时取线程上下文或会话元数据 + +### 6.2 `documentId` + +用途: + +- 标识当前右侧文档 +- 首版可选 +- 如果当前系统还没有独立文档 ID,可先允许为空 + +### 6.3 `selection.from` / `selection.to` + +用途: + +- 帮助前后端联调排查 +- 首版后端通常不需要真正使用偏移量 +- 建议保留,便于日志定位 + +### 6.4 `selection.text` + +用途: + +- 这是本轮最核心输入 +- 后端实际重写的主文本 + +### 6.5 `action` + +允许值: + +- `polish` +- `expand` +- `shorten` +- `tone` + +### 6.6 `tone` + +仅当 `action = tone` 时使用。 + +建议允许值: + +- `professional` +- `casual` +- `readable` +- `academic` +- `expressive` + +### 6.7 `surroundingContext.before` + +用途: + +- 提供选区前文 +- 帮助模型理解语气、主语、叙事连续性 + +建议: + +- 控制长度 +- 不要塞太多无关上下文 + +### 6.8 `surroundingContext.after` + +用途: + +- 提供选区后文 +- 帮助模型在扩写、改语气时与后续内容衔接 + +--- + +## 7. 返回体定义 + +建议返回体如下: + +```json +{ + "output": "AI 改写后的候选文本", + "originalSelection": { + "from": 120, + "to": 260, + "text": "待改写文本" + }, + "metadata": { + "action": "polish", + "tone": null, + "model": "your-model-name" + } +} +``` + +--- + +## 8. 返回字段要求 + +## 8.1 `output` + +必须: + +- 只包含候选正文 +- 尽量不夹带解释语 +- 能直接被前端替换或插入 + +## 8.2 `originalSelection` + +作用: + +- 前端可以做校验 +- 联调时方便确认是针对哪段文本返回的 + +## 8.3 `metadata` + +作用: + +- 便于埋点 +- 便于日志记录 +- 便于问题追踪 + +--- + +## 9. 错误响应规范 + +建议统一错误结构: + +```json +{ + "error": { + "code": "WRITING_REWRITE_FAILED", + "message": "rewrite failed" + } +} +``` + +建议错误码: + +- `WRITING_REWRITE_FAILED` +- `WRITING_INVALID_ACTION` +- `WRITING_INVALID_TONE` +- `WRITING_EMPTY_SELECTION` +- `WRITING_MODEL_UNAVAILABLE` +- `WRITING_CONTEXT_TOO_LARGE` + +--- + +## 10. 动作语义定义 + +## 10.1 `polish` + +目标: + +- 保持原意 +- 改善表达 +- 提升通顺度、自然度和可读性 + +不应: + +- 引入新事实 +- 改写成完全不同内容 + +## 10.2 `expand` + +目标: + +- 保持主旨 +- 扩充细节 +- 增强画面感、解释性或完整度 + +不应: + +- 无限制发散 +- 添加明显脱离主题的新内容 + +## 10.3 `shorten` + +目标: + +- 压缩篇幅 +- 保留关键信息 +- 减少重复表达 + +不应: + +- 丢失关键论点 +- 压缩到语义残缺 + +## 10.4 `tone` + +目标: + +- 不改变原意 +- 调整语言风格 + +不应: + +- 改写事实 +- 改写逻辑结构到完全不同 + +--- + +## 11. Prompt 设计原则 + +## 11.1 通用系统约束 + +所有改写类 prompt 都应包含以下约束: + +- 直接输出最终可用正文 +- 不输出标题,除非原文本身就是标题改写 +- 不输出解释 +- 不输出分析过程 +- 不输出“以下是结果”之类前缀 +- 保持与上下文语气一致 + +## 11.2 上下文使用原则 + +前后文只用于理解,不要求模型重写前后文。 + +明确告诉模型: + +- 只改写选中文本 +- 前后文仅用于参考衔接 + +## 11.3 长度控制原则 + +- `polish`:长度与原文接近 +- `expand`:长度可明显增加,但不要失控 +- `shorten`:长度明显缩短,但要保留关键信息 +- `tone`:长度尽量与原文接近 + +--- + +## 12. Prompt 模板建议 + +## 12.1 润色模板 + +```text +你是一名中文写作编辑助手。 + +请在不改变原意的前提下,对“选中文本”进行润色,使表达更自然、更流畅、更清晰。 + +要求: +1. 保留原文事实和核心意思。 +2. 不要添加原文没有的新事实。 +3. 不要输出解释,不要输出前缀,不要输出分析过程。 +4. 直接输出润色后的正文。 + +前文参考: +{before} + +选中文本: +{selection} + +后文参考: +{after} +``` + +## 12.2 扩写模板 + +```text +你是一名中文写作编辑助手。 + +请在不偏离主题的前提下,对“选中文本”进行扩写,增加必要细节、画面感或补充说明,使内容更充实。 + +要求: +1. 保持原文主旨不变。 +2. 增加内容时要自然,不要跑题。 +3. 不要输出解释,不要输出前缀,不要输出分析过程。 +4. 直接输出扩写后的正文。 + +前文参考: +{before} + +选中文本: +{selection} + +后文参考: +{after} +``` + +## 12.3 缩写模板 + +```text +你是一名中文写作编辑助手。 + +请在保留关键信息和原意的前提下,对“选中文本”进行缩写,使其更精炼。 + +要求: +1. 不要丢掉核心信息。 +2. 去掉重复、冗余和拖沓表达。 +3. 不要输出解释,不要输出前缀,不要输出分析过程。 +4. 直接输出缩写后的正文。 + +前文参考: +{before} + +选中文本: +{selection} + +后文参考: +{after} +``` + +## 12.4 改语气模板 + +```text +你是一名中文写作编辑助手。 + +请在不改变原意和事实的前提下,把“选中文本”改写成更{tone_label}的表达方式。 + +要求: +1. 保持原文信息不变。 +2. 只调整表达风格,不改变事实和逻辑。 +3. 不要输出解释,不要输出前缀,不要输出分析过程。 +4. 直接输出改写后的正文。 + +前文参考: +{before} + +选中文本: +{selection} + +后文参考: +{after} +``` + +--- + +## 13. Tone 映射建议 + +建议前端传标准值,后端映射中文标签: + +- `professional` -> 专业、正式 +- `casual` -> 口语化、轻松自然 +- `readable` -> 更易读、更清晰 +- `academic` -> 学术、严谨 +- `expressive` -> 更有文采、更有表现力 + +--- + +## 14. 上下文截取策略 + +## 14.1 推荐策略 + +前端传: + +- 选区前固定长度文本 +- 选区后固定长度文本 + +例如: + +- 前文 200 到 500 字 +- 后文 200 到 500 字 + +### 原因 + +- 足够帮助模型理解文气和衔接 +- 不会让请求太重 + +## 14.2 不建议 + +- 把整篇长文全量塞进去 +- 把整个线程消息都塞进改写接口 + +如果后端确实要参考线程上下文,也建议只取最近和写作相关的少量消息摘要。 + +--- + +## 15. LangGraph 接入建议 + +## 15.1 推荐接入方式 + +在现有 LangGraph / gateway 架构中新增一个写作改写专用入口。 + +建议二选一: + +### 方案 A + +新增专用 router: + +- `POST /api/writing/rewrite` + +内部调用现有模型层 / agent 层。 + +### 方案 B + +新增专用 graph node 或 tool: + +- `rewrite_selection` + +再由 router 调用该能力。 + +## 15.2 更推荐方案 + +推荐: + +- 对外暴露统一 router +- 内部走已有模型封装或 LangGraph 节点 + +这样前端接口更稳定,后续后端内部重构不会影响前端。 + +--- + +## 16. 后端模块拆解 + +## 16.1 模块 A:接口层 + +负责: + +- 请求校验 +- 错误响应 +- 参数标准化 + +需要完成: + +- 统一 rewrite API +- action / tone 校验 +- 空选区校验 + +## 16.2 模块 B:上下文拼装层 + +负责: + +- 拼装 before / selection / after +- 必要时提取线程相关信息 + +需要完成: + +- 上下文长度控制 +- 清洗空白和异常字符 + +## 16.3 模块 C:Prompt 层 + +负责: + +- 选择模板 +- 填充 action 和 tone + +需要完成: + +- 4 类动作模板 +- tone 映射 + +## 16.4 模块 D:模型调用层 + +负责: + +- 走现有模型配置体系 +- 执行大模型请求 + +需要完成: + +- 统一调用入口 +- 模型不可用错误处理 + +## 16.5 模块 E:结果清洗层 + +负责: + +- 去掉解释性前缀 +- 去掉多余包裹 +- 标准化返回 + +需要完成: + +- 输出清洗 +- metadata 填充 + +--- + +## 17. 返回结果清洗建议 + +即使 prompt 已经约束,模型仍可能输出: + +- “以下是润色后的内容:” +- “当然,这里是改写结果:” +- “优化如下:” + +建议后端加一层轻量清洗: + +- 去掉常见说明性前缀 +- 去掉包裹性 markdown 代码块 +- 去掉多余首尾空白 + +注意: + +- 清洗必须保守 +- 不要误删正文 + +--- + +## 18. 日志与观测建议 + +建议记录: + +- `threadId` +- `documentId` +- `action` +- `tone` +- `selection_length` +- `before_length` +- `after_length` +- `model_name` +- `latency_ms` +- `success / fail` + +不要直接把整段用户正文原文打到普通日志里,避免敏感信息风险。 + +--- + +## 19. 后端测试清单 + +## 19.1 单元测试 + +- action 校验 +- tone 校验 +- 空选区校验 +- prompt 选择逻辑 +- 输出清洗逻辑 + +## 19.2 集成测试 + +- `polish` +- `expand` +- `shorten` +- `tone-professional` +- `tone-casual` +- `tone-readable` +- `tone-academic` +- `tone-expressive` + +## 19.3 边界测试 + +- 选区过短 +- 选区过长 +- 前后文为空 +- 多段文本带换行 +- 模型超时 +- 模型不可用 + +--- + +## 20. 联调约束 + +## 20.1 前后端必须统一 + +- `action` 枚举值 +- `tone` 枚举值 +- 错误码 +- 返回体字段名 + +## 20.2 联调重点 + +- 多段落文本中换行保留是否正确 +- AI 返回内容是否适合直接落文档 +- 超时和失败时前端是否能优雅重试 + +## 20.3 联调建议顺序 + +1. 先 mock 返回固定文本 +2. 再接真实模型 +3. 先验证单段落 +4. 再验证多段落 +5. 最后验证大段文本 + +--- + +## 21. 优先级建议 + +### P0 + +- 统一 rewrite API +- 4 类动作支持 +- 输出纯净正文 +- 错误结构标准化 + +### P1 + +- 输出清洗增强 +- 埋点与日志 +- 上下文截断策略优化 + +### P2 + +- 更细粒度风格控制 +- 结果质量二次校验 + +--- + +## 22. 完成定义 + +后端满足以下条件即可视为本轮完成: + +- 前端能通过统一接口发起改写 +- 4 类动作均可稳定返回候选文本 +- 返回文本基本可直接用于替换或插入 +- 多段落文本能稳定处理 +- 错误结构规范统一 + +--- + +## 23. 结论 + +本轮后端最重要的,不是做复杂文档结构编辑,而是把“选区改写”做成稳定、可预测、可直接接入前端编辑器的能力。 + +最稳妥的路线是: + +- 统一接口 +- 统一动作枚举 +- 统一 prompt 模板 +- 统一错误结构 +- 统一输出约束 + +只要这层做稳,前端的 Tiptap 写作编辑器就能很顺畅地完成豆包式“选中即改、预览后应用”的核心体验。 diff --git a/frontend-web/docs/ai-writing-assistant-frontend-checklist.md b/frontend-web/docs/ai-writing-assistant-frontend-checklist.md new file mode 100644 index 00000000..3fd885ac --- /dev/null +++ b/frontend-web/docs/ai-writing-assistant-frontend-checklist.md @@ -0,0 +1,703 @@ +# AI 写作助手前端开发任务清单 + +## 1. 文档目标 + +本文档用于把《AI 写作助手右侧编辑器升级需求文档》进一步拆成前端可直接执行的任务清单。 + +目标是让前端团队按模块并行推进,最终完成: + +- 保留左侧聊天区 +- 右侧升级为 `Tiptap` 写作编辑器 +- 支持选区浮层 +- 支持润色 / 扩写 / 缩写 / 改语气 +- 支持替换 / 插入 +- 支持标题 / 列表 / 引用 / 代码块工具条 +- UI 参考豆包 + Novel + open-canvas + +--- + +## 2. 本轮前端改造范围 + +### 2.1 保留不动 + +- 左侧聊天主链路 +- 现有线程消息流 +- 现有模型选择器 +- 现有输入框的 `writing_mode` 总入口 + +### 2.2 重点改造 + +- 右侧 Artifact 面板承载方式 +- 新增独立写作工作区 +- 富文本编辑器内核 +- 选区浮层 +- AI 改写结果预览 +- 文档级工具条 + +--- + +## 3. 推荐目录结构 + +建议新增独立模块目录: + +```text +frontend-web/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 + WritingEmptyState.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/ + apply-rewrite.ts + markdown.ts + editor-style.ts +``` + +--- + +## 4. 现有代码落点 + +## 4.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 逻辑 + - 不要继续承载写作编辑器状态 + +## 4.2 不建议继续沿用的方式 + +- 不要把编辑器主状态存成 `string[] artifacts` +- 不要把右侧主体验继续建在 `artifact-file-detail.tsx` 上 +- 不要让 AI 改写结果先回聊天,再由用户手动复制 + +--- + +## 5. 任务分阶段拆解 + +## 阶段 A:路由与页面壳 + +### 目标 + +先把新的写作工作区页面立起来,让后续编辑器与交互都有落点。 + +### 任务 + +- 新增 `WritingRoutes.tsx` +- 新增 `WritingWorkspacePage.tsx` +- 在 `PageRoutes.tsx` 中挂入 `page/writing/*` +- 确认新页面进入方式 +- 确定是: + - 通过左侧聊天上下文进入 + - 通过 `writing_mode` 入口进入 + - 或二者都支持 + +### 交付物 + +- 新写作页面能被路由访问 +- 页面有基础左右布局和空态 + +### 验收 + +- 打开 `page/writing` 能进入工作区 +- 页面不报错 + +--- + +## 阶段 B:编辑器底座 + +### 目标 + +把右侧正式替换成富文本编辑器。 + +### 任务 + +- 安装 Tiptap 依赖 +- 建立 `TiptapEditor.tsx` +- 建立 `TiptapExtensions.ts` +- 配置节点: + - paragraph + - heading + - bulletList + - orderedList + - listItem + - blockquote + - codeBlock + - hardBreak +- 配置 marks: + - bold + - italic + - underline + - strike + - code +- 建立编辑器初始化逻辑 +- 建立编辑器销毁逻辑 +- 定义最小文档状态 + +### 交付物 + +- 可编辑正文区域 +- 初始文档可加载 +- 内容可读可写 + +### 验收 + +- 可以直接输入正文 +- 可以换行、加标题、切换列表 +- 不出现内容错位和明显闪烁 + +--- + +## 阶段 C:主工具栏 + +### 目标 + +右侧具备正式写作工具栏。 + +### 任务 + +- 新增 `WritingToolbar.tsx` +- 新增 `useWritingToolbar.ts` +- 实现按钮: + - 正文 + - H1 + - H2 + - H3 + - 有序列表 + - 无序列表 + - 引用 + - 代码块 + - 加粗 + - 斜体 + - 下划线 + - 删除线 +- 处理 active 状态 +- 处理不可用状态 +- 处理光标块状态联动 + +### 交付物 + +- 主工具栏可用 + +### 验收 + +- 工具条按钮能正确反映当前块状态 +- 操作后编辑器内容正确变化 + +--- + +## 阶段 D:选区状态与浮层 + +### 目标 + +实现豆包式选区浮层基础能力。 + +### 任务 + +- 新增 `useWritingSelection.ts` +- 新增 `selection.ts` +- 新增 `WritingBubbleMenu.tsx` +- 基于 Tiptap 监听 selection 变化 +- 过滤掉空选区 +- 处理多段连续选区 +- 浮层按钮: + - AI 改写 + - 加粗 + - 斜体 + - 标题 + - 复制 +- 处理滚动定位 +- 处理窗口尺寸变化 + +### 交付物 + +- 选中内容后出现浮层 + +### 验收 + +- 单段可触发 +- 多段可触发 +- 浮层位置稳定 + +--- + +## 阶段 E:AI 改写菜单 + +### 目标 + +把选区浮层接到 AI 改写工作流。 + +### 任务 + +- 新增 `WritingAiMenu.tsx` +- 新增 `useWritingRewrite.ts` +- 新增 `api/rewrite.ts` +- 实现一级动作: + - 润色 + - 扩写 + - 缩写 + - 改语气 +- 实现改语气二级菜单: + - 更专业 + - 更口语化 + - 更易读 + - 更学术 + - 更有文采 +- 封装请求入参 +- 增加 loading 态 +- 增加 error 态 +- 增加 retry 入口 + +### 交付物 + +- AI 改写菜单和请求链路 + +### 验收 + +- 4 个动作都能发请求 +- 改语气的二级菜单可正常展开 +- 请求失败时有反馈 + +--- + +## 阶段 F:候选结果预览 + +### 目标 + +把 AI 结果变成“可预览、可决策、可回退”的候选内容。 + +### 任务 + +- 新增 `WritingRewritePreview.tsx` +- 新增 `apply-rewrite.ts` +- 显示原文与候选内容 +- 提供按钮: + - 替换 + - 插入 + - 重试 + - 取消 +- 用 transaction 应用结果 +- 处理应用成功后的焦点与滚动 + +### 交付物 + +- 改写结果预览卡片或面板 + +### 验收 + +- 替换准确 +- 插入准确 +- 取消后文档保持原样 + +--- + +## 阶段 G:文档状态与容器体验 + +### 目标 + +补齐正式产品的壳层体验。 + +### 任务 + +- 新增 `WritingShell.tsx` +- 新增 `WritingHeader.tsx` +- 新增 `WritingStatusBar.tsx` +- 新增 `WritingEmptyState.tsx` +- 补充文档标题区域 +- 补充文档状态提示 +- 补充空态和加载态 + +### 交付物 + +- 页面完整壳层 + +### 验收 + +- 页面不是裸编辑器 +- 有完整的文档工作区感 + +--- + +## 阶段 H:视觉打磨 + +### 目标 + +让整体观感接近成熟产品。 + +### 任务 + +- 调整右侧阅读宽度 +- 调整字体大小和行高 +- 调整段距和标题层级 +- 调整工具栏阴影、边框、圆角 +- 调整浮层动效 +- 调整 AI 预览卡片质感 +- 优化深浅色模式兼容 + +### 交付物 + +- 完整视觉优化 + +### 验收 + +- 明显优于当前版本 +- 有豆包 / Novel 风格的编辑器质感 + +--- + +## 6. 组件级开发清单 + +## 6.1 `WritingWorkspacePage.tsx` + +职责: + +- 页面级容器 +- 获取线程 / 文档上下文 +- 组织左右布局 + +必须完成: + +- 页面初始化 +- 与左侧聊天协同 +- 右侧编辑区挂载 + +## 6.2 `WritingShell.tsx` + +职责: + +- 写作工作区总壳层 +- 布局标题区、工具栏、正文区、状态区 + +必须完成: + +- 自适应布局 +- 桌面端优先 +- 窄屏降级 + +## 6.3 `TiptapEditor.tsx` + +职责: + +- 包装 Tiptap EditorContent +- 负责 editor 实例初始化 + +必须完成: + +- `onUpdate` +- `onSelectionUpdate` +- 内容同步 + +## 6.4 `WritingToolbar.tsx` + +职责: + +- 顶部主工具栏 + +必须完成: + +- 所有基础格式化命令 +- 当前状态高亮 + +## 6.5 `WritingBubbleMenu.tsx` + +职责: + +- 选区浮层 + +必须完成: + +- 跟随选区 +- 基础快捷操作 +- AI 改写入口 + +## 6.6 `WritingAiMenu.tsx` + +职责: + +- AI 改写动作菜单 + +必须完成: + +- 一级菜单 +- 改语气二级菜单 +- 动作触发 + +## 6.7 `WritingRewritePreview.tsx` + +职责: + +- 展示候选内容 + +必须完成: + +- 替换 +- 插入 +- 重试 +- 取消 + +--- + +## 7. Hook 级开发清单 + +## 7.1 `useWritingEditor.ts` + +负责: + +- editor 生命周期 +- 初始内容装载 +- 内容变更同步 + +## 7.2 `useWritingSelection.ts` + +负责: + +- 当前选区抽取 +- 选区文本缓存 +- 多段落纯文本拼接 + +## 7.3 `useWritingRewrite.ts` + +负责: + +- 改写请求 +- loading / success / error +- 结果缓存 +- 重试 + +## 7.4 `useWritingToolbar.ts` + +负责: + +- toolbar active 状态 +- editor command 映射 + +--- + +## 8. API 对接清单 + +前端需向后端约定以下接口能力: + +- `POST /api/writing/rewrite` + +前端请求内容至少包括: + +- `threadId` +- `documentId` +- `selection.from` +- `selection.to` +- `selection.text` +- `action` +- `tone` +- `surroundingContext.before` +- `surroundingContext.after` + +前端需处理的返回字段: + +- `output` +- `originalSelection` +- `metadata` + +--- + +## 9. 状态管理建议 + +建议新增独立 Context: + +- `WritingEditorContext.tsx` + +建议持有: + +- 当前文档内容 +- 当前 editor 实例 +- 当前选区 +- 当前改写请求状态 +- 当前候选结果 +- 当前 UI 面板状态 + +不建议继续复用旧 Artifact Context 的原因: + +- 旧 Context 关注文件列表和文件路径 +- 新编辑器关注选区、结构、候选结果、应用动作 +- 关注点完全不同 + +--- + +## 10. 前端联调检查点 + +## 10.1 与后端联调前 + +- 先用 mock 数据打通浮层和预览 +- 先验证替换 / 插入逻辑 + +## 10.2 与后端联调时 + +- 检查多段落选区拼接结果 +- 检查 AI 返回内容是否带说明性前缀 +- 检查替换后位置是否准确 + +## 10.3 联调后 + +- 验证大段文本性能 +- 验证撤销 / 重做 +- 验证快速连续触发是否会状态错乱 + +--- + +## 11. 前端测试清单 + +## 11.1 功能测试 + +- 输入正文 +- 插入标题 +- 切换列表 +- 插入引用 +- 插入代码块 +- 加粗 / 斜体 / 下划线 / 删除线 +- 选区浮层显示 +- 选区浮层隐藏 +- AI 改写菜单打开 +- 改语气二级菜单打开 +- 改写结果替换 +- 改写结果插入 +- 改写结果取消 + +## 11.2 场景测试 + +- 单段短文本润色 +- 多段文本润色 +- 多段文本扩写 +- 多段文本缩写 +- 多段文本改语气 +- 连续两次改写同一段 +- 快速切换线程后重新进入 + +## 11.3 回归测试 + +- 左侧聊天是否正常 +- 模型切换是否正常 +- `writing_mode` 是否正常 +- 原有 artifact 模块是否仍可使用 + +--- + +## 12. 任务优先级 + +### P0 + +- 路由与页面壳 +- Tiptap 接入 +- 主工具栏 +- 选区浮层 +- 改写菜单 +- 替换 / 插入 + +### P1 + +- 页面头部与状态 +- 优雅 loading / error / retry +- 多段落稳定性 +- UI 打磨 + +### P2 + +- 空态优化 +- 动效优化 +- 快捷键支持 + +--- + +## 13. 建议分工 + +### 前端 1 号 + +负责: + +- 路由与页面壳 +- Tiptap 接入 +- 主工具栏 + +### 前端 2 号 + +负责: + +- 选区状态 +- BubbleMenu +- AI 菜单 + +### 前端 3 号 + +负责: + +- 候选结果预览 +- 替换 / 插入 +- 状态栏与页面体验 + +### 联调负责人 + +负责: + +- 前后端请求协议 +- 错误态规范 +- 多段落测试和回归 + +--- + +## 14. 前端完成定义 + +满足以下条件可视为前端完成: + +- 右侧能作为正式编辑器独立使用 +- 选区后可直接发起 AI 改写 +- 改写后可替换或插入 +- 视觉上明显优于当前版本 +- 左侧聊天和现有系统不被破坏 + +--- + +## 15. 下一步建议 + +前端团队可以按以下顺序开工: + +1. 先起页面和路由 +2. 再接 Tiptap 与主工具栏 +3. 再做选区浮层 +4. 再接 AI 菜单和结果预览 +5. 最后做视觉打磨 + +这个顺序风险最小,也最容易在中途验收。 diff --git a/frontend-web/docs/ai-writing-assistant-source-map.md b/frontend-web/docs/ai-writing-assistant-source-map.md new file mode 100644 index 00000000..0dbbd7f6 --- /dev/null +++ b/frontend-web/docs/ai-writing-assistant-source-map.md @@ -0,0 +1,457 @@ +# 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 现有路由、线程、模型体系做宿主 + +这样推进,既不会脱离你们现有工程,也能尽量快地把右侧编辑区拉到更接近成熟产品的水平。 diff --git a/frontend-web/docs/ai-writing-assistant-upgrade.md b/frontend-web/docs/ai-writing-assistant-upgrade.md new file mode 100644 index 00000000..a8ffcf1d --- /dev/null +++ b/frontend-web/docs/ai-writing-assistant-upgrade.md @@ -0,0 +1,1191 @@ +# 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 的成熟交互 + +只要按照本文档分阶段推进,这个需求虽然大,但完全可以拆成多组并行、逐步验收、持续落地的工程任务,而不是一次性大爆炸改造。