> For the complete documentation index, see [llms.txt](https://tinyhumans.gitbook.io/openhuman/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tinyhumans.gitbook.io/openhuman/zh/gong-neng/obsidian-wiki/memory-tree.md).

# 记忆树

<figure><img src="/files/d35b6fc623896ca971d0227edc0ce81c7ab824c8" alt=""><figcaption><p>记忆树。您的所有文档的高度压缩视图。</p></figcaption></figure>

记忆树是 OpenHuman 的知识库。它不是带有薄薄一层“记忆”包装器的向量数据库。它是一个确定性的、按桶封存的流水线，把您一天中的杂乱流——聊天、邮件、文档、集成同步结果——转化为结构化、可查询、由摘要支撑的 Markdown，并保存在您的机器上。

## 功能

您连接的每个来源都会进入同一条流水线：

```
源适配器（聊天 / 邮件 / 文档）
        |
        v
规范化    规范化后的 Markdown + 溯源元数据
        |
        v
分块器         确定性 ID，<=3k token 的受限分段
        |
        v
content_store   磁盘上的原子 .md 文件（正文 + 标签）
        |
        v
store           持久化（块、评分、摘要、任务）
        |
        v
score           信号 + 嵌入 + 实体提取
        |
        v
来源 / 主题 / 全局树   各作用域的摘要树
        |
        v
检索       搜索 / 下钻 / 主题 / 全局 / 获取
```

热路径（规范化 → 分块 → 快速评分 → 持久化 → 入队后续工作）很快。重活——嵌入、实体提取、封存摘要桶、每日摘要——在后台工作线程中运行，因此 UI 永远不会阻塞。

嵌入和摘要树构建可以运行 **在本地设备上通过 Ollama** 如果您开启 [本地 AI](/openhuman/zh/gong-neng/model-routing/local-ai.md)；否则它们会像任何其他模型调用一样通过 OpenHuman 后端。

## 三棵树，三个作用域

* **来源树**，每个来源一个滚动缓冲区（L0），缓冲区填满后会封存为 L1 → L2 → …。Gmail 每个标签一个，Slack 每个频道一个，上传的每个文档一个，等等。
* **主题树**，按实体生成的摘要由 *热度*按需延迟物化。某个实体（人、项目、代码、仓库）出现得越多，它的主题树就会越积极地构建和刷新。
* **全局树**，每天一份覆盖当天全部摄取内容的全局摘要。

检索可以针对任何作用域：搜索单个来源、下钻到某个主题，或者拉取全局摘要。

## 它在磁盘上的位置

位于您的工作区内（默认 `~/.openhuman`，或者由 `OPENHUMAN_WORKSPACE` 指向的任意位置）：

| 路径                      | 内容概览                                                                       |
| ----------------------- | -------------------------------------------------------------------------- |
| `memory_tree/chunks.db` | 块、评分、摘要、实体索引、任务、热度                                                         |
| `wiki/`                 | Markdown 保管库 - 见 [Obsidian Wiki](/openhuman/zh/gong-neng/obsidian-wiki.md) |

一切都在本地。除非您明确发送一条包含原始数据的聊天消息，否则任何原始数据都不会离开您的机器。

## 为什么是树，而不是向量存储

向量存储回答的是“与这个查询相似的是什么？”而记忆需要回答的不止这些：

* **今天发生了什么？** （全局摘要）
* **关于这个人最近有什么新进展？** （主题树，受热度驱动）
* **上周二下午 3 点 Stripe 的 webhook 说了什么？** （来源树 + 溯源）

树给您带来压缩 *以及* 和导航。嵌入仍然存在于其中，因此语义搜索依然可用，但上层结构才是让记忆像大脑而不是碎片袋的原因。

## 流水线如何工作？

面向用户的说法很简单：接入一个来源，智能体就会获得它的持久记忆。实现这一承诺的流水线横跨一个由 HTTP 触发的摄取路径、一个持久作业队列、一组后台工作线程、三棵独立的摘要树，以及一个每日 UTC 调度器

### 1. 摄取

新聊天 / 邮件 / 文档到达。热路径将其规范化为 Markdown，把它拆分为带有确定性 ID 的受限块，执行一次廉价的快速评分，把所有内容作为单个事务持久化，将每个块标记为 `待提取`，并将后续工作入队给工作线程。

这里有三个关键属性：

* **确定性。** 块 ID 以内容为地址，因此对相同输入重复运行摄取绝不会产生重复项。
* **快速。** 这条路径中没有 LLM 调用——只有廉价的启发式方法。
* **写入受限。** 所有操作都在一个事务中完成，因此部分摄取不会留下悬挂的行。

### 2. 队列

后续工作会进入一个持久作业队列（与块位于同一磁盘存储中）。每个作业都带有类型、载荷、去重键、重试账本以及一个调度窗口。类型包括：

| 类型              | 功能                                      |
| --------------- | --------------------------------------- |
| `extract_chunk` | 深度评分 + 实体提取。决定 `接纳` 还是 `丢弃`.            |
| `append_buffer` | 把一个已接纳的叶子加入来源（或主题）树的 L0 缓冲区。可能触发封存。     |
| `seal`          | 将一个 L0 缓冲区压缩为一个 L1 摘要；如果父缓冲区现在已满，则级联向上。 |
| `topic_route`   | 在热度检查的门控下，将一个叶子路由到按实体划分的主题树中。           |
| `digest_daily`  | 构建全局每日摘要节点。                             |
| `flush_stale`   | 强制封存停留过久的缓冲区。                           |

### 3. 工作线程

一小组后台工作线程（默认 3 个）从队列中取出作业并执行它们。摄取路径会立即唤醒线程池，同时还有一个短轮询兜底，因此即使错过唤醒也不会让工作滞留。一个共享信号量限制并发的 LLM 相关调用，所以新来源的突发涌入不会意外扩散成数十个并发嵌入请求。

启动时，任何其工作线程租约已过期的作业（由于崩溃或被杀死）都会被放回队列。崩溃不会丢失已接纳但尚未封存的工作。

### 4. 树状态

三棵独立的树都由同一条叶子流构建。

* **来源树** ——每个来源一棵。新叶子进入 L0 缓冲区；当缓冲区满了（或触发过期刷新）时， `seal` 会写入一个 L1 摘要，随后级联继续向上。
* **主题树** ——每个高热度实体一棵。路由器会检查某个实体是否足够“热”而值得拥有自己的树，如果是，就把它追加到它的缓冲区。
* **全局树** ——一棵树，每个 UTC 日增长一个节点，随着天数累积沿层级向上遍历。

### 5. 调度器

一个调度循环独立于摄取路径运行。每天 00:00 UTC，它会为昨天入队一个全局每日摘要，并为今天入队一个过期刷新。调度器 **不** 本身不运行摘要器——一切都通过队列完成，因此重试、去重和过期锁恢复都保持集中化。

### 6. 叶子生命周期

每个块都会经过一个小型状态机：

```
待提取 --> 已接纳 --> 已缓冲 --> 已封存
        \
         --> 丢弃
```

* 提取会根据深度评分决定 `接纳` 还是 `丢弃` 。
* 已接纳的叶子会进入缓冲区（`已缓冲`).
* 当缓冲区封存时，里面的每个叶子都会被标记为 `已封存`.
* `丢弃` 叶子到此为止。它们的块行仍保留以便溯源，但没有任何缓冲区或摘要引用它们。

