内容
# 🪨 agentcairn
[](https://github.com/ccf/agentcairn/actions/workflows/ci.yml)
[](https://github.com/ccf/agentcairn/actions/workflows/trivy.yml)
[](https://pypi.org/project/agentcairn/)
[](https://pypi.org/project/agentcairn/)
[](https://github.com/ccf/agentcairn/blob/main/LICENSE)
**AI 智能体的本地优先记忆 - 您实际上可以阅读、编辑和拥有的记忆。**
> **cairn** /kɛən/ · *noun* — 一堆石头,标记着一条小径或一个值得记忆的地方,留给后来者。
agentcairn 为您的编码智能体提供持久、高质量的记忆 - 但与将其锁定在不透明的数据库或云服务中不同,**您的记忆以纯 Markdown 文件存储在您拥有的 Obsidian 知识库中。** 一个快速、可重建的 DuckDB 索引位于其上层,用于检索。打开您的知识库,阅读智能体记住的内容,手动修复错误事实,或添加您自己的笔记 - 智能体会接收所有这些信息。
## 为什么 agentcairn 与众不同
大多数智能体记忆系统将数据库或云存储作为事实的来源,并将文件(如有)视为单向导出。agentcairn 则相反:
- **📂 您的知识库是事实的来源 - 不是导出。** 记忆是人类可读的 Markdown 文件,带有 frontmatter 和 `[[wikilinks]]`。在 Obsidian 中编辑它;索引会尊重您的编辑。
- **♻️ 索引是可处置的。** DuckDB 是一个可重建的缓存(`cairn reindex`)。您的记忆在模型升级、索引损坏、模式更改或卸载工具时存活下来 - **零数据丢失**,因为事实只是磁盘上的文件。
- **🧠 从构造上看不丢失信息。** 完整的笔记始终被保留。蒸馏只会 *添加*派生笔记,这些笔记链接回源头 - 它永远不会默默地删除它认为在写入时不需要提取的事实。
- **🔒 在每次写入前进行编辑。** 机密信息会在写入前被清除(正则表达式 + 熵 + URL 凭证检测)- 正文、标题或标签 - 以确保写入的是您可以阅读的文件。我们将凭证泄漏视为最严重的故障模式。
- **🕸️ 免费、确定性的知识图谱。** 您的 `[[wikilinks]]` 和 frontmatter *是* 图谱 - 无需大型语言模型提取,无需虚构实体。`cairn link` 将每个笔记的顶级语义邻居写入 `related:` frontmatter 列表(确定性,可选)以便在 Obsidian 中显示图谱。
- **🔮 在 Obsidian 中阅读您的记忆。** 配套的 [agentcairn-obsidian](https://github.com/ccf/agentcairn-obsidian) 插件(在 Obsidian 社区商店上)添加了一个知识库原生的 **记忆视图**:一个可筛选的笔记列表,带有出处和时效,以及一个 d3-force **记忆图**,显示 `related:` 链接 - 按项目着色,按重要性调整大小,过期笔记变暗。**0.4.0** 添加了一个 **facet-hub 图**(“按”项目/测试框架/标签分组 → 中心节点),让您可以一目了然地看到记忆的形状。
- **🤖 适用于您使用的所有智能体。** 适用于 Claude Code、Codex 和 Antigravity 的插件;适用于 Cursor 和任何其他 MCP 主机的 MCP 服务器 + 技能;以及适用于 Hermes 的原生 [Hermes](https://github.com/NousResearch/hermes-agent) `MemoryProvider`([`integrations/hermes/`](integrations/hermes/))- 所有这些都共享同一个知识库,因此您的记忆在不同智能体之间无缝切换,而不是按工具碎片化。`cairn sweep` 自动检测并摄取 Claude Code、Codex、Antigravity 和 Cursor 会话;`cairn schedule install` 在托管的 launchd/crontab 作业中保持运行,作为主机无关的捕获备份。
- **🪶 无守护进程,无外部数据库。** 一个嵌入式 DuckDB 文件执行语义向量搜索、BM25 全文搜索和图遍历。无需始终在线的服务器,无需 Neo4j/Postgres/Qdrant,无需云密钥 - 只需一个 `cairn` CLI 和一个按需 MCP 服务器。
- **🔍 诚实地衡量。** 一个可复制的 LongMemEval-S + LoCoMo 测试框架包含在 [`benchmarks/`](benchmarks/) 中 - 带有真实数字、消融和明确的注意事项,而不是一个挑选的标题(如下所示)。
## 安装
使用 [Claude Code](https://claude.com/claude-code) 或 [Codex](https://github.com/openai/codex) 的插件是最简单的使用 agentcairn 的方法 - 一个安装程序连接了 MCP 服务器、环境记忆(会话开始时回忆,会话结束时捕获)、记忆技能和斜杠命令(Claude Code):
```bash
# Claude Code
claude plugin marketplace add ccf/agentcairn
claude plugin install agentcairn@agentcairn
# Codex(来自 Codex 插件市场)
codex plugin marketplace add ccf/agentcairn
codex plugin add agentcairn@agentcairn
```
在安装时,您选择一个知识库路径(默认为 `~/agentcairn`);它将在第一个会话时**自动创建** - 无需 Obsidian 设置。从那时起,agentcairn 在每个会话开始时显示相关的记忆,将每个会话蒸馏到您的知识库中,并为您提供 `/agentcairn:recall`、`/remember`、`/memory`、`/savings` 和 `/ingest`。无需 pip 安装 - 插件通过 `uvx` 运行发布的包。
> 不使用 Claude Code 或 Codex?agentcairn 也是一个独立的 MCP 服务器 + CLI,适用于任何主机 - 请参阅[直接使用](#使用它直接)。
## 工作原理
```mermaid
flowchart LR
T["会话记录<br/>(独立)<br/>"]
H["您 · Obsidian<br/>(手动编辑)<br/>"]
V["📂 Obsidian 知识库<br/>Markdown + frontmatter + wikilinks<br/><b>事实的来源</b>"]
I["♻️ DuckDB 索引<br/>向量 + BM25 + 图<br/><b>可重建的缓存</b>"]
M["MCP 工具<br/>记住 · 回忆 · 搜索 · 构建上下文 · 最近"]
T -- "编辑 → 判断 → 蒸馏 → 合并" --> V
H -- "编辑" --> V
V -- "解析 / 协调启动" --> I
I -- "只读混合回忆" --> M
M -. "记住(编辑后写入)" .-> V
classDef truth fill:#eaf1ff,stroke:#317cff,color:#191919;
classDef cache fill:#f5f5f3,stroke:#999999,color:#191919;
class V truth
class I cache
```
- **捕获** 读取您的智能体框架的会话记录(追加,只在磁盘上)*独立* - 设计稳健,无需脆弱的实时钩子 - 然后编辑 → 去除重复 → 判断(语义持久性;可选的 LLM 蒸馏通过 `CAIRN_JUDGE=anthropic`)→ 门控 → 蒸馏到知识库中,非丢失。`cairn sweep` 自动检测每个存在的框架(支持 Claude Code、Codex、Antigravity CLI 和 Cursor),因此您可以在所有四个框架中获得统一的记忆,而无需额外的配置。在 LLM 层,它还 **合并**:复制现有记忆的记忆会被跳过,并且演变的事实的新版本会标记旧笔记 `superseded_by`(保留 + 降级回忆,从不删除)- 故障保护,确保错误的调用不会删除不同的记忆(`CAIRN_CONSOLIDATE=0` 禁用)。此外,还有一个智能体驱动的 `remember` 工具,用于精选的高价值记忆。
- **检索** 融合 BM25 + 语义向量与相互排名融合,应用可选的图增强,并 **优雅地降级** 到仅关键词,当没有嵌入模型可用时 - 因此回忆 **永远不会** 默默地死亡。可选的交叉编码器重新排序器增加精度。
- **混合智能:** 默认情况下,离线本地嵌入(FastEmbed / `nomic-embed-text-v1.5`)开箱即用 - 自身强大 *且* 在混合融合中(使用 `nomic`,矢量边缘优于 BM25,即使在短回合中;参见基准)。将 `CAIRN_EMBED_MODEL` 设置为选择另一个 FastEmbed 模型,或将 `CAIRN_EMBEDDER=ollama` 设置为本地 Ollama 模型。对于更高的召回质量,以网络调用为代价,设置 `CAIRN_EMBEDDER=voyage`(默认模型 `voyage-3`,需要 `VOYAGE_API_KEY`)或 `CAIRN_EMBEDDER=openai`(默认 `text-embedding-3-small`,需要 `OPENAI_API_KEY`;设置 `OPENAI_BASE_URL` 以适应任何 OpenAI 兼容的端点)。两个云嵌入器都是可选的 - 默认设置保持完全本地。**隐私:** 启用云嵌入器时,您的笔记文本(已经在写入时编辑过)和回忆查询将发送到提供商。这与可选的 `CAIRN_JUDGE=anthropic` LLM 层一致。**成本:** 切换嵌入器或模型会触发完整的知识库重新嵌入(维度更改)- 实际的 API 成本和延迟;请相应地计划。
- **时间记忆:** 笔记可能带有 `valid_from`/`valid_until`/`superseded_by` frontmatter。回忆是有效性感知的 - 它软化了过时和过期的事实(*当前* 事实获胜),而不会隐藏它们(非丢失),并注释每个结果的状态(`current`/`superseded`/`expired`/`not_yet_valid`)以及 `as_of` 锚点,以便智能体可以推理时间。对于没有有效性字段的笔记, inert。
- **出处感知的回忆:** 笔记带有 `project`/`harness` 出处,回忆会提升您当前项目的记忆(非丢失 - 跨项目命中仍然会显示,标记 `[from: <project>]`)。传递 `--project <repo>` 以目标另一个仓库,或 `--scope project` 以严格过滤到当前项目。
## 直接使用
插件是最简单的路径,但 agentcairn 只是一个包 - 无需 Claude Code,通过按需 MCP 服务器(适用于任何 MCP 主机)或 `cairn` CLI 使用:
```bash
uvx agentcairn # 适用于任何 MCP 主机的按需 MCP 服务器
cairn ingest --vault ~/vault # 将最近的智能体会话蒸馏到知识库中
cairn sweep --vault ~/vault # 摄取 + 重建索引,一次运行(适合 cron)
cairn schedule install --vault ~/vault # 自动运行 sweep(launchd 在 macOS 上,crontab 在 Linux 上)
cairn schedule status # 显示托管作业的状态(cairn schedule uninstall 以删除)
cairn link --vault ~/vault # 将相关邻居写入 frontmatter(填充 Obsidian 图谱)
cairn recall "我们如何修复身份验证错误?" # 从 CLI 进行混合回忆
cairn savings # 回忆节省了多少上下文
cairn reindex ~/vault # 从 Markdown 重建索引(始终安全)
cairn doctor # 索引健康检查
```
`cairn schedule install/status/uninstall` 管理一个 launchd(macOS)或 crontab(Linux)作业,定期运行 `cairn sweep` - 一个主机无关的捕获备份,以便即使对于没有环境钩子的主机,记忆也能流动。
### 配置
所有设置都存储在一个文件中 - `~/.agentcairn/config.toml` - 环境变量作为覆盖(优先级:CLI 标志 > 环境变量 > 配置文件 > 默认值):
```bash
cairn config --init # 搭建一个完整的注释模板(chmod 600)
cairn config # 显示每个设置的实际值和来源
```
例如,启用 LLM 记忆裁判是两个取消注释的行 - 无需 shell 导出(插件的后台扫描直接读取文件):
```toml
judge = "anthropic"
anthropic_api_key = "sk-ant-..."
```
## 支持的智能体
agentcairn 在两个级别工作。**插件主机**(Claude Code、Codex 和 Antigravity)获得一流的插件 - 一个捆绑的 MCP 服务器(回忆/搜索/记住)和一个内存技能,并且(在 Claude Code 和 Codex 上)环境会话钩子;`cairn install <host>` 通过调用主机的 CLI 安装插件。**MCP 主机**(其他所有主机)获得相同的回忆/搜索/记住工具,通过便携的 MCP 服务器;`cairn install <host>` 以非破坏性的方式写入 MCP 服务器配置(保留其他服务器,原始备份到 `<config>.bak`)。知识库保持单个全局 `~/agentcairn`,因此内存跨每个主机共享。
| 主机 | 支持 | 设置 | 环境捕获 |
|---|---|---|---|
| **Claude Code** | 🟢 插件 | `cairn install claude-code` | ✅ 会话开始时回忆 + 会话结束时捕获 |
| **Codex** | 🟢 插件 | `cairn install codex` | ◐ 回忆/记住实时;捆绑插件(验证)[^codex-hooks] |
| Cursor | 🔌 MCP 服务器 + 技能 + 摄取 | `cairn install cursor` | ◐ `cairn sweep` 自动检测记录[^cursor-sweep] |
| **OpenCode** | 🟢 插件 + MCP + 摄取 | `cairn install opencode` | ✅ 每轮回忆 + 捕获[^opencode-plugin] |
| **Hermes Agent** | 🟢 内存提供者插件 | 见 [`integrations/hermes/`](integrations/hermes/) | ✅ 每轮回忆 + 会话结束时捕获 |
| **Antigravity** | 🟢 插件 + 摄取 | `cairn install antigravity` | ◐ `cairn sweep` 自动检测记录[^antigravity-sweep] |
| VS Code (Copilot) | 🔌 MCP 服务器 | `cairn install vscode` | — |
| Claude Desktop | 🔌 MCP 服务器 | `cairn install claude-desktop` | — |
| 任意其他 MCP 主机 | 🔌 MCP 服务器 | `uvx agentcairn`(粘贴 `cairn install … --print` 剪贴板) | — |
[^codex-hooks]: Codex 插件安装,其捆绑的 MCP 服务器(回忆/搜索/记住)实时在 Codex 中验证。环境会话钩子(会话开始时回忆,会话结束时捕获)包含在插件中,使用 Codex 的文档钩子方案,但其在 Codex 上的行为尚未端到端确认;捕获也通过 `cairn sweep` 进行,无论如何。
[^antigravity-sweep]: Antigravity 插件捆绑 MCP 服务器 + 技能;`cairn install antigravity --source <dir>` 通过 `agy plugin install` 安装它(使用 `agy plugin install` 需要 **本地目录`或注册的 marketplace(不是 git 仓库),因此指向克隆的检查点的 `plugin/` 目录)。Antigravity 没有识别的插件钩子,因此环境捕获通过 `cairn sweep` 进行(路径:`~/.gemini/antigravity-cli/brain/<uuid>/.system_generated/logs/transcript.jsonl`)。
[^cursor-sweep]: Cursor 没有插件钩子,因此环境捕获通过 `cairn/..system_generated/logs/transcript.jsonl`)。
[^opencode-plugin]: `cairn install opencode` 将 MCP 服务器条目写入 `~/.config/opencode/opencode.json`(在 `mcp` 键下),复制环境插件(`agentcairn.ts` → `~/.config/opencode/plugin/`),该插件通过 `experimental.chat.system.transform` 将回忆注入每个系统提示,并捕获 `session.idle`/`session.compacted` 事件,并在 `~/.config/opencode/commands/` 安装 `/recall` + `/remember` 斜杠命令。摄取通过 `cairn sweep` 进行(OpenCode 会话记录)。
`cairn install` 根据主机类型自动路由:
```bash
cairn install # 检测已安装的主机并预览(不写入任何内容)
cairn install codex # 安装 Codex 插件(shell 到 `codex plugin …`;剥去任何陈旧的 MCP 块 `/codex/config.toml`)
cairn install antigravity --source ./plugin # 从本地检出安装 Antigravity 插件(参见注释)
cairn install cursor # 编写 MCP 配置 + 为 Cursor 安装内存技能
cairn install --all # 配置每个检测到的主机
cairn install codex --source /path/to/agentcairn # 使用本地检出而不是市场
```
MCP 主机需要一个 JSON `mcpServers` 条目(VS Code 使用其 `servers` 键)。插件主机(Claude Code、Codex、Antigravity)通过插件安装插件 - MCP 服务器捆绑在插件中,不需要单独的配置文件。如果您以前使用 `cairn install antigravity` 将 MCP 条目写入 `~/.gemini/config/mcp_config.json`,请重新运行 `cairn install antigravity` 以自动删除该过时条目。
## 基准测试
我们以一种我们希望内存系统被衡量的方式进行基准测试 - **可复制,具有消融和单一的选定指标,而不是一个挑选的数字。** 测试框架 (`benchmarks/`) 运行 **LongMemEval-S** 和 **LoCoMo**,通过版本固定的下载器(永远不会使用内嵌的数据集),确定性地评估检索(recall/nDCG@k,MRR - 无需 API 密钥,在 CI 上使用综合测试用例运行),并提供一个可选的 LLM 评估的 QA 层。
### 检索 - LoCoMo
完整的 LoCoMo 集合,每轮,宏观平均值,FastEmbed `nomic-embed-text-v1.5`(默认嵌入器):
| 武器 | recall@5 | recall@10 | MRR |
|---|---|---|---|
| 仅限 BM25 | 0.527 | 0.604 | 0.459 |
| 仅限向量 | 0.536 | 0.637 | 0.433 |
| 混合(RRF)| 0.562 | 0.648 | 0.477 |
| 混合 + 图增强 | 0.562 | 0.648 | 0.477 |
| **混合 + 重新排序器** | **0.662** | **0.735** | **0.608** |
我们从中读取并大声说:
- **混合优于单独的任一分支** - RRF 融合值得一试。
- **交叉编码器重新排序器是最大的杠杆**(+0.10 recall@5 超过混合);“ms-marco 领域偏移可能有害”的担忧在对话式数据中没有实现。
- **默认嵌入器现在发挥作用** - 使用 `nomic`,仅矢量边缘超过 BM25(0.536 vs 0.527);从旧的 `bge-small` 默认值(落后于 0.483)缩小差距,一个 5 模型 FastEmbed 扫描确定了选择 - `nomic`(768-d)胜于质量/维度;更大的 1024-d 模型无法超越它。完整的表格:[`benchmarks/README.md`](benchmarks/README.md)。
### 检索 — LongMemEval-S
完整的500实例集 — 一个较简单的任务,证据会话之间有很好的分离。会话级别是之前工作报告的粒度;回合级别是更细致、揭示语料库的切片:
| 方法 | 会话召回率@5 | 会话MRR | 回合召回率@5 | 回合召回率@10 | 回合MRR |
|---|---|---|---|---|---|
| 仅BM25 | 0.920 | 0.918 | 0.680 | 0.791 | 0.638 |
| 仅向量 | 0.936 | 0.916 | 0.507 | 0.692 | 0.454 |
| 混合(RRF) | 0.954 | 0.938 | 0.640 | 0.798 | 0.544 |
| **混合 + 重排序器** | **0.969** | **0.963** | **0.788** | **0.891** | **0.716** |
诚实地看:
- **我们的0.969会话召回率@5与之前工作的≈0.95处于同一水平**,在相同的完整500问题集上 — 而且在完整规模下,它具有*区分度*(0.920 BM25 → 0.969 重排序器),而不是像小样本那样饱和。
- **重排序器再次成为最大的杠杆** — 回合召回率@5从0.640 → 0.788,会话召回率@5从0.954 → 0.969。
- **回合级别揭示语料库:** 这里,仅BM25(0.680)*优于* RRF混合(0.640),因为仅向量在这些单回合证据跨度上较弱(0.507);重排序器是将默认值拉高的原因。(对比LoCoMo,其中仅向量优于BM25。)
### 上下文效率
agentcairn *回忆*的上下文代理比您通常带入模型的完整历史要小多少?默认配置(混合 + 重排序器,k=10):
| 数据集 | 查询数 | 平均上下文大小 | 平均回忆(k=10) | 上下文减少倍数 |
|---|---|---|---|---|
| LoCoMo(3次对话) | 497 | 25,646 ток | 529 ток | **51.1倍平均 / 50.3倍中位数** |
| LongMemEval-S(完整500) | 470 | 136,552 ток | 2,207 ток | **64.7倍平均 / 61.6倍中位数** |
估计(~4字符/ ток),不是计费成本;"上下文" = 完整的索引历史,"回忆" = 返回的top-k块。它衡量上下文*大小*,独立于检索质量。
### 问答准确率
问答准确率数字(LLM评判)也可获得,但使用Anthropic评判器而非论文中的GPT-4o,因此**与已发布的排行榜不可比较** — 仅对相对消融信号有效。参见[`benchmarks/README.md`](benchmarks/README.md)了解如何运行它以及如何读取数字。
## 开发
agentcairn 独家使用 [uv](https://docs.astral.sh/uv/) 进行依赖管理和工具链管理。
**请勿使用pip、poetry或全局虚拟环境。**
```bash
# 首次设置
uv sync # 创建.venv并安装所有依赖(包括开发依赖)
uv run pre-commit install # 安装git钩子(每提交运行ruff + pytest)
# 日常使用
uv run pytest # 运行测试套件
uv run cairn --help # 运行CLI
uvx agentcairn # 临时运行已安装的工具(与MCP服务器相同)
# 格式化和 linting
uv run ruff format . # 格式化所有Python文件
uv run ruff check --fix . # lint并自动修复
uv run pre-commit run --all-files
# 基准测试(离线检索指标无需API密钥)
uv run pytest benchmarks/tests/ # 离线合成fixture套件
PYTHONPATH=benchmarks uv run --group bench python -m cairn_bench.run --dataset locomo
```
MCP服务器通过`uvx agentcairn`启动 — 无需全局安装。
## 许可证
[Apache License 2.0](LICENSE) — 允许的,带有明确的专利授权。版权所有 © 2026 Charles C. Figueiredo。
连接信息
猜你喜欢
暂无推荐服务器