AI 工程

OKF Agent Memory 實戰:把 coding agent 的記憶搬進 git,附完整接線步驟

HN 上一個叫 okf-agent-memory 的 repo,上線第一天就衝到 76 分。點進去看,它想解的問題我每天都在遇到:coding agent 每開一個新 session 就失憶一次。

你昨天跟 Claude Code 花半小時才講清楚「session TTL 為什麼是 30 分鐘不是 15 分鐘」,今天開新視窗,它又問你一次。於是大家的標準做法是往 CLAUDE.md / AGENTS.md 裡塞——塞到 400 行、800 行,然後撞上第二個病:那份檔案每一輪都全文進 context,agent 讀到第 300 行時前面的注意力早就稀釋掉了,而且裡面有一半是三個月前就作廢的決策,沒人記得要刪。

context bloat 加 memory rot,一個都躲不掉。

OKF Agent Memory 給的答案是:別再維護一個大檔案,改成一個「可被搜尋的知識目錄」,而且它就住在你的 git repo 裡,用 git diff 就能審。

這篇把它的機制拆開講清楚,然後給你一份可以直接照做的接線步驟(安裝 → bootstrap → MCP 設定 → 寫第一條記憶 → CI gate → prompt 招式)。最後誠實講數字:我把 repo 裡九份 benchmark 結果檔逐一調出來比對,發現它 README 上寫的數字跟實際 commit 進去的結果檔對不上——這點也一起說。

先分清楚:OKF 是 Google 的規格,okf-agent-memory 是別人的實作

這兩個東西常被混在一起講,先切開。

Open Knowledge Format(OKF) 是 Google Cloud 提出的開放規格。Sam McVeety(Tech Lead, Data Analytics)與 Amir Hormati(Tech Lead, BigQuery)在 2026 年 6 月 13 日的 Google Cloud Blog 上發表 v0.1,規格現在住在 GoogleCloudPlatform/open-knowledge-formatknowledge-catalog/okf/SPEC.md 也有一份)。它的野心不大,正因為不大所以好用:知識就是一個目錄的 Markdown 檔,每個檔案上面掛一段 YAML frontmatter。

規格本身有多寬鬆?看 SPEC 的 conformance 條款就懂:一份 bundle 只要滿足「每個 .md 的 frontmatter 能被解析」「每個 frontmatter 有非空的 type 欄位」「保留檔名 index.md / log.md 結構正確」就算合規。type 是唯一必填欄位titledescriptionresourcetags 全部是建議而非強制;而且規格明確寫了消費端 MUST NOT 因為缺少 optional 欄位或看到不認識的 type 就拒絕整份 bundle。

v0.2 是向後相容的小改版,主要加的是「信任訊號」:sources(來源與可信度)、generated(誰、何時產生)、verified(誰、何時確認過)、status(draft / stable / deprecated)、stale_after(絕對時間的過期點)。同時做了兩個更名:v0.1 的 timestampgenerated.at 取代,body 裡的 # Citations 清單被 frontmatter 的 sources 取代。

okf-agent-memory 則是 GitHub 上 okf-memory 這個 org 做的獨立第三方實作,不是 Google 官方產品。幾個該知道的事實:repo 建立於 2026-09-05,隔天發 v0.1.1,語言是 Go 1.26、零外部依賴、MIT 授權,作者本人以 okf_memory 帳號在 2026-09-05 貼上 HN。

所以:這是一個上線兩天的專案。 規格是穩的,工具是新的。下面所有「照做」的部分請帶著這個前提讀——它值得你花 15 分鐘在 side project 上試,但還不到「明天就搬進主 repo」的成熟度。

運作原理:五層堆疊 + Progressive Disclosure

repo 的 README 用一張 mermaid 圖把自己拆成五層,我覺得這個分層是全案最有價值的部分,因為它把「規格」「行為約定」「提示詞」「工具」「資料」分開了:

  1. OKF v0.2 規格 — 檔案長什麼樣(normative)
  2. Agent Memory Convention v0.1 — agent 該怎麼行為:search、review、trust
  3. Agent Skill — 實際餵給 LLM 的提示詞與工作流
  4. Tooling Layer — Go 函式庫與 CLI:解析、驗證、搜尋、MCP
  5. Knowledge Corpus — 你專案的 knowledge/ bundle

真正的運作核心叫 Progressive Disclosure(漸進揭露)。用一句話講:agent 先讀一句摘要決定要不要讀全文,而不是把全部知識倒進 context。

OKF Progressive Disclosure 與 monolith context dump 的流程對比圖

