Files
mnote/recycle/design/mindmap-ai-agent-api.md
T
2026-04-13 19:21:42 +08:00

145 lines
4.5 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.
# Mindmap AI Agent API 设计(读写思维导图,类似 CLI 工具)
## 目标
让 AI 不再“只输出一段文本”,而是像 CLI 一样:
1. **读**:获取当前页面中某个 Mindmap 的完整数据(包含节点、链接、引用)。
2. **改**:以结构化的 `ops`(操作序列)形式修改导图(新增/删除/改名/加链接/加引用/加备注)。
3. **可追溯**:每次 AI 修改都能记录“为什么这样改/引用来自哪里”(refs 作为第一公民)。
4. **安全**:必须校验登录态 + document 权限;只能操作该 document 下的 mindmap 文件。
## 现状(简述)
- 目前 Mindmap 的保存/加载已经存在(按文件树保存,支持同页多个独立 mindmap)。
- AI v2 的 `/api/mindmap-ai/outline-to-mindmap` 能把 PDF 转成 mindmapData(节点带 `hyperlink``refs`)。
- 仍缺少:AI 直接对“已有导图”做增量修改的能力(例如“补完此节点”“根据搜索扩展子节点”)。
## 设计原则
- **客户端只负责 UI/交互**:选择节点、展示进度、应用结果。
- **服务端负责权限与落盘**:验证用户、读写 mindmap JSON、生成 ops、应用 ops。
- **AI 输出必须是 ops**:避免 AI 直接吐一棵全量树造成覆盖/丢数据;也利于审计与回滚。
- **引用强制**:默认每个新增节点都要给 `refs`(至少页码/URL),没有引用则标记为 `待核验`
## 核心数据结构
### 1) Mindmap 节点引用 `NodeRef`(已在实现中使用)
```ts
export type NodeRef = {
kind: "pdf" | "docx" | "pptx" | "url";
assetId?: string;
fileUrl?: string;
page?: number; // 1-based
slide?: number; // 1-based
title?: string;
snippet?: string;
};
```
### 2) 操作协议 `MindmapOp`
> 说明:这里的 `uid` 指 simple-mind-map 节点 `data.uid`(当前实现已使用)。
```ts
export type MindmapOp =
| { op: "addChild"; parentUid: string; node: { uid?: string; text: string; hyperlink?: string; refs?: NodeRef[]; note?: string } }
| { op: "addSiblingAfter"; targetUid: string; node: { uid?: string; text: string; hyperlink?: string; refs?: NodeRef[]; note?: string } }
| { op: "updateText"; uid: string; text: string }
| { op: "setHyperlink"; uid: string; hyperlink: string | null }
| { op: "setRefs"; uid: string; refs: NodeRef[] }
| { op: "appendNote"; uid: string; markdown: string }
| { op: "deleteNode"; uid: string };
```
### 3) 服务端应用 ops(纯 JSON 层)
- 以“树遍历 + uid 索引”应用变更,保证:
- 不依赖浏览器端实例;
- 不依赖 simple-mind-map 内部状态;
- 可在服务端记录变更日志。
## API 设计(建议新增)
### 1) 读取导图
`GET /api/mindmap/[documentId]/[mindmapId]`
返回:
```json
{
"mindmapId": "xxx",
"documentId": "xxx",
"data": { "data": { "text": "...", "uid": "..." }, "children": [] },
"updatedAt": "2026-01-09T00:00:00.000Z"
}
```
### 2) 应用 ops(增量修改 + 自动保存)
`POST /api/mindmap/[documentId]/[mindmapId]/ops`
入参:
```json
{
"ops": [ { "op": "addChild", "parentUid": "...", "node": { "text": "...", "hyperlink": "...", "refs": [] } } ],
"actor": { "kind": "ai", "provider": "online", "model": "gemini-2.5-flash" },
"reason": "补完该节点:……(可选)"
}
```
出参:
```json
{
"ok": true,
"applied": 7,
"data": { "data": { "text": "...", "uid": "..." }, "children": [] }
}
```
### 3) AI 补完(服务端编排:检索 → 生成 ops → 应用 ops)
`POST /api/mindmap-ai/expand-node`
入参(建议):
```json
{
"documentId": "xxx",
"mindmapId": "xxx",
"targetUid": "xxx",
"instruction": "请补完该节点,要求每条必须带引用",
"sources": { "rag": true, "searxng": true }
}
```
输出:
```json
{
"ok": true,
"providerUsed": "online",
"ops": [ ... ],
"applied": 7
}
```
> 注意:该接口内部会调用 `/api/mindmap/[...]/ops` 做落盘,避免重复代码。
## 与 SearxNG / RAG 的关系
- 对“搜索补完”:服务端先走检索(LightRAG + 可选 SearxNG),把证据(标题/URL/snippet)整理成短上下文,再让在线 AI 输出 `MindmapOp[]`
- 必须要求:每个新增节点都附带 refs(url 或 pdf page),否则标记为“待核验”并限制输出量。
## 验收建议(后续 pw-tests
1. 选中某节点,点击“AI 补完”,等待生成。
2. 导图新增 ≥ 3 个子节点。
3. 每个新增节点包含可点击 `hyperlink``refs`
4. 刷新页面后仍存在(说明落盘成功)。