前不久,AI 领域知名研究者 Andrej Karpathy 开源了他的 LLM Wiki——一个用大语言模型维护的个人知识库。它的思路非常简洁:把知识以纯文本形式存在本地,由 LLM 负责理解和更新。这个项目一经发布便引发了广泛讨论,很多开发者开始思考:LLM + 本地存储,到底能把“个人知识管理”做到什么程度?
我在看了 Karpathy 的 LLM Wiki 和 Garry Tan 的 GBrain 之后深受启发——他们用最简单的组合(LLM + 本地存储)搭建出了一个能“理解”知识的系统。我想在这个基础上再往前走一步,于是做了 ex-brain。
现有工具的局限
市面上的知识管理工具,大致分为两类,但各有不足:
传统笔记(Notion、Obsidian 等)——功能强大,但你写进去的东西,它不会帮你“消化”。一条笔记写进去,三个月后依然原封不动地躺在那里。想找关联?只能靠手动翻阅。
AI 笔记(Mem、Granola 等)——确实有 AI 帮你整理了,但感觉就整理那一下,之后呢?更重要的是,AI 怎么理解你的内容、怎么归类、怎么提取要点,这些逻辑你完全没法控制。它的脑子不是你的脑子。
如果知识库能像人脑一样,每次写入新信息都自动“更新”认知,会怎样?
这正是 ex-brain 的核心理念。它引入了一个核心概念:Compiled Truth(编译后的真相)。名字听起来有些拗口,但原理很直观。
核心机制一:智能编译
问题:信息越记越多,越看越累
传统工具的处理方式很简单:要么追加到页面末尾,要么新建一个页面。结果就是信息越堆越多,但认知并不会自动更新。
举个例子,假设你记录了三条关于 River AI 的信息:
3月:River AI 完成 A 轮融资,5000 万美元
6月:Sarah Chen 接任 CEO,创始人转顾问
8月:B 轮 1.2 亿美元
半年后你想了解 River AI 的现状,需要读完三条记录,再在脑中拼凑出“现在是什么情况”的全貌。而人脑的工作方式很自然——接收到新消息后,会自动将旧信息标记为“已过时”。但传统工具做不到这一点。
“编译”你的知识库
ex-brain 的核心机制正是“编译”机制。通过一条命令,即可触发知识的智能更新:
ebrain compile companies/river-ai \
"River AI 上了 A 轮,5000 万美元" \
--source meeting_notes \
--date 2024-05-20
系统会自动执行以下流程:
第一步:让 LLM 分析信息类型
系统会判断这条消息属于哪种类型:
-
状态变了(融资阶段从 Seed 变成 Series A)?
-
还是发生了一个事件(产品发布了)?
-
还是更正了旧信息?
第二步:根据类型选择处理策略
-
状态类信息(融资阶段、CEO)→ 直接更新,旧值归入历史记录
-
事实类信息(成立年份、行业)→ 追加,不删旧的
-
事件类信息 → 同时记录到时间线中
第三步:更新 Compiled Truth
编译完成后,页面呈现为结构化的“当前真相”:
## Status
- **Funding Stage**: Series A(Source: meeting_notes, 2024-05-20)
- **Valuation**: ~$50M
## History
- 之前是 Seed(到 2024-05-20 为止)
## Facts
- A 轮领投方是 Sequoia
- 2020 年成立的
“当前真相”一目了然,历史信息完整保留在 History 中,不会干扰对当前状态的理解。
设计理念
不同类型的知识,有着不同的生命周期——有些会“过期”,有些不会:
这套分类并非写死的规则,而是由 LLM 在每次编译时基于语义自动判断,而非简单的关键词匹配。
核心机制二:时间线自动抽取
时间是理解变化的关键维度
人要理解事物的变化,时间线是最直观的方式。观察一家公司的发展历程,本质上就是在阅读它的时间线。
ex-brain 能够自动从文本中提取时间线事件:
ebrain timeline extract companies/river-ai
系统会从 Compiled Truth 和历史记录中,自动提取并结构化关键事件:
e[
{
"date": "2024-05-20",
"summary": "A 轮融资完成,5000 万",
"detail": "Sequoia 领投"
},
{
"date": "2024-06-15",
"summary": "Sarah Chen 接任 CEO"
}
]
灵活的日期识别
系统支持多种日期格式,无需手动统一:
-
2024-05-20(ISO)
-
2024年5月20日(中文)
-
May 20, 2024(英文)
-
last week、yesterday(相对日期)
系统会自动识别并标准化这些格式。
编译与时间线抽取协同工作
时间线并非独立功能,而是与编译机制深度集成。每次执行 compile 操作时,系统会自动将文本中的事件提取到时间线中。
完整流程如下:
你写:"River AI 上了 A 轮"
↓
系统:这是状态更新 + 事件
↓
系统:更新融资阶段 → Series A
↓
系统:时间线加一条 → "A 轮完成"
核心机制三:自动关联实体
知识不是孤立的事实
一条知识之所以有价值,往往是因为它与其他知识存在联系。“Ali Partovi 是 Neo 创始人”——这条信息的核心不只是 Ali 或 Neo,而是“创始人”这个关系本身。
ex-brain 利用 LLM 自动识别文本中的实体关系:
ebrain put people/ali-partovi --file notes.md
# 系统自动认出:
# - Ali Partovi founder_of Neo
# - Ali Partovi invested_in 其他公司
它能识别的关系类型:
关系被发现时,自动建页面
当系统识别出一个新实体时,会自动建个页面记下来:
# 自动创建的 people/sarah-chen
## Facts
- **CEO_of** [River AI](companies/river-ai): 2024年6月接任
知识网络就这样在使用过程中自然生长。
核心机制四:混合检索
单一搜索方式的局限
在知识库检索中,单靠一种搜索方式往往不够理想:
全文搜索——精确,但不理解语义。搜“融资”,找不到“funding round”。
向量搜索——理解语义,但可能漏掉精确词。搜“Sequoia”,可能返回一堆“sequoia tree”的无关结果。
实际使用中,我们需要的是两者的结合——既能精确匹配关键词,又能理解查询意图。这正是 混合搜索(Hybrid Search) 的核心价值。
ex-brain 使用了 seekdb 的混合搜索,它在一个引擎中统一了向量搜索、全文搜索与标量过滤,支持在一条查询中同时完成语义召回和关键词召回。
这意味着你不需要拼接两套检索系统,一条 SQL 就能同时利用向量相似度和 BM25 关键词匹配:
# 精确关键词搜索
ebrain search "River AI Series A"
# 语义查询
ebrain query "哪些公司最近融资了?"
在底层,seekdb 的混合搜索支持多路召回与多阶段排序链路:先通过向量索引和全文索引分别召回候选结果,再通过加权融合或 RRF(Reciprocal Rank Fusion)进行重排序,甚至支持基于大模型的 Rerank。这套机制确保了召回的全面性和排序的精准性。
搜索结果的智能加权
ex-brain 在 seekdb 混合检索的基础上,进一步引入了多维度评分逻辑:
-
语义匹配占主导(85%)——基于向量相似度
-
新鲜度有加成(10%)——最近更新的内容优先级更高
-
类型权重也有影响(5%)——人物类型通常值得优先关注
多维加权确保搜索结果既相关、又新鲜、又重要。
技术实现
为什么选 seekdb
ex-brain 的底层数据库选用了 seekdb。作为一个 AI 原生数据库,seekdb 在以下几个方面与 ex-brain 的需求高度契合:
嵌入式部署,零运维:seekdb 支持嵌入式模式,一个数据库文件即可运行,无需搭建独立的数据库服务。对于个人知识库这类本地优先的应用场景,这是最轻量的选择。轻量到什么程度?1C2G 的配置即可流畅运行。
原生混合检索:seekdb 在一个引擎中同时支持向量搜索、全文搜索和标量过滤,并且支持粗排 + 精排的多阶段搜索链路。向量索引方面,支持基于内存的 HNSW、HNSWSQ、HNSWBQ,以及基于磁盘的 IVF、IVF_PQ 等多种索引类型,可根据数据规模灵活选择。全文搜索支持关键字、短语及布尔表达式等多种匹配模式,并支持 BM25 排序。
内置 AI 函数:seekdb 提供了一套完整的数据库内 AI 工作流。通过 AI_EMBED 函数可在 SQL 中直接将文本转换为向量嵌入,通过 AI_COMPLETE 函数可执行文本生成,通过 AI_RERANK 函数可调用重排序模型对结果进行精排。支持 OpenAI、DashScope 等多种模型服务,也支持注册自定义模型。这意味着嵌入生成、语义检索和推理可以在数据库内一站式完成,无需在应用层拼接多套系统。
SQL 兼容:seekdb 源于成熟的 OceanBase 引擎,兼容 MySQL 生态。熟悉 SQL 的开发者可以直接上手,建表、建索引、写查询都遵循标准 SQL 语法。同时支持实时写入、实时可查,具备完整的 ACID 事务保证。
多模数据统一管理:除了向量和文本,seekdb 还在同一引擎内支持标量、JSON、GIS 等多模数据及索引。对于 ex-brain 这样需要同时管理结构化元数据(页面属性、关联关系)和非结构化内容(文本、向量嵌入)的应用,一套数据库即可覆盖全部需求。
灵活的部署模式:除了嵌入式模式,seekdb 还支持 Client/Server 模式。如果未来需要团队协作共享知识库,只需切换到远程服务模式即可,应用代码无需大幅改动。
以下是 ex-brain 中使用 seekdb 的核心代码:
// 连接数据库——就是一个文件路径
const db = await BrainDb.connect("~/.ebrain/data/ebrain.db");
// 创建向量集合
const pages = await db.getOrCreateCollection({
name: "ebrain_pages",
embeddingFunction: createBrainEmbeddingFunction(settings.embed),
});
// 混合检索
const hits = await pages.hybridSearch({
query: { whereDocument: { $contains: "融资" } },
nResults: 10,
});
seekdb 将数据存储与语义检索统一在一个引擎中,省去了拼接多套系统的复杂度。对于 AI 应用开发者而言,这意味着更简洁的架构和更低的维护成本。
数据结构
ex-brain 的数据存储结构设计如下:
-
pages 表:存储每个知识页面(slug、标题、compiled\_truth)
-
links 表:存储实体之间的关联关系
-
timeline\_entries 表:存储时间线事件
-
ebrain\_pages 集合:存储向量嵌入,用于语义检索
关系表和向量集合位于同一套数据库中,数据一致性由 seekdb 的 ACID 事务保证,无需额外操心。
让 AI 直接操作你的知识库
ex-brain 内置了 MCP Server。如果你使用 Claude,只需简单配置即可让它直接读写你的知识库:
// Claude Desktop 配置
{
"mcpServers": {
"ebrain": {
"command": "ebrain",
"args": ["serve"]
}
}
}
配置完成后,Claude 即可使用以下工具:
你可以让 Claude 帮你整理知识,它直接操作本地数据库,无需手动复制粘贴。
设计原则
本地优先——数据存储在本地,一个 seekdb 文件。无需联网,不必担心服务商停运。
完全可编程——所有操作均可通过命令行执行,方便编写脚本、接入 AI、实现自动化:
# 管道输入
cat note.md | ebrain put my/note --stdin
# JSON 输出,方便脚本处理
ebrain get companies/river-ai --json | jq '.compiledTruth'
幂等操作——重复执行不会产生副作用。对同一个文件执行十次 put,结果保持一致。
命令结构统一——采用resource verb的命名模式:
ebrain timeline list companies/river-ai
命令结构可预测,降低学习成本。
数据导入
知识库需要内容填充。手动输入效率不高,从网页复制粘贴又需要清理格式。
推荐使用 MarkSnip——一个浏览器扩展,可以一键将网页内容剪藏为干净的 Markdown。
核心能力:
-
一键剪藏整页或选中内容
-
自动提取正文(基于 Mozilla Readability)
-
代码块带语言标签,表格对齐,数学公式支持
-
本地处理,不传云端
配合 ex-brain 使用:
# MarkSnip 剪藏后保存为 article.md
# 然后导入知识库
cat article.md | ebrain put articles/my-article --stdin
# 或者智能编译(让 LLM 整理)
ebrain compile companies/river-ai --file article.md --source web_clip
这样就形成了一个完整的工作流:浏览网页 → MarkSnip 剪藏 → ex-brain 编译 → 知识库自动更新。
快速开始
npm 地址:
# 安装
bun install -g ex-brain
# 初始化——就是建个数据库文件
ebrain init
# 写第一个页面
ebrain put companies/river-ai --type company --content "
River AI 是一家 AI 分析平台公司。
2020 年成立。
"
# 编译一条新信息
ebrain compile companies/river-ai \
"River AI 上了 A 轮,Sequoia 领投" \
--source news \
--date 2024-05-20
# 搜一下
ebrain search "River AI 融资"
# 启动 MCP 服务(配合 Claude 使用)
ebrain serve
未来探索方向
这个项目仍处于早期阶段,但核心机制已经可以正常运行。以下是几个值得继续探索的方向:
冲突处理——当新信息与已有记录矛盾时(例如新信息说 CEO 是 Sarah Chen,但之前记录的是 John Doe),目前的做法是直接替换并将旧值归入 History。更理想的方式是标记冲突,由用户确认。有时两条信息都正确,只是对应不同时间点;有时确实是错误信息,需要人工判断。
信息衰减——一条信息长期未更新,其可信度是否应该降低?例如 2022 年记录的“公司有 50 人”,到 2024 年很可能已经过时。系统可以标注“上次更新:2022 年”,提醒用户关注时效性。这不是简单的过期删除,而是为用户提供一个判断信号。
关联传播——River AI 的 CEO 变了,Sarah Chen 的页面是否应该自动更新?目前系统会创建关联页面,但不会反向同步。理想情况是:一处更新,关联页面收到提醒,但不会自动修改——因为 Sarah Chen 可能同时担任其他职位。
批量编译——当需要一次性整理 100 条关于某公司的新闻时,逐条 compile 效率太低,但一次性输入又可能超出 LLM 的处理能力。需要设计分批处理、增量合并的方案,在效率和质量之间取得平衡。
这些方向涉及的不只是功能迭代,而是“知识该如何管理”的根本问题。如果你有想法,欢迎在评论区交流。
写在最后
做这个项目,本质上是在探索一个问题:知识库应该是什么样的?
好的知识库不应该只是一个“仓库”。它应该像人的记忆一样——会更新、会标记过时、会把新旧信息串联起来。现有工具大多做到了“存”,但没有做到“活”。
Karpathy 和 Garry Tan 的实践给了我启发:用 LLM 来“消化”知识。ex-brain 在此基础上进一步探索——信息的时效性分类、时间线自动抽取、实体关联自动生长。这些机制让知识库不再是静态的笔记集合,而是能随着认知更新而持续演进的系统。
当然,这个项目还有很多不完善的地方。编译逻辑还不够智能,时间线提取偶尔会遗漏,实体关联有时会误判。但核心理念是明确的:知识是活的,工具也应该让它活起来。
如果你也在思考如何让知识库更“聪明”,不妨试试 ex-brain。或者你有更好的想法,欢迎来讨论——知识管理这件事,还有很多可以探索的空间。
关于 seekdb
ex-brain 的数据存储与检索能力由 seekdb 支持。
seekdb 是一个开源的 AI 原生混合搜索数据库,在一个引擎中统一了向量搜索、全文搜索、结构化数据与 AI 函数,专为 RAG、语义搜索、AI Agent 等应用场景设计。无论是嵌入式的个人项目,还是需要团队协作的生产环境,seekdb 都能灵活适配。
如果你也在开发需要“存储 + 语义检索 + AI 推理”能力的应用,欢迎试试 seekdb:
-
官网:seekdb.ai
-
开源地址:github.com/oceanbase/seekdb(欢迎 Star ⭐️)
-
快速上手:
pip install -U pyseekdb -
文档:docs.seekdb.ai