Ian Chou's Blog

CtxFST CH20 - Interactive Plan Critique:讓 Planner 進入真正的人機協作

CtxFST CH20:Interactive Plan Critique,讓 Planner 進入真正的人機協作

如果說:

那下一步就很自然了:

既然 planner 已經能解釋,那人類能不能直接根據這份解釋介入規劃?

這個問題一旦成立,系統的性質就會再變一次。

因為 explanation 不再只是 log,也不再只是 debug 輸出,而會開始變成:

人類與 planner 互動的介面。

這就是 CH20 要做的事情:

CtxFST 的 planner 不只會找 plan、解釋 plan,還能接受人類對 plan 的即時回饋。

也就是 interactive plan critique。


先講一句最短的定義

這次升級可以濃縮成一句話:

CH19 的 explanation 是單向可讀;CH20 的 critique 則是雙向可改。

這個差別非常大。

CH19 裡,人類能做的是:

但系統仍然是:

先算好,然後你只能旁觀。

到了 CH20,這件事變成:

先算好,解釋給你聽,然後你可以說「不要這條」、「先跳過這個 skill」、「我想強制走另一條」。

這時候 planner 就真正進入 human-in-the-loop 階段了。


這一步為什麼重要?

因為很多 agent 系統做到 explanation 就停了,覺得已經很透明。

但其實對真實 workflow 來說,光透明還不夠。

人類更常需要的是:

也就是說,真正的人機協作不是:

AI 解釋給人聽

而是:

AI 解釋給人聽,然後人可以修正 AI 的規劃。

這才是 critique 的核心價值。


這次做的不是 execution confirmation,而是 planning-level critique

這一點很重要,必須先講清楚。

這次新增的不是「執行前按一下 yes/no」那種簡單確認框。

它做的是更高一層的事情:

在 execution 之前,先讓人類對 plan 本身提出批評、限制、偏好與重規劃要求。

所以它不是:

而是:

這就是為什麼我會把它叫做 planning-level critique,而不是 execution confirmation。


critique_plan() 到底補了什麼?

核心很簡單:

critique_plan(explanation, state, skills, max_depth) 讓 planner 的 explanation 變成可互動的 replanning loop。

它發生的位置也很準確:

也就是說,流程變成:

find_plan_with_explanation()
-> 顯示 best plan + step traces + alternatives
-> critique_plan()
-> 接受人類指令
-> 若有需要則重新規劃
-> 最後才執行第一步

這個插入點非常合理,因為它剛好卡在:

這是最適合人類介入的時機。


這次提供的 5 個指令,非常實用

這套 critique 介面目前有 5 個指令,我覺得切得很好。

指令 意義 適用情境
a Accept 我接受這條 plan,照目前第一步執行
s <skill> Skip 先不要某個 skill,請排除後重規劃
f <skill> Force 我想強制某個 skill 當第一步
r Reset 清掉目前 constraints,從頭重規劃
q Quit 中止整個 loop

這五個指令的好處是,它們剛好對應人類在規劃階段最常見的五種回饋:

也就是說,這不是任意湊出來的 CLI 指令,而是很貼近實際協作的設計。


一個很典型的使用場景

這次 feature 最好懂的地方,就是它的互動流程非常直覺。

例如 planner 先提出:

Best plan (3 steps): analyze-resume → match-skills → generate-plan

然後人類看完說:

s match-skills

系統就會回:

Replanning without match-skills...

接著如果有 alternative:

Best plan (3 steps): analyze-resume → alt-match → generate-plan

最後人類再輸入:

a

系統才真的開始執行。

這個流程很重要,因為它代表 planner 不再只是給你一條路,而是:

先提出路徑,再允許你對這條路徑做偏好修正。

這已經很像真正的協作式規劃了。


為什麼 skip 很重要?

我覺得這五個指令裡,skip 特別有代表性。

因為它其實在表達一種很真實的人類需求:

我不是不知道你這條路合理,但我現在就是不想走這個 skill。

可能的原因很多:

skip 的價值就在於:

人類不用自己重新規劃整條路,只要指出「這個不行」,planner 就應該幫你重算。

這正是人機協作最理想的分工方式。


force 更進一步:不是只排除,而是注入偏好

如果說 skip 是負向約束,那 force 就是正向約束。

它表示:

我知道你有自己的排序,但我想指定下一步先走這個 skill。

當然,這個強制不是無條件亂來。

它仍然會先檢查:

