Ian Chou's Blog

CtxFST CH26 - World State 是導航系統:為什麼 Graph 只是地圖,Agent 還需要知道「你在這裡」

CtxFST CH26:World State 是導航系統,Graph 只是地圖

CH25 講了 graph layer 可以換,CtxFST 或 LightRAG 都行,重點在 Phase 6-7。

但「重點在 Phase 6-7」這句話太抽象了。Phase 6 的 world state 到底做了什麼?為什麼不能光靠 graph?

這篇用一個比喻把它講透:Graph 是地圖,World State 是導航系統。


現在的 Graph Query:每次問,每次同一個答案

假設你的 .ctxfst.md 裡有這些 entity 和 relation:

Analyze Resume --REQUIRES--> Upload Resume
Analyze Resume --LEADS_TO--> Generate Report

現在問系統:

"What is required before Analyze Resume?"

Graph 查到的結果:

## Missing Preconditions
- state:resume-uploaded

## Relevant Entities
- Analyze Resume (skill)

## Related Entities (Graph)
- Upload Resume (REQUIRES, score: 0.95)
- Generate Report (LEADS_TO, score: 0.92)

看起來很聰明。

但問題是:不管你已經上傳了 resume 還是沒有,不管你已經 analyze 過了還是沒有,這個答案永遠一模一樣。

它只是在讀一張靜態的圖。

你上傳完 resume 再問一次「What is required before Analyze Resume?」,它還是告訴你 state:resume-uploaded 是 missing precondition。因為它根本不知道你做過什麼。


Phase 6-7 之後:答案會隨狀態變化

加上 world state 之後,系統維護一份 session-scoped 的狀態:

Session state: {
  active_states: ["state:resume-uploaded", "state:resume-parsed"],
  completed_skills: ["entity:upload-resume", "entity:analyze-resume"],
  blocked_by: []
}

現在問:

"What should I do next?"

Planner 看到的不只是 graph,還有 state:

  1. Upload Resume → completed_skills 裡有,跳過
  2. Analyze Resume → completed_skills 裡有,跳過
  3. Generate Report → preconditions 是 [state:resume-parsed],檢查 active_states…… 有!條件滿足

輸出:

## Next Action
- Generate Report(resume 已解析完成,這是下一個可執行的步驟)

同一張圖,但因為 state 不同,答案不同。

如果你還沒上傳 resume,planner 會告訴你先去上傳。如果你全部都做完了,它會告訴你沒有下一步。


地圖 vs 導航

這就是整個差異的本質:

Graph Query State-Aware Planner
回答的問題 「什麼和什麼有關?」 「現在該做什麼?」
輸入 query + 靜態 graph query + graph + session state
同 query 會變嗎 不會,永遠同結果 會,隨 state 變化
類比 地圖 導航

地圖告訴你所有路都存在。導航告訴你「你在這裡,你要去那裡,下一個路口右轉」。

沒有 session state,系統不知道「你在這裡」。

這就是為什麼 Phase 6 是 world state(知道你在哪),Phase 7 是 planner(規劃怎麼走)。Graph 本身只是地圖,不會因為你走過一段路就自動告訴你下一步。


OpenClaw 現在很強,但強在哪?

OpenClaw 目前熱門,不是因為它有完整的 state-aware planner。它強在三件事:

1. 工具執行能力

它很會調用工具、shell、編輯檔案、跑 repo workflow、串 gateway/plugin。這是「能做事」。

2. 上下文整合能力

它能把 chat、memory、plugins、hooks、channels 接在一起。這是「知道有哪些東西可用」。

3. Agent Runtime

它有 session、channel、gateway、auth、tool routing、multi-agent/runner 這些基礎設施。這是「能穩定跑」。

但這三件事回答的都是同一個問題:

你叫我做,我能不能做得漂亮?

Phase 6-7 回答的是另一個問題:

在這個流程裡,現在最合理的下一步是什麼?


臨場判斷 vs 系統決策

OpenClaw 現在的「聰明」,來自幾個來源:

所以它常常能做出不錯的下一步判斷,看起來很聰明、很會執行。但那是:

LLM 在當下根據上下文臨場判斷。

不是:

系統裡有一份明確的 world state,planner 依據 state machine 決定下一步。

差在哪裡?差在可靠性。

LLM 臨場判斷可能:

系統層的 world state 不會有這些問題。因為狀態是 explicitly tracked 的,不是 LLM 自己「記得」的。


三層架構:從肌肉到大腦

把整件事攤開來,就是三層:

