# 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”保证可靠性。
- 核心点:模型输出 `...`,服务端解析后执行工具,再把 `...` 回喂模型。
### 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 工具标签协议(最小可用)
模型输出只能出现以下块之一:
- `...`:请求执行工具
- `...`:结束并输出最终结果
工具参数采用子标签:
```xml
gemini 3 tokens price
5
```
工具结果回喂:
```xml
search_web
{"results":[...]}
```
解析器参考:
- `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 JSON(documentId + 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-12)
> 说明:本节用于记录“已经落地到代码”的进度,避免只停留在规划层。
> ✅=已完成;🟡=部分完成/已打通但仍需扩展;⬜=未开始
| 里程碑 | 条目 | 状态 | 备注(对应实现) |
| --- | --- | --- | --- |
| 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 Registry(Tool/ToolSet) | ✅ | `wolai-frontend/src/lib/ai-agent/tools/registry.ts` + `wolai-frontend/src/lib/ai-agent/tools/builtins/registryBuiltins.ts` |
| M0 | Agent Runtime(step budget + 工具日志) | ✅ | `wolai-frontend/src/lib/ai-agent/runtime/runAgent.ts` |
| M0 | SSE 输出(assistant/tool_call/tool_result/completion) | ✅ | `/api/ai-agent/run` 已支持 SSE |
| Infra | 公共环境文件(服务域名统一配置) | ✅ | `wolai-frontend/public/mnote-env.json`(Supabase/Backend/OnlyOffice Web/Desktop) |
| Infra | 桌面端默认远程客户端行为(启动不再走 127.0.0.1 登录) | ✅ | `desktop-electron/main.js`(networkMode=remote-client + 强制 Supabase/Backend 走 Tunnel) |
| Infra | OnlyOffice 构建兼容(useSearchParams + Suspense) | ✅ | `wolai-frontend/src/app/onlyoffice/page.tsx` + `wolai-frontend/src/app/onlyoffice/OnlyOfficeClientPage.tsx` |
| 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 | UI:Cline 风格工具栏 + 侧边栏内切页 | ✅ | 文档/思维导图 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 Registry(Tool/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 “改写成更简洁版本并保留要点”,结果直接落入文档(不是生成一段文本)。
### M3(OnlyOffice):插件端实时改文档 + 文档驱动导图
- [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(章→节→要点)并落盘
- [ ] 引用:节点 refs(page/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 的“工具 + 上下文 + 日志 + 权限”工程化形态。