19 KiB
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 + 在线/本地模型切换 +(有限)工具选择。
痛点(用户反馈的核心):
- AI 常变成“对话 + 兜底链接”,看起来没真正调用工具完成“写入/修改/跳转/补全”。
- 缺少跨区域能力:主编辑区、OnlyOffice 没有统一的 AI 工具体系。
- 缺少可观测性:用户看不到 AI 做了哪些步骤、调用了哪些工具、产生了哪些改动。
- 工具调用协议不稳定:不同模型/网关对 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 页码、获取思维导图当前选中节点)。
设计为两类工具:
- Server Tools(在 Next Route 执行)
- searxng 检索、LightRAG 查询、读写 mindmap JSON、生成导图 ops、读写 BlockNote 文档存储等。
- 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>:结束并输出最终结果
工具参数采用子标签:
<search_web>
<query>gemini 3 tokens price</query>
<count>5</count>
</search_web>
工具结果回喂:
<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 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 前/后插入 blocksdoc_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_nodetoolset.doc_write:doc_insert_blocks、doc_replace_rangetoolset.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 截图:保持简洁,但必须有三块:
- 顶部:会话标题 + 模型选择(在线/本地 + model)
- 中部:对话历史 + 工具执行日志(可折叠)
- 底部:输入框 +
@选择附件 + 工具选择(自动/手动、多选 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 + 工具协议 + 日志
- 新增
POST /api/ai-agent/run(先不替换现有 mindmap-ai,做并行) - 实现 XML-like 工具协议解析器(参考 cline 的 parse-assistant-message)
- 实现 Tool Registry(Tool/ToolSet/inputSchema/权限标记)
- 前端统一 AI 面板(可嵌入 mindmap/sidebar、主编辑区、OnlyOffice 页面)(已在 dev + mindmap 接入,BlockNote/OnlyOffice 待推进)
- SSE 输出:assistant 文本 + tool_call + tool_result + completion
验收(pw-tests):
- 输入“请给出 gemini-3 tokens 价格”,能看到工具日志(至少 search_web),并返回带来源的答案。
M1(思维导图):把 mindmap AI 从“对话”升级为“增量 ops 写入”
- 复用
design/mindmap-ai-agent-api.md:完善mindmap_get、mindmap_apply_ops mindmap_expand_node:服务端检索→生成 ops→apply,并强制 refs- UI:在 mindmap 中选择节点后,@mindmapSelection 自动注入上下文(通过
context.selectedUids注入)
验收(pw-tests):
- 选中节点“补完”,新增子节点≥3,刷新仍存在,且每个新增节点带 refs/可跳转链接。
M2(主编辑区 BlockNote):让 AI 能“读选区并结构化改写/插入”
- 定义 BlockNote 文档操作 API(只允许增量,禁止覆盖整篇)(当前以“块级插入/替换”为最小可用)
- 工具:
doc_insert_blocks、doc_replace_range、doc_find(另含doc_get) - UI:输入框支持
@selection(或“引用当前选区”按钮)
验收(pw-tests):
- 选中一段文本,让 AI “改写成更简洁版本并保留要点”,结果直接落入文档(不是生成一段文本)。
M3(OnlyOffice):插件端实时改文档 + 文档驱动导图
- OnlyOffice 插件注入(autostart + pluginsData + CORS)
- oo_* 工具(选区增/删/改/查):
oo_get_selection/oo_replace_selection/oo_insert_* - 前端工具宿主(OnlyOffice 版):SSE
client_tool_call↔ 回调/api/ai-agent/client-tool-result asset_extract_outline:PDF 优先(基于 MinerU 的 content_list 提取 text_level + page_idx)asset_to_mindmap:从文档大纲生成 mindmap(章→节→要点)并落盘- 引用:节点 refs(page/slide)+ hyperlink(
#page=)在 OnlyOffice/PDF 预览器中可稳定跳转(仍需实测与兼容)
补充说明(OnlyOffice “能否穿透拿到信息”):
- 常规集成(不做插件):OnlyOffice Docs 集成侧主要通过
editorConfig.callbackUrl回传保存/状态;外部并不会天然得到“当前文档全文/选区文本”。 - 要拿到编辑器内信息:需要(A)保证文档已落盘(callback + 保存/forcesave)后从存储侧读取,或(B)开发 OnlyOffice 插件/宏(在编辑器内执行 Office API,再把结果回传到宿主)。
- 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. 风险与策略
- 安全/误操作:默认只允许增量 ops;涉及删除/覆盖需要二次确认或显式指令。
- 上下文过长:引入“attachments 省略/摘要”,并在会话接近上限时自动 compact(参考 opencode/crush)。
- 模型差异:工具协议用 XML-like,避免强依赖 function-calling;必要时提供 provider 特化 prompt。
- 性能/长任务: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 的“工具 + 上下文 + 日志 + 权限”工程化形态。