0.5 缩减重构
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# 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. 刷新页面后仍存在(说明落盘成功)。
|
||||
|
||||
Reference in New Issue
Block a user