エージェントのメモリにOpenTelemetryの瞬間が必要
Agent memory needs its OpenTelemetry moment (lorekit.io)
要約
AIエージェントが生成するメモリ形式の断片化が進んでおり、相互運用性が失われている。OpenTelemetryが観測可能性(Observability)分野で標準化を達成したように、エージェントメモリの分野でもデータモデル、セマンティック規約、プロトコルなどの共通の枠組みを確立することが急務である。
全文翻訳
エージェントのメモリにOpenTelemetryの瞬間が必要
マシンのメモリ形式を数える
コーディングツールが「記憶」として何かを保持している場所をすべてリストアップしてください。典型的な現在のセットアップは以下のようになります。
- ほとんどのリポジトリにある
AGENTS.mdまたはCLAUDE.md、および一部のリポジトリにある.cursor/rules/*.mdc - Anthropicのメモリツールを通じて
/memoriesディレクトリにファイルを書き込むエージェント - GitHub側で各リポジトリに関する事実を保持するCopilot
- JSONL知識グラフを保持するメモリMCPサーバー
これらは4つの異なる形式であり、どれも互いに読み取ることができません。CIエージェントが学習した教訓は、それを書き込んだものの中に留まります。エディタエージェントはそれを読み取れず、次に試すツールも読み取れません。
各形式は単独では合理的です。しかし、それらが組み合わさると、同じ小さなアイデアが何度も再構築されます。「あるアドレスに保存され、しばらくの間有効な、エージェントが将来の自分自身のために残したメモ」です。
そして、そのリストは増え続けています。r/ClaudeAI、r/LocalLLaMA、r/cursorを閲覧すると、「エージェントのためにメモリレイヤーを構築した」という投稿が定期的に見つかります。それぞれ独自のストレージ、スキーマ、MCPツールを備えています。これは問題が現実であることを示す良い証拠です。人々はそれをひどく経験して、何かを構築するほどになっています。しかし、新しいソリューションごとに、他のものが読み取れない形式が1つ増えるだけです。問題はツールの不足ではありません。合意の欠如です。そしてそれはコミュニティが協力して取り組むことによってのみ得られます。
私はこれらのツールの1つであるLoreKitを開発しており、これはオープンソースです。これはLoreKitがメモリ問題を解決したという宣伝ではありません。その形式は、それ自体にもギャップがある複数の提案の1つです。重要なのは、共有の形状に合意する時が来たということであり、別の分野がすでにその方法を示しているということです。
以前にも同じようなことがあった
2019年以前は、すべてのオブザーバビリティベンダーが独自の С, 独自のインストルメンテーションライブラリ、独自のデータ形式を出荷していました。ベンダーを切り替えるということは、コードに再度インストルメンテーションを適用することを意味しました。OpenTracingとOpenCensusという2つのオープンプロジェクトがそれを修正しようとしましたが、互いに競合もしました。
2019年に、それらはOpenTelemetryに統合されました。ベンダーが競合をやめたことが重要だったのは以下の点です。
- データモデル: スパン、メトリック、ログレコードが何であるか。
- セマンティック規約:
service.nameやhttp.*のような共有名。 - プロトコル: OTLP、データを送信する1つの方法。
- リファレンス実装: 共有SDKとコレクター。
ベンダーはデータのストレージ、クエリ、分析といった、データを使った処理で競合を続けました。ユーザーは一度だけインストルメンテーションを行います。私はDash0で毎日OpenTelemetryと協力していますが、その合意のおかげで、ツールエコシステム全体がお互いのデータを読み取ることができます。
[画像: 2つの列が、OpenTelemetryが解決したオブザーバビリティと、まだオープンなエージェントメモリを、データモデル、セマンティック規約、プロトコル、実装の4つのレイヤーで比較しています。メモリについては、最初の3つのレイヤーはまだ誰も合意していないため、破線で描かれています。]
同じ4つのレイヤーです。オブザーバビリティはそれらに合意し、データ到着後の処理で競合しています。エージェントメモリには多くの実装がありますが、その下に合意されたものはありません。
エージェントメモリは、2019年以前のオブザーバビリティと同じ状況です。タイミングは良いです。形式はまだ新しいため変更可能であり、エージェント標準のためのニュートラルなホームがすでに存在します。MCPとAGENTS.mdはどちらもLinux FoundationのAgentic AI Foundationの下にあります。
形状のツアー
これらは急速に変化するため、詳細は2026年後半のスナップショットとして扱ってください。
| ファミリ | 例 | メモリの単位 | アドレス指定 | 忘却 |
|---|---|---|---|---|
| 命令ファイル | AGENTS.md, CLAUDE.md, Cursor .mdc ルール | Markdownファイル全体 | ファイルパス(Cursorの場合は globs を追加) | なし。人が編集する |
| エージェント管理ファイル | Anthropicのメモリツール | /memories 下のファイル | モデルが選択するパス | モデルが削除しない限りなし |
| ホストされたリポジトリの事実 | GitHub Copilot Memory | コード参照付きの事実 | 1つのリポジトリ | 未使用期間が28日後に削除 |
| コンテキストブロック | Letta core memory | ラベル付きブロック(文字数制限あり) | エージェントの label | なし。常にコンテキスト内 |
| 抽出された事実 | Mem0 | メッセージからサービスが抽出した事実 | user_id / agent_id / run_id / app_id | オプションの有効期限 |
| 名前空間ストア | LangGraph BaseStore | ラベル付き値辞書 | namespace タプル + key | オプションのTTL(デフォルトでは読み取り時にリセット) |
| 知識グラフ | MCPリファレンスメモリサーバー | エンティティ、関係、観測 | エンティティ名 | なし |
| 時間的グラフ | Graphiti / Zep | グラフエッジ上の事実 | エンティティ + エッジ | 事実は削除されるのではなく、2つのタイムラインで無効化される |
| アドレス指定可能なレコード | LoreKit | スコープ、キー、ライフサイクルを持つレコード | スコープ文字列 + key | TTLが設定されていない限りなし |
これらのうちいくつかは、共有仕様が維持すべき正しい点を持っています。Copilot Memoryは、コードと照合できる参照とデフォルトでの忘却をペアにしていますが、1つの製品にロックされています。LangGraphは、コアがいかに小さいかを示しています: put(namespace, key, value)。Graphitiは時間を適切にモデル化しており、事実がいつ真実であったか、いつ記録されたかの別々のタイムラインがあります。そしてAGENTS.mdは、既知のパスにあるプレーンなファイルが標準になり得ることを示しています。
すでに存在する提案
すでに数人がこの分野に着手しています。MacPaw ResearchのPortable Memoryは、バイト単位で再現可能なシリアライゼーション、削除のトゥームストーン、オプションの署名を含む.memバンドルです。その著者は、まだ広く採用されていないと述べています。Open Memory Protocolは、会話とその派生メモリをZIPファイルとマニフェストとしてプラットフォーム間で移動するための2026年4月のドラフトです。CogneeのCOGX形式は、Mem0、Letta、Zepからインポートします。
これらは主にエクスポートを解決します。つまり、ある人のメモリをベンダーAからベンダーBに移動することです。コーディングツールには、もう1つのオープンな問題があります:ライブアドレス指定です。CIジョブ、エディタエージェント、レビューボットが同じリポジトリで同時に作業している場合、それらはどのようにして同じ場所を読み書きし、その意味について合意できるのでしょうか?完全な仕様には両方が必要です。
[画像: 2つの問題が並べて表示されています。左はエクスポート:ベンダーAのメモリは、.memファイル、.omp.zip、またはCOGXのようなバンドルにパックされ、ベンダーBで展開されます。右はライブアドレス指定:CIジョブ、エディタエージェント、レビューボットがすべて同時に1つのアドレス、repo::acme/checkoutを読み書きします。]
エクスポートは、1人の所有者のメモリをベンダー間で移動させます。ライブアドレス指定は、多くのツールが同時に1つの場所を共有できるようにします。既存の提案は、前者に焦点を当てています。共有アドレスは、後者をカバーするためにレコード内に配置することができます。
ブランド名を剥ぎ取ると、すべての形式は同じ4つの質問に異なる方法で答えています:メモリが有効な場所、そのID(2回目の書き込みは更新するのか、複製するのか?)、内容、そしていつ無効になるのか。それらが重要であることに誰も異論はありません。ツールが意見を異にするのは、OpenTelemetryが始まった場所と同じ、その答えです。
1つだけ本当の分岐点があります:メモリを誰が書くかです。命令ファイルでは人が書きます。メモリツール、Letta、LoreKitではモデルが書きます。Mem0とGraphitiでは、サービスが会話から事実を抽出します。仕様は1つを選ぶ必要はありません。それは記録する必要があります。そうすれば、読者は読み取るものをどれだけ信頼できるかを知ることができます。
以下は、1つのレコードがファイルとしてどのように見えるかの概略です。これはデータモデルを示しており、フィールド名は提案ではありません。
---
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.
フロントマターは封筒です:addressとkeyはそれが有効な場所を示し、idはその識別子、lifecycleはいつ無効になるかを示し、written_byはその分岐点に答えます。その下のMarkdownはメモリ自体であり、content_typeは読者にそれをどのように扱うべきかを伝えます。ツールが必要とするその他のものは、他のツールが無視できる名前空間の下にあるattributesに入ります。同じレコードは、ワイヤー越しに送信したいツールにとって、JSONとしても同様によくシリアライズされます。
そのレコードの周りに、仕様はOpenTelemetryのレイヤーを反映するでしょう:
- 規約: アドレスレベル(
global,project,repo,branch、およびモノレポに必要なもの)、種類、属性名前空間(vcs.*,ci.*,agent.*)の共有名。これらは1つのバージョン管理されたレジストリにあります。 - 契約: いくつかの操作(書き込み、読み取り、リスト、検索、アーカイブ)で、固定の入力と出力があり、MCP経由で公開されます。多くのメモリサーバーは現在MCPインターフェースを提供していますが、それぞれが異なるツールを異なる意味で公開しています。
- リファレンス実装の代わりに適合性テスト: レコードをラウンドトリップし、何も失われていないか、未知の属性が書き換えで生き残るか、有効期限が記載通りに動作するかを確認します。
外に出しておくことも同様に重要です:ストレージ、ランキング、埋め込み、ユーザーインターフェース。そこがツールが競合すべき場所です。そして仕様は、LoreKitのリポジトリや単一のベンダーのリポジトリではなく、ニュートラルな場所に置かれるべきです。
懐疑論者の意見
「あなたはメモリツールを開発しているので、当然、それに似た標準を欲しがるでしょう。」 公平です。だからこそLoreKitはテンプレートではなく、テーブルの1行なのです。共有仕様が異なるように見えるなら、LoreKitはそれでも採用すべきです。
「MCPはすでに標準です。」 MCPはレコードではなく、呼び出しを標準化します。OpenTelemetryにはプロトコルとデータモデルの両方が必要でした。メモリにも両方が必要です。
「共有メモリはプロンプトインジェクションチャネルです。」 はい。エージェントが読み取るものは何でもエージェントを誘導でき、共有メモリはそれを書き込める人を広げます。仕様はそれを可視化すべきです:各メモリを誰が書いたかを記録し、署名を許可し(Portable Memoryはすでにそうしています)、読者がそのコードが変更されたかどうかを確認できるように、レコードが依存するコードを指すようにします。どの形式も悪用を不可能にはしません。
「別の標準が断片化を解決することはない。」 それはxkcd 927であり、最も強力な反対意見です。私の答えはOpenTelemetryのそれと同じです:既存のプロジェクトが統合されたときに合意が生まれ、誰かがもう1つ追加したときではありません。ここでの作業も同じです。既存の提案やツールがそれぞれ正しく行ったことを取り入れ、それらが共有する部分に合意することです。
未解決の質問
これらの質問に対する答えは私にはわかりません。そして、公に議論したいと思っています。
- どのアドレスレベルが必要か? モノレポは
repoとbranchの間のレベルを求めています。レベルは固定リストか、規約か? - 忘却はデフォルトであるべきか? Copilotはデフォルトで忘却しますが、LoreKitはそうではなく、LangGraphは読み取り時に寿命を延ばします。
- レコードは依存するコードを指すべきか? それは古いメモリに対する最良の保護策ですが、レコードをコードホストに結び付けます。
- 誰が調整すべきか? 作業グループ、財団、それとも変更を送信できるドラフト仕様?
もしあなたがテーブルにあるツールのいずれかを開発したことがある、または提案のいずれかを書いたことがあるなら、情報交換をしたいです。LoreKitのスキーマとオンディスク形式は、MITライセンスで1つの具体的な入力として提供されています。実際のレコードを見るために、LoreKitのオフラインストアは、開いて、grepして、diffできるプレーンなMarkdownファイルを書き出します。
npx @lorekit/cli install
それらを他のツールが書き出すものと比較し、共有フォーマットに必要で、それらのどれにもまだないものは何かを教えてください。