---
title: 手搓属于你的 LLM Wiki｜基于 seekdb，我做了一个升级版
description: Karpathy 的 LLM Wiki 用 LLM + 本地存储做知识管理，ex-brain 在此基础上再往前走一步——Compiled Truth 智能编译让知识自动更新，时间线自动抽取，实体关联自然生长，底层用 seekdb 混合搜索统一向量与关键词检索。本地优先、完全可编程、MCP 直连 Claude。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

[AI](https://www.oceanbase.com/obi) 咨询热线

前不久，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 中，不会干扰对当前状态的理解。

### **设计理念**

不同类型的知识，有着不同的生命周期——有些会“过期”，有些不会：

| 类型 | 怎么处理 | 例子 |
| 状态信息 | 会过期，要更新 | 融资阶段、CEO、员工数 |
| 事实信息 | 不过期，留着 | 成立时间、行业、总部 |
| 事件信息 | 记下来当历史 | 产品发布、融资完成 |

这套分类并非写死的规则，而是由 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 其他公司它能识别的关系类型：
```

| 关系 | 例子 |
| 创始人 | Ali founder_​of Neo |
| 工作地 | Sarah works_​at River AI |
| 领导 | John leader_​of Engineering |
| 投资 | Sequoia invested_​in River AI |
| 收购 | Google acquired YouTube |

### **关系被发现时，自动建页面**

当系统识别出一个新实体时，会自动建个页面记下来：

```
# 自动创建的 people/sarah-chen
## Facts- **CEO_​of** [River AI](companies/river-ai): 2024年6月接任
```

知识网络就这样在使用过程中自然生长。

![oceanbase database](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/obc-blog/img/1789717251350/image.png)

## **核心机制四：混合检索**

### **单一搜索方式的局限**

在知识库检索中，单靠一种搜索方式往往不够理想：

- **全文搜索** ——精确，但不理解语义。搜“融资”，找不到“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 即可使用以下工具：

| 工具 | 功能 |
| `brain_​get` | 读取页面 |
| `brain_​put` | 写入页面 |
| `brain_​search` | 搜索知识 |
| `brain_​compile` | 编译新信息 |
| `brain_​link` | 建立关联 |

你可以让 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 地址：https://www.npmjs.com/package/ex-brain

```
# 安装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。或者你有更好的想法，欢迎来讨论——知识管理这件事，还有很多可以探索的空间。

![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*5Oy_QZjvTg8AAAAAAAAAAAAADiGDAQ/original)
