Ian Chou's Blog

CtxFST CH29 - .ctxfst.md 是手動建的,不是聊天自動生出來的

CtxFST CH29:.ctxfst.md 是手動建的,不是聊天自動生出來的

前面二十八篇講了 parser、graph、retrieval、world state、planner。

讀完可能會有一個很自然的假設:這些 .ctxfst.md 檔案,應該是 OpenClaw 在聊天過程中自動從對話生出來的吧?

不是。

這篇把這件事講清楚。然後講一個更實際的問題:如果不是自動的,那日常怎麼維護?


現在的 Reality

目前的落地狀態是這樣的:

聊天紀錄 — 照常存在 session/transcript,這是對話的逐字稿。

ctxfst — 是你另外提供給系統的 structured memory file。

像放在 ~/.openclaw/workspace/memory/ 裡的那些:

retrieval-test.ctxfst.md
minimal.ctxfst.md
full.ctxfst.md

這些都是「餵給 memory engine 的知識文件」,不是聊天時自動產生的逐字稿格式。

兩個東西的性質完全不同:

聊天紀錄 .ctxfst.md
產生方式 自動,每次對話都有 手動建立
格式 非結構化,逐字稿 結構化,entities / states / chunks / relations
用途 回顧對話內容 餵給 memory engine,建立可查詢的世界模型
存放位置 session 目錄 ~/.openclaw/workspace/memory/

為什麼不能讓它自動產生?

很多人的直覺是:既然是記憶系統,為什麼不讓模型在背景自動把對話轉成 ctxfst 結構就好?

這其實是一個誤解。因為 .ctxfst.md 要解決的核心問題不是「過濾對話雜訊來記流水帳」

它的真正目的是精準控制一個專業的 OpenClaw Agent,讓手動微調的要求能被嚴格執行,且 Agent 能時時了解自己的狀態。

以一個「專業生圖 Agent」為例,你可能會需要:

這種涉及「精確約束與狀態追蹤」的系統,如果交給模型從發散的日常對話中去「自動猜測」,很容易把你除錯時的一句氣話或暫時性的嘗試,全當成未來的永久規則。

所以,手動建立不是因為做不到自動化。而是因為 Agent 的專業行為規範,本來就需要人類給予明確、強制性的宣告。


不需要從零開始

手動不代表每次都要從空白檔案開始寫。

最務實的起步方式:

先寫最小版本

只放最基本的結構:

---
id: my-project
type: knowledge
---

## Entities
- entity:deploy-pipeline | skill | Deploy the app to production
- entity:staging-env | resource | Staging environment

## States
- state:code-reviewed | Code has been reviewed and approved
- state:deployed-to-staging | App deployed to staging

## Relations
- entity:deploy-pipeline REQUIRES state:code-reviewed
- entity:deploy-pipeline LEADS_TO state:deployed-to-staging

## Chunks
### deploy-pipeline overview
[tags: entity:deploy-pipeline]
Pipeline runs on GitHub Actions, triggered by merge to main.
Takes about 8 minutes.

丟進 ~/.openclaw/workspace/memory/,然後:

pnpm openclaw memory index --force
pnpm openclaw memory prompt-preview --expand-graph "deploy pipeline"

看 retrieval 效果。不好再補欄位。

2-5 個 chunks 就夠開始了。 不要等到寫完一整份完美文件才丟進去。


真正的用途:Agent 規範與行為矯正

既然不是用來記對話流水帳,那 .ctxfst.md 到底什麼時候寫?

它的真正用途是**「宣告式地定義 Agent 的世界」。你應該把它看成一種設定檔或行為腳本**,而不是被動的對話紀錄。

最常見的兩個使用情境:

1. 打造 Agent 時:定義工作流程與規範

當你在建立一個特定的 Agent(例如 Code Reviewer、佈署助手、寫作編輯),你不會希望它每次遇到問題都靠大腦(模型權重)通靈。

你可以用 .ctxfst.md 來規範它的行為界線與流程:

寫好這份 ctxfst,Agent 在啟動時一旦讀取,就能正確理解這個世界的「遊戲規則」,按照你設定的拓樸結構來推進任務。

2. 行為矯正:手動修改 Memory 來 Debug

這是最常發生的日常情境:你在跟 OpenClaw 協作時,發現它「一直反覆犯同一個錯」或「記不住某個你早就講過的專案偏好」。

這時候,與其在對話裡繼續跟它鬼打牆(「我不是說過不要這樣做嗎!」),不如煞車,去改 memory

做法很直覺:

  1. 打開對應的 .ctxfst.md
  2. 針對出錯的地方對症下藥:加一條 REQUIRES 確保一定要先跑測試,或補一段 Chunk 講明這個 edge case 的解法
  3. 存檔,讓 engine 重新 index
  4. 回到對話,讓它重新回答。它這時候檢索到的世界模型已經被你「熱更新」了,行為馬上就會改變。

這就像在 debug 軟體一樣:發現 Bug,去改程式碼(ctxfst),然後重新編譯,就可以立刻看到更正後的行為。


什麼該進 ctxfst,什麼不該進

既然這是用來規範行為的,那內容就必須精準。

Workflow & Guardrails(該進)

這些是「控制模型行為」的護欄,寫進去後可以確保它未來的表現穩定,像一個上路的自動駕駛有地圖可循。

一次性的對話或暫時想法(不該進)

把這些放進去,你的 graph 會長滿雜草,每次檢索都會被干擾。

一句話原則:

把你希望 Agent 嚴格遵守的「規則、流程與事實」宣告在 ctxfst 裡;把探索、試錯跟發散留在對話中。


聊天時 Memory 怎麼用

到這裡可能會問:那我每次聊天都要先跑 CLI 嗎?

不用。有兩條路徑。

路徑一:日常對話

OpenClaw 在聊天時可以直接用 memory。

extensions/memory-core/index.ts 裡把 memory_searchmemory_get 註冊成了聊天時可用的工具。extensions/memory-core/src/prompt-section.ts 裡明確寫了:在回答「prior work / decisions / preferences / todos」相關問題前,要先跑 memory_search,再用 memory_get 讀需要的內容。

所以模型會自己在對話中調用這些工具查你的 .ctxfst.md。你不需要手動觸發。

路徑二:CLI Debug

prompt-preview 是你手動用的 debug 入口。它讓你檢查:

路徑一(聊天):
  使用者提問 → 模型判斷需要 memory
    → memory_search → memory_get → 回答

路徑二(CLI debug):
  開發者手動跑 prompt-preview
    → 看 retrieval 結果 → 看 graph expansion → 看最終 prompt

差別在於:

日常對話路徑 CLI debug 路徑
誰在操作 模型自己 你(開發者)
觸發方式 對話中自動判斷 手動跑命令
用途 實際使用 memory 回答問題 驗證 ctxfst 那層到底抓到了什麼
走不走 Phase 5-7 不一定完整走 planner CLI 的輸出格式 完整展示每一層的結果

一句話:

OpenClaw 可以在對話中直接用 memory 裡的東西;prompt-preview 只是讓你人工驗證 ctxfst 那層到底抓到了什麼。


聊天路徑 ≠ Planner CLI 路徑

這裡要多講一點,避免混淆。

聊天時模型用 memory_search / memory_get,這是走 memory 的工具介面。但這不等於每一輪聊天都完整走你在 Phase 5/6/7 看到的 planner CLI 輸出格式。

也就是說:

聊天路徑:模型 + memory_search 工具 → 直接用 memory 回答
CLI 路徑:prompt-preview / planner / state 命令 → 展示完整的 ctxfst 世界模型能力

CLI 那條路徑是把 ctxfst 的世界模型能力更直接、更完整地展示給你看。

聊天路徑則是模型根據需要去查 memory,不一定每次都用到 graph expansion 或 planner routing。

兩條路徑操作的是同一份 .ctxfst.md 資料,只是進入點和完整程度不同。


收尾

一句話版本:

.ctxfst.md 不是對話自動產生的逐字稿,而是你用來「定義 Agent 流程」與「手動除錯修正行為」的結構化設定檔。

完整版本:

問題 答案
ctxfst 是自動產生的嗎? 不是,目前是手動建立
為什麼不自動? 對話裡太多雜訊,自動轉換會污染 world model
什麼時候該修改它? 打造 Agent 規範工作流時,或是模型犯錯需要矯正行為時
要從零開始寫嗎? 不用,先寫最小版本,2-5 個 chunks 加上關鍵 state 就夠開始
聊天時要手動跑 CLI 嗎? 不用,模型會自己調用 memory_search / memory_get
prompt-preview 是做什麼的? 讓你手動驗證 ctxfst retrieval 到底抓到了什麼、prompt 怎麼被組裝

.ctxfst.md 當作寫給 Agent 看的「程式碼與架構圖」來維護。與其一直跟模型吵架,不如去修改它眼中的世界模型。這是目前落地狀態下,控制 AI 行為最有效也最精準的做法。