Agent 记忆需要它的 OpenTelemetry 时刻
Agent memory needs its OpenTelemetry moment

原始链接: https://www.lorekit.io/blog/open-agent-memory-format

编码工具各自以不兼容的格式存储智能体"记忆"(AGENTS.md、.cursor/rules、/memories、Copilot facts、MCP servers),因此在一个工具中学到的经验无法被另一个工具读取。解决方法不是另一个工具,而是社区标准,就像OpenTelemetry在2019年统一了可观测性一样。智能体记忆需要四个约定的层:数据模型(包含地址、键、id、生命周期、写入者、内容、属性的记录),语义约定(共享的地址层级与属性命名空间),协议(MCP操作),以及一致性测试。现有提案主要处理厂商之间的导出;一个共享规范还必须支持实时寻址,以便多个工具同时读写同一个仓库。该规范应记录每条记忆的写入者(个人、智能体或服务),以便读者判断信任程度,并允许签名与代码引用以缓解过时与提示注入。存储、排序与UI保持竞争。作者邀请记忆工具的构建者协作;LoreKit的MIT许可schema是其输入之一。格式还足够年轻,现在就可以改变。

一篇 Hacker News 帖子题为“Agent memory needs its OpenTelemetry moment”,获得 5 分和 3 条评论。标题暗示智能体记忆需要一种标准化的、类似可观测性的格式。评论者反驳:有人说智能体已经能读取多种记忆文件;另一人认为智能体记忆常常有害、会记住错误内容,更喜欢明确的文件笔记;第三人质疑为能读取非结构化文本的机器再增加一种复杂格式。总体而言,讨论凸显了对标准化智能体记忆与依赖智能体解析文件及明确、受控记忆的怀疑。
相关文章

原文