流程是這樣的:

  • knowledge/index.md 是根目錄索引,每一行只放「概念標題 + 一句話描述 + 相對連結」。
  • agent 拿到任務後,先跑 okf search "<query>",Go 核心在記憶體裡做 BM25 排名,回傳前 N 筆的 id / 分數 / 一句話 description / 命中欄位
  • agent 讀那幾句 description,判斷哪一個真的相關,才用 okf show <concept-id> 把單一概念的全文載進來。
  • 概念之間用相對 Markdown 連結互相指涉,形成一張圖;okf show 會一併回傳 inbound / outbound 連結,agent 可以沿著圖走。

對照組是所謂的 monolith dump:把整份 MONOLITH_DOCS.md 塞進去,agent 在裡面自己找。差別就在這裡。

一份 concept 檔案長什麼樣

這是 repo 內 examples/software/decisions/jwt-tokens.md 的原文,非常樸素:

---
type: Decision
title: Ed25519 Stateless JWT Tokens
description: Architectural decision adopting Ed25519-signed stateless JWTs for inter-service API authorization.
tags: [decision, jwt, security, auth]
generated: { by: agent/gemini-3.7-flash, at: 2026-08-27T12:00:00Z }
status: stable
---

# Decision: Ed25519 Stateless JWT Tokens

## Context
Downstream services required fast authorization verification without
overwhelming the central database on every HTTP request.

## Decision
The [auth-service](../architecture/auth-service.md) issues Ed25519 asymmetric
JWT tokens. Downstream services cache the public key and verify signatures
locally without network calls.

注意兩件事。第一,description 規定是恰好一句話——這不是文青要求,而是 Progressive Disclosure 的成本控制:search 結果只回這一句,它必須一句就讓 agent 判斷「要不要展開」。第二,generated: { by: agent/gemini-3.7-flash, ... } 老實記錄了這條知識是機器寫的。

為什麼是 BM25 而不是 embedding

這是全案最實用的設計選擇。okf 用的是詞彙式(lexical)BM25,整份索引在記憶體裡,不是向量檢索。README 給的數字是搜尋 < 300 µs、50+ 概念的全語料解析與圖驗證 ~4.0 ms、單一 binary 冷啟動 < 4 ms、RSS < 15 MB、每千次檢索 API 成本 $0.00。

好處很明確:沒有 embedding API 費用、沒有網路往返、沒有要維運的向量資料庫、沒有「索引跟檔案不同步」的問題(每次都是現場建)。對於一個會在 agent tool-calling 迴圈裡被呼叫幾十次的東西,這個取捨我認為是對的。

代價也很明確:BM25 不懂同義詞。 你的概念寫「session TTL」,agent 搜「登入逾時」就打不中。這是後面「什麼時候別用」會回來談的重點。

信任分層:agent 寫的跟人審過的不能混在一起

這是 OKF v0.2 相對於「一個大 Markdown 檔」最實質的升級,也是 HN 上使用者 lukevp 最買單的點——他的原話是,OKF 0.2 解決了「AI 產生海量文件、卻跟人類真正核准並 commit 的東西被等權對待」的問題。

OKF concept 檔案結構與三層信任分級解剖圖

規格定義的信任層級是推導出來的、不是存進去的

  • Unverified — 沒有 verified 欄位。agent 寫完就這樣。
  • Machine-confirmedverified 裡的 actor 是非人類(例如 agent/...process/...)。
  • Human-reviewedverified 裡出現 human:<id>

actor 字串有慣例:agent 用 <producer>/<version>、人用 human:<id>、自動化流程用 process:<id>

repo 的 AGENTS.md 把這件事寫成硬規則:agent 寫 frontmatter 時必須記 generated: { by, at },而且「Never mark agent-generated knowledge as human: verified」。它的測試案例 TC-05 專門測這個:給一個帶 verified: - by: human/lead-architect 的概念,叫 agent 去改內容,通過條件是改了 body 但保留 verified 區塊、並且只加自己的 generated

這是我覺得整個專案最該被抄走的觀念,就算你不用它的工具:你的 agent 記憶裡,機器猜的跟人拍板的,必須在資料結構上分得開。

手把手:把它接上你的 coding agent

以下步驟依據 repo 的 README.mddocs/CLI.mddocs/GETTING_STARTED.md 與官網 okf-memory.dev 整理。我沒有實際跑過完整流程(專案上線兩天、我只讀了原始碼與文件),所以每一步我都標了「文件怎麼說」,你照做時若行為不同,以你機器上的輸出為準。

Step 1|裝 CLI

官網給的一行安裝:

curl -fsSL https://okf-memory.dev/install.sh | sh

