当多个智能体依据同一组事实工作时，事实会发生变化，而各个智能体并不会同时得知变化。付款到期日就能清楚地说明这个问题。

假设发票 INV-2041 写着付款期限是 10 月 22 日，而供应商后来发来的邮件把期限改为 10 月 29 日。一个智能体读了发票，另一个读了邮件，第三个则根据自己找到的材料准备本周付款。第一个回答 10 月 22 日，第二个回答 10 月 29 日，第三个回答它先找到的那个日期。这套安排没有规定哪个日期算数，因此管理这些智能体的人还得亲自核对。

这张具体发票是我虚构的，但背后的工作安排是真实的。我让[三个工具中的智能体](https://markmhendrickson.com/posts/what-my-agentic-stack-actually-does)共同使用一个 [Neotoma](https://neotoma.io/) 实例。一个邮件轮询程序保存收到的邮件及其来源，并把需要处理的邮件转成任务；Claude Code、Codex 和 Cursor 中的会话接手[同一批任务和计划](https://markmhendrickson.com/posts/the-swarm-that-runs-my-work)。本文正是从这套安排以及我把 Neotoma 建设为全面记录系统的工作中产生的。

![一份文件和一个信封分别连接到不同的事实卡片](/images/posts/neotoma-paper/observation.svg "paper|虚构示例 · INV-2041|两个来源对同一张发票给出了不同说法：PDF 写着 10 月 22 日到期，后来的邮件写着 10 月 29 日。")

## 回忆擅长的是另一件事

检索能找到看起来与问题相关的材料。向量索引或很长的聊天记录都很擅长这一点，对许多任务而言也已经足够。但检索本身并不[确定哪项事实当前有效](https://markmhendrickson.com/posts/agentic-search-and-the-truth-layer)。询问到期日时，检索会返回发票和邮件，按它们与问题的相似程度排序，而不是按哪一个反映当前情况排序。

工具和智能体运行环境越多，问题就越难处理。一个智能体把[笔记留在 Markdown 文件里](https://markmhendrickson.com/posts/the-markdown-memory-ceiling)，另一个把学到的内容留在自己的聊天产品里，第三个读取共享文件夹。每份副本在写入时都正确。事实改变后，各副本在不同时间更新，甚至根本不更新。没有一个智能体能问“哪份副本为准”，因为不存在能回答这个问题的地方。记录系统必须位于任何单个工具之外，放在所有工具都能访问的同一个地方。

今年年初，我曾称 Neotoma 为[记忆层和真相层](https://markmhendrickson.com/posts/truth-layer-agent-memory)。后来我不再这样说，因为我认为“记忆”不是描述 Neotoma 的合适类别：这个说法[容易造成混淆](https://markmhendrickson.com/posts/your-ai-remembers-your-vibe-but-not-your-work)，人们也总把 Neotoma 同记忆类产品比较。我需要智能体保留的是关于多种事物的准确数据，而且这些数据应当可审查。存放这些数据的地方，用朴素的话说，就是记录系统。

我所说的记录系统，就是能说明当前有效的值是什么、它来自哪里、又取代了什么的地方。相似性搜索答不了这些问题，因为相似性既不说明时间，也不说明来源。

> **检索与记录**
>
> **记忆和检索工具帮助智能体保留并找到上下文。记录系统承担另一项工作：它根据已接受的观察计算当前值，并为每个字段保留返回其依据的路径。这两项工作有所重叠，一个产品也可能同时覆盖多项。**

## Neotoma 今天能做什么

我开发的 Neotoma 是面向 AI 智能体的记录系统。它以 MIT 许可证开源，在本地运行，数据目录由使用者选择。以下描述的是已发布的软件包（npm 上的 0.25.0）今天所能做的事。

每次写入都会保存为一条新的观察，并关联到它所来自的来源。新值加在旧值旁边，而不是覆盖旧值。Neotoma 可以把[原始 PDF 或邮件](https://github.com/markmhendrickson/neotoma/blob/v0.25.0/docs/developer/source_storage_by_reference.md)与从中提取的结构化实体一起保存，同时保持观察与来源的关联。

观察归属于实体。实体的 ID 由实体类型及其识别字段推导。在同一个实例中，如果身份识别规则相同，相同的识别值就会确定性地产生相同 ID，因此两个智能体保存同一张发票时会写入同一个实体。

实体之间也可以建立关联：把发票关联到供应商，或把后续任务关联到它涉及的发票。智能体会明确创建这些关系。关系说明记录之间如何相连，而来源链接则指向某条观察背后的 PDF 或邮件。

Neotoma 会自动对每个字段应用模式中规定的合并规则，根据观察计算它的当前值。对大多数字段来说，最新的观察胜出。给定相同的观察和相同的合并规则，归并过程就会生成相同的快照，不必每次读取时都让模型重新选择。

每个当前字段都会指明设定它的观察，已保存的观察则指明自己的来源。这是一条通向依据的线索，并不证明智能体正确阅读了依据。更正是又一条观察，而不是编辑；旧值仍会保留在列表中。还可以读取 Neotoma 在过去某个时刻所记录的实体状态。

回到发票。两个智能体的写入都落到同一个实体。到期日现在是 10 月 29 日，并指向来自邮件的那条观察。金额仍指向第一条观察，因为金额没有变化。付款智能体读到 10 月 29 日，而关于 10 月 22 日的观察仍连同其来源保留在记录中。

![分开的发票和邮件以细线连接到一张标记过的记录卡片](/images/posts/neotoma-paper/invoice-example.svg "paper|当前记录 · INV-2041|到期日现在是 10 月 29 日。改变的字段指向较晚的观察。金额仍来自第一条观察。两条观察都保留在记录中。")

智能体通过 MCP 服务器、REST API 和命令行工具访问 Neotoma。安装指南说明如何连接受支持的工具和运行环境。要共享记录，就让各工具指向同一实例和数据配置，或同一个 MCP 入口；不同入口可以使用不同数据库。

人们可以在随 Neotoma 提供的应用中查看自己的记录。

一项被接纳的[签名请求](https://markmhendrickson.com/posts/know-which-of-your-agents-wrote-what/)可以确立经过验证的智能体身份。有效且限定范围的授权决定允许执行哪些操作；仅有签名并不等于获得权限。

## 接下来要走向哪里

到这里，我描述的是为智能体确定当前事实的记录系统。下一步设想是由人与智能体共同维护记录系统：任何人都能问当前值是什么、哪个来源引入了它、它是观察所得、推断所得还是决策所得、谁有权更正它，以及哪些智能体曾依赖旧版本。计划中的治理能力超出了今天已有的签名身份、范围受限的授权和应用：

- 为每个领域指定明确的负责人，把更正记录的权限限定在该领域内。
- 明确表示相互竞争的主张、尚未解决的争议和正式立场。
- 展示一个值为何有效、它遵循谁的权限，以及改动会影响什么。

Ateles 在操作层面延伸了这一方向。在 [Ateles 的适配器设计](https://github.com/markmhendrickson/ateles/blob/a3e4d9ed2c33ac867bb67447221d559cbe8c5810/docs/foundation/adapters.md#L14-L22)中，适配器把邮件、日历、代码托管平台等系统的信息带入 Neotoma，并把经授权的操作送回这些系统。Neotoma 存储记录；连接的工具执行工作。

完整愿景及各部分的当前状态见 [README](https://github.com/markmhendrickson/neotoma#vision-and-execution-status)。

![领域归属：获授权的持有人触及两个有边界的区域之一](/images/posts/neotoma-paper/vision-domain.svg "paper|领域归属|领域归属将说明谁可以更正记录系统中各个有边界的部分。")
![立场跟踪：两项保留的主张连接到一份档案，其中一个立场标记为已选](/images/posts/neotoma-paper/vision-positions.svg "paper|立场跟踪|立场跟踪将保留相互竞争的主张，并使明确选定的立场可供查看。")
![解释：抬起当前字段后显露其依据和一组有边界的影响](/images/posts/neotoma-paper/vision-explanation.svg "paper|解释|解释将展示一个值为何有效、它遵循谁的权限，以及更改可能影响哪些关联值。")

## 记录系统，而不只是检索

答案不是更好的索引。检索帮助智能体找到过去说过的话。[记录系统则告诉它当前有效的是什么](https://markmhendrickson.com/posts/the-spine-of-the-loop)。跨多个工具工作的智能体需要后者，并且要有一个它们都能访问的地方。只有智能体既向记录系统写入又从中读取，记录系统才能发挥作用。

如果你在不止一个工具或运行环境中使用智能体，可以先选一个事实和实体彼此关联的工作流程：

```
npm install -g neotoma
neotoma init
neotoma setup --tool claude-code
```

使用适合你工具或运行环境的设置选项；安装指南涵盖其他受支持的集成。接着让一个智能体保存这一工作流程中相互关联的事实和实体，再让连接到相同配置实例及数据配置或 MCP 入口的另一个智能体读取它们。

安装指南位于 [neotoma.io/install](https://neotoma.io/install?utm_source=site&utm_medium=blog&utm_campaign=essay-system-of-record)。代码和问题跟踪器位于 GitHub：[github.com/markmhendrickson/neotoma](https://github.com/markmhendrickson/neotoma)。

> **愿景**
>
> **Neotoma 是面向 AI 智能体的记录系统。我们的愿景是让人与智能体拥有可共同查看、共同治理的理解：已知的是什么、为何相信它、分歧在哪里，以及谁有权改变它。这种理解应当超越任何单一模型、工具或应用而延续。**
