951 lines
20 KiB
Markdown
951 lines
20 KiB
Markdown
# Open Canvas 模式需求拆解文档
|
||
|
||
## 1. 文档目标
|
||
|
||
本文档用于指导 DeerFlow 在现有架构中新增一个 `open-canvas` 风格的 Canvas 模式。
|
||
|
||
目标不是直接照搬 `langchain-ai/open-canvas` 的 Next.js + LangGraph.js 实现,而是在当前项目技术栈内完成一套等价能力的实现:
|
||
|
||
- 前端:基于 `React 19 + Vite + react-router-dom`
|
||
- 后端:基于 `Python + FastAPI + LangGraph`
|
||
- 模型层:支持云模型与本地模型自由配置
|
||
- 状态层:支持结构化 artifact、版本历史、局部改写、快速动作、画布编辑
|
||
|
||
本文档重点是把需求拆成“可实现、可排期、可验收”的阶段性任务。
|
||
|
||
---
|
||
|
||
## 2. 最终目标
|
||
|
||
### 2.1 用户视角目标
|
||
|
||
用户进入一个新的 Canvas 工作模式后,可以获得与 open-canvas 接近的体验:
|
||
|
||
- 左侧是聊天区,右侧是 Canvas 编辑区
|
||
- 可以从空白文本或代码模板快速开始
|
||
- 可以通过聊天让 AI 生成一份结构化 artifact
|
||
- 可以对 artifact 整体重写,也可以对选中的局部内容进行改写
|
||
- artifact 支持版本历史切换
|
||
- artifact 支持文本和代码两种主要类型
|
||
- 支持快速动作,例如扩写、压缩、改风格、改语气、加注释、修 bug、换语言
|
||
- 支持启用 Web 搜索增强
|
||
- 支持切换模型
|
||
- 支持使用本地模型,例如 Ollama 或 OpenAI-compatible 本地服务
|
||
|
||
### 2.2 工程视角目标
|
||
|
||
新增的 Canvas 模式需要满足以下工程原则:
|
||
|
||
- 不破坏现有 DeerFlow 工作区
|
||
- 不影响现有基于 `artifacts: string[]` 的文件产物功能
|
||
- 可逐阶段上线
|
||
- 前后端状态协议清晰
|
||
- 可兼容现有 LangGraph 线程、消息流、认证和模型接口
|
||
|
||
---
|
||
|
||
## 3. 范围定义
|
||
|
||
### 3.1 本次需求包含
|
||
|
||
- 前端新增 `open-canvas` 专用目录
|
||
- 在 [PageRoutes.tsx](../src/pages/PageRoutes.tsx) 中引入新的 Canvas 路由
|
||
- 前端新增 Canvas 页面、上下文、组件、状态管理
|
||
- 后端新增 Canvas 专用线程状态字段
|
||
- 后端新增 Canvas Agent 图或在现有 Agent 体系中新增 Canvas 模式分支
|
||
- 模型配置统一为 DeerFlow 后端配置驱动
|
||
- 支持本地大模型配置与模型列表动态下发
|
||
- 支持结构化 artifact 的保存、读取、更新、版本切换
|
||
|
||
### 3.2 本次需求不包含
|
||
|
||
- 一次性复刻 open-canvas 全部 UI 细节
|
||
- 完整照搬 Supabase 鉴权体系
|
||
- 直接复用 open-canvas 的 Next.js API Route
|
||
- 直接运行 open-canvas 的 LangGraph.js 后端
|
||
- 首阶段就实现所有快捷动作、所有富文本效果、所有搜索增强能力
|
||
|
||
### 3.3 迁移原则
|
||
|
||
- 借鉴 open-canvas 的能力模型,不直接迁移其运行时架构
|
||
- 前端尽量复用其交互设计和数据结构
|
||
- 后端以 Python 实现同等能力
|
||
- 配置以 DeerFlow 为真源,不以 open-canvas 的 TS 文件为真源
|
||
|
||
---
|
||
|
||
## 4. 总体设计思路
|
||
|
||
### 4.1 前端设计思路
|
||
|
||
在现有 `frontend-web/src` 下新增一个专用目录,例如:
|
||
|
||
```text
|
||
src/
|
||
open-canvas/
|
||
pages/
|
||
routes/
|
||
components/
|
||
contexts/
|
||
hooks/
|
||
types/
|
||
api/
|
||
utils/
|
||
constants/
|
||
```
|
||
|
||
建议将 Canvas 模式作为一个独立的页面子系统接入,而不是把现有工作区页面强行改造成 Canvas。
|
||
|
||
建议路由形式:
|
||
|
||
- `/canvas`
|
||
- `/canvas/:threadId`
|
||
|
||
也可以挂在现有页面布局下,例如:
|
||
|
||
- `/workspace/canvas`
|
||
- `/workspace/canvas/:threadId`
|
||
|
||
推荐优先采用独立一级功能路由:
|
||
|
||
- 逻辑更清晰
|
||
- 状态隔离更容易
|
||
- 不容易污染现有 `workspace` 功能
|
||
|
||
### 4.2 后端设计思路
|
||
|
||
后端不建议直接改造现有通用 Agent 去同时承担全部 Canvas 行为,而是建议采用以下两种方案之一:
|
||
|
||
#### 方案 A:新增独立 Canvas Assistant
|
||
|
||
- 新增 `canvas_agent`
|
||
- 使用单独的 LangGraph 状态定义
|
||
- 前端调用时通过 `assistant_id=canvas_agent`
|
||
|
||
优点:
|
||
|
||
- 与现有 `lead_agent` 隔离
|
||
- 风险更低
|
||
- 更容易对齐 open-canvas 的图结构
|
||
|
||
缺点:
|
||
|
||
- 会产生一套新的 Agent 图维护成本
|
||
|
||
#### 方案 B:在现有 Lead Agent 中增加 Canvas 模式分支
|
||
|
||
- 在 thread metadata 或 configurable 中增加 `ui_mode=canvas`
|
||
- Agent 根据模式进入 Canvas 路径
|
||
|
||
优点:
|
||
|
||
- 统一入口
|
||
|
||
缺点:
|
||
|
||
- 会显著增加现有 Agent 复杂度
|
||
- 容易影响现有聊天和文件产物模式
|
||
|
||
推荐先做方案 A。
|
||
|
||
### 4.3 模型配置设计思路
|
||
|
||
模型配置统一以 DeerFlow 后端 `config.yaml` 为真源。
|
||
|
||
前端不维护固定模型常量列表,而是通过 `/api/models` 获取模型能力元数据。
|
||
|
||
为了实现 open-canvas 风格体验,需要后端模型接口至少返回:
|
||
|
||
- `name`
|
||
- `display_name`
|
||
- `provider`
|
||
- `supports_thinking`
|
||
- `supports_reasoning_effort`
|
||
- `supports_vision`
|
||
- `supports_tool_calling`
|
||
- `supports_artifact_editing`
|
||
- `supports_code_editing`
|
||
- `temperature_range`
|
||
- `max_tokens_range`
|
||
- `base_url_source` 或 provider 标识
|
||
- `is_local`
|
||
|
||
---
|
||
|
||
## 5. 与当前项目的关键差异
|
||
|
||
### 5.1 当前 DeerFlow 现状
|
||
|
||
当前 DeerFlow 线程状态中的 artifact 主要是文件路径列表:
|
||
|
||
- `artifacts: string[]`
|
||
|
||
这更接近“生成文件产物”的工作模式。
|
||
|
||
前端当前 artifact 面板也主要是:
|
||
|
||
- 文件列表
|
||
- 文件详情
|
||
- 文件下载/预览
|
||
|
||
### 5.2 open-canvas 的关键能力
|
||
|
||
open-canvas 的核心不是“生成文件”,而是“维护一个结构化的当前文档对象”:
|
||
|
||
- 一个 conversation 对应一个主 artifact
|
||
- artifact 具有类型、标题、内容、版本
|
||
- 用户可以选中部分内容让 AI 改写
|
||
- 每次改写都会生成新版本
|
||
|
||
### 5.3 需要新增的核心能力
|
||
|
||
为支持 Canvas 模式,需要在 DeerFlow 中新增一套结构化 artifact 状态:
|
||
|
||
- 当前 artifact
|
||
- 当前版本索引
|
||
- 历史版本列表
|
||
- 选区信息
|
||
- 当前编辑模式
|
||
- 快速动作状态
|
||
- Web 搜索结果状态
|
||
|
||
---
|
||
|
||
## 6. 分阶段实施方案
|
||
|
||
以下为推荐的 8 个阶段,每个阶段都可单独开发、联调和验收。
|
||
|
||
---
|
||
|
||
## 7. 阶段一:前端路由与目录骨架
|
||
|
||
### 7.1 目标
|
||
|
||
在不影响现有页面的前提下,建立 Canvas 模式的前端骨架。
|
||
|
||
### 7.2 需求
|
||
|
||
- 新增 `src/open-canvas/` 目录
|
||
- 新增 Canvas 页面路由
|
||
- 将路由接入 [PageRoutes.tsx](../src/pages/PageRoutes.tsx)
|
||
- 提供 Canvas 首页和 Canvas Thread 页
|
||
- 支持空状态展示
|
||
|
||
### 7.3 建议目录
|
||
|
||
```text
|
||
src/open-canvas/
|
||
api/
|
||
threads.ts
|
||
runs.ts
|
||
models.ts
|
||
components/
|
||
layout/
|
||
chat/
|
||
canvas/
|
||
artifacts/
|
||
quick-actions/
|
||
selectors/
|
||
contexts/
|
||
CanvasThreadContext.tsx
|
||
CanvasGraphContext.tsx
|
||
CanvasUIContext.tsx
|
||
hooks/
|
||
useCanvasThread.ts
|
||
useCanvasStream.ts
|
||
useCanvasArtifact.ts
|
||
pages/
|
||
CanvasHomePage.tsx
|
||
CanvasThreadPage.tsx
|
||
routes/
|
||
OpenCanvasRoutes.tsx
|
||
types/
|
||
artifact.ts
|
||
thread.ts
|
||
model.ts
|
||
utils/
|
||
artifact.ts
|
||
selection.ts
|
||
stream.ts
|
||
constants/
|
||
index.ts
|
||
```
|
||
|
||
### 7.4 路由建议
|
||
|
||
- 在 `PageRoutes.tsx` 中新增 `canvas/*`
|
||
- 在 `src/open-canvas/routes/OpenCanvasRoutes.tsx` 中维护子路由
|
||
|
||
建议形式:
|
||
|
||
```text
|
||
/canvas
|
||
/canvas/:threadId
|
||
```
|
||
|
||
### 7.5 验收标准
|
||
|
||
- 能访问 Canvas 首页
|
||
- 能访问指定 thread 的 Canvas 页面
|
||
- 不影响现有 `workspace/*` 与 `strategy/*`
|
||
- 页面有独立布局骨架
|
||
|
||
---
|
||
|
||
## 8. 阶段二:前端 Canvas 布局与交互容器
|
||
|
||
### 8.1 目标
|
||
|
||
先做出“左聊天、右画布”的基础容器,不接真实 AI 改写逻辑。
|
||
|
||
### 8.2 需求
|
||
|
||
- 左侧聊天区
|
||
- 右侧画布区
|
||
- 支持面板拖拽或折叠
|
||
- 初始空状态
|
||
- 支持“快速开始”:
|
||
- 新建空白文本 artifact
|
||
- 新建代码 artifact
|
||
|
||
### 8.3 组件拆分建议
|
||
|
||
- `CanvasShell`
|
||
- `CanvasSidebar`
|
||
- `CanvasChatPanel`
|
||
- `CanvasArtifactPanel`
|
||
- `CanvasEmptyState`
|
||
- `QuickStartActions`
|
||
|
||
### 8.4 快速开始能力
|
||
|
||
用户进入空线程时可以选择:
|
||
|
||
- 开始写文章
|
||
- 开始写代码
|
||
- 从模板开始
|
||
|
||
首版模板可只做最小集:
|
||
|
||
- 空白文档
|
||
- HTML 模板
|
||
- React 组件模板
|
||
- Python 脚本模板
|
||
|
||
### 8.5 验收标准
|
||
|
||
- 页面可稳定展示双栏布局
|
||
- 快速开始能创建前端本地 artifact 状态
|
||
- 代码和文本可分别进入不同渲染器
|
||
|
||
---
|
||
|
||
## 9. 阶段三:结构化 Artifact 数据模型
|
||
|
||
### 9.1 目标
|
||
|
||
定义 DeerFlow 的 Canvas Artifact 协议,作为前后端统一契约。
|
||
|
||
### 9.2 核心要求
|
||
|
||
需要支持以下能力:
|
||
|
||
- 文本 artifact
|
||
- 代码 artifact
|
||
- 标题
|
||
- 当前版本索引
|
||
- 版本历史
|
||
- 当前选中版本切换
|
||
- 后续支持局部高亮编辑
|
||
|
||
### 9.3 建议数据结构
|
||
|
||
```ts
|
||
type CanvasArtifact = {
|
||
currentIndex: number;
|
||
contents: Array<CanvasArtifactText | CanvasArtifactCode>;
|
||
};
|
||
|
||
type CanvasArtifactText = {
|
||
index: number;
|
||
type: "text";
|
||
title: string;
|
||
fullMarkdown: string;
|
||
};
|
||
|
||
type CanvasArtifactCode = {
|
||
index: number;
|
||
type: "code";
|
||
title: string;
|
||
language: string;
|
||
code: string;
|
||
};
|
||
```
|
||
|
||
### 9.4 线程状态建议新增字段
|
||
|
||
前端与后端需共同支持:
|
||
|
||
- `artifact`
|
||
- `highlighted_text`
|
||
- `highlighted_code`
|
||
- `canvas_mode`
|
||
- `web_search_enabled`
|
||
- `web_search_results`
|
||
- `quick_action_id`
|
||
|
||
### 9.5 与现有 `artifacts: string[]` 的关系
|
||
|
||
建议保留现有 `artifacts: string[]` 不动。
|
||
|
||
新增字段:
|
||
|
||
- `artifact` 用于 Canvas 主文档
|
||
- `artifacts` 继续用于文件产物
|
||
|
||
这样可以兼容未来“Canvas 生成网页文件、导出文件、保存文件”的场景。
|
||
|
||
### 9.6 验收标准
|
||
|
||
- 前端类型定义完成
|
||
- 后端状态字段设计完成
|
||
- 确认与现有线程状态兼容
|
||
|
||
---
|
||
|
||
## 10. 阶段四:后端线程状态与 API 扩展
|
||
|
||
### 10.1 目标
|
||
|
||
让后端线程状态可以安全存储和返回 Canvas Artifact。
|
||
|
||
### 10.2 需求
|
||
|
||
- 扩展 Python `ThreadState`
|
||
- 扩展状态序列化逻辑
|
||
- 确保 `/api/threads/*` 返回结构化 `artifact`
|
||
- 确保 LangGraph 流中可带上 `artifact` 更新
|
||
|
||
### 10.3 后端改造点
|
||
|
||
建议关注以下模块:
|
||
|
||
- `packages/harness/deerflow/agents/thread_state.py`
|
||
- 线程 state serializer
|
||
- `app/gateway/routers/threads.py`
|
||
- 流事件适配层
|
||
|
||
### 10.4 注意事项
|
||
|
||
- 旧线程没有 `artifact` 字段时必须兼容
|
||
- 状态更新不能破坏现有消息结构
|
||
- 必须确保 JSON 可序列化
|
||
|
||
### 10.5 验收标准
|
||
|
||
- 新建线程可写入 `artifact`
|
||
- 读取线程时可返回 `artifact`
|
||
- 不影响现有线程读取
|
||
- 前端能从线程 state 中恢复 Canvas 内容
|
||
|
||
---
|
||
|
||
## 11. 阶段五:Canvas 专用 Agent 图
|
||
|
||
### 11.1 目标
|
||
|
||
实现与 open-canvas 类似的 AI 路由能力。
|
||
|
||
### 11.2 推荐方案
|
||
|
||
新增 `canvas_agent`,单独维护图逻辑。
|
||
|
||
### 11.3 节点拆分建议
|
||
|
||
首版建议至少拆成这些节点:
|
||
|
||
- `route_user_intent`
|
||
- `reply_general_input`
|
||
- `generate_artifact`
|
||
- `rewrite_artifact`
|
||
- `update_highlighted_text`
|
||
- `update_highlighted_code`
|
||
- `generate_followup`
|
||
|
||
二期可加:
|
||
|
||
- `rewrite_artifact_theme`
|
||
- `rewrite_code_theme`
|
||
- `change_length`
|
||
- `change_reading_level`
|
||
- `translate_artifact`
|
||
- `add_comments`
|
||
- `add_logs`
|
||
- `fix_bugs`
|
||
- `port_language`
|
||
- `web_search_enrich`
|
||
|
||
### 11.4 路由逻辑要求
|
||
|
||
系统需要能判断:
|
||
|
||
- 用户是在闲聊
|
||
- 用户要新生成 artifact
|
||
- 用户要整体重写当前 artifact
|
||
- 用户要局部修改当前 artifact
|
||
- 用户要执行某个快捷动作
|
||
|
||
### 11.5 状态输入要求
|
||
|
||
节点需要读取:
|
||
|
||
- 当前消息历史
|
||
- 当前 artifact
|
||
- 当前选区
|
||
- 当前模型配置
|
||
- Web 搜索开关
|
||
|
||
### 11.6 输出要求
|
||
|
||
节点输出必须能更新:
|
||
|
||
- `messages`
|
||
- `artifact`
|
||
- `web_search_results`
|
||
- `followup`
|
||
|
||
### 11.7 验收标准
|
||
|
||
- 能根据输入创建新 artifact
|
||
- 能根据输入整体改写 artifact
|
||
- 能保留版本历史
|
||
- 能在改写后返回自然语言 followup
|
||
|
||
---
|
||
|
||
## 12. 阶段六:前端流式同步与版本管理
|
||
|
||
### 12.1 目标
|
||
|
||
让前端能像 open-canvas 一样在流式过程中更新画布与聊天。
|
||
|
||
### 12.2 需求
|
||
|
||
- 复用现有 LangGraph stream client
|
||
- 在 Canvas 模式中解析 `artifact` 更新
|
||
- 支持流式文本更新
|
||
- 支持版本切换
|
||
- 支持断线后恢复线程状态
|
||
|
||
### 12.3 前端状态层建议
|
||
|
||
- `CanvasThreadContext`:线程基础信息
|
||
- `CanvasGraphContext`:消息、artifact、streaming 状态
|
||
- `CanvasUIContext`:面板、编辑态、选中态
|
||
|
||
### 12.4 关键能力
|
||
|
||
- 当前版本切换
|
||
- 新版本创建后自动定位到最新版本
|
||
- 手动编辑内容后保存
|
||
- 流结束后线程状态持久化
|
||
|
||
### 12.5 验收标准
|
||
|
||
- 发送消息时聊天和画布可同步更新
|
||
- 版本数会增加
|
||
- 切换历史版本稳定
|
||
- 刷新页面后线程状态能恢复
|
||
|
||
---
|
||
|
||
## 13. 阶段七:局部选区改写
|
||
|
||
### 13.1 目标
|
||
|
||
实现 Canvas 模式最关键的差异化能力之一:选中局部内容进行 AI 改写。
|
||
|
||
### 13.2 文本选区需求
|
||
|
||
- 支持在 Markdown 文本中选择一段文本
|
||
- 记录选区位置与原始文本
|
||
- 用户发出修改请求后,仅重写该选区
|
||
- 将选区结果合并为新版本 artifact
|
||
|
||
### 13.3 代码选区需求
|
||
|
||
- 支持在代码编辑器中选择一段代码
|
||
- 记录 start/end index 或行列信息
|
||
- AI 只返回替换片段
|
||
- 前端或后端负责将新片段拼接回完整代码
|
||
|
||
### 13.4 实现建议
|
||
|
||
首版建议:
|
||
|
||
- 文本:前端记录纯文本字符位置
|
||
- 代码:使用 CodeMirror selection 信息
|
||
|
||
不建议首版就做复杂块级富文本局部编辑。
|
||
|
||
### 13.5 风险
|
||
|
||
- Markdown 渲染态与源码态位置映射复杂
|
||
- 富文本块级位置难维护
|
||
- 流式更新中选区同步容易错位
|
||
|
||
### 13.6 首版折中方案
|
||
|
||
首版文本只基于 `fullMarkdown` 纯文本改写,不做 BlockNote 富文本块定位。
|
||
|
||
### 13.7 验收标准
|
||
|
||
- 文本局部改写成功
|
||
- 代码局部改写成功
|
||
- 原内容未改动部分保持不变
|
||
- 新版本正确入历史
|
||
|
||
---
|
||
|
||
## 14. 阶段八:快捷动作系统
|
||
|
||
### 14.1 目标
|
||
|
||
实现 open-canvas 风格的快捷动作体系。
|
||
|
||
### 14.2 首批推荐动作
|
||
|
||
文本类:
|
||
|
||
- 扩写
|
||
- 精简
|
||
- 改正式语气
|
||
- 改口语语气
|
||
- 改阅读难度
|
||
- 翻译
|
||
|
||
代码类:
|
||
|
||
- 加注释
|
||
- 加日志
|
||
- 修复 bug
|
||
- 优化代码
|
||
- 转换语言
|
||
|
||
### 14.3 设计方式
|
||
|
||
快捷动作不要直接写死在 UI,建议配置化:
|
||
|
||
- `id`
|
||
- `label`
|
||
- `type`
|
||
- `applicable_to`
|
||
- `prompt_template`
|
||
|
||
### 14.4 后端设计
|
||
|
||
快捷动作可通过:
|
||
|
||
- 前端传 `quick_action_id`
|
||
- 后端路由节点根据动作 id 选择 prompt
|
||
|
||
### 14.5 验收标准
|
||
|
||
- 文本动作可执行
|
||
- 代码动作可执行
|
||
- 结果进入新版本
|
||
- 不同动作提示词可扩展
|
||
|
||
---
|
||
|
||
## 15. 阶段九:模型配置统一与本地模型支持
|
||
|
||
### 15.1 目标
|
||
|
||
让 Canvas 模式支持和主系统统一的模型选择,并且能自由配置本地大模型。
|
||
|
||
### 15.2 原则
|
||
|
||
- 后端 `config.yaml` 为真源
|
||
- 前端只展示后端暴露的模型信息
|
||
- 不维护一份脱离后端的前端常量模型表
|
||
|
||
### 15.3 本地模型支持范围
|
||
|
||
建议优先支持两类:
|
||
|
||
- `Ollama`
|
||
- OpenAI-compatible 本地服务
|
||
- LM Studio
|
||
- vLLM
|
||
- LocalAI
|
||
- one-api 风格代理
|
||
|
||
### 15.4 后端配置建议
|
||
|
||
后端模型配置应至少支持:
|
||
|
||
- `name`
|
||
- `display_name`
|
||
- `use`
|
||
- `model`
|
||
- `api_key`
|
||
- `base_url`
|
||
- `supports_vision`
|
||
- `supports_thinking`
|
||
- `supports_tool_calling`
|
||
- `is_local`
|
||
- `canvas_capabilities`
|
||
|
||
### 15.5 Canvas 模式额外要求
|
||
|
||
由于不是所有模型都适合 Canvas 改写任务,建议增加能力标识:
|
||
|
||
- `supports_canvas_generation`
|
||
- `supports_canvas_rewrite`
|
||
- `supports_canvas_code_edit`
|
||
- `supports_streaming_text`
|
||
- `supports_streaming_tool_calls`
|
||
|
||
### 15.6 与 open-canvas 的关系
|
||
|
||
可以借鉴其命名习惯和能力分层,但不建议直接依赖其 `packages/shared/src/models.ts` 作为配置源。
|
||
|
||
### 15.7 验收标准
|
||
|
||
- 前端模型选择器可显示后端返回模型
|
||
- 可切换本地模型
|
||
- Canvas 模式能用本地模型生成和改写
|
||
|
||
---
|
||
|
||
## 16. 阶段十:Web 搜索增强
|
||
|
||
### 16.1 目标
|
||
|
||
实现类似 open-canvas 的可选 Web 搜索增强。
|
||
|
||
### 16.2 需求
|
||
|
||
- UI 提供 Web 搜索开关
|
||
- 后端在需要时走搜索节点
|
||
- 搜索结果写入线程状态
|
||
- 结果可在画布旁侧栏展示
|
||
|
||
### 16.3 首版建议
|
||
|
||
只做:
|
||
|
||
- 开关
|
||
- 搜索结果列表
|
||
- 搜索结果用于生成 artifact
|
||
|
||
暂不做复杂网页抓取编辑链路。
|
||
|
||
### 16.4 验收标准
|
||
|
||
- 打开搜索后可返回搜索结果
|
||
- 搜索结果可参与 artifact 生成
|
||
- 结果展示不阻塞主画布
|
||
|
||
---
|
||
|
||
## 17. 阶段十一:持久化、导出与文件产物联动
|
||
|
||
### 17.1 目标
|
||
|
||
让 Canvas 文档与 DeerFlow 原有文件能力协同。
|
||
|
||
### 17.2 需求
|
||
|
||
- artifact 持久化在线程 state 中
|
||
- 可手动导出为文件
|
||
- 可生成真实 HTML/Markdown/代码文件到现有 outputs
|
||
- Canvas artifact 与 `artifacts: string[]` 可双向关联
|
||
|
||
### 17.3 推荐能力
|
||
|
||
- 导出 Markdown
|
||
- 导出代码文件
|
||
- 另存为 artifact file
|
||
- 从 artifact file 回填到 Canvas
|
||
|
||
### 17.4 验收标准
|
||
|
||
- 当前版本可导出
|
||
- 导出文件可在现有文件面板查看
|
||
- 文件型 artifact 和 Canvas artifact 能共存
|
||
|
||
---
|
||
|
||
## 18. 推荐开发顺序
|
||
|
||
建议严格按以下顺序推进:
|
||
|
||
1. 路由和目录骨架
|
||
2. Canvas 页面布局
|
||
3. 前端 artifact 数据模型
|
||
4. 后端线程状态扩展
|
||
5. 新建 Canvas Agent 图
|
||
6. 前后端流式同步
|
||
7. 整体生成与整体改写
|
||
8. 局部选区改写
|
||
9. 快捷动作
|
||
10. 本地模型支持完善
|
||
11. Web 搜索增强
|
||
12. 导出与文件联动
|
||
|
||
不要先做局部改写和快捷动作,否则前面的状态与路由契约不稳定,返工会很多。
|
||
|
||
---
|
||
|
||
## 19. 里程碑定义
|
||
|
||
### M1:页面可进入
|
||
|
||
- 路由接通
|
||
- 双栏布局完成
|
||
- 本地 mock artifact 可渲染
|
||
|
||
### M2:后端状态打通
|
||
|
||
- 线程可保存结构化 artifact
|
||
- 页面刷新后能恢复
|
||
|
||
### M3:AI 生成可用
|
||
|
||
- 可新建文本/代码 artifact
|
||
- 可整体改写
|
||
- 可产生版本历史
|
||
|
||
### M4:核心体验可用
|
||
|
||
- 选区改写可用
|
||
- 快捷动作可用
|
||
- 模型切换可用
|
||
|
||
### M5:增强能力完整
|
||
|
||
- 本地模型支持完善
|
||
- Web 搜索增强
|
||
- 导出和文件联动
|
||
|
||
---
|
||
|
||
## 20. 风险与难点
|
||
|
||
### 20.1 最大难点
|
||
|
||
- 结构化 artifact 状态从无到有
|
||
- 局部选区改写的精确性
|
||
- 流式状态与版本管理的一致性
|
||
- 不破坏现有 DeerFlow 文件型 artifact 体系
|
||
|
||
### 20.2 技术风险
|
||
|
||
- 线程 state JSON 结构过大
|
||
- 大模型对局部改写指令遵循不稳定
|
||
- 本地模型 tool calling 与流式能力差异大
|
||
- 文本渲染态与源码态位置映射复杂
|
||
|
||
### 20.3 规避建议
|
||
|
||
- 首版只支持 Markdown 源码态编辑,不做复杂富文本编辑
|
||
- 首版只支持文本和代码两种 artifact 类型
|
||
- 首版先做整体生成和整体改写,再做局部改写
|
||
- 本地模型先支持“能生成、能重写”的最小能力,不强求与顶级闭源模型完全同效
|
||
|
||
---
|
||
|
||
## 21. 验收总清单
|
||
|
||
### 21.1 前端
|
||
|
||
- 有独立 Canvas 路由
|
||
- 有专用目录和模块边界
|
||
- 双栏布局可用
|
||
- 文本和代码两类 artifact 可渲染
|
||
- 历史版本可切换
|
||
- 选区改写可交互
|
||
- 快捷动作可触发
|
||
- 模型可切换
|
||
|
||
### 21.2 后端
|
||
|
||
- 线程状态支持 `artifact`
|
||
- 新增 `canvas_agent` 或等价模式
|
||
- 生成、重写、局部改写可用
|
||
- 流式返回稳定
|
||
- 模型列表接口支持 Canvas 能力元数据
|
||
|
||
### 21.3 本地模型
|
||
|
||
- 可配置 Ollama
|
||
- 可配置 OpenAI-compatible 本地服务
|
||
- 前端可见并可切换
|
||
- 至少能完成文本生成和整体改写
|
||
|
||
---
|
||
|
||
## 22. 推荐首版最小可交付范围
|
||
|
||
如果要控制风险,建议首版只交付以下内容:
|
||
|
||
- 新增 `canvas/*` 路由
|
||
- 双栏布局
|
||
- 结构化 `artifact`
|
||
- `canvas_agent`
|
||
- 文本/代码 artifact 新建
|
||
- 整体生成
|
||
- 整体改写
|
||
- 历史版本切换
|
||
- 后端模型动态加载
|
||
- Ollama 或本地 OpenAI-compatible 至少一种可用
|
||
|
||
先不要把以下内容放进首版强制目标:
|
||
|
||
- 富文本块级精确编辑
|
||
- 全量快捷动作
|
||
- 复杂 Web 搜索增强
|
||
- 多 artifact 并行管理
|
||
|
||
---
|
||
|
||
## 23. 后续实施建议
|
||
|
||
建议下一步基于本文档继续输出两份落地文档:
|
||
|
||
### 23.1 前端实施清单
|
||
|
||
逐文件列出:
|
||
|
||
- 要新建哪些文件
|
||
- 哪些组件可复用
|
||
- 哪些页面要接入路由
|
||
- 哪些状态要从现有 hooks 抽离
|
||
|
||
### 23.2 后端实施清单
|
||
|
||
逐模块列出:
|
||
|
||
- 要改哪些 Python 文件
|
||
- 新增哪些状态字段
|
||
- 新增哪些 Agent 节点
|
||
- 哪些 API 需要扩展
|
||
|
||
---
|
||
|
||
## 24. 结论
|
||
|
||
这个需求很大,但完全可拆。
|
||
|
||
正确做法不是“先抄 UI”,而是按下面的主线推进:
|
||
|
||
- 先建前端 Canvas 子系统
|
||
- 再建结构化 artifact 状态
|
||
- 再建 Canvas Agent 图
|
||
- 再补局部改写和快捷动作
|
||
- 最后统一本地模型能力
|
||
|
||
只要按本文档阶段推进,这个需求是可以落地的,而且能和你现在的 DeerFlow 架构保持长期兼容。
|