这就是为什么检索能够在不重新运行流水线的情况下显示溯源：块行加上其最终生命周期状态就足够了。

## 触发摄取

* **自动** ——每个启用中的集成都每二十分钟自动拉取一次；见 [自动获取](/openhuman/zh/gong-neng/obsidian-wiki/auto-fetch.md).
* **手动** ——桌面应用中的“记忆”选项卡为每个来源提供一个“运行摄取”触发器。
* **RPC** - `openhuman.memory_tree_ingest` ，用于高级工作流。

## 在桌面应用中——智能选项卡

从底部导航栏打开它。

**系统状态。** 页面顶部显示当前状态（空闲、摄取中、汇总中）以及一个 **运行摄取** 按钮，可手动对任何已连接来源触发同步。

**记忆指标：**

| 指标            | 显示内容                                                       |
| ------------- | ---------------------------------------------------------- |
| **存储**        | 的总大小以及 `<workspace>/memory_tree/chunks.db` 和 Obsidian 保管库。 |
| **来源**        | 已摄取的不同来源数量（Gmail 每个标签、Slack 每个频道、每个文档等，各算一个）。              |
| **块**         | 存储中的总 ≤3k token 块数。                                        |
| **主题**        | 到目前为止已物化的主题树数量（由“热”实体构建的按实体摘要）。                            |
| **最早 / 最新记忆** | 最旧和最新块的时间戳。                                                |

**记忆图。** 一个基于力导向的实体及其关系可视化，来自实体索引。随着自动拉取带来更多数据，图会不断增长——最初较稀疏，几天内就会变得更密集。

**Obsidian 保管库。** 一个 **在 Obsidian 中查看 vault** 按钮会打开 `<workspace>/wiki/` 直接通过一个 `obsidian://open?path=...` 深链接。您也可以在任何文件浏览器中打开该文件夹。

**摄取活动。** 一个显示随时间变化的摄取事件热图，类似 GitHub 贡献图。对于发现自动拉取空闲的时期很有用（例如连接中断并停止同步）。

**搜索与检索。** 记忆树上的搜索栏。支持来源作用域、主题作用域或全局查询，且任何结果都会链接回您 Obsidian 保管库中的底层块文件，以提供完整溯源。

**路由。** 智能选项卡还会显示智能体在每项任务中使用的是哪个模型——见 [自动模型路由](/openhuman/zh/gong-neng/model-routing.md).

## 切换后端

记忆树流水线（分块器 → 评分 → 封存 → 汇总）是默认方案。自托管的运营者如果希望 OpenHuman 在多个智能体之间共享同一个持久存储，可以通过 [agentmemory](https://github.com/rohitg00/agentmemory) 采用外部后端 `MemoryConfig.backend = "agentmemory"`。见 [agentmemory 后端](/openhuman/zh/gong-neng/obsidian-wiki/agentmemory-backend.md) ，了解配置键、字段映射、端点表、安全性和故障模式。
