Files
mnote/design/ai-agent-platform-v1.md
T
2026-01-11 12:35:53 +08:00

345 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Agent 平台 v1(把 Wolai 当成“Web 版 VSCode + Cline”来做)
> 目标:不只在思维导图里,而是在**主编辑区(BlockNote**、**OnlyOffice**、**思维导图**三处都能使用同一套“会用工具做事”的 AI。
>
> 我们把当前项目类比为 VSCode:
> - UI 里有一个统一的 Chat 面板(像 VSCode Chat / Cline Webview
> - AI 不是“输出一段文本”,而是能调用工具(像 Cline 的工具 + VSCode 的 languageModelTools
> - 工具调用可追溯、可控(权限/确认/日志),且可扩展(MCP / 内置工具 / 用户自定义)
---
## 0. 现状与痛点(为什么现在“不智能”)
当前项目的 AI 主要集中在 mindmap 相关 Next Route + 面板:
- `wolai-frontend/src/app/api/mindmap-ai/*`:PDF 大纲生成导图、补完节点、agent 路由等。
- `wolai-frontend/src/components/editor/blocks/MindmapAiAgentPanel.tsx`:对话 UI + 在线/本地模型切换 +(有限)工具选择。
痛点(用户反馈的核心):
1) AI 常变成“对话 + 兜底链接”,看起来没真正**调用工具**完成“写入/修改/跳转/补全”。
2) 缺少跨区域能力:主编辑区、OnlyOffice 没有统一的 AI 工具体系。
3) 缺少可观测性:用户看不到 AI 做了哪些步骤、调用了哪些工具、产生了哪些改动。
4) 工具调用协议不稳定:不同模型/网关对 JSON tool-calling 的支持差异大,容易进入循环/步数耗尽。
---
## 1. 设计目标(对齐 Cline / VSCode Chat 的能力)
### 1.1 统一入口:一个 AI 面板,多处可用
- 右侧/浮层 AI 面板:所有区域共用(思维导图、BlockNote、OnlyOffice)。
- 支持“快速对话”与“任务模式”(像 Cline:可以多步执行、展示步骤与工具日志)。
- 支持 `@` 选择文件树资产/上传文件/引用当前选区。
### 1.2 统一协议:工具调用必须稳定、可解析、可追溯
参考 cankao/cline-main
- 使用**XML-like 工具标签协议**(而不是依赖模型原生 function-calling):
- 优点:更跨模型、可流式解析、可用“严格 parser”保证可靠性。
- 核心点:模型输出 `<tool_name>...</tool_name>`,服务端解析后执行工具,再把 `<tool_result>...</tool_result>` 回喂模型。
### 1.3 统一工具模型:Tool / ToolSet / 权限 / 确认
参考 cankao/vscode 的 chat tools
- Tool 定义包含:id、展示名、modelDescription、inputSchema、来源、是否需要确认、是否可在 prompt 中被引用等。
- ToolSet:工具集合(方便“手动勾选一组工具”或“按场景启用”)。
- 权限策略:读操作默认允许;写操作可配置为“自动/需确认/禁止”。
### 1.4 统一上下文模型:Attachments / Variables@ 引用)
参考 VSCode chat 的 attachments / variables
- `@file`/`@folder`/`@selection`/`@mindmap`/`@onlyoffice` 统一变成“上下文条目”。
- 每个条目可计算 token 预算,必要时“省略/压缩/摘要”。
---
## 2. 总体架构(分层 + 运行时)
### 2.1 模块拆分(建议新增)
`wolai-frontend/src/lib` 下新增统一平台包(后续逐步迁移 mindmap AI 逻辑):
- `src/lib/ai-agent/protocol/`
- 工具标签协议(解析/序列化/流式切分)
- 参考:`cankao/cline-main/src/core/assistant-message/*`
- `src/lib/ai-agent/tools/`
- 工具注册表(Tool、ToolSet、schema
- 参考:VSCode `languageModelTools*`
- `src/lib/ai-agent/runtime/`
- Agent 循环(step budget、工具执行、结果回喂、压缩/续写)
- 参考:Cline “tool use + new_task + context management”
- `src/lib/ai-agent/context/`
- Attachments/Variables@ 引用)
- token 预算与省略策略
- `src/lib/ai-agent/providers/`
- 在线/本地模型统一适配(复用现有 `openaiCompatibleChat`
### 2.2 服务端编排(主入口 API)
新增统一入口(示例):
- `POST /api/ai-agent/run`
- 输入:会话信息 + 用户输入 + attachments + 工具允许集(auto 或手动)
- 输出:SSE 流(推荐)或 JSON:
- assistant 文本流
- tool_call / tool_result 事件流
- 最终 completion(包含“做了什么/改了什么/引用来源/失败原因”)
为什么需要 SSE
- 让 UI 像 Cline 一样逐步显示:正在检索/正在读取文档/正在写入导图/已保存等。
### 2.3 客户端工具宿主(可选但很关键)
很多能力必须在浏览器侧执行(例如读取当前选区、定位 OnlyOffice 页码、获取思维导图当前选中节点)。
设计为两类工具:
1) **Server Tools**(在 Next Route 执行)
- searxng 检索、LightRAG 查询、读写 mindmap JSON、生成导图 ops、读写 BlockNote 文档存储等。
2) **Client Tools**(在浏览器执行)
- 读取当前编辑器选区、读取 OnlyOffice 当前页/选中区域、读当前 mindmap 选中节点等。
执行方式(v1 推荐):
- `/api/ai-agent/run` 只执行 Server Tools
- Client Tools 先不做“由 AI 主动触发”,而是通过 attachments 提前把必要上下文注入(@selection@currentFile@mindmapSelection)。
执行方式(v2 目标):
- 引入“前端工具宿主”:当服务端需要执行 Client Tool 时,通过 SSE 向前端发起请求,前端执行后再回传结果(类似 VSCode extension host / Cline host provider)。
- 现状:已在 OnlyOffice 场景落地(SSE 事件 `client_tool_call` → 前端调用 OnlyOffice 插件 API → 回调 `/api/ai-agent/client-tool-result`)。
- 后续:把该机制抽象成通用 Client Tool Host,复用到 BlockNote/思维导图的“选区/选中节点”等能力。
---
## 3. 协议:工具调用(建议采用 Cline 风格 XML 标签)
### 3.1 为什么不用纯 JSON tool-calling
- 不同在线网关/模型对 `response_format=json_object`、function-calling 支持不一致。
- 一旦输出不符合 schema,容易进入循环(步数耗尽),用户只看到“兜底链接”。
### 3.2 v1 工具标签协议(最小可用)
模型输出只能出现以下块之一:
- `<tool_name>...</tool_name>`:请求执行工具
- `<attempt_completion>...</attempt_completion>`:结束并输出最终结果
工具参数采用子标签:
```xml
<search_web>
<query>gemini 3 tokens price</query>
<count>5</count>
</search_web>
```
工具结果回喂:
```xml
<tool_result>
<tool_name>search_web</tool_name>
<result>{"results":[...]}</result>
</tool_result>
```
解析器参考:
- `cankao/cline-main/src/core/assistant-message/parse-assistant-message.ts`
---
## 4. 工具体系(跨 Mindmap / BlockNote / OnlyOffice
### 4.1 核心内置工具(v1 必做)
#### A. 检索与证据
- `search_web`:通过 searxng 搜索,返回 title/url/snippet(必须可追溯)
- `rag_query`:通过 LightRAG 查询(文档内检索)
#### B. 思维导图(Mindmap
(复用并升级 `design/mindmap-ai-agent-api.md` 的 ops 思路)
- `mindmap_get`:读取某个 mindmap JSONdocumentId + mindmapId
- `mindmap_apply_ops`:应用 ops 并落盘(增量修改,禁止全量覆盖)
- `mindmap_expand_node`:检索→生成 ops→apply(服务端组合工具)
#### C. 主编辑区(BlockNote 文档)
> 目标:让 AI 像“写代码”一样能对文档做结构化编辑,而不是生成一段文本让用户复制粘贴。
- `doc_get_selection`v1 先做成 attachment 注入;v2 再做成 client tool
- `doc_insert_blocks`:在某个 block 前/后插入 blocks
- `doc_replace_range`:替换某个选区(或某 block 的内容)
- `doc_find`:在文档内查找某段文本/标题定位位置
#### D. OnlyOffice(文档阅读/编辑)
v1(先做最基础的增/删/改/查 + 可落地的“文档驱动导图”):
- `oo_get_selection`:读取当前选区(查)
- `oo_replace_selection`:替换当前选区(改/删;删=传空字符串)
- `oo_insert_text` / `oo_insert_html`:插入内容(增)
- `oo_insert_image`:插入图片(增)
- `asset_extract_outline`:附件(PDF 优先)→结构化大纲(含页码)
- `asset_to_mindmap`:附件大纲→思维导图落盘(含 refs/hyperlink
v2 再做:
- `onlyoffice_jump`:跳转到某页/某段(依赖 OnlyOffice API 能力)
- `onlyoffice_insert_comment`:插入批注/引用锚点
- `onlyoffice_forcesave`:强制保存/落盘(用于“编辑中→解析/索引→生成”闭环)
### 4.2 ToolSet(便于 UI 一键勾选)
建议默认提供:
- `toolset.readonly`search_web、rag_query、asset_get、mindmap_get(只读)
- `toolset.mindmap_write`mindmap_apply_ops、mindmap_expand_node
- `toolset.doc_write`doc_insert_blocks、doc_replace_range
- `toolset.onlyoffice_editor`oo_get_selection、oo_replace_selection、oo_insert_*(选区增删改查)
- `toolset.onlyoffice_read`/`toolset.onlyoffice_write`asset_extract_outline / asset_to_mindmap(文档驱动导图)
---
## 5. UI/交互(对齐“像 Cline 一样智能”)
### 5.1 一个统一的 AI 面板(简洁)
参考你给的 CherryStudio 截图:保持简洁,但必须有三块:
1) 顶部:会话标题 + 模型选择(在线/本地 + model)
2) 中部:对话历史 + 工具执行日志(可折叠)
3) 底部:输入框 + `@` 选择附件 + 工具选择(自动/手动、多选 ToolSet/Tool
关键交互规则:
- 焦点在输入框:Enter = 发送;Shift+Enter = 换行;不触发思维导图/编辑器快捷键。
- 焦点不在输入框:Enter/Tab 等交由当前编辑器(mindmap 节点快捷键、BlockNote 等)。
### 5.2 可观测性:必须展示“AI 做了什么”
每条消息可附:
- 计划(可选)
- 调用过的工具列表(工具名 + 输入 + 输出摘要 + 耗时 + 是否保存)
- 改动摘要(例如:对 mindmap 增加了 7 个子节点;对文档插入了 3 个段落)
### 5.3 “自动 vs 手动”的真正含义
- 自动:AI 在允许的 ToolSet 范围内自行调用工具。
- 手动:只允许用户勾选的工具/ToolSet;AI 只能在这个集合内调用。
---
## 6. 里程碑计划(慢慢实现,但每一步都可验收)
### 完成进度(截至 2026-01-11
> 说明:本节用于记录“已经落地到代码”的进度,避免只停留在规划层。
> ✅=已完成;🟡=部分完成/已打通但仍需扩展;⬜=未开始
| 里程碑 | 条目 | 状态 | 备注(对应实现) |
| --- | --- | --- | --- |
| M0 | `POST /api/ai-agent/run` | ✅ | `wolai-frontend/src/app/api/ai-agent/run/route.ts` |
| M0 | XML-like 工具标签协议解析器 | ✅ | `wolai-frontend/src/lib/ai-agent/protocol/toolTagProtocol.ts` |
| M0 | Tool RegistryTool/ToolSet | ✅ | `wolai-frontend/src/lib/ai-agent/tools/registry.ts` + `wolai-frontend/src/lib/ai-agent/tools/builtins/registryBuiltins.ts` |
| M0 | Agent Runtimestep budget + 工具日志) | ✅ | `wolai-frontend/src/lib/ai-agent/runtime/runAgent.ts` |
| M0 | SSE 输出(assistant/tool_call/tool_result/completion | ✅ | `/api/ai-agent/run` 已支持 SSE |
| M0 | 前端 AI 面板(可复用) | 🟡 | 已在 dev + 思维导图 + OnlyOffice 接入;BlockNote 仍需继续推进 |
| M1 | mindmap 读写工具(增量 ops + 细粒度工具) | ✅ | `wolai-frontend/src/lib/ai-agent/tools/builtins/mindmap/mindmapServerTools.ts` |
| M1 | `mindmap_expand_node`(检索→生成→落盘) | ✅ | 同上(支持可选 `search_web` 证据) |
| M1 | UI:选中节点上下文注入(给 AI) | ✅ | 思维导图面板通过 `context.selectedUids` 注入;并对用户显示纯文本节点内容 |
| M1 | UI:最大步数可配置(不再固定 6) | ✅ | 思维导图面板/Dev 面板支持 1~24,默认 10 |
| M2 | ToolSet 按位置隔离(避免工具混淆) | ✅ | `/api/ai-agent/run``scope` 强制过滤;各面板按场景传不同 toolSets |
| M2 | BlockNote 文档工具(doc_* | 🟡 | 已实现 doc_get/doc_find/doc_insert_blocks/doc_replace_range + 文档侧边 AI 面板;`@selection`/更丰富块类型仍需扩展 |
| M2 | LightRAG 检索工具(rag_* | ✅ | `rag_lightrag_query`(调用 `LIGHTRAG_URL``/query` |
| M2 | 跨页面文档工具(docs_* | ✅ | `docs_search` + `docs_read`(按 title/raw_text |
| M2 | 图片读取工具(OCR) | ✅ | `image_read`(读取 `media_assets.ocr_text` |
| M2 | 斜杠命令工具 | ✅ | `slash_run`/new 创建文档、/rename 重命名) |
| M2 | UICline 风格工具栏 + 侧边栏内切页 | ✅ | 文档/思维导图 AI 面板统一顶部工具栏(工具/历史/账户/设置),不再使用居中弹窗 |
| M2 | UI:工具日志可折叠 | ✅ | tool_call/tool_result 支持折叠展开,便于长日志查看 |
| M3 | OnlyOffice 作用域(scope=onlyoffice+ ToolSet | ✅ | `/api/ai-agent/run/route.ts` 支持 onlyoffice scope,并允许 `toolset.onlyoffice_*`(含 `toolset.onlyoffice_editor` |
| M3 | OnlyOffice 客户端工具桥接(SSE↔回调) | ✅ | `wolai-frontend/src/lib/ai-agent/runtime/clientToolBridge.ts` + `/api/ai-agent/client-tool-result` + SSE `client_tool_call` |
| M3 | oo_* 工具(选区增/删/改/查) | ✅ | `registryBuiltins.ts` 注册 + OnlyOffice 插件 `wolai-frontend/public/onlyoffice/plugins/agent-tools/*` |
| M3 | OnlyOffice AI 面板接入(浮层) | ✅ | `wolai-frontend/src/app/onlyoffice/page.tsx` + `wolai-frontend/src/components/onlyoffice/OnlyOfficeAiAgentPanel.tsx` |
| M3 | `asset_extract_outline`PDF→大纲,含页码) | 🟡 | `wolai-frontend/src/lib/ai-agent/tools/builtins/onlyoffice/onlyofficeServerTools.ts`MinerU content_list |
| M3 | `asset_to_mindmap`(附件→导图落盘) | 🟡 | 同上(把大纲转成 mindmap ops + refs + hyperlink |
### M0(基础设施):统一 Agent Runtime + 工具协议 + 日志
- [x] 新增 `POST /api/ai-agent/run`(先不替换现有 mindmap-ai,做并行)
- [x] 实现 XML-like 工具协议解析器(参考 cline 的 parse-assistant-message
- [x] 实现 Tool RegistryTool/ToolSet/inputSchema/权限标记)
- [ ] 前端统一 AI 面板(可嵌入 mindmap/sidebar、主编辑区、OnlyOffice 页面)(已在 dev + mindmap 接入,BlockNote/OnlyOffice 待推进)
- [x] SSE 输出:assistant 文本 + tool_call + tool_result + completion
验收(pw-tests):
- 输入“请给出 gemini-3 tokens 价格”,能看到工具日志(至少 search_web),并返回带来源的答案。
### M1(思维导图):把 mindmap AI 从“对话”升级为“增量 ops 写入”
- [x] 复用 `design/mindmap-ai-agent-api.md`:完善 `mindmap_get``mindmap_apply_ops`
- [x] `mindmap_expand_node`:服务端检索→生成 ops→apply,并强制 refs
- [x] UI:在 mindmap 中选择节点后,@mindmapSelection 自动注入上下文(通过 `context.selectedUids` 注入)
验收(pw-tests):
- 选中节点“补完”,新增子节点≥3,刷新仍存在,且每个新增节点带 refs/可跳转链接。
### M2(主编辑区 BlockNote):让 AI 能“读选区并结构化改写/插入”
- [x] 定义 BlockNote 文档操作 API(只允许增量,禁止覆盖整篇)(当前以“块级插入/替换”为最小可用)
- [x] 工具:`doc_insert_blocks``doc_replace_range``doc_find`(另含 `doc_get`
- [ ] UI:输入框支持 `@selection`(或“引用当前选区”按钮)
验收(pw-tests):
- 选中一段文本,让 AI “改写成更简洁版本并保留要点”,结果直接落入文档(不是生成一段文本)。
### M3OnlyOffice):插件端实时改文档 + 文档驱动导图
- [x] OnlyOffice 插件注入(autostart + pluginsData + CORS
- [x] oo_* 工具(选区增/删/改/查):`oo_get_selection` / `oo_replace_selection` / `oo_insert_*`
- [x] 前端工具宿主(OnlyOffice 版):SSE `client_tool_call` ↔ 回调 `/api/ai-agent/client-tool-result`
- [x] `asset_extract_outline`PDF 优先(基于 MinerU 的 content_list 提取 text_level + page_idx
- [x] `asset_to_mindmap`:从文档大纲生成 mindmap(章→节→要点)并落盘
- [ ] 引用:节点 refspage/slide+ hyperlink`#page=`)在 OnlyOffice/PDF 预览器中可稳定跳转(仍需实测与兼容)
补充说明(OnlyOffice “能否穿透拿到信息”):
1) **常规集成(不做插件)**OnlyOffice Docs 集成侧主要通过 `editorConfig.callbackUrl` 回传保存/状态;外部并不会天然得到“当前文档全文/选区文本”。
2) **要拿到编辑器内信息**:需要(A)保证文档已落盘(callback + 保存/forcesave)后从存储侧读取,或(B)开发 OnlyOffice 插件/宏(在编辑器内执行 Office API,再把结果回传到宿主)。
3) **M3 v1 策略(双通道)**
- **实时编辑(Word/PPT/Excel 的基础增删改查)**:走 OnlyOffice 插件(编辑器内执行)→ 通过前端工具宿主把结果回传给服务端 Agent。
- **结构化理解/导图生成**:走“附件/存储→MinerU 结构化解析→导图写入”,不依赖编辑器能直接吐出全文/层级信息。
- 后续再补:`onlyoffice_forcesave`(保证拿到最新落盘版本)+ 更强的“书签/页码/定位”跳转能力。
验收(pw-tests):
- 对指定 PDF 生成“章→节→内容”层级导图,点击节点跳到对应页(至少 URL 含 `#page=`)。
### M4(v2):前端工具宿主 + MCP 工具 + 类“技能”系统
- [ ] 前端工具宿主(通用版):允许 AI 请求 client tool(读取 BlockNote 选区、思维导图当前选中节点、OnlyOffice 当前页等)
- [ ] MCP:把 supabase_local / searxng / 未来自定义 MCP 作为工具源(像 cline)
- [ ] skills:把“工作流说明”做成可加载的技能文件,AI 可按需激活(类似你现在的 Codex skills
验收:
- AI 能在一个任务里自行组合:检索→读文档→写导图→在主编辑区插入总结→生成可跳转引用。
---
## 7. 风险与策略
1) **安全/误操作**:默认只允许增量 ops;涉及删除/覆盖需要二次确认或显式指令。
2) **上下文过长**:引入“attachments 省略/摘要”,并在会话接近上限时自动 compact(参考 opencode/crush)。
3) **模型差异**:工具协议用 XML-like,避免强依赖 function-calling;必要时提供 provider 特化 prompt。
4) **性能/长任务**:PDF 解析/大纲生成走后端 job(可加队列/轮询),前端只显示进度与结果。
---
## 8. 与现有 design 的关系(不推倒重来)
- `design/mindmap-ai-v2.md`:保留“PDF/小结/RAG 补完”的业务目标与验收用例。
- `design/mindmap-ai-agent-api.md`:保留“mindmap ops 增量协议”,作为 v1 中 Mindmap 工具的核心。
- 本文档新增的是:**把 mindmap 的思路抽象成全站统一的 AI Agent 平台**,并且对齐 Cline/VSCode 的“工具 + 上下文 + 日志 + 权限”工程化形态。