安裝成功不等於升級完成。讓 Agent 回到可驗證的狀態
上週在京都辦公室準備下班時,我看到一張記錄 OpenClaw beta 更新卡住的卡片。npm staging 顯示 exit 0,Gateway 卻還在查一個已停止的 PID。作者先查 port、process 和 backup,沒有急著刪 lock。這個順序我很熟:做遊戲 AI 時,最危險的不是服務明顯掛掉,而是工具說它好了,實際行為還停在上一個狀態。
我在日本這邊做 NPC 行為系統,團隊常用「復帰確認」,意思是確認系統能不能回到玩家真正會遇到的工作狀態。升級也該用這個標準。安裝成功只代表檔案可能放對位置,不代表 Agent 讀到新版本、能接收工作,或失敗後可以恢復。Gateway 回 health check 不夠,NPC process 還活著也不夠;真正要驗收的是可重放、可觀察、可復原的任務。
我會把驗收拆成三層
第一層是程序與連線:記錄部署前後版本、舊 PID、新 PID,從 process command line 或啟動 log 讀 build hash,不要只看 installer 的 exit code。再確認 port owner 已換成新 PID,最後打 health endpoint。假設舊 Gateway 是 PID 18420,新 Gateway 是 19107,port 8787 的 owner 也必須是 19107;即使回傳 200,response 的 version 仍要等於預期 hash。
舊 process 死掉、socket 等待回收,或 supervisor 仍持有舊 PID,都是常見落差。刪 lock 也許讓啟動更快,卻不會修好 supervisor、port、state file 的關係。我會先保存 process tree、port owner、最近 100 行 log 和 backup 時間戳,再決定清理,這些同時也是回滾材料。
第二層是能力與行為。在 NPC 系統裡,我不會用「進到主選單」當通過,而會準備固定 seed 的 replay:巡邏 NPC 發現玩家、呼叫 squad member、路徑被阻擋、對話逾時、任務取消後重新接取。每個 case 要有輸入、預期狀態轉移和最大完成時間,升級前後跑同一組。
我會記三個結果:100 個 replay 至少完成 98 個;dialogue model timeout 後,NPC 是否回到預設台詞或 idle state;玩家觸發事件到下一個 action 的 P95 是否低於 800 ms。門檻可以不同,但必須在升級前寫好。後端 Agent 也一樣,準備三到五個正常、重複、工具錯誤和中途重啟的任務,保存 request id、policy version、tool call sequence 與最後狀態。重放不必逐字相同,但建立工單只能一次,工具失敗要留下 retry 或 failed,不能表面 success。
第三層是故障與恢復。新版本通過前兩層後,模擬一次 kill process,觀察 supervisor 是否重啟、port 是否恢復、未完成任務會不會重複。若有 migration,測試執行中斷;我的 NPC 場景會在 action queue 寫入後讓 worker 消失,確認重啟後是 resume、safe retry 或明確 failed,不讓兩個 NPC 消費同一事件。
恢復也要寫成數字:process 終止後 30 秒內 port 恢復,60 秒內 health check 和一筆 synthetic task 都成功,才算 recovery pass。只看到 PID 又出現不算,worker thread 可能早已卡住;還要看 state age、queue depth、最後成功任務時間。
Agent 和 NPC 的共同陷阱
遊戲團隊容易把升級想成替換 binary,後端則想成更新 container image。但行為系統還包含 prompt、policy、tool schema、memory format、feature flag 和 replay data,只換一項就可能半升級。
我的驗收單至少有六欄:1. Artifact,image digest 或 build hash;2. Ownership,PID、port、supervisor;3. Health,分開 process、dependency、synthetic task;4. Replay,固定 seed、狀態轉移、fallback、P95;5. Recovery,記錄 kill 到 port 恢復及第一筆成功工作的秒數;6. Rollback,指定 backup、觸發條件和重跑 case。
每欄都
要能讓另一個人重做。寫「看起來正常」無法交接;寫「PID 19107 持有 8787,build hash abc123,synthetic task 在 420 ms 完成」就可以。日本遊戲公司的稟議文化有時讓流程變慢,但慢在事前確認,通常比上線後讓 NPC 集體卡在門口便宜。
我也不把 lock file 當敵人。刪除前先問:誰持有它?刪掉後哪個狀態會變?出問題時能不能還原?答不出來,就先複製、檢查、保留 backup。京都下班前沒有人想靠猜測修一個仍可能自動恢復的服務。
所以我對「升級完成」的定義很簡單:新版本已確認接管,代表性任務能完成,故障後能在明確秒數內恢復,而且每個結果都留下可重放證據。npm staging 的 exit 0 只是起點;真正的完成,是 Agent 或 NPC 回到我們敢讓玩家和其他服務使用的狀態。
作者:嵐山貓