(官網另外列了 Go install、Homebrew tap 與原始碼編譯。若你跟我一樣不喜歡 curl | sh,直接 clone 後 make build,產物在 bin/okf。)

Step 2|在專案裡 bootstrap

okf bootstrap /path/to/my-project --name "My Service"

docs/CLI.md,這一步會裝四樣東西:

  • knowledge/ — OKF v0.2 bundle,含 index.md(宣告 okf_version: "0.2")與 log.md
  • .agents/skills/okf-memory/ — agent skill 定義與能力說明
  • AGENTS.md — 給 coding agent 的操作指令
  • Makefilemake validatemake search q="..." 兩個便利指令

這裡有個關鍵細節值得單獨講: bootstrapAGENTS.md非破壞性的 smart-append,它會加一段有分隔標記的區塊,不會蓋掉你原本的內容。要覆蓋得自己加 --overwrite-agents-md。如果你只想要 bundle 不想要其他東西,用 --no-skill --no-makefile --no-agents-md;反過來只想要一個空 bundle,用 okf init my-project/knowledge

Step 3|接 MCP

okf 內建 MCP server,走 stdio。文件說 Claude Code、Cursor、Codex 都是這樣接:

{
  "mcpServers": {
    "okf-memory": {
      "command": "/path/to/okf-agent-memory/bin/okf",
      "args": ["mcp", "/path/to/project/knowledge"]
    }
  }
}

接上之後,agent 手上會多六個工具(依 docs/CLI.md 的表):

工具 參數 做什麼
okf_search query, limit BM25 查記憶
okf_show concept_id 取單一概念的 frontmatter、body、圖連結
okf_create id, type, title, description, body, tags 建概念,自動更新 index 與 log
okf_update id, title, description, body 改概念,寫入 log.md
okf_relate source_id, target_id, description 連兩個概念
okf_validate strict, drift 驗證 bundle

多 bundle 的 repo 可以在呼叫時帶 bundle 參數,例如 okf_search(query="...", bundle="examples/software")

Step 4|寫第一條記憶

先示範 CLI 版,因為你在 CI 或 shell 裡也會用到:

okf create decisions/session-ttl knowledge \
  --type Decision \
  --title "Redis Session TTL = 30 分鐘" \
  --desc "把 Redis session TTL 從 15 分鐘調到 30 分鐘,換掉行動端頻繁被登出的問題。" \
  --tags "decision,redis,session" \
  --actor "human:abao"

create 會自動做三件簿記:寫概念檔、更新父層 index.md 的條目、在 log.md 追加一筆有日期的變更紀錄(要跳過可加 --no-log / --no-index)。

要把兩個概念連起來:

okf relate decisions/session-ttl architecture/auth-service knowledge \
  --desc "TTL 決策影響 auth-service 的 token 刷新"

在 agent 裡的 prompt 招式,重點是把「search-before-write」講成硬性順序,不要只說「記得存記憶」:

把我們剛剛決定的 Redis session TTL 改動存進專案記憶。
順序必須是:
1. 先用 okf_search 查 "Redis session TTL",limit 3
2. 如果找到既有概念 → 用 okf_update 改它,不要建新檔
3. 只有確認完全不存在 → 才用 okf_create
4. 最後跑 okf_validate strict=true
描述限一句話。generated 的 by 填你自己的 model id,不要填 human:。

這段對應的是 repo 測試案例 TC-03(反重複):文件說通過條件是 agent 更新既有的 decisions/session-ttl.md,而不是生出一個 timeout-v2.md。這也是所有 agent 記憶系統最常爛掉的地方——同一件事被寫成五個版本,然後互相矛盾。

Step 5|把 validate 變成 CI gate

這是我認為 git-native 路線真正的紅利:記憶進 PR,就能被 lint、被 review。

okf validate knowledge --strict --drift

三個旗標的意思:--strict 把連通性警告(孤兒概念、壞掉的相對連結、provenance 缺漏)升級成致命錯誤;--drift 抓「概念 frontmatter 的 description」跟「父層 index.md 裡那一行」不一致;--json 給機器讀。退出碼定義得很乾淨:0 合規、1 不合規或沒過 strict gate、2 檔案系統/載入錯誤——直接丟進 CI 即可。

JSON 輸出長這樣,欄位夠你做報表:

{
  "bundle_path": "knowledge",
  "declared_version": "0.2",
  "concept_count": 7,
  "errors": [], "warnings": [], "broken_links": [], "orphans": [],
  "stale_count": 0,
  "is_conformant": true,
  "gate_passed": true
}

Step 6|抄它 AGENTS.md 裡最狠的那一條

bootstrap 產出的 AGENTS.md 裡有一條規則,就算你完全不用這個工具也該抄進自己的 agent 設定:

DO NOT use list_dirgrep_searchfind 或 raw view_file 去掃 knowledge/ 目錄。
DO NOT 把所有知識檔倒進 context。
只能透過 okf search "<query>" --limit 3 --json 查,先看 description 再決定要不要 okf show

為什麼要寫得這麼兇?因為 coding agent 的預設本能就是 lscat 全部——你不明文禁止,Progressive Disclosure 的效果會被 agent 自己的搜尋習慣抵銷掉。同一份文件還有一條安全規則值得抄:docs/SECURITY.md 明列了絕對不能寫進 knowledge/ 的四類東西——密鑰與憑證、PII、原始 chain-of-thought 與工具呼叫日誌、大型 stack trace 與 dump。理由很現實:這是 git 的永久紀錄,寫錯了要清歷史。

數據:80% 是怎麼算出來的,以及不該怎麼引用

repo 的行銷語是「Slashes token bloat by 80%」,官網寫「up to 80.1% context overhead reduction」與「5.2x faster TTFT」。這些數字是真的存在於 repo 裡的,但適用前提比標語窄很多,這裡完整攤開。

測的是什麼: benchmarks/ 下只有一個情境——叫模型實作一段企業級加密 payload。對照組是把整份專案文件(約 11.5k 字元、約 3,000 tokens,涵蓋架構、資料庫、Kubernetes、Stripe、Redis、telemetry、安全政策)全塞進 prompt;實驗組是先用 BM25 撈出唯一相關的概念 security/encryption-policy(約 500 tokens)再餵。品質指標是四項政策遵循檢查:有沒有用 AES-256-GCM、有沒有用 96-bit nonce、有沒有加上 X-OKF-Encryption-Version header、有沒有誤用 ECB/CBC。

以下是我從 benchmarks/results/ 九份結果檔裡挑出的實測數字(全部標了硬體與日期,可查):

模型 執行環境 Input tokens(前 → 後) TTFT(前 → 後) 政策遵循
gpt-5.6-sol OpenAI API(客戶端 M2 Pro) 3,034 → 603(−80.1%) 9,226.8 ms → 8,682.0 ms(1.1×) 4/4 → 4/4
ministral-3-14b-reasoning LM Studio / M2 Pro 3,034 → 603(−80.1%) 18,311.2 ms → 3,510.5 ms(5.2×) 4/4 → 4/4
qwen3-coder-30b LM Studio / M2 Pro 3,058 → 627(−79.5%) 10,607.5 ms → 2,458.1 ms(4.3×) 4/4 → 4/4
gemma-4-26b-a4b-qat LM Studio / M2 Pro 3,034 → 603(−80.1%) 36,099.3 ms → 20,886.4 ms(1.7×) 4/4 → 4/4
gemma-4-12b-qat LM Studio / M2 Pro 3,034 → 603(−80.1%) 60,254.1 ms → 43,938.2 ms(1.4×) 4/4 → 4/4

(資料來源:benchmarks/results/BENCHMARK_RESULTS_*.md,測試日期 2026-09-05,硬體 Apple M2 Pro / 32 GB,temperature 0.10。)

三個必須說的但書:

第一,我查到 README 跟結果檔不一致。 benchmarks/README.md 上寫 Gemma 26B 是「47.7s → 27.1s,1.8x faster」、Gemma 12B 是「50.1s → 45.8s,1.1x faster,政策遵循 1/4 → 4/4」。但 benchmarks/results/ 裡實際 commit 的結果檔寫的是 26B「36,099.3 ms → 20,886.4 ms,1.7×」、12B「60,254.1 ms → 43,938.2 ms,1.4×,政策遵循 4/4 → 4/4」。同一份 README 的目錄樹也只列了 2 個結果檔,實際有 9 個——README 明顯是舊的。那個最有說服力的「1/4 → 4/4,Progressive Disclosure 防止幻覺」在現行結果檔裡我找不到對應證據。要引用數字,請引結果檔,不要引 README。

第二,TTFT 加速的來源是「prompt 短了 80%」,不是這個工具跑得快。 換句話說,任何能把 3,000 tokens 砍到 600 tokens 的方法都會拿到類似的加速。而且看得出強相關:本地量化模型(prefill 慢)獲益最大(4.3×、5.2×),走雲端 API 的 gpt-5.6-sol 只有 1.1×。你的 agent 如果跑 Claude 或 GPT 的雲端 API,別預期 5 倍。

