项目地址:github.com/huaxustar/bramble · MIT 协议 从 辣椒AI 的「AI 思维导图」工具中抽取,重写为独立开源项目。
一、我们踩过的坑
做 AI 生成思维导图,最直觉的做法是让模型直接输出一棵嵌套的 JSON 树,前端拿到就能渲染。
这个做法在实践中很脆弱:
- 括号会不配对。 层级一深,模型漏个括号,整棵树解析失败。
- 字段会写错。 有时候是
children,有时候变成child,有时候多一个不认识的字段。 - 深层嵌套容易崩。 树越深,出错概率越高,而思维导图恰恰需要深层结构。
- 失败是全有全无的。 JSON 解析失败就是彻底失败,拿不到任何可用内容。
我们试过各种补救:加 schema 约束、加示例、加重试、写容错解析器。都能改善,但没有一个能真正解决问题——因为我们在要求模型做一件它不擅长的事。
为什么 JSON 对模型这么难
模型生成 JSON 的困难不是随机错误,它有结构性的原因:
- 自回归生成没有"回看"机制。 模型在生成第 50 层的
}时,已经"忘记"了第 3 层是否闭合。它不像人类写 JSON 那样可以抬头看看上面有没有漏括号。 - 嵌套结构的熵随深度增加。 浅层结构(1-3 层)正确率很高,但思维导图常常需要 5-8 层。每多一层,出错概率乘法级增长。
- schema 约束是"软"的。 即使在提示词里写了明确的 JSON Schema,模型也只在"大概率遵循"的水平上做到——它可以保证 95% 的字段正确率,但思维导图需要 100% 才能被解析。
二、换个中间格式
模型最擅长生成什么?Markdown 大纲。
# 中心主题
## 分支一
- 要点
- 子要点
- 要点
## 分支二
- 要点这是模型在训练数据里见过千万次的形态,生成起来极其稳定。层级用 # 和缩进表达,没有括号可以漏,没有字段名可以写错。
所以 Bramble 的核心设计是:
主题/材料 → 模型生成 Markdown 大纲 → 确定性解析 → 思维导图树 → 可编辑画布
解析是确定性的——不是让另一个模型去理解大纲,而是用规则把缩进结构转成树。规则解析要么成功,要么在明确的位置失败,不存在"解析出一个看起来对但其实错了的结果"。
万一解析失败(极少发生),触发重新生成,而不是把一堆脆弱的 JSON 塞回给模型让它修。
为什么这个方案行得通
本质上是在做一件事:让模型输出它训练数据中分布最密集的格式。 Markdown 大纲在互联网上随处可见——README 目录、维基百科层级导航、论文大纲、书籍目录。模型见过几十亿个这样的结构,生成它们只需要"重复学过的模式"。
而嵌套 JSON 虽然语法简单,但训练数据中完整的、深层的、格式正确的 JSON 树数量远小于 Markdown 大纲。模型需要靠"推理"来构建正确结构——这正是出错的地方。
三、往返:让对话式编辑真的可用
单向生成只解决了一半问题。真正有用的是:用户在画布上手动改了几个节点后,再对 AI 说"把『方法』这个分支展开",AI 要在他改过的版本上继续。
Bramble 的做法是让转换双向可逆:
大纲 ──解析──▶ 树 ──▶ 画布(用户手动编辑)
▲ │
└──────── 反向序列化 ◀────────┘用户编辑后的画布状态可以被序列化回 Markdown 大纲,再作为上下文喂给模型。所以模型看到的永远是"当前这张图",包括用户的手动修改。
这个往返能力是整个设计的关键。没有它,对话式编辑就只能重新生成整张图,用户的修改全部丢失。
实际使用场景
一个典型的交互流程:
- 用户在文本框里输入"云计算技术栈概览",点「生成」
- Bramble 生成一张包含 IaaS、PaaS、SaaS、Serverless 等分支的导图
- 用户手动把「Serverless」的分支名称改成「无服务器计算架构」,在下面加了两个子节点
- 用户选中「PaaS」分支,对 AI 说"展开主流产品"
- 系统将当前画布序列化为大纲(包括用户的所有修改),附上指令发给模型
- 模型在现有大纲的「PaaS」下新增子节点,返回完整大纲
- 前端增量更新画布——「Serverless」分支依然保持用户的修改
整个过程用户感知到的是"我在和一张活着的导图对话",而不是"每次改完都要从头生成"。
四、项目结构
bramble/
├── packages/
│ ├── bramble-core/ Python —— 大纲提示词、解析器、生成引擎
│ └── bramble-react/ @bramble/react —— 基于 mind-elixir 的受控 React 组件
├── examples/
│ └── fullstack/ 可运行的完整示例:FastAPI 服务端 + Vite/React 前端
└── docs/architecture.md两个包可以独立使用:只想要生成能力就用 bramble-core,只想要可编辑画布就用 @bramble/react。示例项目把两者接起来,可以直接跑。
画布基于 mind-elixir(MIT),我们做的是它的受控封装,不重复造轮子。
五、模型兼容
支持 Anthropic 和 OpenAI 两种协议,通过一个环境变量切换。这意味着 OpenAI、DeepSeek、Qwen、以及 Ollama、vLLM 等本地部署的服务都能直接用。
对企业用户来说这一点比较实际——能在内网用自己部署的模型跑,而不是必须调外部 API。
在实际测试中,不同模型生成大纲的质量差异远小于生成 JSON 的差异。因为 Markdown 大纲是所有模型都大量见过的格式,即使用较小的本地模型也能稳定生成。这使得 Bramble 在弱模型上的可用性显著高于 JSON-based 方案。
六、为什么要单独开源
有人问过我们,为什么不把它留在产品里当护城河。
我们的想法是:这个设计的价值在于它是一个通用解法,不是我们的专有优势。 "让模型输出它擅长的格式,而不是强迫它输出你想要的格式"——这条经验对任何做 LLM 结构化输出的人都有用。
把它抽出来开源,一方面是我们自己也能从社区反馈里改进,另一方面这类基础组件被更多人用、被更多场景检验,最终受益的还是我们自己的产品。
另外还有一个实际考虑:开源之后,我们的产品可以直接依赖开源版本。产品代码更干净(没有"内部专用"的模块),而且社区提的 PR 修复的是同一份代码——改一处,产品也受益。
七、欢迎试用
如果你在做类似的功能,或者只是想在自己的应用里加一个"AI 生成思维导图",可以直接拿去用。有问题欢迎在仓库里提 issue。
想在你的业务里试试同样的做法?
告诉我们业务问题与数据现状,我们会给出方案建议与落地路径。
需要帮助?
联系我们的团队,获取贴合你业务场景的方案建议。