List every place your coding tools keep something they "remember". A typical setup today:

  • an AGENTS.md or CLAUDE.md in most repos, and .cursor/rules/*.mdc in a few
  • an agent writing files to a /memories directory through Anthropic's memory tool
  • Copilot keeping facts about each repo on GitHub's side
  • a memory MCP server keeping a JSONL knowledge graph

That's four different shapes, and none of them can read the others. A lesson your CI agent learns stays in whatever wrote it. Your editor agent can't read it, and neither can the next tool you try.

Each format is reasonable on its own. Together, they rebuild the same small idea again and again: a note an agent left for its future self, stored at some address, true for a while.

And the list keeps growing. Browse r/ClaudeAI, r/LocalLLaMA or r/cursor and you'll find a steady stream of "I built a memory layer for my agent" posts, each with its own storage, its own schema and its own MCP tools. That's good evidence the problem is real: people keep hitting it badly enough to build something. But every new solution adds one more format that nothing else can read. The problem isn't a missing tool. It's a missing agreement, and that only comes from the community working on it together.

I build one of these tools, LoreKit, which is open source. This isn't a pitch that LoreKit has solved memory. Its format is one proposal among several, with gaps of its own. The point is that this is the moment to agree on a shared shape, and that another field has already shown how.

Before 2019, every observability vendor shipped its own agent, its own instrumentation library and its own data format. Switching vendors meant instrumenting your code again. Two open projects, OpenTracing and OpenCensus, tried to fix that and competed with each other too.

In 2019 they merged into OpenTelemetry. What mattered was what the vendors agreed to stop competing on:

  1. A data model: what a span, a metric and a log record are.
  2. Semantic conventions: shared names like service.name and http.*.
  3. A protocol: OTLP, one way to send the data.
  4. Reference implementations: shared SDKs and the Collector.

Vendors kept competing on what they do with the data: storage, querying, analysis. Users instrument once. I work with OpenTelemetry every day at Dash0, and that agreement is why a whole ecosystem of tools can read each other's data.

Two columns compare observability, which OpenTelemetry settled, with agent memory, which is still open, across four layers: data model, semantic conventions, protocol, and implementations. For memory, the first three layers are drawn dashed because nobody has agreed on them yet.
The same four layers. Observability agreed on them and competes on what happens after the data arrives. Agent memory has plenty of implementations, but nothing agreed underneath them.

Agent memory is where observability was before 2019. The timing is good: the formats are young enough to change, and there's already a neutral home for agent standards. MCP and AGENTS.md both sit under the Linux Foundation's Agentic AI Foundation.

These change quickly, so treat the details as a snapshot from late 2026.

FamilyExampleThe unit of memoryAddressed byForgetting
Instruction filesAGENTS.md, CLAUDE.md, Cursor .mdc rulesA whole Markdown fileFile path (plus globs for Cursor)Never. A person edits it
Agent-managed filesAnthropic's memory toolA file under /memoriesA path the model picksNever, unless the model deletes it
Hosted repo factsGitHub Copilot MemoryA fact with code citationsOne repositoryDeleted after 28 days unused
Context blocksLetta core memoryA labeled block with a character limitA label on an agentNever. Always in context
Extracted factsMem0A fact the service extracts from messagesuser_id / agent_id / run_id / app_idOptional expiration date
Namespaced storeLangGraph BaseStoreA JSON value dictA namespace tuple + keyOptional TTL, reset when the item is read (by default)
Knowledge graphMCP reference memory serverEntities, relations, observationsEntity nameNever
Temporal graphGraphiti / ZepA fact on a graph edgeEntities + edgeFacts are invalidated rather than deleted, on two timelines
Addressed recordLoreKitA record with a scope, key and lifecycleA scope string + keyNever, unless a TTL is set

A few of them got something right that a shared spec should keep. Copilot Memory pairs citations you can check against the code with forgetting by default, though it's locked inside one product. LangGraph shows how small the core can be: put(namespace, key, value). Graphiti models time properly, with separate timelines for when a fact was true and when it was recorded. And AGENTS.md shows that a plain file at a known path can become a standard.

The proposals that already exist

Several people have started on this. MacPaw Research's Portable Memory is a .mem bundle with byte-reproducible serialization, deletion tombstones and optional signing; its authors say it isn't widely adopted yet. The Open Memory Protocol is an April 2026 draft for moving conversations and the memories derived from them between platforms as a ZIP with a manifest. Cognee's COGX format imports from Mem0, Letta and Zep.

These mostly solve export: moving one person's memory from vendor A to vendor B. Coding tools also have a second, open problem: live addressing. When a CI job, an editor agent and a review bot work in the same repo at once, how do they read and write the same place and agree on what it means? A complete spec needs both.

Two problems side by side. Left, export: memory in vendor A is packed into a bundle such as a .mem file, an .omp.zip or COGX, and unpacked in vendor B. Right, live addressing: a CI job, an editor agent and a review bot all read and write one address, repo::acme/checkout, at the same time.
Export moves one owner's memory between vendors. Live addressing lets many tools share one place at the same time. The existing proposals focus on the first. A shared address could sit inside their records to cover the second.

Strip away the branding and every format answers the same four questions differently: where a memory is true, what its identity is (does a second write update it or duplicate it?), what it says, and when it stops being true. Nobody disagrees that those matter. The tools only disagree on the answers, which is where OpenTelemetry started too.

There's one real fork: who writes the memory. In instruction files it's a person. In the memory tool, Letta and LoreKit, it's the model. In Mem0 and Graphiti, a service extracts facts from the conversation. A spec doesn't need to pick one. It needs to record which, so a reader knows how much to trust what it reads.

Here's roughly what one record could look like as a file. It illustrates the data model; the field names aren't a proposal:

---
spec: agent-memory/0.1
id: 8f0c2a6e-4b1d-4c7a-9e2f-3a5b6c7d8e9f
address: { level: repo, value: github.com/acme/checkout }
key: tests-need-local-postgres
kind: lesson
written_by: { type: agent, name: claude-code }
content_type: text/markdown
lifecycle: { expires_at: null, extended_by: write }
attributes: { vcs.pr: 482, ci.run_url: "https://ci.example/runs/123" }
---
Integration tests fail with `ECONNREFUSED 127.0.0.1:5432` unless Postgres
is already running. Start it before `pnpm test`:

    docker compose up -d db

The test setup does not start it for you.

The frontmatter is the envelope: address and key say where it's true, id is its identity, lifecycle says when it stops, and written_by answers the fork. The Markdown below it is the memory itself, and content_type tells a reader how to treat it. Anything else a tool needs goes in attributes, under a namespace other tools can ignore. The same record serialises to JSON just as well, for a tool that wants to send it over the wire.

Around that record, a spec would mirror OpenTelemetry's layers:

  • Conventions: shared names for address levels (global, project, repo, branch, and whatever monorepos need), for kinds, and for attribute namespaces (vcs.*, ci.*, agent.*), in one versioned registry.
  • A contract: a few operations (write, read, list, search, archive) with fixed inputs and outputs, exposed over MCP. Many memory servers now offer an MCP interface, but each exposes different tools with different meanings.
  • Conformance tests in place of a reference implementation: round-trip a record and check nothing was lost, check that unknown attributes survive a rewrite, check that expiry behaves as stated.

What stays out matters as much: storage, ranking, embeddings, the user interface. That's where tools should compete. And the spec should live somewhere neutral, not in LoreKit's repo or any single vendor's.

"You build a memory tool, so of course you want a standard shaped like it." Fair. It's why LoreKit is one row in the table rather than the template. If a shared spec looks different, LoreKit should adopt it anyway.

"MCP already is the standard." MCP standardises the call, not the record. OpenTelemetry needed a protocol and a data model. Memory needs both too.

"Shared memory is a prompt-injection channel." Yes. Anything an agent reads can steer it, and shared memory widens who gets to write it. A spec should make that visible: record who wrote each memory, allow signatures (Portable Memory already does), and let a record point at the code it depends on so a reader can check whether that code changed. No format makes poisoning impossible.

"Another standard won't fix fragmentation." That's xkcd 927, and it's the strongest objection. My answer is OpenTelemetry's: agreement came when existing projects merged, not when someone added another one. The work here is the same: take what the existing proposals and tools each got right, and agree on the parts they share.

I don't know the answers to these, and I'd rather work them out in public:

  • Which address levels? Monorepos want a level between repo and branch. Should levels be a fixed list or conventions?
  • Should forgetting be the default? Copilot forgets by default, LoreKit doesn't, and LangGraph extends life on read.
  • Should a record point at the code it depends on? It's the best protection against stale memory, but it ties a record to a code host.
  • Who should coordinate? A working group, a foundation, or a draft spec people send changes to?

If you build any of the tools in the table, or wrote one of the proposals, I'd like to compare notes. LoreKit's schema and on-disk format are MIT-licensed as one concrete input. To see real records, LoreKit's offline store writes plain Markdown files you can open, grep and diff:

npx @lorekit/cli install

Compare them with what your other tools write, and tell me what a shared format would need that none of them have yet.

联系我们 contact @ memedata.com