第三——這是最重要的一條——它沒有測 retrieval 的 recall / precision。 HN 上 langs 講得很直接:「我不懂。為什麼是 benchmark 延遲而不是 recall/precision?在 LLM 呼叫的脈絡下,優化毫秒級延遲根本沒有意義。準確率才是這工具最大的價值,怎麼反而沒測?」svyatov 也問了同一件事。這個批評是成立的。 一個記憶系統真正會失敗的方式是「該撈到的沒撈到」,而 BM25 的同義詞弱點正好落在這個死角上——但 repo 裡沒有任何針對它的量測。

什麼時候該用、什麼時候別用

別用的情況:

  • 小專案、單人、知識量在 10 條以內。 HN 上 swordsith 的意見我認為值得認真對待:「我一直覺得 AI 的『記憶』對使用者體驗來說是痛點多過好處……它跟『skills』一樣浪費 context。最有效率的工作流,是在乾淨的 codebase 裡放幾份寫得好的(不是 AI 寫的)md 檔。」在小規模下,BM25 索引、圖驗證、drift 檢查全是純開銷,三份手寫 Markdown 完勝。
  • 你的團隊嚴重依賴 harness 原生記憶。 mbreese 的顧慮很實際:「這類非第一方工具一直是我的主要疑慮。Anthropic 可以調校 Opus、Fable 和他們的 harness 去使用自家的記憶格式或偏好的工具呼叫方式。我讓 LLM 穩定使用第三方工具的結果一直好壞參半。」這不是猜測,是所有 MCP 工具都會遇到的採用率問題——工具裝了不等於 agent 會用它,你得靠 AGENTS.md 的硬規則去逼。
  • 想要跨專案記憶。 skeledrew 明說他要的是 cross-project memory 且「全部存純文字、不要向量搜尋」。okf-agent-memory 的定位是 per-repo 的 knowledge/,跨專案不在它的設計裡。
  • 查詢語言跟知識寫法不同語系或高度同義。 中文團隊要特別注意:你用中文寫概念、agent 用英文搜(或反過來),BM25 直接失效。務實解法是 tagstitle 中英並列。

該用的情況:

  • 多人、多 agent、長壽命的 repo。 尤其是「新人 agent 進來、沒有任何對話歷史,要靠 repo 自己接手」這個場景——repo 的 docs/AGENT_TESTING.md 直接把它寫成 The Ultimate Test。
  • 決策需要被人類審核與追溯的團隊。 generated / verified 分層 + git 歷史 = 你可以在 PR 上 review agent 想寫進長期記憶的東西。這件事向量資料庫做不到。
  • 知識量已經多到單檔塞不下(幾十條以上)。 Progressive Disclosure 的收益隨語料量成長,AGENTS.md 的收益隨語料量遞減,交叉點大概就在這附近。
  • 不想付 embedding 錢、不想維運向量 DB。 單一 Go binary、零依賴、零 API 成本,這個組合在合規嚴格的環境裡特別香。

順帶一提,同一個生態還有別的選擇:scaccogatto/okf-skills(給 Claude Code 的 OKF plugin / skills / GitHub Action)、fellowgeek/mcp-memory(OKF 後端 + SQLite FTS5 的 MCP server)。如果你只想要 OKF 的格式紀律、不想引入新 binary,前者可能更輕。

對工程團隊的意義:可以今天就做的四件事

就算你決定不裝這個工具,這裡有四個可以直接搬走的做法:

  1. CLAUDE.md / AGENTS.md 拆成「索引 + 概念檔」。 主檔只留一句話描述加連結,細節下放到 knowledge/xxx.md。不需要任何工具,agent 用 grep 也能走。
  2. 每條長期知識都標作者身分。 至少分兩層:by: agent/<model>by: human:<id>。這是你未來清理記憶時唯一可靠的依據——AI 寫的可以大膽刪,人拍板的要問過才刪。
  3. 加上過期機制。 OKF 用 status: draft|stable|deprecatedstale_after 的絕對時間。memory rot 不是因為知識會爛,是因為沒人被通知該複查
  4. 在 CI 加一道記憶 lint。 就算只是檢查「每個概念檔有 frontmatter、description 是一句話、index.md 裡的描述沒有 drift」,也能擋掉八成的腐化。okf validate --strict --drift 的退出碼設計可以直接抄。

最後回到現實:這是一個兩天大的 v0.1.1 專案,規格本身(Google 的 OKF v0.2)比它的實作穩定得多。我的建議是先把觀念抄走、在 side project 上跑一週 okf bootstrap 看看你的 agent 到底會不會乖乖用那六個 MCP 工具——那個採用率,才是決定這條路成不成立的真正變數,不是 300 微秒。

來源

整理:DataAgent · Coding Agent 實戰教學

發表迴響

%d 位部落客按了讚: