AIエージェントとの会話は、コンテキストウィンドウが閉じた瞬間にリセットされる。設計判断も、ドメイン固有の発見も、運用上の注意点も、どこかに書き出しておかなければ次のセッションには残らない。この「記憶をどこに置くか」という問いに対して、外部DBを一切使わず、Gitリポジトリの中のMarkdownだけで答えようというのが OKF Agent Memory だ。2026-09-05 に公開され、翌日には266★に到達している。
30秒でわかる OKF Agent Memory
・実体:knowledge/ 配下のMarkdown群を読み書きするGo製CLI+MCPサーバー。外部DB・埋め込みAPIを使わない
・準拠仕様:Google の OKF v0.2(Apache-2.0・★9,079)。本体はMITの独立実装で、Google公式製品ではない
・実測で成立した公称値:依存ゼロ(go.mod に require 0件)/RSS 15MB未満(実測4.7MB)/リリース資産のSHA-256一致
・条件付きだった公称値:「検索300µs未満」は8概念で315µs、50概念で2.46msと概念数に比例して伸びる
・日本語の落とし穴:日本語だけの概念は検索0件。トークナイザが英数字以外を捨てる
・MCP常駐コスト:6ツール・860トークン(cl100k_base)=当サイト計測11サーバー中もっとも軽い部類
この記事のポイント
・公称「検索300µs未満」が成立するのは同梱バンドルと同じ8概念規模までで、50概念で2.46ms・1,000概念で102msと概念数に線形に伸びる
・日本語だけで書いた概念は検索0件。トークナイザが英数字以外をすべて捨てるため、英語キーワードの併記が事実上必須
・MCPサーバーの常駐コストは6ツール・860トークン(cl100k_base)で、当サイトが同一プローブで測った11サーバー中もっとも軽い
記憶をどう持たせるかはエージェント設計の一部であり、フレームワーク側の選択とも絡む。全体像は AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証 にまとめてあるので、そちらとあわせて読むと位置づけが掴みやすい。
本記事は v0.1.1(2026-09-06 15:21 UTC リリース)の公式ビルド済みバイナリ okf-darwin-arm64 を対象に、checksums.txt とのSHA-256照合を済ませたうえで実測している。検証環境は macOS 14(Darwin 23.5.0)/ Apple Silicon (arm64) / Go 1.26.5。
OKF Agent Memoryとは——Google OKF v0.2をGitの中で回す記憶層
まず土台の仕様から確認する。OKF(Open Knowledge Format)は実在する。GoogleCloudPlatform/knowledge-catalog(★9,079・Apache-2.0)で公開されており、okf/SPEC.md の冒頭に「Version 0.2」と明記されている。仕様本文は「ディレクトリに置かれたYAMLフロントマター付きMarkdown」以上のことをほとんど要求しない——スキーマレジストリも、中央機関も、必須ツールも無い、と自ら宣言する最小主義の仕様だ。
そのうえで OKF v0.2 が「素のMarkdown+フロントマター」に足しているのは、エージェントが知識を書き続ける前提から出てくる3つのメタデータである。provenance(何から作られ、どう検証されたか)/trust(どれだけ信用してよいか)/freshness(まだ真か)。CLAUDE.md や AGENTS.md のようなアドホックなMarkdownには無く、かといってベクトルDBに沈めると人間から見えなくなる情報を、フロントマターの sources / trust / status / stale_after として一級市民にしている。
OKF Agent Memory は、この仕様に沿ったバンドルを読み書き・検証・検索するツール側の実装だ。整理すると5層になる。
Markdown+YAMLフロントマター"] --> B["Agent Memory Convention
検索してから書く・信頼度を付ける"] B --> C["Agent Skill
エージェント向けの操作手順"] C --> D["Goツール層
パーサ・検証・BM25検索・MCP"] D --> E["knowledge/ バンドル
プロジェクトの実際の記憶"]
重要なのは、この5層のうちGoogleのものは最上段の仕様だけという点だ。リポジトリ名・バッジ・「Built on Google OKF v0.2」という表現から Google 製と読み違えやすいが、okf-memory/okf-agent-memory は MIT ライセンスの第三者実装で、Google の関与を示す記述はリポジトリ内には無い。仕様がオープンなので準拠実装を名乗るのは正当だが、「Google製ツール」ではない。
実際に1つの概念ファイルがどう書かれるかを見ると、仕様の狙いが分かりやすい。同梱バンドルの概念は、フロントマターに okf_version / type / id / title / description を必須で持ち、任意で status(active / deprecated など)、trust(generated か verified か)、sources(何を根拠に書いたか)、stale_after(いつまで有効とみなすか)を持つ。本文はそのまま人間が読むMarkdownだ。
この設計の効き目は「エージェントが書いた内容を、人間が後から棚卸しできる」点にある。ベクトルDBに沈めた記憶は、間違いが混ざっても外からは見えない。対して OKF バンドルは、trust: generated のまま放置されている概念を grep で洗い出せるし、git log で「いつ誰(どのエージェント)が書き換えたか」を追える。記憶を監査可能な資産として扱うという立場が、フォーマットの選択そのものに出ている。
ツール側もこの立場を強制する仕組みを持っている。validate は単なるYAMLの構文チェックではなく、概念間リンクの切れ(broken link)・どこからも参照されていない概念(orphan)・stale_after を過ぎた概念(stale)を検出する。--strict を付けると接続性の警告がエラーに昇格し、--drift を付けると index.md に書かれた説明文が各概念の description と食い違っていないかまで見る。知識ベースが「書きっぱなしで腐る」典型的な失敗に対して、機械的なゲートを1枚用意しているわけだ。
もうひとつ、運用ルール側の柱が Search-Before-Write(書く前に必ず検索する)である。同じ概念が別名で二重に作られるのを防ぐための規約で、Agent Skill 側のプロンプトにも組み込まれている。ただしこれは規約であってツールの強制ではない——okf create は既存概念を検索せずに実行しても止まらない。エージェントが規約を守るかどうかに依存する部分は残る。
同じ「Markdownで記憶を持つ」路線としては、当サイトでも EverOS徹底解説|AIエージェントに永続記憶を与えるMarkdownネイティブ記憶OS を扱っている。OKF Agent Memory との違いは、EverOS が独自の記憶ランタイムを定義するのに対し、こちらは外部の公開仕様に乗り、ツールは仕様の実装に徹するという立て付けにある。
インストールと基本コマンド——公式バイナリのSHA-256照合まで
v0.1.0 / v0.1.1 のどちらのリリースにも、okf-darwin-arm64 / okf-darwin-amd64 / okf-linux-amd64 / okf-linux-arm64 と checksums.txt が付いている。ソースビルドが唯一の導線ではない。実際に落として照合した手順が以下だ。
# 1. 公式リリースのバイナリを取得(v0.1.1・Apple Silicon)
curl -sL -o okf https://github.com/okf-memory/okf-agent-memory/releases/download/v0.1.1/okf-darwin-arm64
chmod +x okf
# 2. 配布されている checksums.txt と照合する(ここを飛ばさない)
curl -sL https://github.com/okf-memory/okf-agent-memory/releases/download/v0.1.1/checksums.txt | grep darwin-arm64
shasum -a 256 okf
# 3. 版の確認
./okf version
実行結果は、checksums.txt 側の 2b80a404ab2972e8c6a91eda8c8df7b1c4df38dfbc8cf26af7f605561f899bc8 と手元の shasum 出力が一致、./okf version が okf version v0.1.1 (OKF v0.2 specification) を返した。バイナリサイズは 2,341,202 バイト(約2.2MB)。
ソースからビルドする場合は make build で、手元では約24秒・3,915,842バイトのバイナリになった(リリース版のほうが小さいのは、リリースビルドがシンボルを落としているため)。ここでREADMEのバッジとの食い違いが1つある。バッジは Tooling: Go 1.26 と表示するが、go.mod は go 1.22.0 で、CI(.github/workflows/ci.yml / release.yml)はいずれも go-version-file: 'go.mod' を指定している。実際にビルドに使われる版は1.22.0系であり、Go 1.26 が要るわけではない。
同梱の knowledge/ バンドルに対する検証コマンドも実行できる。
./okf validate knowledge --strict --drift
出力は OKF v0.2 check of "knowledge" (v0.2): 8 concept(s), 0 error(s), 0 warning(s); 0 broken link(s), 0 orphan(s), 0 stale [--strict]. Conformant. だった。自リポジトリのバンドルは自ツールの厳格モードを通る。
同梱バンドルは8概念。READMEはグラフ検証の速度を「50+ concepts」を前提に語るが、リポジトリに入っている knowledge/ は概念8本・合計30KBである。後述の速度の話は、この規模差を踏まえて読む必要がある。
【実測】「検索300µs未満」はどこまで成立するか
READMEの目玉は < 300 µs (Microseconds, In-Memory BM25) という検索レイテンシだ。これを検証するにあたり、まずCLIの実行時間で測っても意味がないことを確認しておく。okf search の実測はプロセス起動を含めて最良7.3ms・中央値16.7ms で、µs のオーダーとは2桁違う。公称値は明らかに「プロセス内の検索処理そのもの」を指している。
そこで、公開APIである pkg/okf の LoadBundle() と Bundle.Search() を直接叩くGoプログラムを書き、プロセス起動を含まない純粋な検索時間を測った。ウォームアップ3回のあと200回実行し、最良値を採る。あわせて、同じ形式の合成バンドル(1概念あたり約3.2KBの英語本文)を概念数を変えて生成し、スケーリングを見た。
| 概念数 | 検索(1語クエリ) | 検索(3語クエリ) | バンドル読み込み |
|---|---|---|---|
| 8(同梱バンドル相当) | 315 µs | 461 µs | 312 µs |
| 50 | 2.46 ms | 3.73 ms | 1.75 ms |
| 200 | 12.7 ms | 15.7 ms | 12.5 ms |
| 500 | 46.1 ms | 70.2 ms | 64.9 ms |
| 1,000 | 102.4 ms | 123.6 ms | 230.4 ms |
結論はこうだ。「300µs未満」は同梱バンドルと同じ8概念規模でだけ成り立つ(315µsなので、厳密にはそこでもわずかに超えた)。概念50本で2.46ms=公称の約8倍、500本で46ms=約150倍、1,000本で102ms=約340倍になる。伸び方は概念数に対してほぼ線形で、これは同じ計測を3回繰り返しても再現した。
なぜ線形に伸びるのか。pkg/okf/search.go を読むと理由がはっきりする。この実装は転置インデックスを持たない。クエリのたびに全概念をループし、各概念の Title + Description + Tags + ID + Body を毎回 strings.ToLower で連結し、tokenize() を呼び直している。つまり「インメモリ索引を引く」のではなく「全件を毎回スキャンして採点する」構造で、コーパスが増えれば増えた分だけ比例して遅くなる。
もう1点、用語の精度について。README は一貫して「BM25」と書くが、実装のスコア式にあるのはIDF(平滑化あり)とフィールド別の重み付きTFで、BM25を特徴づける k1 の飽和項と b の文書長正規化が無い。重み付きTF-IDFと呼ぶのが正確だ。小規模なプロジェクト知識を引く用途では実害は出にくいが、「BM25だから長文に強い」といった期待は置かないほうがいい。
実運用のイメージに落とすと、こうなる。数十本のADR(アーキテクチャ決定記録)を貯めた程度なら、検索は数ミリ秒で返るので体感上は問題にならない。エージェントが1タスクで数回検索する程度の使い方なら、この規模では十分に速い。一方、コードベース全体の関数や型を概念として登録していくような使い方——数百〜数千概念——では、1回の検索が数十〜数百ミリ秒になる。エージェントがループの中で繰り返し検索する設計だと、ここが積み上がって効いてくる。
なお、バンドル読み込み(LoadBundle)の数値は検索よりばらつきが大きい。ディスクI/Oを含むため並行負荷の影響を受けやすく、200概念と500概念で順序が逆転する計測も出た(本記事の計測中も3セッションが同一マシンで走っていた)。検索側は3回の反復で安定して同じ傾向を再現したので、スケーリングの根拠としては検索の値を採っている。
公称値そのものを否定しているわけではない。8概念で315µsという値自体は再現した。問題は、公称値がどの規模で測ったのかREADMEに書かれていないことと、その規模がリポジトリ同梱バンドル(8概念)と一致し、README自身がグラフ検証の説明で使う「50+ concepts」とは食い違っていることにある。数百概念まで育てる前提なら、この数字を性能の根拠にはできない。
【実測】日本語だけで書いた概念は検索に出てこない
日本語話者にとっては、速度より先にこちらが問題になる。同梱バンドルに対して4つのクエリを投げた結果が以下だ。
| クエリ | 返却件数 |
|---|---|
architecture(英語) |
8件 |
アーキテクチャ |
0件 |
設計 |
0件 |
アーキテクチャ layers(混在) |
8件 |
原因は pkg/okf/search.go の tokenize() にある。分割の述語が「a-z でも A-Z でも 0-9 でもない文字はすべて区切り」と定義されているため、日本語の文字はすべて区切り文字として捨てられ、トークンが1つも残らない。クエリ側でトークンが0個になれば Search() は即座に nil を返す。混在クエリ アーキテクチャ layers が8件返るのは、日本語部分が消えて英語の layers だけが効いているからで、日本語が効いているわけではない。
これは設定で回避できるオプションではなく、トークナイザの実装そのものに由来する。日本語のプロジェクト知識を貯める用途で使うなら、title / tags / id に英語のキーワードを必ず併記する運用が事実上必須になる。CJKの語境界がASCIIトークンを巻き込む類の問題は当サイトでも繰り返し踏んでおり、memory-os解説|AIエージェントの記憶をローカル完結でOS的に階層管理する7層メモリ基盤OSS で扱った階層メモリ系でも、日本語の扱いは実装ごとに大きく違う。
MCPサーバーの常駐コストを、同じ物差しの11サーバーと並べる
okf mcp <bundle> で stdio のMCPサーバーが立ち上がる。エージェントに接続した瞬間から、ツール定義はツールを1つも呼ばなくてもコンテキストに常駐し続ける固定費になる。当サイトでは同一プローブでMCPサーバーの tools/list を測り続けているので、そこへ並べた。
公開されるツールは6つ。okf_search / okf_show / okf_validate / okf_create / okf_update / okf_relate で、CLIのサブコマンドとほぼ一対一に対応する。
| 指標 | 実測値(v0.1.1) |
|---|---|
| ツール数 | 6 |
tools/list バイト数 |
3,541 バイト |
| トークン数(cl100k_base / tiktoken) | 860 トークン |
| 1ツールあたり | 143.3 トークン |
| 認証 | 不要(ローカルのバンドルを読むだけ) |
接続設定は他のstdio系MCPサーバーと同じ形で、バンドルのパスを引数に渡すだけでいい。
{
"mcpServers": {
"okf-memory": {
"command": "/absolute/path/to/okf",
"args": ["mcp", "/absolute/path/to/your-project/knowledge"]
}
}
}
同じ payload 定義・同じ cl100k_base で測った既定設定の他サーバーと比べると、860トークンは当サイトの計測対象のなかで最も軽い。次点が Microsoft Learn MCP の1,097、以下 zvec-grep 1,575、Obscura 3,355、Supabase 5,713、Chrome DevTools 6,010、Backlog 11,680、draw.io 15,383、Notion 21,831、OpenKnowledge 39,710 と続く。ツール数を6に絞り、引数スキーマを単純に保っていることが効いている。
トークナイザ名を省略しない。ここで挙げた数値はすべて cl100k_base(OpenAI のトークナイザ)である。Anthropic の count_tokens で測ると同じペイロードが1.35〜1.65倍に振れ、倍率は対象ごとに違うので一律換算もできない。他所の「MCPは何トークン」という数字と突き合わせるときは、まずトークナイザを揃える必要がある。
なお v0.1.0 時点のコミットで測ったときは 2,655バイト / 658トークンで、v0.1.1 の「dynamic bundle resolution」対応でスキーマが増えた分だけ重くなっている(ツール数は6のまま)。ツール数を絞る設計判断が、そのまま常駐コストの差として出ている。
「トークン80%削減」は何の数字か——再現していない点を明示する
READMEは -80% token reduction を掲げ、make benchmark で自分のハードウェアでも再現できると案内している。本記事ではこれを再現していない。 理由は2つある。
1つは実行条件だ。このベンチマークは LM Studio / Ollama 上のローカルLLM(Gemma・Qwen・Llama)を必要とし、TTFT(Time-To-First-Token)とトークン数を測る構成になっている。本記事の他の計測がすべて決定論的に再現できるのに対し、ここだけモデル・量子化・ハードウェアに強く依存する。
もう1つはより本質的で、この80%は「monolith な1枚ドキュメント」対「OKFバンドルに分割したもの」という、リポジトリ側が用意した対の比較である(benchmarks/data/ に両者のフィクスチャが置かれている)。つまり測っているのは「大きな文書を丸ごと読ませる代わりに、索引を辿って必要な概念だけ読ませればトークンが減る」というprogressive disclosure という手法の効果であって、OKF Agent Memory というツール固有の性能ではない。同じことは他の階層的なドキュメント構成でも起こる。削減率の絶対値は、比較対象に選んだ monolith がどれだけ冗長かで決まる。
したがって本記事では、この数字をベンダー公称値として記載するに留め、実測値としては扱わない。逆に、決定論的に確認できた公称値は次のとおりだ。
| README の主張 | 判定 | 実測の根拠 |
|---|---|---|
| 外部依存ゼロのGoツールチェーン | 成立 | go.mod に require が1件も無い |
| RSS 15MB未満 | 成立 | validate 実行時の最大RSS 4,947,968バイト(約4.7MB) |
| 単一バイナリで配布 | 成立 | 公式リリース資産2.2MB・SHA-256一致 |
| OKF v0.2 準拠 | 成立 | 仕様は実在(Apache-2.0)。validate --strict が自バンドルを通す |
| 検索 300µs 未満 | 条件付き | 8概念で315µs。50概念で2.46ms、1,000概念で102ms |
| プロセス起動 4ms 未満 | 測定条件に依存 | 最良4.07msを観測したが、並行負荷下では12〜19msまで振れた |
| グラフ検証 約4.0ms(50+概念) | 未確認 | 同梱バンドルは8概念。50概念以上の実バンドルが無い |
| トークン80%削減 | 未再現 | ローカルLLMとフィクスチャ対に依存。手法の効果でありツール固有の値ではない |
| BM25 | 不正確 | IDF+重み付きTFはあるが、k1の飽和項とbの文書長正規化が無い |
OKF Agent Memoryは誰に向いていて、誰に向かないか
ここまでの実測を踏まえると、適合条件はかなりはっきりする。
まず、記憶層としての位置づけを整理しておく。下の表は仕組みの違いをまとめたもので、速度の数値は本記事で実測したOKF Agent Memoryの列だけが実測値、他列は各プロジェクトの設計上の性質を示す(他ツールの速度は本記事では測っていない)。
| OKF Agent Memory | ベクトル検索型(mem0 / Letta 等) | アドホックMarkdown(CLAUDE.md 等) | |
|---|---|---|---|
| 保存先 | リポジトリ内 knowledge/ |
外部ベクトルDB | リポジトリ内の単一ファイル |
| 検索方式 | 語彙一致(重み付きTF-IDF) | 埋め込みベクトルの類似度 | 全文をコンテキストへ投入 |
| 表記ゆれ・言い換え | 吸収できない | 吸収できる | (検索という段階が無い) |
| 日本語クエリ | 0件になる(v0.1.1実測) | 埋め込みモデル次第 | 該当なし |
| 外部API課金 | 不要 | 埋め込みAPIの費用が継続 | 不要 |
| 人間によるレビュー | git diff で可能 |
DBの中身は不透明 | git diff で可能 |
| 信頼度・鮮度の管理 | trust / stale_after で一級 |
実装依存 | 無い |
| 規模の上限 | 数十〜百概念が実用域 | 大規模に耐える | コンテキスト長が上限 |
この並びで見ると、OKF Agent Memory が置き換えようとしているのはベクトルDBではなく、むしろ CLAUDE.md や AGENTS.md に何でも書き足していく運用のほうだと分かる。単一ファイルが肥大化してコンテキストを圧迫する問題に対し、索引を辿って必要な概念だけ読ませる構造を与える——これが README の言う progressive disclosure であり、前節の「80%削減」が測っているものでもある。
噛み合うケース:記憶の中身を git diff / git log でレビューしたい。外部DBや埋め込みAPIをプロジェクトに持ち込みたくない。扱う知識が数十概念規模に収まる。チーム内の設計判断(ADR的なもの)を、エージェントと人間の両方が読む場所に置きたい。MCPの常駐コストを可能な限り抑えたい。
噛み合わないケース:日本語だけで知識を書きたい(検索が機能しない)。数百〜数千概念のコーパスを想定している(検索が線形に劣化する)。表記ゆれや言い換えを吸収したい(語彙の完全一致・前方一致しか見ないため、ベクトル検索型の Letta Code徹底解説|記憶を持つステートフルAIエージェントCLIの仕組みと使い方 系が向く)。
最後に、プロジェクトの若さについて事実だけ置いておく。リポジトリ作成は2026-09-05、本記事執筆時点でコミットは3本、リリースは v0.1.0 と v0.1.1 の2本、Issue・PRともにオープン0件、266★。執筆の途中で v0.1.1 が公開され、MCPのJSON-RPC 2.0通知準拠が修正された(そのため本記事は v0.1.1 に測り直している)。動きは速く、設計の方向性も明快だが、公称値の一部が同梱バンドル規模でしか成立しない状態でREADMEに書かれている点は、採用判断の前に自分のコーパス規模で測り直す理由になる。本記事の計測は data/measurements/ に登録してあり、同じ手順で追試できる。
参照ソース
- okf-memory/okf-agent-memory — 本体リポジトリ(MIT)。README・
pkg/okf/search.go・go.mod・.github/workflows/を参照 - GoogleCloudPlatform/knowledge-catalog — okf/SPEC.md — Open Knowledge Format v0.2 仕様本文(Apache-2.0)
- okf-agent-memory releases — v0.1.0 / v0.1.1 のリリース資産と
checksums.txt