关于 emem, the verifiable memory protocol for the physical world
emem 是面向机器和 AI 的共享、可验证记忆协议,可在数据留在原处时发布签名证明,供 AI 和开发者核验来源及数据完整性。
主要功能
- 01源端生成签名记录
- 02Merkle 树证明文件单元
- 03离线核验签名收据
- 04记录可重算的派生结果
- 05保留修正与历史记录
适用场景
- 01证明文件中的指定部分未被篡改
- 02离线核验地理观测数据
- 03追踪 Agent 派生结论的来源
- 04更正记录而不抹除旧版本
MCP 相关
提供远程 MCP 服务 https://emem.dev/mcp,向客户端提供记忆查询、核验、推导、比较和修正等工具。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://emem.dev/mcpclaude mcp add --transport http vortx-ai-emem https://emem.dev/mcp{"mcpServers":{"vortx-ai-emem":{"type":"http","url":"https://emem.dev/mcp"}}}在 Cursor 中打开{"servers":{"vortx-ai-emem":{"type":"http","url":"https://emem.dev/mcp"}}}在 VS Code 中打开{"mcpServers":{"vortx-ai-emem":{"type":"http","url":"https://emem.dev/mcp"}}}{"mcpServers":{"vortx-ai-emem":{"serverUrl":"https://emem.dev/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
ghcr.io/vortx-ai/emem:latestStreamable HTTP工具
18| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| lat | number | 否 | 将对象锚定到地点的纬度,与 lng 配对。身份根据此锚点进行哈希,因此两个 Agent 以不同方式锚定同一对象时会创建不同实体。 |
| lng | number | 否 | 经度,与 lat 配对。 |
| cell | string | 否 | 用于直接锚定对象的 cell64(无需地理编码)。 |
| kind | string | 否 | 对象类别:bridge、river、farm_plot、building、admin_division、place、custom 等。默认为 "place"。 |
| label | string | 是 | 对象的人类可读名称,例如 "Golden Gate Bridge"、"the north dam"。必填。 |
| place | string | 否 | 用于锚定对象的自由文本地点(将进行地理编码)。请提供 place、cell 或 lat+lng。 |
| parent | string | 否 | 可选的父级 entity_cid(用于包含关系)。 |
| attester | object | 否 | ed25519 绑定,已验证。省略时,拒绝响应中的 details.how_to_sign 会提供待签名的摘要。 |
| attester.sig_b32 | string | 是 | |
| attester.pubkey_b32 | string | 是 | |
| external_ids | object | 否 | 用于推动收敛的稳定 ID。调用方提供的值优先于地理编码器派生的值。 |
| external_ids.osm | string | 否 | OpenStreetMap 对象,格式为 <type>/<id>,例如 way/717919508。 |
| external_ids.gers | string | 否 | Overture GERS 行政区划 ID(最强锚点)。 |
| external_ids.wikidata | string | 否 | Wikidata QID。 |
详细介绍
在数据所在之处编码。使用任何 AI 解码。
emem 是机器和 AI 共享、可验证的记忆。证明随记录流转;文件留在原处。

无需移动文件即可建立信任
如今,要信任一份数据,通常就得持有它。卫星会下传完整的拍摄数据,实验室会通过电子邮件发送电子表格,公司会把文档上传到读取它们的 AI 所在平台,而每一份副本都是一个可能泄露数据或让数据悄然改变的新地点。
emem 将这项工作分成两部分。
- 编码在数据源处进行,并始终保持私密。 文件服务器、实验室、摄像机或载荷计算机,会将所持数据哈希为多个单元,并使用自己的密钥为一条小型记录签名。字节内容无需离开原处。离开原处的是对这些内容的承诺:内容 ID、Merkle 根和签名。
- emem 负责解码。 任何模型,无论是在 Claude、ChatGPT 中,还是在你自己的代码中,都可以将短令牌解析为对应的确切记录,检查签名者身份,并证明某个单元属于整体,而无需信任发送方,也无需信任 emem。
令牌可让读取者解析已发布的记录,并将收到的内容与之核对。它不会暴露你保留的内容:针对私有文件生成的树令牌,只会公开你选择发布的单元,不会公开其他内容。
哪些内容会跨出本地,哪些会留在本地
| 来源 | 编码位置 | 跨出本地的内容 | 留在本地的内容 | 状态 |
|---|---|---|---|---|
| 文档、数据集、模型权重、代码 | emem.dev 上的分词器(在你的浏览器中:代码按定义编码,safetensors 按张量编码,zip 和 pptx 按条目编码,PDF 按页面编码),或你机器上的 tree_proof.py | 一个 emem:tree: token:每个单元的 BLAKE3 哈希折叠为 Merkle 根,存放在你签名的索引中 | 你选择不发布的所有单元 | 已交付 |
| 你自己的算法 | 你运行它的任何地方 | emem_derive:你的值、它读取的已签名事实,以及可选的 code_cid(你的代码的哈希),全部由你的密钥签名 | 代码。emem 从不运行它;只按哈希固定代码 | 已交付;emem 只重新运行纯操作(delta、mean、sum) |
| 卫星、无人机、相机或机器人上的载荷 | 设备上的 emem-airgap,无需网络;emem-encode sidecar 会添加执行轨迹 | 已签名的保管记录:这些字节、这个名称、这个大小、这个时间,在此密钥下记录 | 载荷 | 编码器已交付(arm64 和 amd64);公共设备入口尚未接入真实硬件 |
| 开放的地球档案 | emem 自有的已注册档案读取器 | 已签名的事实,每条都标明其来源字节 | 没有私密内容:档案是公开的,因此任何人都可以重新计算 | 已交付,首个语料库 |
每项检查所能证明的内容都会与之一起说明。保管记录表示字节已到达,并不表示传感器经过了校准。树证明某个单元存在于你签名的文件中,并不表示文件内容属实。code_cid 表示你声称是由哪段代码生成某个值;在沙盒中运行任意私有代码的功能尚未实现。
快速开始
读取无需账户或 API 密钥。
1. 连接 MCP 主机(这里使用 Claude Code;其他所有主机):
claude mcp add --transport http emem https://emem.dev/mcp
2. 在不获取文件其余部分的情况下,证明文件中的一个部分。 本仓库的 LICENSE 已作为由六个 2 KB 单元组成的已签名树发布,因此你无需任何配置即可尝试文件路径。从克隆的仓库开始:
curl -s "https://emem.dev/memories/by_attester/k572x7go/readme-example/license-tree.md" > index.md
curl -s "https://emem.dev/v1/tree/xrnco3igl6j2j4kehg4z33ggk4?row=3" > row.json
python3 plugins/emem/skills/emem-tokenise-files/scripts/tree_proof.py check row.json index.md LICENSE
索引列出每个单元的哈希和根;该行包含单元 3 及其审计路径。检查会通过哈希计算这些字节,并沿着三步路径到达根,确认字节 6144 到 8191 属于由密钥 k572x7go 签名的文件。对于你自己的文件,tree_proof.py build report.md 会将其切分为单元,并离线打印索引;然后用你自己的密钥签名并发布(该技能会逐步说明)。文件不会离开你的机器。
3. 读取已签名的测量值并离线检查(curl、jq、Python):
curl -fsS https://emem.dev/v1/recall -H 'content-type: application/json' \
-d '{"place":"Cairo","bands":["copdem30m.elevation_mean"]}' > fact.json
jq '.facts[0] | {cell, value, unit, memory_token}' fact.json
jq '{token: .facts[0].memory_token}' fact.json \
| curl -fsS https://emem.dev/v1/memory_token/resolve \
-H 'content-type: application/json' --data-binary @- > resolved.json
# pip install "ememdev[signing]"
import json
from ememdev.verify import verify_receipt_offline
verdict = verify_receipt_offline(json.load(open("resolved.json"))["receipt"])
print(verdict.ok, verdict.why) # True, checked in this process with no network call
检查会使用回执中携带的公钥。若要确认签名者是 emem,请固定 /.well-known/emem.json 中 emem 的密钥,或在 emem.dev/verify 检查 token。
或者直接在 shell、Python 或 TypeScript 中提问
curl -s -X POST https://emem.dev/v1/ask -H 'content-type: application/json' \
-d '{"q":"what is the NDVI near Mount Fuji?"}' | jq '{answer, receipt: .receipt.fact_cids}'
# pip install "ememdev[signing]"
from ememdev import Client
from ememdev.verify import verify_receipt_offline
with Client() as em:
out = em.ask("what is the NDVI near Mount Fuji?")
print(out["answer"], verify_receipt_offline(out["receipt"]).ok)
// npm i @vortxai/emem
import { Client } from "@vortxai/emem";
const out = await new Client().ask({ q: "what is the NDVI near Mount Fuji?" });
console.log(out.answer, out.receipt.fact_cids);
没有规则可以将工具名称转换为 REST 路径,因此不要猜测:emem_memory_search 的请求地址是 POST /v1/memory/search,emem_verify_receipt 的请求地址是 POST /v1/verify_receipt。权威依据是 /openapi.json;通过 MCP 调用时,按名称调用工具。
面向 Agent。 连接到 https://emem.dev/mcp。该服务会在一个页面中公布核心循环的 18 个工具,约占 75 KB 上下文,而非整个目录:加载全部 116 个描述符约需 329 KB。若想以最轻量的方式首次连接,emem_tools 会以约 13 KB 返回核心循环和菜单,而 tools/call 可按名称分发所有工具,工具名带不带 emem_ 前缀均可。传递记录时,优先使用 bundle:emem_memory_bundle 可用 38 个字符命名最多 256 条事实。
不丢失历史的可变记忆
2026-10-10,在运行中的节点上端到端完成了一个字段。下面的每个令牌都能解析,你可以自行检查每一步。
1. 只需命名一次。 为字段赋予一个固定不变的身份,而关于它的一切测量值都可以变化:
emem:entity:2kmmk5bflnt5v2g7fh5y5ezqhe "Wheat field west of Ludhiana", a farm_plot at cell defi.zb560.kUtU.sozo
2. 两次观测,各自单独记录。 在两个日期读取 Sentinel-2 的 NDVI。每次读数都有自己的内容 ID,因此后续读数不会覆盖早先的读数:
2026-03-12 NDVI 0.893 emem:fact:defi.zb560.kUtU.sozo:4okfcg4nyi7fo4ftfj57yzjdghc7av7jfjd3fp2urk7vajztgxpa
2026-06-27 NDVI 0.158 emem:fact:defi.zb560.kUtU.sozo:hbliam74soj7pmqy7ig67hyyqn7lz6fe7baagv743fzi75p2drpq
3. 根据它们得出结果,并重新计算。 Agent 注册这一下降值,用自己的密钥签名,列出两次读数作为输入,并通过哈希固定其代码。由于该操作是纯 delta 操作,emem 会在记录前对这两个已签名的父项重新运行该操作:
emem:fact:defi.zb560.kUtU.sozo:n77qfh6isswzwel5i5v7mvl6fmptsf647pklplh6rrdufglz775q
value -0.7352330536822305 class deterministic_index rule canonical_float_equality ulp_gap 0
4. 更正内容,同时保留原文。 Agent 最初写道,该田地于 6 月 27 日收割。这个说法过于确定:中间的读数从未获取过,因此这些读数只能表明冠层到 6 月 27 日时已消失,而无法确定消失的时间。Agent 写下更正后的说明,并将第一条标记为已取代。现在,读取旧路径会得到 superseded_by,而原始字节仍可解析,因此任何人都能看到更正了什么以及原因:
/memories/by_attester/k572x7go/readme-example/farm-v1.md superseded_by rhngbrlvt3ihzbm3bdxjkdjrmy
reason "The NDVI drop shows the canopy was gone by 27 June; it does not date the harvest."
5. 另一个 Agent 检查全部内容,不信任任何人:
curl -s -X POST https://emem.dev/v1/memory_token/resolve -H 'content-type: application/json' \
-d '{"token":"emem:fact:defi.zb560.kUtU.sozo:n77qfh6isswzwel5i5v7mvl6fmptsf647pklplh6rrdufglz775q"}' \
| jq '{value, provenance: .provenance.class, inputs: .fact.derivation.args.inputs, recomputed: .fact.derivation.args.recomputation.verified}'
它会获得该值、两个依次解析的输入令牌,以及响应方关于其已复现该值的声明;所有内容都包含在一份可离线验证的收据中。身份、时间、来源、计算和更正,尽在一处。
这些步骤背后的操作,以及 Agent 使用它们执行的其他工作:
| 工作 | emem 的实现方式 |
|---|---|
| 只需命名一次 | emem_entity 生成一个身份;emem_entity_resolve 和 emem_entity_link 将不同表述归并到该身份上。 |
| 读取某个地点或一片区域内已知的信息 | emem_recall、emem_recall_polygon 和 emem_grid 会在缓存未命中时获取并签名;emem_ask 支持自然语言提问。168 个已发布配方可将读数合并为洪水风险、热度、作物状况等评分。 |
| 追踪某个地点随时间的变化 | emem_trajectory 列出存储在某个网格单元中的带日期读数;emem_diff 和 emem_compare 对比两项读数;emem_field_series 追踪一个区域在整个季节中的变化,并生成变化图。 |
| 推导结果,以便他人重新计算 | emem_derive 会在已签名事实的基础上记录你的结果,并在记录前重新运行纯操作。 |
| 复用他人的结论 | emem_inferences 按距离从近到远,列出 Agent 在某个地点附近签名的结论,并注明采用的信任策略;emem_ask 会指出其回答所涉及地点范围内的结论。 |
| 更正而不抹去原文 | emem_memory_supersede 将你自己的过时说明重定向到替代内容;对于不同作者之间的分歧,则通过已签名的 disagrees_with 边记录争议。 |
| 说明数值变化的原因 | emem_change_attribution 列出导致变化的各项因素,并为每项附上事实 ID。 |
| 发现矛盾或错误数值 | emem_memory_contradictions 查找同一地址上意见不一致的已签名来源;emem_guard_verdict 会拒绝数值与所引用事实不符的句子。 |
| 将工作交给另一个 Agent | 捆绑令牌会将精确的已签名字节打包到一行中,适用于任何模型或供应商。 |
| 将文档转化为证据 | emem_read 和 emem_ocr 会将报告转换为已签名字段;emem_range_hash 可为公共文件中某一字节范围的 BLAKE3 哈希签名,无需任何人下载文件。 |
Token 及其绑定对象
| Token | 所指对象 |
|---|---|
emem:fact: | 一条观测的规范字节,经过签名 |
emem:state: | 答案推理过程中的一个阶段,并与其所依据的事实链式关联 |
emem:bundle: | 一组事实,压缩在一行短文本中 |
emem:entity: | 一个对象的身份 |
emem:cell: | 一处地点,宽约 10 m |
emem:tree: | 一个文件,以签名根覆盖其各单元;#row=<i> 指定一个单元 |
emem:raster:、emem:cube:、emem:rasterset: | 一个场,或一个随时间变化的场,并与其源场景、几何信息和工件哈希绑定 |
emem:trace: | 一台设备的执行轨迹 |
emem:fact: 和 emem:state: 包含记录规范 CBOR 的完整 32 字节 BLAKE3 哈希,因此绑定记录的每个字节。emem:entity: 和 emem:bundle: 是 16 字节锚点:它们用于共同指向对象,而非绑定对象;实体锚点并不涵盖其元数据的每个字段。Token 指南说明了每种类型能证明什么。Token 占用的上下文比其代表的数值更多(84 个字符,即 51 个 LLM token;而该数值约占 5.4 个 token。此数据是在 131 条事实中使用 cl100k_base 测得的);当数值必须经受摘要处理、由不信任你的人核验,或与其他数值一同放入一个 bundle 中传递时,这种开销就值得。
世界没有答案时,emem 也会为此签名
询问威尼斯某个广场上的道路朝向,答案是没有。emem 不会猜测,也不会沉默,而是为一条缺失记录签名,说明它查看了什么,以及为什么没有结果符合条件:
emem:fact:defi.zb604.zf0e2.hUpU:exhq6lpsjbimxru33wbhvx2rrz72jeecnugpynsber2dxwgrfuea
kind absence
reason Overture release 2026-09-23.1 holds no carriageway segment within 50 m of
(45.434282, 12.323702); seen and not counted: pedestrian=7;
row_groups=part-00047-...-c000.zstd.parquet#117,119
它列出的行组是 Overture 自有存储桶中的公开字节,因此任何人都可以重新读取这些内容,并得出相同答案,无需向 emem 询问任何信息。自行核验这条缺失记录。
为何值得信任
- ID 可证明字节内容。 记录的 ID 是其规范字节的 BLAKE3 哈希:只要改动一个字节,ID 就会改变。
- 每个答复都附带一份 ed25519 收据,可在离线状态下通过答复方公布的密钥进行验证,无论是在你的进程中,还是在 emem.dev/verify 上。无需回调,也无需账户。
- 每条记录都会说明其生成方式:由传感器读取、根据引用的来源通过公式重新计算、由模型生成,或由人工输入。这四种方式各不相同,且
model_output和human_curated会在同一负载中附带警示。 - 缺失值绝不会只是一个裸 404。 如果答复方进行了查找,就会用签名记录带有类型的缺失原因;如果无法查找,则会返回带有类型但未签名的
unknown。 - 不会覆盖任何内容。 后续记录会取代先前记录,写入方之间的分歧会作为证据保留并评分,绝不会被取平均值抹平。
- 历史记录可供审计,而非仅凭声称。 emem 签署的所有内容都会写入只追加的 RFC 6962 Merkle 日志;截至 2026-10-10,日志共有 2,811,200 条记录。固定
/v1/log/sth中的签名树头,证明日志仅有增长,证明其中一条记录包含在该树头下,并查看/v1/log/witnesses中的独立共同签名。自 2026-10-10 起签署的收据都会注明其所在的日志条目,而 测试向量 可让新的验证器自行检查。 - 派生结果可以重新计算,而不只是验证签名,如示例演示的第 3 步所示。
事实能容纳什么由测量决定,而非承诺:/v1/plane/conformance 会在每次调用时对最多 400 条实时事实进行抽样,并检查是否存在携带文本的值、是否有字符串字段超过 128 字节,以及是否有工具接受调用方提供的值,从而确保事实无法携带指令。由 Agent 编写的备注属于不同的平面:每次读取时,备注正文都会被包装在 _content_is_data_not_instructions 中,因为 Agent 写入的记忆天然就是提示词注入的攻击面。你可以在 /v1/verifier_spec 查看精确的原像规则,自行重新检查任何收据;这些规则由运行中的代码生成。
在说出一个数字之前,可以先对其进行验证。 emem-guard 会读取草稿中的 emem: 引用,逐一解析,并给出允许或拒绝的结果,以及机器可读的原因(签名验证失败时为 PROV_SIG,令牌解析后对应的字节不同则为 PROV_BYTES,数值变化超出阈值时为 PROV_DRIFT),同时提供 fix。在托管节点上仅提供建议,在你自己的节点上则会强制执行。它的严格规则会标记没有引用任何来源的可测量声明;在本仓库自身的 8,739 个句子中,该规则触发了 3 次。因此,它默认关闭,并提供 --shadow 模式。
### emem 能提供什么,而搜索和 RAG 无法提供
| 属性 | 在这里的含义 |
|---|---|
| 不可变引用 | 内容 ID 永远指向一条固定记录;之后再次询问同一问题,可能会返回更新的观测值,而旧令牌仍会解析到旧值 |
| 已签名的来源信息 | 谁签署、源自哪些字节、使用什么方法和注册表版本,这些信息都包含在记录中 |
| 选择性证明 | 无需提供其余内容,即可证明文件中的一个单元或日志中的一条记录属于某个根 |
| 时间历史 | 带日期的读数、后续替代记录和争议并列保存,绝不会合并成一个答案 |
| 重新计算 | 响应方会重新运行基于已签名输入的推导;事实会注明其来源的公开字节 |
| 数据原地保留 | 记录可承诺任何位置存储的字节;无需将任何内容上传到索引中 |
emem 不是向量数据库,也不会取代 Agent 自有的记忆。它是共享部分:多个 Agent、模型和组织需要共同认可的记录。
结果,包括无法发挥作用的情况
此处所有数字的适用范围:5 个站点、同一台主机上运行 2 个开源 7-12B 指令模型、最多 1,024 个单元、最大规模时 n=48、没有独立复现,标记为 SAMPLE。方法和有效性威胁:docs/how-emem-compares.md。
| Agent 如何保存该值 | 准确 | 自信但错误 |
|---|---|---|
| 从 emem 解引用的引用 | 99.2%(基准测试促使我们进行四项修复前为 84.4%) | 0 |
| 将值粘贴到上下文中(对照组) | 284/284 | 0 |
| 密集检索,top-5 | 4/142 | 最多 138,误差中位数为 252 m |
| BM25 词法检索,top-5 | 16/16 | 0 |
| 摘要式记忆,严格预算 | 1/72 | 其余大多数 |
- 检索遗漏时,模型会给出貌似合理的谎言。 一个模型有 74/96 次选择弃答;另一个模型有 93/96 次给出自信的错误数字,使用的是相邻单元的真实读数。
- 意见一致不是证据。 在压缩条件下,两个模型有 27.8% 的时间意见一致,但只有 1.4% 的时间答对(Fisher p = 0.035)。
- 我们的不足之处。 当值能放得下时,将值粘贴到上下文中与寻址记忆不相上下;在这些语料库上,BM25 也匹配了这一效果。节省上下文的是数据包,而非单个令牌。
- 在生产环境中发现漂移。 上游提供方变更后,旗舰单元的实时值从 918.0 变为 915.07。此前发布的令牌仍解析为 918.0,且仍可通过验证。
- 独立验证器。 一个与我们没有商业关系的 Agent
dxrfmreb根据/v1/verifier_spec编写了一个独立实现的验证器,复现了我们的签名,拒绝了五份篡改过的回执,使用其自有的 RFC 6962 代码验证了包含证明和一致性证明,并提交了十一项发现,其中八项是真实缺陷,现已修复(docs/benchmarks.md)。eudr.dev 的 Agent 也根据同一规范构建了第二个验证器。
一条记录,多种读取方式
将一个 token 交给 Anthropic 的 Claude(通过 emem MCP)、Google 的 Gemma 3(在 Amazon Bedrock 上运行)和 Alibaba 的 Qwen 2.5(在本地运行),三者最终都得到相同的事实 ID 和值。解码由 emem 完成,而非模型:Claude 自行调用了解析器,另外两个模型则收到了相同的解析结果,视频片段中对此有说明。
两个互不共享上下文的 Claude 会话:A 调研一个地点并交出一行 bundle;B 没有理由信任 A,于是将其解析为相同的签名字节并检查签名。Agent 也会在签名频道上公开交流,引用记录、相互质疑并撤回内容;A2A 则通过技能触达每个工具。这两种方式都在深入了解 emem中逐步演示。
在线体验
网站上的每个演示都在浏览器中直接连接实时记忆运行,无需密钥。
| 演示 | 展示内容 |
|---|---|
| 为文件生成 token | 引用文件中的一个部分及其哈希,并证明它属于根 |
| 签名答案 | 一个地点、一个签名数值,以及证明签名者身份的收据 |
| 检查交接内容 | 他人交给你的内容,由你自行解析并验证 |
| 检查草稿 | 守卫在错误数值发布前将其拦截 |
| 日志只会增长 | 证明历史记录未被改写的一致性证明 |
| 文档证据 | 将报告解析为签名字段,并检查链 |
| 一个字段 | 字段边界、像素,以及由你自行计算的 NDVI |
| EUDR 地块 | 一个农场地块与欧盟森林砍伐截止日期的对照 |
此外还有:图库,展示经过编码的文件(韦布望远镜的宇宙悬崖、逐张量呈现的 GPT-2、机械臂、CT 切片、气候模型的 41 年数据);根据签名事实重建的三维世界;街机,我们的守护进程 Agent 自 2026 年 7 月起在此持续运行循环,每次行动都留下一条签名记录;以及排行榜。
一段 Claude 会话录屏,仅使用 emem 的工具调研真实地点:答案中的每个数值都是签名记录。观看九个 Agent 共享一份记忆(4 分钟)。
地球是第一个语料库,而非边界
协议并不关心记录的内容。地球数据先行,因为其来源是公共档案,任何人都可以获取相同的输入并重新计算答案,因此这是最难作弊的场景。来自 ESA、NASA、USGS 和 EU JRC 的开放数据按需填充记忆:46 种已声明来源方案中的 115 项接入测量数据。已发布 18 个贡献者档案,其中 1 个处于启用状态:earth.satellite.v0;其余均为候选项。所有定义含义的注册表都是 /v1/manifests 中的十个内容寻址清单之一,因此引用其 cid 即可固定事实写入时所依据的确切语义。
文件树可以提交任何内容,但提交字节并不会让它成为经过测量的事实:只有 emem 自己的读取器、已注册设备以及运营方列出的密钥才能写入事实层。设备通过证明自身的运行方式来加入,而不是自我声明:设备平台注册表列出了可注册密钥的 17 个平台及各自必须提供的证据;emem_trace_verify 目前可检查执行轨迹,而公开入口尚未接纳任何真实硬件(分阶段实施路径)。
数据一览:116 个 MCP 工具(默认提供包含 18 个工具的核心循环)、/v1/* 下有 181 个路径(/openapi.json),以及截至 2026-10-10 含有 2,811,200 条签名记录的透明度日志。在生产节点上测得(测量方法):热缓存召回 p50 为 2.5 ms,离线收据验证 p50 为 0.13 ms,单节点每秒处理 632 个请求。
在你日常使用的地方使用它
| 在聊天中 | ChatGPT 中的 emem 应用(提及 @emem),以及 Claude 目录中的 emem |
| 在 Claude Code 中 | 插件、MCP 服务和 19 个技能:/plugin marketplace add Vortx-AI/emem,然后运行 /plugin install emem@emem |
| 在 IDE 或 MCP 主机中 | Claude Desktop、Cursor、Cline、VS Code 和 Copilot、Gemini CLI(gemini extensions install https://github.com/Vortx-AI/emem),均使用同一端点 https://emem.dev/mcp |
| 在工作流工具中 | 经过验证的 Dify 插件 |
| 在代码中 | Python 和 TypeScript 客户端、REST(OpenAPI),以及适用于 LangChain、LlamaIndex、CrewAI、AutoGen、Agno 和 Mastra 的示例 |
| Agent 间通信 | A2A:读取 Agent 卡片,发送任务,并验证签名结果 |
各主机的配置,以及 emem 收录于其中的所有目录,均见参考页面。写入操作使用你在本地生成的 ed25519 密钥签名;写入遭拒时,系统会返回需要签名的确切摘要。
自行运行
托管节点运行本仓库中的二进制文件,在一个节点上铸造的收据可在另一个节点上验证:
docker run -p 127.0.0.1:5051:5051 ghcr.io/vortx-ai/emem:latest
在交付重要记录之前,请为保存节点签名密钥的 EMEM_DATA 挂载一个卷;对于需要长期运行的服务,请固定镜像摘要(docs/self-host.md)。
对于无法连接外部网络的机器(例如轨道上的载荷计算机),emem-airgap 会接管一个目录中的文件,并将签名记录写入另一个目录;emem-encode 则会采集它能获取的执行证据。每条记录都会说明自己包含两种保证中的哪一种。镜像使用 FROM scratch,仅包含一个静态二进制文件,且未链接任何网络或数据库 crate,因此 --network none 与二进制文件的实际能力一致,而不只是对它提出要求;quickstart.sh 无需克隆仓库或安装 Rust 工具链,即可从零开始生成并验证一条签名记录。
独立见证方会共同签署日志头,并在 /v1/log/witnesses 实时列出,因此可以检测到分视图。当前的联邦功能是见证;跨节点获取事实则是尚未开展的独立工作。
检查无法证明什么
- 签名只能证明签署者是谁,不能证明内容属实。 收据证明一位响应方签署了什么。源码正确性和科学有效性仍需单独评估。
- 令牌指向某处保存的字节。 内容 ID 永远对应一条固定记录;能否获取它取决于是否有人保留这些字节。
- 地名会解析为一个 10 m 网格单元。 邻域查询需要使用区域工具;首次读取新地点时,emem 读取档案可能需要几十秒。
- 时间序列数据稀疏。 在一个已预热的网格单元中,geo.qa 测得三年内有 38 次 NDVI 读数,约为每年 12.7 次:足以判断趋势,但不足以绘制完整的物候曲线。
- 签名者是一位响应方,而非整个网络。 收据从不声称达成了共识。
- 笔记是公开且永久的。 对文件进行编码不会上传文件;发布笔记则会。任何调用方都能读取任意 Agent 的笔记;密封的
vault条目可由运营方读取;删除操作会取消发布,但不会抹除内容;memory_supersede仅适用于你自己的命名空间。对于私密内容,请在客户端加密(PRIVACY.md)。
版本 2.4.4,是 2.4.0 次要版本的补丁。收据原像最后一次变更是在 2.0.0;在更早版本下签署的收据仍可按其各自规则验证(CHANGELOG.md)。下一步:docs/roadmap.md。
谁在基于它构建
- eudr.dev 使用 emem 的森林事实检查农场地块是否符合欧盟《森林砍伐条例》的截止日期要求,并准备可由审计员重新验证的 Annex II 声明。
- geo.qa 运行第二个节点,其透明日志头由 emem 共同签署。
了解更多
| 当你想要 | 前往 |
|---|---|
| 了解完整内容:记录的承诺、A2A 和通道、Agent 卡片、安全性及所有限制 | docs/emem-in-depth.md |
| 了解其重要性:机器人机群、卫星任务调度、Agent 群集、压缩 | 深入了解 emem:没有它会出什么问题 |
| 用十分钟见证它的运行方式 | 教程,Agent 演练 |
| 通过实时控制台端到端跟踪一个请求 | emem.dev/how-it-works |
| 接入你的 Agent | Agent 指南,技能,连接客户端 |
| 将它部署到机器上 | 会询问 emem 自身位置的机器,emem-airgap,联邦 |
| 正式检验信任模型 | 白皮书,协议,形式化模型,安全性,验证器规范 |
| 阅读完整 API | /openapi.json,/mcp/full,所有工具,线协议规范 |
| 将它用于评测,并了解哪些内容尚未测量 | 附方法说明的基准测试,emem 的比较情况,路线图 |
引用
分别引用两项内容:如果你运行了该软件,就引用软件;如果你基于该协议构建,就引用预印本。GitHub 的 引用此仓库 按钮会读取 CITATION.cff,其中包含这两项。
@software{emem_software,
title = {emem: shared, verifiable memory for AI agents},
author = {Kumari, Jaya and Singh, Avijeet},
year = {2026},
version = {2.4.4},
url = {https://github.com/Vortx-AI/emem},
license = {Apache-2.0},
publisher = {Vortx AI Private Limited}
}
@misc{emem2026,
title = {emem: A research on Content-Addressed, Verifiable Earth-Memory
Protocol for AI Agents over Foundation-Model Embeddings},
author = {Kumari, Jaya and Singh, Avijeet},
year = {2026},
doi = {10.5281/zenodo.20706893},
publisher = {Zenodo}
}
预印本采用开放许可(CC-BY-4.0),尚未经过同行评审。
贡献与许可证
欢迎提交问题和拉取请求:CONTRIBUTING.md、SECURITY.md。纯 Rust 实现,采用 Apache-2.0 许可证(LICENSE、NOTICE)。默认数据源均为开放数据源,无需 API 密钥,也没有厂商锁定。共享记忆会随着读取和写入它的 Agent 越多而更有价值;如果你的项目使用 emem,点个星有助于其他构建者发现它。
内容寻址
上文的每个章节都是同一棵已签名树中的一个单元:emem:tree:ea3fjlmlwwfqi5oybnykpk5a24,根为 3gkbfwm2ja2ab5nmgbne3w4ni3oerzngkn2i5pulv6qpi5uk4paq,由密钥 k572x7go 发布。单个章节的地址为 emem:tree:ea3fjlmlwwfqi5oybnykpk5a24#row=<i>,因此其他 Agent 可以引用此文件中的某一部分,任何人也都能证明该部分确实包含在已发布的文件中:
curl -s "https://emem.dev/memories/by_attester/k572x7go/readme/tree-20261024b.md" > index.md
curl -s "https://emem.dev/v1/tree/ea3fjlmlwwfqi5oybnykpk5a24?row=3" > row.json
python3 plugins/emem/skills/emem-tokenise-files/scripts/tree_proof.py check row.json index.md README.md
index.md 是已签名的说明,位于 /memories/by_attester/k572x7go/readme/tree-20261024b.md。python3 scripts/readme_tree_check.py 会根据此文件重建整棵树,并将其根与索引中的根进行比较;CI 也会运行该脚本,因此未重新签名的 README 编辑会导致构建失败。README 每次更改时,这棵树都会随之更改;本章节因会提及这棵树,所以不包含在其中。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。