Tolaria 不内嵌 AI,1.8 万 star 背后是一个人
- Tolaria 项目 2 月 14 日创建,到 7 月 1 日已达 17963 Star、1222 Fork,MIT 协议,五个月增长速度惊人
- 反主流设计:不内嵌 AI 功能,专注于本地优先的笔记数据管理,解决 Obsidian 用户对数据所有权的焦虑
- 单人开发壮举:git log 显示主作者 LucaRonin 几乎独立完成核心开发,证明好产品不需要大团队
- 核心差异:相比 Obsidian 的插件生态和官方云同步,Tolaria 走极简、本地、可控路线,切中隐私敏感用户痛点
前阵子一个用 Obsidian 的朋友跟我抱怨,说他攒了三千多篇笔记,插件装了一堆,同步还得买官方云服务。「数据是我的还是它的」,他原话这么说的。我给他推了 Tolaria。
推完我自己去翻了一遍仓库。说实话,吓了一跳。
这个 2 月 14 号才建仓的项目,到 7 月 1 号已经 17963 颗 star、1222 个 fork。更夸张的是 git log,主作者 LucaRonin 一个人提交了 3004 次,排第二的人类贡献者只有 10 次。差不多是一个人扛着一万八千个收藏在跑。
一个人,五个月,一万八千颗 star。
这背后到底是什么?我花了一晚上把它的 README、架构文档、ADR、还有源码翻了个底朝天,发现它真正值钱的不是功能多,是它对「谁来管你的笔记」这件事的态度特别轴。
一份被反复许下的承诺,这次落到文件系统上
Tolaria 是个桌面端 Markdown 知识库,macOS、Windows、Linux 三端通吃,底层是 Tauri 加 React 加 TypeScript。其实就是拿 Rust 壳子套个 web 前端,比 Electron 轻,比纯原生快。
但技术栈不是重点。重点是它给自己立的几条规矩,你听着可能耳熟。
文件第一,笔记就是磁盘上的纯 markdown。Git 第一,每个仓库就是一个 git 仓库,版本历史、远程、冲突解决全给你。离线第一,零锁定,没账号没订阅没云依赖。AI 优先但不只靠 AI。
这些话 Obsidian 也说过一半,Notion 一个都没说过。区别在哪?在于 Tolaria 把这些写进了架构文档,还用源码一条条兑现。
你想想看,市面上大多数笔记应用的「文件优先」是营销话术。数据库才是真相,文件只是导出格式。Tolaria 反过来,docs/ARCHITECTURE.md 第一句就钉死,文件系统是唯一真相,缓存、React 状态、内存里的一切表示都是派生的,删了都能重建。有冲突的时候,磁盘上的文件赢。
它原话是 the file on disk wins。而且它真的为这句话付了代价。
git 当能力,不是当假设
很多工具把 git 集成当成一个开关,要么有要么没有。Tolaria 的处理更细,它把 git 定义成「per-vault 的能力」而不是前提。
仓库可以是 git-backed 的,那历史、提交、同步、冲突解决、AutoGit 全开。也可以是纯文件夹,照样能扫描、编辑、搜索、跳转,只是状态栏和命令面板里 git 相关的入口换成「Initialize Git for Current Vault」。plain folder 只有用户明确点一下,才会变成 git 仓库。
这种「能力分层」听着像炫技,其实救场。
我读到一段设计,特别有意思。init_git_repo 这个初始化函数有个硬性拒绝逻辑,当用户选的目录看着像 Documents、Desktop、Downloads 这种宽泛的个人根目录,又没有 Tolaria 管理标记时,它直接拒跑 git,让你新建一个专门的子文件夹。源码注释大意是说,在用户整个家目录上 git init 是灾难。
老实说我看到这个挺感慨的。多少工具为了「上手快」会偷偷在用户根目录 git init,留一堆 .git 污染。Tolaria 宁可多问一句也不干这种事。这是 files-first 哲学落到代码里的样子,不是嘴上说说。
AGENTS.md,把 AI 当访客而不是房客
这块是我最想聊的,也是 Tolaria 跟 Notion、Obsidian 拉开身位的地方。
README 里有一句话,AI-first but not AI-only。说人话就是,笔记库天生适合喂给 AI Agent,但不强制你用谁,支持 Claude Code、Codex CLI、Gemini CLI 三条接入路径,你想换别的也行。
它怎么实现的?不是内置一个 AI 助手按钮。是往你的仓库根目录写一个 AGENTS.md 文件,告诉任何能读文件的 AI Agent 这个仓库是什么、怎么操作、有哪些约定。然后 CLAUDE.md 和 GEMINI.md 都是兼容垫片,指向同一个 AGENTS.md。这个 AGENTS.md 模板就放在 src-tauri/resources/agent-docs/ 里,新建仓库时落地。
这个思路我觉得特别正。AI Agent 不该是应用的内嵌功能,而该是来访的客人。应用把门打开、把家规贴墙上,客人来了照规矩办事,走了你不损失任何东西。换 Claude、换 Codex、换 Gemini,对你来说就是换个访客,笔记库一个字不用动。
我再往里挖了一层。src/components/ClaudeCodeOnboardingPrompt.tsx 这个组件配合 useClaudeCodeStatus 这个 hook,启动时会探测你机器上装没装 Claude Code,状态分 installed、missing、checking 三档,没装就引导你去装。AiProviderSettings.tsx 里 AI provider 的 api_key_storage 字段只有两个取值,local_file 或 env,API key 要么存本地文件要么走环境变量,不碰云。
你看,连 AI 的密钥都坚持不上云。这条 files-first 的线,它贯彻到底了。
不过这里我得说一句不太舒服的话。
README 把三条 AI 接入路径写得挺平等的,Claude Code、Codex CLI、Gemini CLI 并列。但你真去翻 ADR,0058-claude-code-first-launch-onboarding-gate.md 这个架构决策记录白纸黑字写着,Claude Code 是首启动的 onboarding gate,是头等公民。Codex 和 Gemini 拿到的是 0091-gemini-cli-external-ai-setup.md、0097-gemini-cli-agent-adapter.md 这种后补的适配,而且启动时只探测 Claude Code 一家。
说真的,这不算骗。一个项目早期押注一个 AI 工具,把 onboarding 做扎实,是合理的工程取舍。后来 0062-selectable-cli-ai-agents.md 才把 Agent 做成可选。但你要是从 README 那句三家并列推断一视同仁,那就会被误导。Tolaria 的 AI 是访客没错,但 Claude Code 是它请的贵宾。
类型是透镜,不是牢笼
知识库应用最容易翻车的地方,是「类型系统」。
Notion 的 database schema 强制你填字段,Obsidian 的 properties 半软半硬。Tolaria 的态度很有意思,架构文档原话叫 types as lenses, not schemas。类型是导航用的透镜,不是约束用的牢笼。
具体怎么落地?笔记的 type: 字段写在 frontmatter 里,可以是 Project、Person、Procedure 任何值。注意,类型只来自 frontmatter,绝不从文件夹位置推断。所有笔记平铺在仓库根目录,改类型只改一个字段,文件不用挪窝。
每个类型还可以有一个「类型文档」,一个 type: Type 的 markdown 文件,定义这个类型的图标、颜色、排序、模板。但即便如此,类型文档定义的「实例 schema」也不会回头改已有笔记。已有的实例该怎么写怎么写,类型文档只是在 Inspector 里用灰色占位符提示你缺哪些字段,新建实例时才把默认值抄过去。
我还注意到一个细节,系统属性用下划线开头。任何 frontmatter 字段名以 _ 打头就是系统属性,不显示在属性面板,不进搜索,但能在原始编辑器里手改。_pinned_properties、_icon、_color、_order 全走这个约定。Rust 端的 vault/mod.rs 和 TS 端的 utils/frontmatter.ts 两个解析器都一致地把 _* 字段过滤掉再传给 UI。
这套设计的好处是,笔记对人和对 AI 都同样可读。一份 markdown,人看是笔记,AI Agent 看是结构化上下文,谁都不被锁死。坦白讲,这种「约定优于配置」的克制,是它能把 AI 接入做得这么轻的前提。
一个人扛的项目,绕不开的几道坎
夸了这么多,该说点不中听的了。
第一道坎是 bus factor。我数过 contributors,24 个账号里 LucaRonin 一个人 3004 次提交,排第二的 evolanakis 10 次,再往后都是个位数。去掉 bot,这就是个 bus factor = 1 的项目。一个人撑着 1.8 万 star 的应用,哪天他不想维护了,整个生态就悬了。这不是 Tolaria 的错,是你选型时必须掂量的现实。
第二道坎是协议。AGPL-3.0-or-later。开源是开源,但这是强 copyleft。你要是 fork 出来做个托管版对外提供服务,modifications 必须同等开源。对个人用笔记毫无影响,但想拿它做商业二开的人得先找律师聊聊。README 里这句是诚实写出来的,不算藏,但很多人看到 open source 就默认 MIT,这里得提个醒。
第三道坎就是前面说的 Claude Code 特殊待遇。如果你是 Codex 或 Gemini 的重度用户,别指望首启动体验跟 Claude Code 一样顺,得自己补适配。
还有几个真实的开放 issue 值得看一眼。#878 macOS 上 Tolaria 反复刷新还自动滚到顶,#904 找不到 AI 工具,#905 整个 UI 缺 user-select none 导致误选。这些都是五个月项目会有的成长痛,不算硬伤,但你要上生产前心里有数。
我一直觉得,看一个项目诚不诚实,不是看它 README 写得多漂亮,是看它的 issue 区敢不敢把难堪的 bug 晾着。Tolaria 的 issue 区挺干净的,该报的都报了,没人删负面反馈。这比任何 star 数都让人安心。
给 AI 留门,而不是给 AI 装门
翻完这一圈,我脑子里剩下的是一个模式。
我把它叫做「访客型 AI 集成」。跟它相对的是「内嵌型」,比如 Notion AI、各种应用里那个紫色的 AI 按钮。内嵌型的特点是 AI 是应用的一部分,能力强但绑死,应用停更 AI 就没了,数据也搬不走。
访客型反过来。应用只负责把数据管好、把规矩写清楚,AI 是外来的、可换的、走了不伤筋动骨的访客。AGENTS.md 就是那张贴在门口的家规。
这个模式其实不止适用于笔记应用。你做任何要跟 AI Agent 打交道的本地工具,CLI 也好、桌面应用也好,都可以问自己一句,我是要把 AI 装进来,还是要给 AI 留一扇门。Tolaria 给的答案是留门。而且它把门做得很扎实,files-first 让数据永远属于你,git-first 让历史永远可追溯,AGENTS.md 让 AI 永远可替换。这三件事叠在一起,才是它 1.8 万 star 的真正底气,不是功能多,是它没让你交出任何东西。
至于那个 bus factor = 1 的风险,我自己用下来的取舍是,数据是 markdown 加 git,就算哪天 Tolaria 没了,我的笔记一行不丢,换 VS Code 接着写。这大概就是 files-first 哲学给你的最大保险。
你愿意赌一个认真的单人项目,换一份谁也拿不走的知识库吗?这题我自己已经想清楚了。
评论互动