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

4.5 KiB
Raw Blame History

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(节点带 hyperlinkrefs)。
  • 仍缺少:AI 直接对“已有导图”做增量修改的能力(例如“补完此节点”“根据搜索扩展子节点”)。

设计原则

  • 客户端只负责 UI/交互:选择节点、展示进度、应用结果。
  • 服务端负责权限与落盘:验证用户、读写 mindmap JSON、生成 ops、应用 ops。
  • AI 输出必须是 ops:避免 AI 直接吐一棵全量树造成覆盖/丢数据;也利于审计与回滚。
  • 引用强制:默认每个新增节点都要给 refs(至少页码/URL),没有引用则标记为 待核验

核心数据结构

1) Mindmap 节点引用 NodeRef(已在实现中使用)

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(当前实现已使用)。

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]

返回:

{
  "mindmapId": "xxx",
  "documentId": "xxx",
  "data": { "data": { "text": "...", "uid": "..." }, "children": [] },
  "updatedAt": "2026-01-09T00:00:00.000Z"
}

2) 应用 ops(增量修改 + 自动保存)

POST /api/mindmap/[documentId]/[mindmapId]/ops

入参:

{
  "ops": [ { "op": "addChild", "parentUid": "...", "node": { "text": "...", "hyperlink": "...", "refs": [] } } ],
  "actor": { "kind": "ai", "provider": "online", "model": "gemini-2.5-flash" },
  "reason": "补完该节点:……(可选)"
}

出参:

{
  "ok": true,
  "applied": 7,
  "data": { "data": { "text": "...", "uid": "..." }, "children": [] }
}

3) AI 补完(服务端编排:检索 → 生成 ops → 应用 ops)

POST /api/mindmap-ai/expand-node

入参(建议):

{
  "documentId": "xxx",
  "mindmapId": "xxx",
  "targetUid": "xxx",
  "instruction": "请补完该节点,要求每条必须带引用",
  "sources": { "rag": true, "searxng": true }
}

输出:

{
  "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. 每个新增节点包含可点击 hyperlinkrefs
  4. 刷新页面后仍存在(说明落盘成功)。