关于 Compartment
Compartment 是面向 AI Agent 的离线加密记忆 MCP 服务,将持久记忆保存在本地保险库,供不同 Agent 和会话共享。它结合向量与关键词检索,并支持来源日期记录、过期设置和关系链接。
主要功能
- 01加密的本地记忆保险库
- 02向量与关键词混合搜索
- 03记忆来源、日期和过期设置
- 04关系、标签与意见更新
- 05本地嵌入且不发起网络调用
- 06仪表板和 Agent 集成
适用场景
- 01跨会话共享 Agent 记忆
- 02让敏感记忆数据保持离线
- 03按来源和日期上下文检索事实
- 04查看保险库内容和记忆关系
MCP 相关
Compartment 向 MCP 客户端提供记忆存储、检索、关系查询和近期记忆视图。它可与 Claude Code、Claude Desktop、Hermes Agent、OpenClaw、Cursor、Codex 等 MCP 客户端配合使用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
14收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kind | enum | 否 | fact | opinion |
| tags | any | 否 | |
| text | string | 是 | |
| source | string | 是 | |
| expires | any | 否 | |
| namespace | any | 否 | |
| discovered | any | 否 | |
| importance | number | 否 | |
| supersedes | any | 否 | |
| quarantined | boolean | 否 |
详细介绍
Compartment
为 AI Agent 提供加密、完全离线的记忆。 在你自己的电脑上使用一个保险库,由 Claude Code、Claude Desktop、Hermes Agent、OpenClaw、Cursor、Codex 和任何其他 MCP 客户端读取和写入。无需 API 密钥、账号、网络连接或遥测。
一键安装(安装并运行 compartment init 后):
Claude Code、Claude Desktop、Hermes Agent 和 OpenClaw 则可通过一条命令完成配置:compartment integrate claude、hermes 或 openclaw。
Compartment 是为 AI Agent 提供的持久记忆,存储在你自己的电脑上。Agent 在某次会话中学到的内容,在之后的每次会话、每个项目中,以及这台机器上的每个 Agent 都可以使用,而且任何内容都不会离开这台机器。
每条记忆都是一项独立的陈述,并记录其来源和学到的日期。记忆可以过期:设置 expires 后,记忆会在该日期之后删除。当偏好发生变化时,新偏好会取代旧偏好。回忆功能通过内存索引执行向量与关键词混合搜索,约 12 ms 即可作答,并且只返回相关内容。
嵌入模型已包含在软件包中。磁盘上的所有内容都会加密,包括嵌入向量,只有你的密码短语才能解锁。新建知识库会附带约 6,700 条关于硬件、操作系统、端口、编码和 Shell 工具的参考事实。它们都是普通记忆,只需切换一个开关即可将其从搜索中移除。
与其他记忆服务的比较
根据各项目截至 2026 年 9 月 2 日的文档,比较各服务保存记忆的位置及其保护方式。来源和完整表格见 docs/COMPARISON.md;欢迎针对该文件提交 PR 进行更正。
| 静态存储的记忆 | 加密 | 账户 / API 密钥 | 运行时网络 | |
|---|---|---|---|---|
| Compartment | 一个加密文件;索引存于 RAM | 是,向量也加密 | 无 | 无,由 CI 强制检查 |
@modelcontextprotocol/server-memory | 明文 memory.jsonl,子串搜索 | 否 | 无 | 无 |
| mem0(开源) | 向量存储 + LLM 提取的事实;其 MCP 服务仅托管在线上 | 未说明 | LLM 密钥 | LLM 调用;默认启用遥测 |
| Graphiti(Zep)/ Letta | Neo4j / 服务 + 数据库 | 未说明 | LLM 密钥 | LLM 调用;默认启用遥测 |
| claude-mem | 本地 SQLite + Chroma | 未说明 | 需要登录 | 账户 + 提供商调用;默认启用遥测 |
| basic-memory(AGPL) | Markdown + SQLite | 未说明 | 无 | 默认启用遥测 |
| Hindsight(Vectorize) | 一个容器,内含嵌入式 PostgreSQL | 未说明 | LLM 密钥(可配置本地模型) | LLM 调用;供应商声明不收集遥测 |
| Supermemory | 云服务,或可自托管的预构建二进制文件 | 未说明 | 账户(云端)或 LLM 密钥(自托管) | 云端调用;自托管:供应商声明不收集遥测 |
| Cognee | 本地 SQLite + LanceDB + Kuzu,或云端 | 未说明 | LLM 密钥 | LLM 调用;默认启用遥测 |
| MemOS | 自托管的 Neo4j + Qdrant,或云端 | 未说明 | LLM 密钥 | LLM 调用;默认启用遥测 |
记忆逻辑
几乎所有内容都会被存储。 只有空回合会被丢弃。单独一句“好的”代表一项决定,而非噪声:当 Agent 问 “现在要我把这条回复发给客户端吗?”,而用户回答 “好的” 时,Compartment 会将这项决定与它所回应的问题一并存储。闲聊也会保留,但排名最低。
重要性按固定等级分配。 决定和同意为 0.90,个人事实和偏好为 0.80,用户的机器和配置为 0.75,其他实质性陈述为 0.55,闲聊为 0.20。重要性会乘以匹配分数,而非与之相加,因此它能在分数接近时优先考虑重要内容,而且绝不会让与问题不匹配的记忆浮现。
强制每条记忆只包含一项主张。 存储区会拒绝超过 200 个字符(max_memory_chars 设置)的内容,也会拒绝包含列表、标题或段落的内容,并给出说明如何拆分的错误提示。仅靠指令不起作用:在一个真实的知识库中,Agent 写入的记忆中位长度为 1,938 个字符,内容是带项目符号的会话日志。memory_store_many 可在一次调用中存储一批记忆;compartment atomize 可拆分现有知识库中超出限制的记忆;每个拆分后的部分都会保留原记忆的日期,原记忆则会标记为已取代,但仍可通过 id 读取。
每条记忆都会记录来源和日期。 必须提供 source,例如“来自聊天”“从 pyproject.toml 读取”“网页搜索”。discovered 是获知事实的日期,与保存日期分开。两者都会作为简短的补充说明附加到文本末尾,例如 [网页搜索,2026-08-01]。
记忆可以过期。 对于已知会在某个日期后失效的事实,例如促销价、预订或门禁密码,可将 expires 设置为该日期(2026-09-03)或一个时长(14d、2w、3m、1y)。记忆会在该日期后移除。compartment expire 可手动执行清理;expire_memories 会关闭此功能。大多数事实不应设置过期时间;错误的过期设置会删除用户想保留的记忆。
事实会累积,观点会更新。 新事实会与其他事实并存:门禁密码已更改、某个脚本位于某个路径、某个版本已发布。观点则会替换旧观点。存储偏好时使用 kind="opinion",知识库会先查找相似的有效观点。若找到,就返回旧记录而不插入新记录;调用方可通过重新发送并指定 supersedes=[old id] 来替换它,或指定 supersedes=[] 来保留两者。重述一条有效观点会刷新其日期,而不是存储副本。已被取代的记录会从搜索结果中移除,但仍保留在审计链中,并可通过 ID 读取,同时附有指向替代记录的指针。supersedes 也适用于事实,可用于更正。观点排名会加上事实排名没有的时效性加分,因此最新的观点会胜出。compartment opinions audit 可在较旧的知识库中查找相互重叠的有效观点,并保留最新的一条,或将它们报告出来以供手动合并。
捕获不依赖模型。 在系统提示词中声明了自身记忆的宿主,可以覆盖任何工具指令。因此,integrate claude 会安装一个 PostToolUse 钩子,将 Claude Code 保存的每个记忆文件写入知识库,无论模型是否调用工具。该钩子不会影响其他钩子,会先备份 settings.json,始终成功退出,因此绝不会导致编辑器出错,并且在知识库锁定时不会执行任何操作。可使用 compartment hook status | install | uninstall,或使用 integrate claude --no-hooks。compartment import-claude 可导入钩子遗漏的内容。
搜索会返回相关内容,而不是固定数量。 Compartment 会返回所有得分相对于同一问题最佳结果仍然足够高的记忆,并设有较宽松的上限。截断依据的是相对分数,因为不同问题之间的分数不可比较:在一个真实的知识库中,荒谬的查询“如何烤酸面包”得分高于真实查询“Max 对 Airtable 做了什么决定”。如果知识库中没有某个问题的相关内容,就不会返回任何结果。传入 top_k 可获取确切数量的结果。
标签会保持更新。 记忆所描述的内容不会改变,但它所关联的内容会改变。假设你在一个名为 Northwind 的项目中工作时,了解到客户希望先看数据,再看结论。Agent 会给这条记忆加上 northwind 标签。两年后,同一位客户现在名为 Harbour,再次聘用你,而 Agent 使用 harbour 标签进行搜索。这条记忆仍然正确,但标签筛选找不到它。因此,后台流程会为每条记忆添加其嵌入空间中最近邻所带的标签,并按相似度加权:随着 Harbour 相关记忆不断出现在这条旧记忆附近,它也会获得 harbour 标签。除此之外,还会同时使用另外两种信号:几乎总是同时出现的标签会相互推导;现有标签的短语若出现在记忆文本中,也会被附加上去。该流程只写入标签,不会写入文本、日期或嵌入向量。除非传入 --prune,否则它只会添加标签;tags_origin 会保留原始标签,而 compartment retag --dry-run 会显示将要进行的更改。
既有列表,也有图。 memory_link 用于记录关系:主体、谓词、客体,还可选择关联一条记忆和有效期。memory_relations 可按实体、谓词或指定日期查询。Compartment 会以确定性方式存储和匹配关系;由宿主模型决定要链接哪些关系。
记忆是数据,不是指令。 召回的记忆会附带说明,指出它们是存储的数据。来自不可信来源的内容可标记为 quarantined,这样每次召回时都会附带警告。宿主 Agent 仍必须将记忆视为数据。
每个知识库只使用一种嵌入模型。 模型的 SHA-256 会记录在知识库中,并在打开时进行校验,以确保相似度分数保持可比。若要更换模型,请运行 compartment reindex --re-embed。
内部不包含 LLM。 嵌入在本地运行,使用随附的 384 维 int8
ONNX 模型。所有 Agent 在同一台机器上共用一个约 70 MB 的进程。由宿主模型决定存储和
忘记什么;Compartment 负责捕获、加密和回忆。这种分工确保离线保证绝对可靠,且每项决策都可复现。使用离线
LLM 时,整个 Agent 无需联网即可运行。
看看它学到了什么。 compartment recent 会列出最新记忆,
并隐藏参考事实,让你能看到自己的记忆。
compartment status 会在总数旁报告 organic_records。
memory_recent 则是 MCP 上的相同视图。
应用和仪表板
每个系统都有相同的面板:在 macOS 上位于菜单栏,在 Windows 上位于通知区域,在 Linux 上则是普通窗口,可在应用程序菜单中找到。 Linux 特意采用窗口形式:GNOME 或 Wayland 上可能永远不会显示托盘图标,而解锁记忆的控件 绝不能悄无声息地失效。
面板会显示保险库是否已打开、其中有多少条记忆以及你存储了多少条,还会显示三个值得更改的设置(捕获钩子、搜索中是否显示参考事实、自动锁定)、已连接的 Agent,并提供连接 Claude、Hermes Agent 或 OpenClaw 的按钮,以及最近五条 记忆。你无需使用终端,就能在那里解锁、锁定并更改密码短语。面板会立即打开,显示上次读取的内容,并在后台刷新,且仅在内容确实发生变化时刷新。使用面板期间,一个辅助进程会以只读方式保持保险库打开,并在 Agent 添加新记忆时读取这些新记忆;空闲十分钟后,该进程会退出,因此应用闲置时不会持有保险库或密钥。查看内容不会锁定、解锁或重写保险库。它的设计初衷是成为电脑上众多应用之一,而不是需要你学习使用的东西:每项功能都是一个按钮或开关,默认设置则是经过测量后选定的。
仪表板按钮会在浏览器中打开整个保险库:随时间变化的增长情况、列出所有实体名称的关系图、标签、各 Agent 的数量以及实时搜索。它仅在 127.0.0.1 上从内存提供服务,只读且不会发出外部请求。
数学原理
以下内容都位于同一个文件中:
src/compartment/ranking.py,由
保险库、仪表板和基准测试共用。因此,基准测试分数衡量的就是
产品本身。
存储:长记忆按窗口嵌入
编码器会读取 512 个 token。超出部分完全不可见,因此过去长记忆只能通过开头内容进行搜索。在一个包含 6,705 条记忆的真实 保险库中,40% 的记录超过了窗口限制,57.6% 的文本对语义搜索 不可见。
因此,每条记录都按重叠窗口进行嵌入,窗口大小为 W = 448 个 token,步长为 S = 384,保留 64 个 token 的重叠,以免事实被截成两半,
并以得分最高的窗口作为该记录的分数:
windows(d) = ceil( max(0, tokens(d) - W) / S ) + 1 capped at 64
s_vec(d) = max over windows w of d : cos(q, w)
取最大值,而非平均值:只要记忆的任一部分相关,这条记忆就相关;取平均值 则会因为记忆的其他部分而惩罚长记忆。每条记录只有一个窗口时,这与旧行为完全相同,因此短记忆不受影响。 大多数记忆都很短:6,705 条记录生成了 6,785 个窗口。窗口按模型 token 数计算,而非字符数,因为按字符数设定预算,在普通文本和十六进制摘要之间会相差三倍。
Recall:两个通道,合并为证据
两个索引回答不同的问题。向量索引回答记忆的含义,关键词索引回答记忆的内容。它们的分数不在同一尺度上,如何合并才是关键问题。
在 4.7 之前,Compartment 会将它们相加。相加会让表现尚可的语义匹配压过确凿的字面证据:在真实知识库中搜索一个仅出现在一条记忆里的提交 SHA 时,返回的那条记忆排名低于十条对它的改述,因为求和淹没了排名第一的关键词命中。
两个通道是二选一,而不是相加:任一通道都能单独确立相关性。这是对独立证据进行软 OR 运算,
P(relevant) = 1 - (1 - p_vec)(1 - p_lex)
分数则取其对数,排序结果不变,同时能让顶部附近的结果继续拉开差距,而不是在 1 处饱和:
score(d) = - w_vec · log(1 - p_vec(d)) - w_lex · log(1 - p_lex(d))
w_vec = 0.75 w_lex = 0.25
任一通道接近确定性时,都足以单独支撑这条记忆;两者都不能否决对方。
将余弦相似度转换为概率。 L2 归一化的编码器给出的余弦相似度可以跨查询比较,因此可以用固定边界映射。按每条查询进行最小—最大归一化,会把无望查询中的最佳命中重新缩放到 1.0,从而丢掉这部分信息。
p_vec(d) = clamp( (cos(q, d) - 0.25) / (0.85 - 0.25), 0, 0.88 )
0.88 的上限很重要。余弦相似度表示相似,而非同一:编码器可以判断这说的是同一件事,却无法判断这就是你指定的那条记录。而某条记忆中独有字符串的字面匹配可以做到这一点。因此,语义通道的上限低于字面通道所能达到的分数,并且该上限由权重决定:字面通道的最高分为 0.25 · -log(1 - 0.999) = 1.727,所以 0.75 · -log(1 - cap) < 1.727,得出 cap < 0.90。
在不使用 BM25 的情况下,将关键词命中转换为概率。 BM25 衡量文档的匹配程度,但这并不能解决它与语义命中的竞争。真正决定胜负的是该匹配偶然出现的可能性有多低。每个查询词都携带其在整个知识库中的自信息,而记忆的得分则是它涵盖的查询信息所占的比例:
I(t) = log( N / (1 + df(t)) ) N = records in the vault
p_lex(d) = ( Σ I(t) for query terms t present in d ) / ( Σ I(t) for all t )
某个词若只出现在一条记忆中,就几乎能得出确凿结论;若出现在知识库十分之一的记录中,那它几乎没有信息量,无论 BM25 分数如何。这正是让字面命中与语义命中可以相互比较的关键。
关键词索引会先按 AND 查询,因为精确短语是最强信号。FTS5 的隐式 AND 要求九个词的问题逐字出现,因此当 AND 查询没有结果时,会退回到只针对信息量较高的词进行 OR 查询:凡是出现在超过 10% 记录中的词都会被剔除。这个阈值根据知识库计算,而不是取自英语停用词表,因此对代码、名称或其他语言同样适用。
此外,还会加上一个较小的排名一致性项。这是互惠排名融合表现良好的唯一方面,并将其大小设为足以打破平局:
+ w_rrf · k · [ 1/(k + rank_vec) + 1/(k + rank_lex) ] w_rrf = 0.10, k = 20
重要性和近期性会重新排序分数
evidence(d) = aged( vec term, q(d) ) + lex term + rank residue
final(d) = evidence(d) · ( 1 + w_imp · (2·importance(d) - 1) + w_op )
aged(s, q) = log( 1 + 2^( -q / half_life_share ) · (e^s - 1) )
q(d) = share of the vault's own memories written after this one
half_life_share = 0.5, so the median memory is worth half the odds
w_imp = 0.15, for facts and opinions alike
w_op = 0.30 · 2^( -age_days / 30 ) for an opinion, from the last
re-affirmation (`affirmed`); 0 for a fact
**采用乘法,因此先验只能重新排列已经匹配的记忆。**加法先验会让重要记忆因无关问题而浮现。没有匹配任何内容的记忆得分为零,并会保持为零。
以默认值 0.5 为中心,因此使用 2·importance - 1。每条未加权记忆的权重都是 0.5,包括数千条参考事实;若不做中心化,它们都会获得相同的加成,重要性也就不起作用。经过中心化后,未加权记忆的权重为中性,只有刻意设置的权重才会产生影响。
**记忆的年龄按记忆数量计算,而不是按天数计算。**一条事实不会在六个月后变得不那么真实;旧记忆之所以会成为错误答案,是因为知识库已经发生变化,而变化了多少取决于写入了多少内容。因此,记忆的年龄等于其之后写入的知识库内容所占的比例。两周内新增两条记忆,不会影响一条两周前的记忆;同一两周内新增五百条记忆,则会使其语义证据背后的胜算减半。统计范围是正在搜索的命名空间中知识库自身的活动记忆:不包括参考事实,也不包括已安装的软件包,因为它们会在同一时刻成千上万地加入,按此定义并无年龄。
这一偏移只应用于语义通道,并以胜算的形式计算,因此强匹配只会受到轻微调整,弱匹配则会按比例缩减。字面标识符不受影响:只出现在一条记忆中的提交 SHA,无论是昨天还是去年写入的,都指向那条记忆。而相关性下限读取的是未计入年龄的分数,因此近期性只决定结果的顺序,不会影响哪些结果会被返回。由此带来一个结果:返回记忆所报告的 score 是计入年龄后的分数,可能低于它通过的绝对下限;因此,下限是知识库执行的筛选条件,并非返回数值本身的属性。
观点还会叠加第二个先验,这个先验按时间计算:从上次重申起,每 30 天减半,幅度足够大,因此某个主题上最新的观点会胜出。
检索顺序
命名空间、标签、日期和参考事实筛选器会在排序后运行,因此,如果候选池大小仅等于所请求的结果数量,筛选器可能会清空候选池,而匹配的记忆却恰好排在截断位置之后。候选池从每个通道 200 条开始;如果筛选后数量不足,最多会扩大三次。记录数低于 20,000 时,向量搜索是精确的(SIMD 矩阵运算,召回率 1.0);超过此数量后使用 HNSW,召回率约为 99%,除非 usearch 无法在该机器上使用 SIMD——Agent 的沙盒可能会隐藏它探测的 CPU 特性——这种情况下会保留精确索引,因为每次打开时在无 SIMD 的情况下重建 HNSW,处理 25,000 条记录就要花 50 秒。
安全性与锁定模型
基础机制:对所有静态存储的数据进行 XChaCha20-Poly1305 加密,包括嵌入向量,因为向量可以被反向还原为文本 · 采用 LUKS 风格的 Argon2id 密钥槽 · 每条记录使用单独的密钥,因此 forget --shred 会销毁密钥,使内容无法恢复,而非仅标记为已删除 · 已执行 fsync 的封存日志、原子压缩,以及经过测试的 kill -9 恢复 · 哈希链审计日志(compartment audit verify)· 已签名的知识库清单和软件包 · 使用 stdio 传输且不开放端口;唯一的本地套接字是共享嵌入进程的 Unix 套接字,与解锁凭据位于同一私有目录中,用于输入文本、输出向量,绝不传递密钥 · 运行时防护机制会在任何网络套接字尝试时中止(--assert-offline),CI 会在 Linux、macOS 和 Windows 上启用该机制运行完整测试套件。完整的威胁模型,包括 Compartment 无法防护的情况,见 SECURITY.md。
在应用中
日常操作都只需点击按钮。解锁会要求你输入密码短语;锁定会关闭保险库并清除所有已存储的凭据;更改密码会重新加密保险库;自动锁定可设置为闲置 15、30 或 60 分钟后锁定,也可设置为从不锁定。Compartment 不会生成密码、种子或恢复短语,也不会持有任何你未提供的凭据。
解锁后,只要你不主动关闭,保险库就会一直保持打开状态,即使进程结束、退出登录或重新登录也不例外;直到重启或断电、自动锁定计时器触发,或你手动锁定为止。重启或断电后,保险库始终会锁定:解锁凭据是由每次启动随机生成的密钥包装的主密钥,该密钥仅存在于内核内存中,绝不会写入磁盘,因此新一次启动无法用它打开保险库。单独复制凭据文件毫无用处。
在命令行中
同样的控制方式,另有两项仅在此处提供:
compartment unlock和compartment lock执行与按钮相同的操作。Agent 可以使用memory_lock工具锁定保险库。(较早版本中发行的、带有恢复短语的保险库仍接受该短语。)compartment 2fa enable会添加第二重验证:你的密码短语加上一个密钥文件,例如存放在 USB 盘上的文件。两者会一起输入 Argon2id,因此这一要求由密码学机制强制执行,而非由设置控制;即使窃取了保险库文件和你的密码短语,没有密钥文件也无法打开保险库。系统会记住密钥文件的位置,因此只要它在,解锁过程就和以前一样。- 在 macOS 上,
compartment unlock --keychain是一项明确选择启用且可在重启后保留的选项。
memory_unlock MCP 工具确实存在,但默认关闭,因为启用它会将密码短语放入模型的上下文中。
一个保险库,多个 Agent,任意设备
无需命令行
这台机器上的每个 Agent 都使用同一个保险库,无需进行任何设置:应用中的连接 Agent按钮可配置 Claude、Hermes Agent 和 OpenClaw;一个 Agent 存储的内容,其他 Agent 都能检索。Claude、Hermes Agent、Cursor 和 CLI 可以同时使用保险库:写入操作通过文件锁串行处理,每个进程都会发现其他进程的写入并重新加载,而且每个 Agent 都有自己的身份和命名空间。它们的服务还会共用一个嵌入进程,因此十个 Agent 只需一个模型的内存;最后一个 Agent 退出后,该进程还会保留几分钟。
已锁定的保险库是一个文件:位于你主目录下 .compartment 文件夹中的 memory.vault。要迁移到另一台机器,请先锁定保险库,将该文件复制到新机器,安装 Compartment,然后在应用中使用密码短语解锁。
在命令行中
可以用经过签名的方式完成同样的迁移,让接收方能够验证;此外还有以下备用选项:
compartment lock --sign
scp ~/.compartment/memory.vault other-machine:
compartment --vault memory.vault unlock # your passphrase (+ keyfile if 2FA)
lock --sign 会添加 Ed25519 清单,接收方无需凭据即可使用 compartment verify 验证。export --plaintext 会将保险库导出为 JSONL,import 则可将其重新导入,因此你永远不会被锁定在其中。
FORMAT.md 逐字节说明了 .vault 和 .mpack 文件格式。每个 Agent 的命名空间可在设置文件中授予 rw、ro 或 none 权限,因此临时 Agent 可以读取但无法写入。
记忆包是经过签名的精选记忆只读捆绑包(compartment pack build | install | remove | list | export)。它们安装在 packs/<name> 下,对所有调用方均为只读;include_packs_in_search 可用于切换是否将其纳入搜索。记忆包的签名会根据你信任的密钥验证,而绝不会根据包内的密钥验证。参考事实是唯一一个以普通记忆形式存放在 main 中的记忆包。
PACKS.md 介绍了如何编写记忆包。
compartment setup airgap-bundle 可为无法联网的机器准备安装包;setup download-model 和 setup download-longmemeval 则会下载可选基准测试所需的内容。
在 8 GB 基准笔记本上的实测数据
以下每项数据都可以在你的机器上通过 compartment selftest 和 compartment bench 重现(--longmemeval 会运行检索基准测试);compartment embed-daemon status 会报告共享进程自身的大小。
| 指标 | 实测数据 |
|---|---|
| 全新安装 → 打开保险库,离线 | 数秒,无网络 |
| 向量搜索,20k 条记录(HNSW) | p95 0.68 ms |
| 完整混合搜索(嵌入 + 窗口 + 关键词 + 证据融合) | 中位数 11.6 ms,p95 14.7 ms |
| 共享嵌入进程,每台机器加载一次模型 | 常驻内存 68 MB |
| 对 64 个长文本窗口执行两批处理后 | 71 MB;在 4.9.6 之前,每个 Agent 的服务都占用 1.5 GB,后来增至 3 GB |
| 使用共享守护进程中的模型的 MCP 服务进程 | 60 MB,另加其保险库和索引 |
| 存储一条记忆(嵌入 + 加密 + fsync 日志) | 约 40 ms |
| wheel 大小,含模型 | 约 30 MB |
| 测试套件(加密、篡改、崩溃、离线、并发、双重身份验证、图谱、仪表盘、排名) | 800+ 项测试,离线防护已启用 |
安装
无需命令行。 在 Mac 上,从最新版本下载 Compartment-<version>.pkg(Apple 芯片)或 Compartment-<version>-intel.pkg(Intel),然后打开即可。Python、嵌入模型和所有依赖项都已包含其中。它会要求你选择一个密码短语、创建保险库,并将 Compartment 添加到菜单栏;其中的 Connect an agent 按钮会完成其余操作。
在任何系统上,也可以通过命令行安装:
| pipx(推荐) | pipx install compartment && compartment init |
| uv | uv tool install compartment && compartment init |
| pip | 在虚拟环境中运行 pip install compartment && compartment init。Debian 12+、Ubuntu 23.04+、Fedora、Arch 和 Homebrew 会拒绝系统级 pip install,并显示 "externally-managed-environment";pipx 和 uv 可避免此问题。在 Windows 上,运行 py -m pip install compartment |
| 安装脚本 | 在代码检出目录中运行:bash install/install-linux.sh(Linux、WSL、ChromeOS)、bash install/install-macos.sh 或 powershell -ExecutionPolicy Bypass -File install\install-windows.ps1。每个脚本都会选择适用于该机器的 Python,处理 externally-managed 情况,创建保险库,并连接检测到的 Agent |
| Docker | 在代码检出目录中运行 docker build -t compartment .;参见连接各个 Agent |
Agent 也可以从各自的商店安装它——Claude Desktop 扩展(每个版本中都有 compartment-<version>.mcpb)、Claude Code 和 Codex 插件市场、Gemini CLI 扩展、Hermes Agent 插件等。每种方式仍需要通过 compartment init 创建保险库,因为密码短语由你亲自输入。docs/PLUGINS.md 列出了所有商店及其安装命令。
运行平台
| 系统 | CPU | pip / pipx / uv 所需的 Python 版本 | 应用 |
|---|---|---|---|
| macOS 14 或更高版本 | Apple silicon | 3.11 - 3.14 | 菜单栏;.pkg / .dmg |
| macOS 13.4 或更高版本,以及所有 Intel Mac | Apple silicon、Intel | 3.11 - 3.13 | 菜单栏;Intel 机型使用 -intel.pkg / -intel.dmg |
| Windows 10 / 11 | x64 | 3.11 - 3.14 | 系统托盘图标 |
| Windows 11 on ARM | ARM64 | 3.12 - 3.14 | 系统托盘图标 |
| 使用 glibc 2.28+ 的 Linux(Ubuntu 20.04+、Debian 11+、Fedora、RHEL 8+、Arch、openSUSE)、WSL 2、ChromeOS Linux | x86_64、aarch64(包括 Raspberry Pi 5) | 3.11 - 3.14 | 窗口(需要 Tk:python3-tk 或发行版的等效软件包) |
| Docker | amd64、arm64 | 镜像内置 | 无头模式 |
这些限制来自 onnxruntime,这是唯一无法在所有平台上提供 wheel 的依赖项:从 1.24 起,其 macOS 版本需要 macOS 14;最后一个 Intel Mac 版本(1.23.2)最高支持 Python 3.13。CI 会在表中每个平台上运行测试套件,并检查整个矩阵中是否有需要编译的依赖项(tools/wheel_coverage.py)。在 Windows 上,onnxruntime 还需要
Microsoft Visual C++ runtime
(ARM64);如果缺少该运行时,Compartment 会提示你。
其他平台,使用系统提供的 onnxruntime。 Alpine(musl)、FreeBSD 和 Android(Termux)会自行打包 onnxruntime;请从系统安装,并为 Compartment 提供一个能够访问它的虚拟环境。安装脚本会替你完成这些操作。
# Alpine
apk add python3 py3-onnxruntime
# FreeBSD (default Python 3.12; the compiled dependencies come from packages)
pkg install py312-onnxruntime py312-tokenizers py312-pydantic-core py312-pynacl py312-argon2-cffi py312-numpy py312-cryptography
# Termux
pkg install python onnxruntime python-numpy rust
# then, on any of them
python3 -m venv --system-site-packages ~/.compartment-venv
~/.compartment-venv/bin/pip install compartment && ~/.compartment-venv/bin/compartment init
在 Termux 上,解锁凭据无法跨进程共享,因此请设置 COMPARTMENT_PASSPHRASE,或使用 compartment unlock --once。不支持低于 2.28 的 glibc、32 位系统、armv7 和 riscv64。在 WSL 2 上,虚拟机闲置后关闭会清除解锁凭据,因此保险库会在会话之间重新锁定。
init 会要求你选择一个密码短语、创建保险库、加载参考事实、连接已安装的 Claude Code、Hermes Agent 或 OpenClaw,并启动应用:macOS 上显示菜单栏项目,Windows 上显示系统托盘图标,Linux 上则打开一个窗口。重启 Agent 后,它就拥有记忆了。
若要稍后连接 Agent 或其他客户端:
compartment integrate claude # Claude Code + Claude Desktop
compartment integrate hermes # Hermes Agent
compartment integrate openclaw # OpenClaw
compartment integrate --list # the 33 MCP clients it can wire: Cursor, VS Code, Windsurf, Cline, Roo Code, Kilo Code, Zed, OpenCode, Codex CLI, Gemini CLI, Kiro, Amazon Q, Junie, Goose, LM Studio, Continue ...
compartment integrate --all # every one of them that is installed here
claude、hermes 和 openclaw 还会在各自的 skills 目录中安装 /compartmentalize 技能。其他任何 MCP 客户端都使用此配置块(stdio 传输,无环境变量):
{ "mcpServers": { "compartment": { "command": "compartment", "args": ["serve"] } } }
从 Dock、Finder 或“开始”菜单启动的应用看不到 shell 的 PATH,因此直接使用 compartment 可能会失败,并显示 "spawn compartment ENOENT"。请使用 which compartment(Windows 上为 where compartment)输出的完整路径;integrate 始终会写入该完整路径。
接入各类 Agent
这些操作都不需要终端:应用中的 Connect an agent 按钮会为 Claude、Hermes Agent 和 OpenClaw 执行相同的步骤。以下命令适合偏好使用命令行的用户,也适合接入应用未列出的客户端。在 Windows 上,请在 PowerShell 中运行 py -m pip install compartment,代替 pip install compartment。
Claude(Code + Desktop)
pip install compartment && compartment init && compartment integrate claude
使用 Claude Code CLI 注册 MCP 服务(用户范围,适用于所有项目),导入 Claude Code 已写入其记忆文件的记忆(仅复制且可重复执行;--no-import 可跳过此步骤),安装捕获钩子(--no-hooks 可跳过此步骤),安装 /compartmentalize 技能,在 CLAUDE.md 中写入受管理的代码块;如果已安装 Claude Desktop,则先备份其配置文件,再在其中注册服务。该服务还会在 MCP 握手中介绍自身,告知模型在回答前回忆信息,并存储持久事实、凭据、名称和决策,让 Claude 无需任何手动指示即可使用 Compartment 作为记忆。
Hermes Agent
pip install compartment && compartment init && compartment integrate hermes
将提供程序插件安装到 Hermes 环境中,并运行 hermes memory setup compartment;使用 hermes memory status 验证。Hermes Agent 0.20.0 及更高版本也支持读取可移植的 Agent Plugins 格式,本仓库就是采用此格式的项目。此方式会从 GitHub 安装 MCP 服务和 /compartmentalize 技能:
pip install compartment && compartment init
hermes plugins install MaxFreedomPollard/Compartment
hermes plugins enable compartment
提供程序是更完整的集成方式,因为它会在每轮对话中回忆和存储信息;可移植包只有在模型调用其工具时才会生效。在 macOS 和 Windows 上,两种方式都会安装到同一个插件目录,因此请择一使用。
OpenClaw
pip install compartment && compartment init && compartment integrate openclaw
将 mcpServers 条目写入 ~/.openclaw/openclaw.json,并先进行备份。然后运行 openclaw gateway restart,并使用 openclaw mcp list 检查。
任何 MCP 客户端
compartment integrate <client> 可接入 --list 中列出的 33 个客户端。每次写入配置前都会创建逐字节精确的备份;合并而非替换配置;以原子方式写入;如果文件无法解析,则拒绝修改(并打印可供粘贴的代码块)。如需手动操作,请使用安装中的代码块;VS Code 使用键 servers 和 "type": "stdio",Zed 使用 context_servers,Codex 使用 [mcp_servers.compartment] 下的 TOML。--vault 和 --caller 均为可选项;默认值分别为 ~/.compartment/memory.vault 和调用方 user。各客户端的详细操作指南见 docs/INTEGRATIONS.md。
Docker
在检出目录中运行 docker build -t compartment .,即可构建无头镜像(amd64 和 arm64):仅支持 stdio、不开放端口、使用非特权用户、启用离线保护,并将保险库挂载到 /data。请先在主机上使用 compartment init 创建保险库,因为该步骤会提示输入密码短语,然后向客户端提供以下命令:
docker run -i --rm --network none --user "$(id -u):$(id -g)" \
-v "$HOME/.compartment:/data" -e COMPARTMENT_PASSPHRASE compartment
在 Linux 主机上,--user 可让容器读取权限为 0600 的保险库;在 macOS 和 Windows 上使用 Docker Desktop 则无需此选项。
配置
以下内容均非必需。Compartment 安装后已完成配置;如果想要更改设置,可在此查看所有可配置项。
在应用中
图标后方的面板:Unlock 和 Lock、Change password、Create memories automatically(捕获钩子)、Search starter facts、Auto-lock(15、30、60 分钟或从不)、用于连接 Claude、Hermes Agent 和 OpenClaw 的 CONNECT AN AGENT 按钮、Refresh 和 Quit。
命令
全局标志,放在命令之前:--vault PATH、--caller NAME、
--keyfile PATH、--assert-offline、--version。
| 命令 | 功能 |
|---|---|
init | 创建知识库。--passphrase、--creator、--keychain、--no-session、--no-app |
unlock / lock | 打开或关闭知识库。--passphrase-stdin、--keyfile、--keychain、--once;lock --sign --identity |
status / verify / selftest | 查看其中的内容、检查是否完好、测试是否正常运行 |
store / get / forget | 操作单条记忆。--source(必填)、--discovered、--expires、--namespace、--tag、--importance、--kind fact|opinion、--supersedes ID、--keep-both、--quarantined、--raw;forget --shred |
search / recent | 查找内容。--namespace、--tag、--top-k、--limit、--all、--json |
expire | 删除已过期的记忆 |
atomize | 将超出限制的 blob 记忆列为 JSONL(--out + --plaintext),应用由 Agent 编写的拆分方案(--apply) |
opinions audit | 为符合意见特征的记录补填 kind,聚类有重叠的有效意见,并用 --keep-newest 解决冲突。--threshold、--no-backfill、--json |
link / relations / unlink | 操作关系图及其有效时间窗口(--from、--to、--as-of) |
panel(menubar、tray) | 操作应用。--show、--self-check、--render、--login |
integrate <agent> | 接入 claude、hermes、openclaw 或任意列出的客户端,并安装 /compartmentalize。--list、--all、--no-import、--no-hooks;integrate --refresh 会更新先前写入 Agent 文件的说明,不做其他更改 |
hook | Claude Code 捕获钩子:install --pin-vault、uninstall、status、capture |
import-claude | 导入 Claude Code 已写入的内容。--dir、--namespace、--dry-run |
serve | 通过 stdio 运行 MCP 服务 |
embed-daemon | 供每个 Agent 使用的共享嵌入进程:status、stop、run |
dash | 在浏览器中读取知识库:127.0.0.1、一次性令牌、仅限 GET |
export / import | export --plaintext 会以未加密形式写入;import 会将其读回 |
rekey | 更改密码短语。--new-passphrase-stdin |
2fa | enable、disable、status:使用密钥文件作为第二重验证因素 |
audit | verify、repair 哈希链历史记录 |
retag | 根据当前知识库重新计算标签(--dry-run、--prune);绝不更改记忆文本 |
reindex | 重建索引,并为缺少嵌入窗口的长记录补上窗口。--int8、--f32、--re-embed、--model |
pack | build、install、remove、list、export 签名记忆包(--trusted-key) |
bench | --records、--longmemeval、--variant、--limit |
setup | download-model、download-longmemeval、airgap-bundle |
update | 原地升级,然后刷新 Agent 文件中的说明。--source 接受 GitHub main;--no-app 跳过重启 |
uninstall | 移除它。除非传入 --purge,否则会保留知识库 |
compartment panel --login on | off | status 用于控制是否在登录时启动(在
Linux 上即应用程序菜单项)。在无头机器和 CI 环境中,init --no-app 会跳过应用。
compartment dash 是终端中的 Dashboard 按钮:在浏览器中查看整个知识库、
随时间变化的增长情况、包含所有实体名称的关系图、标签、各 Agent 的计数和实时搜索。它
仅从 127.0.0.1 上的 RAM 提供服务,通过随机 URL 令牌进行保护,只读,不会发起
出站请求,也无需配置。按 Ctrl-C 关闭。
/compartmentalize 技能
compartment integrate <agent> 会将一个文件写入该 Agent 自己的技能目录,而
compartment uninstall 会将其移除:
| Agent | 路径 |
|---|---|
| Claude Code | ~/.claude/skills/compartmentalize/SKILL.md |
| Hermes Agent | $HERMES_HOME or ~/.hermes/skills/compartmentalize/SKILL.md |
| OpenClaw | $OPENCLAW_HOME or ~/.openclaw/skills/compartmentalize/SKILL.md |
三者都使用相同的 Agent Skills 布局,因此只需一个文件。只有用户会运行它。在压缩上下文之前或任何时候输入该指令,Agent 就会将整个对话存入保险库:人物和联系人、凭据及其存放位置、URL 和主机、决策及其原因,以及本次会话的记录。它会进行许多 memory_store 调用。你可以编辑自己的副本;之后重新安装时,会先备份已更改的副本,而不会覆盖它。
设置文件
<vault>.config.json,位于保险库旁,其中包含各调用方的授权,以及:
| 设置 | 默认值 | 含义 |
|---|---|---|
auto_lock_minutes | 30 | 闲置多久后锁定。0 表示永不锁定 |
search_starter_facts | true | 是否将预置事实纳入搜索结果 |
include_packs_in_search | true | 对已安装的资料包是否执行同样操作 |
recency_half_life_share | 0.5 | 在一条记忆的语义证据权重减半前,保险库中必须有多少内容比它更新。0 表示关闭时效性先验 |
expire_memories | true | 自动移除已过期的记忆 |
duplicate_threshold | 0.97 | 判定存储内容重复时所用的余弦相似度阈值 |
max_memory_chars | 200 | 手动编写的记忆的单条主张长度上限。0 表示关闭长度和布局检查 |
opinion_update_threshold | 0.80 | 新观点被视为对现有有效观点的更新、因而需要决定是否取代它的相似度阈值 |
opinion_reaffirm_threshold | 0.97 | 重述的观点被视为重申现有有效记录、而非另行存储的相似度阈值 |
retag_interval_hours | 6 | 后台任务重新计算标签的频率。0 表示关闭 |
retag_prune | false | 该任务是否也可以移除标签 |
index_precision | "f32" | "int8" 只需四分之一的 RAM |
embed_daemon | true | 调用机器共享的嵌入进程获取向量,而不是在当前进程中加载模型 |
unlock_tool_enabled | false | 允许 Agent 解锁保险库。默认关闭,因为口令会进入模型的上下文 |
环境
COMPARTMENT_VAULT 指定要使用的保险库,COMPARTMENT_PASSPHRASE 用于脚本
和 CI,COMPARTMENT_SESSION_DIR 指定解锁凭据的存放位置,
COMPARTMENT_UI_SCALE 设置面板缩放比例,COMPARTMENT_ASSERT_OFFLINE 在发生任何
网络尝试时中止。COMPARTMENT_EMBED_DAEMON=0 会让每个进程各自加载嵌入模型,
而非使用共享进程;COMPARTMENT_EMBED_SOCKET 用于更改该进程的套接字位置,
COMPARTMENT_EMBED_IDLE 指定该进程在最后一个客户端退出后继续运行的秒数(300)。
适用时会读取 HERMES_HOME、OPENCLAW_HOME 和 XDG_DATA_HOME。导出的任何
ENGRAM_* 变量仍然有效。
MCP 工具
每个工具都有标题和只读或破坏性注释,因此客户端在调用前可以区分七个只读工具和会写入的工具。memory_search、memory_store、memory_store_many、
memory_get、memory_recent、memory_forget、memory_link、
memory_relations、memory_unlink、memory_list_namespaces、
memory_status、memory_lock、memory_selftest。memory_unlock 也存在,
但除非你在上方启用,否则默认关闭。
文档
| docs/MEMORY.md | 记忆的存储方式、会记住哪些内容,以及排序设计 |
| docs/PLUGINS.md | 所有插件商店和目录:用户如何从中安装,以及维护者负责什么 |
| docs/INTEGRATIONS.md | 如何在 Hermes Agent、OpenClaw、Claude 及其他工具中选择 Compartment |
| docs/COMPARISON.md | 其他记忆服务,以及相关来源 |
| SECURITY.md | 完整的威胁模型及其局限 |
| FORMAT.md | .vault 和 .mpack 的字节级规范(与语言无关) |
| PACKS.md | 如何编写和分发已签名的记忆包 |
| CONTRIBUTING.md | 环境搭建、优质议题,以及需要保持的保障措施 |
| RELEASING.md | 如何发布新版本 |
隐私政策
Compartment 不会收集任何数据:没有遥测、分析、账户,也不会在运行时联网。记忆仅存储在你的设备上,并使用永不离开设备的密码短语进行 AEAD 静态加密;任何内容都不会与他人共享。完整政策涵盖数据收集、存储、网络访问、与第三方共享、保留期限及联系方式,详见 https://maxfreedompollard.github.io/Compartment/privacy。
在哪里可以找到它
Compartment 已收录于 PyPI、 官方 MCP registry、 Cursor Directory、 Glama、 LobeHub、 MCP Toplist、 MCP Market、 mcpservers.org、 TensorBlock、 toolsdk.ai registry、 Libraries.io、 Snyk Advisor 和 deps.dev,也收录于精选列表 abordage/awesome-mcp、 TensorBlock/awesome-mcp-servers 和 Jenqyang/Awesome-AI-Agents。
Bug 和功能请求:Issues。 支持与问题:Discussions; 安全问题报告:SECURITY.md。 问题和想法:Discussions。
mcp-name: io.github.MaxFreedomPollard/compartment
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。