┌─────────────────────────────────────────┐
│  Layer 3: State / Planner Layer         │  ← Phase 6-7
│  world state, precondition check,       │
│  goal-aware routing, skill chain search │
│  回答:「現在該做什麼?」                │
├─────────────────────────────────────────┤
│  Layer 2: Memory / Graph Layer          │  ← Phase 1-5
│  entity graph, retrieval, expansion,    │
│  prompt assembly                        │
│  回答:「什麼和什麼有關?」              │
├─────────────────────────────────────────┤
│  Layer 1: Execution Layer               │  ← OpenClaw 現在的強項
│  tool routing, gateway, shell,          │
│  plugin, multi-agent runner             │
│  回答:「你叫我做,我做得到。」          │
└─────────────────────────────────────────┘

OpenClaw 的 Layer 1 已經是業界頂級。Layer 2 透過 CtxFST 或 LightRAG 可以補上。

Layer 3 是目前整個生態系都還沒有的。


「不是已經有現成的 state 嗎?」

你可能會說:LangGraph 有 StateGraph,Cognee 有 graph memory,甚至 OpenClaw 社群有人用 PROJECT-STATE.yaml。為什麼還要自己做?

因為它們做的不是同一件事。

LangGraph StateGraph

LangGraph 的 state 是 Python 進程內的記憶體。它跑在 LangGraph 的 runtime 裡,不是 OpenClaw 的 runtime。Session 結束就消失。不會寫回 OpenClaw 的 memory,不會影響 OpenClaw 的 routing。

它是一個孤島。

Cognee Graph Memory

Cognee 做的是 graph construction — 從文件自動抽取 entity 和 relation,建成 knowledge graph。這是 Phase 1-4 的事。它不追蹤 completed_skills,不做 checkPreconditions(),不知道 session 走到哪了。

它是一個圖書館,不是導航。

PROJECT-STATE.yaml

這是一個 prompt convention:讓 LLM 自己讀寫一個 YAML 檔案來追蹤專案狀態。

沒有 schema enforcement。沒有 precondition checking。沒有 planner。本質上就是 LLM 在自己維護一個筆記。

而 LLM 維護筆記的問題是:它會忘記更新、會寫錯格式、會幻覺出不存在的狀態。

對比表

工具 做的事 不做的事
LangGraph StateGraph Python 進程內的 workflow state 不寫回 OpenClaw,session 結束就沒了
Cognee Graph 自動建 knowledge graph 不追蹤 runtime state,不做 precondition check
PROJECT-STATE.yaml LLM 自己讀寫純文字 沒有 schema、validation、或系統保證
Phase 6 World State OpenClaw-native、SQLite persistent、session-scoped、schema-enforced

LLM 自己管 state 為什麼不夠

用 PROJECT-STATE.yaml 或讓 LLM 在 prompt 裡自己追蹤狀態,最大的問題就一個:

LLM 會幻覺。

// LLM 自己管 state:
// "我記得好像 resume 已經上傳了?那我來 analyze..."
// (其實沒上傳,幻覺了)

// Phase 6 world state:
const check = checkPreconditions(db, sessionId, "entity:analyze-resume");
// { ok: false, missing: ["state:resume-uploaded"] }
// 系統直接擋住,不讓 LLM 跳步

Phase 6 做的是把 state 從「LLM 腦中的模糊記憶」變成「系統層的硬約束」。

LLM 可以提議下一步,但系統會 validate。就像導航可以建議路線,但如果前面的路還沒修好,它不會叫你開過去。


穩定性來自哪裡

為什麼要這麼在意「系統層保證」?因為 agent 最脆弱的地方,不是單步執行,而是多步串接。

單步執行,LLM 很強。你叫它寫一個函數、改一個 bug、跑一個 command,它幾乎每次都能做到。

但如果任務是「先分析 resume,再產生報告,再發送通知,再更新資料庫」——四個步驟要按順序做,每一步的 output 是下一步的 input。

這時候靠 LLM 臨場記住「我走到第幾步了」就很危險。尤其是:

這些情況下,LLM 的「記憶」是不可靠的。而 state machine 的狀態是 persistent 的、queryable 的、enforceable 的。

這就是為什麼 Phase 6 不是 nice-to-have,而是 long-horizon task 的必要基礎設施。


從 Reactive 到 Goal-driven

用更學術一點的語言來說,Phase 6-7 做的是把 OpenClaw 從:

Reactive Agent(被動回應:使用者說什麼,我做什麼)

升級成:

Goal-driven Agent(主動規劃:根據目標和當前狀態,決定下一步)

Reactive agent 的行為完全由 input 驅動。你不問它,它不動。你問它同一個問題,它給同一個答案。