如果不滿足,就不能硬塞進 plan。

這個設計很重要,因為它保留了兩件事的平衡:

也就是說,系統不是「人說什麼都照做」,而是:

人在合法行動空間內,可以對規劃加偏好。

這是比較健康的 human-in-the-loop 設計。


reset 的價值:讓 critique 不會把 planner 越帶越歪

當使用者做了一連串:

之後,規劃空間會逐漸被各種 constraint 壓縮。

這時如果沒有 reset,整個互動很容易變得僵硬,甚至讓使用者忘了自己到底加了哪些限制。

所以 reset 的存在很重要。

它代表:

人類不只可以改 plan,還可以撤回自己對 plan 的干預。

這讓 critique 介面不只是「越修越多限制」,而是有真正的可逆性。

這種設計對長一點的互動非常重要。


q / EOF / Ctrl-C 也被正式納入語意,這很好

這次我很喜歡的一點是,quit 不是被當成例外錯誤處理,而是被當成:

合法的 loop termination reason

也就是:

terminated_reason = "user_aborted"

這很合理,因為在真實人機協作裡,「人決定先停下來」本來就是一種正常結果,不應該被當成 crash。

這樣的設計會讓之後的 logs、測試、甚至 UI 都更一致。


這次和 CH19 的 explanation 是怎麼接起來的?

CH19 的 explanation 是這次 critique 能成立的前提。

因為如果 planner 只能吐出:

Best plan: s1 -> s2 -> s3

那人類很難真正做出有根據的 critique。

但現在有了:

人類終於可以有根據地說:

所以這次並不是在 CH19 上多加一個 CLI,而是:

把 explanation 從被動資訊,升級成主動互動界面。

這就是兩章之間最重要的承接。


agent_loop.py --critique 的意義:讓互動式規劃變成正式 runtime 模式

如果這次只是 library 裡多一個 critique_plan(),價值還有限。

真正讓它變成系統能力的,是:

而且這裡還有一個很好的 UX 決策:

如果使用者指定 --critique 但沒指定 --lookahead,系統會自動開啟 lookahead=5

這很合理,因為 critique 本來就是針對 plan,而不是針對單一步驟的。

沒有 lookahead,critique 的價值會大幅下降。

這種「合理預設」很值得保留。


這次的 14 個新測試,讓 critique 不是 demo,而是 contract

這次最重要的工程點之一,是 interactive critique 也不是裸上。

你用 unittest.mock.patch('builtins.input') 把整套 CLI 互動測起來,這非常關鍵。

新增後總測試數來到:

66 tests, all green

而這 14 個新測試,保護的不是小細節,而是整個互動 contract:

這意味著:

人機互動這層現在也正式成為 runtime contract 的一部分。

這很重要,因為很多系統的 interactive mode 都只是 demo 層,沒有測試保護,一改就壞。

現在這層有測試了,後面比較敢持續演化。


這一步代表 CtxFST 的 planner 又變成什麼了?

如果用前幾章來對照:

這一步很關鍵,因為它把 planner 從:

推進成:

這已經不是單純的 agent runtime 了,而是更接近:

一個人類可以和它共同編輯決策方向的 planning substrate。


這還不是最終型,但已經很接近真正的協作介面

現在這版 critique 還是 CLI 形式,但已經很有味道了。

未來很自然可以延伸成:

1. UI 化的人機規劃面板

把:

變成真正可點擊的介面。

2. 偏好持久化

目前 critique 是單次互動。

未來可以把使用者偏好存成:

讓 planner 之後自動學會這些偏好。

3. LLM-assisted critique

現在完全不需要 LLM,這很好。

但未來可以再往上加一層:

這樣互動門檻會更低。


結語:從這一章開始,Planner 不只可解釋,還可被協作地修正

如果 CH19 的核心是:

planner 開始能把理由講清楚

CH20 的核心就是:

planner 現在開始允許人類根據這些理由,直接改變規劃。

這是非常重要的升級。

因為從這裡開始,CtxFST 的 planner 不再只是:

它還開始具備另一個真正面向實務的能力:

在不破壞 world model 合法性的前提下,接受人類對規劃的即時偏好修正。

這就讓系統從「可觀察的 planner」正式跨進「可協作的 planner」。

而這,正是 human-in-the-loop 真正開始成立的地方。


參考實作


📌 CH19 讓 planner 會解釋,CH20 則讓人類可以利用這份解釋直接修正 plan,真正把 explanation 變成協作介面。