Goal-driven agent 的行為由 state + goal 驅動。它知道終點在哪、知道走到哪了、知道下一步該做什麼。即使你不問它,它也可以主動提醒你「下一步應該做 X,因為 Y 已經完成了」。

Reactive:    Input → LLM → Output
Goal-driven: Input + State + Goal → Planner → Action → State Update

兩者不衝突。Goal-driven agent 的每一步執行,還是靠 reactive 的 execution engine(Layer 1)。但決定「執行什麼」的邏輯,從 LLM 的臨場判斷,變成了 planner 的系統決策。


為什麼這件事沒人做過

不是因為難。Phase 6 的核心實作其實不複雜:

CREATE TABLE world_states (
  session_id TEXT,
  state_key TEXT,
  value JSON,
  updated_at TIMESTAMP,
  PRIMARY KEY(session_id, state_key)
);

CREATE TABLE skill_preconditions (
  skill_id TEXT,
  required_states JSON
);
async function checkPreconditions(skillId: string, sessionId: string) {
  const reqs = await db.getPreconditions(skillId);
  const active = await db.getActiveStates(sessionId);
  const missing = reqs.filter(r => !active.includes(r));
  return { ok: missing.length === 0, missing };
}

async function applyPostconditions(skillId: string, sessionId: string) {
  const posts = await db.getPostconditions(skillId);
  for (const state of posts) {
    await db.setWorldState(sessionId, state, true);
  }
}

Code 不多。難的是:

  1. 沒有人從 world model 的角度思考 agent memory。 大家都在優化 retrieval quality(Phase 1-4),很少人想「retrieval 之後呢?」

  2. OpenClaw 的 memory 設計是 chunk-first 的。 要加 world state,得改 memory layer 的核心假設,不是加一個 plugin 就行。

  3. 需要 operational semantics。 普通的 knowledge graph 只有語意關係(related_topart_of)。Phase 6-7 需要的是操作性關係(REQUIRESLEADS_TOBLOCKED_BY),這種 relation type 不會從自動抽取中自然長出來。

  4. 需要 .ctxfst.md 的格式支撐。 Preconditions、postconditions、state_refs 這些欄位,是 CtxFST 特有的。沒有這種結構化的 source of truth,world state 就沒有 schema 可以依據。

所以這不是一個純技術問題,而是一個架構認知問題。大部分人把 graph 當成 retrieval 的增強,不是 planning 的基礎。


實作路線:五個檔案

如果要在 OpenClaw fork 裡實作 Phase 6,核心改動集中在五個地方:

1. world-state-store.ts(新增)

SQLite 裡的 world_statesskill_preconditions 表。提供 checkPreconditions()applyPostconditions()getActiveStates()

2. memory.ts(修改)

在現有的 memory layer 裡加入 world state 的讀寫接口。讓 retrieval 結果可以包含 state 資訊。

3. skill-executor.ts(修改)

在 skill 執行前呼叫 checkPreconditions()。執行成功後呼叫 applyPostconditions()。如果 precondition 不滿足,reroute 到 planner。

4. planner.ts(新增)

Phase 7 的核心。接收 ContextPack + WorldState,輸出 NextAction。考慮 completed skills、blocked states、goal distance。

5. config(修改)

加一個 --world-state-mode flag。預設關閉,開啟後才啟用 precondition checking 和 state tracking。讓不需要這個功能的使用者不受影響。


回到比喻

Google Maps 很強。它有全世界的道路資料、衛星圖、即時路況、商家資訊。

但如果你打開 Google Maps,它只顯示地圖,不顯示你的位置、不規劃路線、不告訴你下一個路口該怎麼轉——那它就只是一張很漂亮的地圖。

導航的核心不是地圖資料量。導航的核心是:

  1. 知道你在哪(GPS = world state)
  2. 知道你要去哪(目的地 = goal)
  3. 根據 1 和 2 規劃路線(routing = planner)
  4. 你每走一步,重新計算(state update = postcondition writeback)

Phase 1-5 建的是地圖。Phase 6 裝的是 GPS。Phase 7 寫的是導航演算法。

三者缺一不可。


收尾

一句話總結:

Graph 是地圖,World State 是 GPS,Planner 是導航。地圖告訴你所有路都存在,GPS 告訴你「你在這裡」,導航告訴你「下一個路口右轉」。沒有 GPS 的地圖,不管多精細,都無法告訴你下一步該做什麼。

OpenClaw 現在的執行引擎是業界最強的車。CtxFST 給它裝上了精確的地圖。Phase 6-7 要做的,是裝上 GPS 和導航系統。

有了車、有了地圖、有了導航,agent 才真正能自己開到目的地。