代理派發生命週期
甚麼是派發
標題為「甚麼是派發」的章節一次派發,就是單一代理、在單一對話中、於單一配接器上的一次執行。它的一切都在 cc_server 上發生:用戶端送出訊息,然後觀看事件串流回來。任何用戶端都不存在派發路徑。
代理被喚醒的原因有六種,執行會把它們當作喚醒上下文一併帶上,讓代理知道自己為何處於喚醒狀態:
| 喚醒原因 | 觸發條件 |
|---|---|
userMessage |
有人在空間中送出訊息,或提及了該代理 |
assignment |
有工單被指派給該代理 |
pipelineStep |
某個管線步驟派發了它 |
childCompleted |
子工單完成 |
followUp |
排程的跟進心跳 |
recovery |
失敗後由復原路徑重新派發 |
喚醒上下文會帶上與該原因相關的 id——工單、空間、訊息、管線執行——它們會被注入代理的環境與提示詞。
提示詞組裝
標題為「提示詞組裝」的章節提示詞分層建構,每一層都是一個有標籤的區塊:
- 身分——代理自己的 id、名稱與工作區 id,並附有明確指示,要求把這些確切的 UUID 傳給工作區範圍的工具。工作區是代理的內在屬性,因此永遠存在。
- 工具目錄與資源協定,然後是工作區佈局。
- 系統提示覆寫(若代理有設定),然後是角色設定(以角色為參數)與團隊簡報。
- 技能——代理身上的名稱。
- 目前模式的執行契約與程序。
- 喚醒上下文與提及上下文:誰召喚了代理,以及它周圍的名冊。
- 模式區塊——由模式的能力設定檔及其具體化工具清單產生,因此提示詞絕不會寫出一次執行實際上沒有的工具。
- 記憶上下文——為該任務檢索出來的事實。
- 對話上下文——最近的空間歷史,上限為 50,000 個原文字元的窗口,不論代理設定的上下文大小為何。較舊的歷史不會被截掉:代理可用
get_messages按需取回,而語意上相關的較舊訊息仍會浮現。
指令分成兩處處理。/todo 與 /compact 在撰寫器中攔截,並刻意永不存成訊息,也不送給代理——儲存 /compact 會把壓縮切點往回推一個回合,並污染對話紀錄。/plan 則兩邊都處理:撰寫器會切換空間的模式,這正是讓工具集、護欄預設與提示詞在本回合及之後每一個回合都一致的關鍵。/goal、/loop 與 /skill:<name> 只在內建運行器上、於執行內部處理——/goal 與 /loop 以成本預算展開自主工作,而帶 skill: 前綴的名稱會當作技能查詢,其 SKILL.md 內容會成為該回合的指示。命名空間正是把這兩套詞彙分開的東西:以往直接用裸名去對技能解析時,叫 plan 或 compact 的技能會被內建指令永久遮蔽。對於命名空間出現之前所寫的訊息,裸的非內建名稱仍可解析。無法辨識的名稱就只是當作純文字放行。
佈建 worktree
標題為「佈建 worktree」的章節在任何東西開始執行之前,對話會取得自己的工作根目錄,底下每個程式庫都有一份隔離的寫入時複製 worktree。預設是連結到工作區的每一個程式庫;PR 空間——或以明確選取範圍建立的空間——只佈建允許清單上的那些程式庫,而 PR 審查對話會把它那一個程式庫固定在 pull request 的 head ref,其餘則留在各自的預設分支。來源簽出永不變更,而整個對話目錄會隨空間刪除一併回收。
凡是有隨附 rift 的地方,寫入時複製就是唯一的實作,由隨附的原生模組支撐。無法 reflink 的檔案系統——或資料目錄與程式庫位在不同磁碟區——會讓佈建失敗,而不是退回其他做法。git worktree 是 Windows 上的後端,因為那裏沒有可建構的寫入時複製後端,而它在其他主機上也不是無聲的降級。在隨附 rift 的平台上缺少它就是安裝損毀——伺服器會拒絕啟動,而不是悄悄退回,因為無聲的回退會把這個損壞永遠藏在較慢的路徑背後。
身分與憑證
標題為「身分與憑證」的章節每次執行都會在啟動任何行程之前解析兩個身分。
Git 作者身分。 代理所作的提交,作者身分都是以代理之名——<Name> (agent) <agentId@agents.control-center.local>,同時用於 GIT_AUTHOR_* 與 GIT_COMMITTER_*——永不冒充人類。本機部分是代理的 UUID,而不是它的名稱 slug。提出請求的人類則以 Co-Authored-By: 尾註記名,該尾註放在環境中,並在系統提示中指示。呼叫者明確設定的身分一律勝過兩者。
程式碼託管身分。 執行的 GitHub 憑證永遠只是仲介的憑證——範圍限於單一程式庫的 App 安裝權杖,或其環境 PAT 後備——絕不是提出請求成員自己儲存的權杖。actingUserId 會限制 PAT 後備,讓不是伺服器擁有者的成員不會繼承伺服器的觸達範圍;它不會把個人權杖覆蓋到代理環境上。
模型供應商憑證按固定順序解析,而這個順序很重要:
- 每個配接器的環境覆寫,
- 呼叫者的環境,
- 伺服器的憑證儲存庫(若 OAuth 權杖接近到期便予以更新),
- 行程環境。
由於每個配接器的覆寫排在最先,它會無聲地壓過在應用程式中連接的供應商帳戶。如果某次執行記帳到錯誤的帳戶,那個覆寫就是第一個該看的地方。供應商憑證是主機全域的——在整個安裝上的每一個工作區之間共用。
這次執行的 GitHub 權杖來自憑證仲介:一個限定於 worktree 程式庫的唯讀權杖。推送會經過代理執行閘道,閘道在轉送前會詢問推送到遠端規則,而且不會注入任何工單金鑰。參見沙箱與保安。
執行會以它的 worktree 作為工作目錄來啟動,而對 Claude Code 來說,還會附上一份產生的 MCP 設定,讓代理能觸達 Control Center 的工具集。ACP 與運行器的 bash 會取得已淨化的環境;經 NoSandboxAdapter 的 Claude Code 則繼承主機環境。
執行會串流回一串有型別的事件序列,串流處理器會把它存成訊息增量、摺疊成對話紀錄分段,並轉成訊息事件:
| 事件 | 攜帶的內容 |
|---|---|
thinking |
推理輸出,行內呈現 |
text |
可見輸出 |
toolCall |
一次工具呼叫,附上它的 id 與結構化引數 |
toolResult |
對應的結果,出錯或是部分串流時會標示 |
usage |
某個計量期間的 token 數量與成本 |
error |
一個錯誤,配接器有回報結構化代碼時會一併附上 |
sandboxViolation |
作業系統拒絕了一次系統呼叫。只在沙箱確實包住行程的地方發出——見上面的備註 |
debug |
執行時診斷(啟動標記、護欄決定、契約提示) |
done |
執行已完成 |
甚麼為一次執行設下界限
標題為「甚麼為一次執行設下界限」的章節各處都刻意沒有回合上限。硬性迭代次數會殺死正當的長時間工作(遷移、扇出清理),卻攔不住下面這些防護更早攔下的任何東西。執行會在下列情況結束:
- 模型自行停下;
- 有人把它停下,或接手該對話(這會在內建運行器下一個乾淨的回合邊界把它暫停——沒有安全邊界的 Claude Code 執行,則改為直接停止);
- 靜默看門狗觸發。 超過門檻沒有輸出,工作階段就會以
silentRun失敗終止。預設是 15 分鐘,在以讀取為主的模式(審查與計劃)降至 10 分鐘;代理可以在 1 至 240 分鐘之間覆寫。看門狗會在子行程回報自己的 PID 時武裝,因此涵蓋 Claude Code CLI——不涵蓋不啟動任何行程的內建運行器; - 成本上限咬住——但只限自主指令。
死循環防護不是終結器:連續三次相同的工具呼叫,迴圈就會引導代理改變做法。
合起來看,內建運行器上一次普通的互動回合,沒有回合上限、沒有成本上限,也沒有靜默看門狗。它會在模型停下或你把它停下時結束。這是刻意的取捨——其他做法都會殺死正當的長時間工作——但這也確實意味着,一次無人看管的互動執行,除了模型自己的判斷之外,沒有任何東西為它設限。
執行途中,送給正在執行代理的訊息會排隊成為引導,並在下一個回合邊界排空,因此你可以在不殺掉一次執行的情況下輕推它。引導、暫停、子代理與完成契約都是內建運行器的功能;Claude Code 一項都沒有。
一次執行如何被記錄
標題為「一次執行如何被記錄」的章節每一次派發都會寫入一份 AgentRunLog:開始與結束時間、摘要、token 數量與預估成本(包括從子代理彙總上來的成本)、配接器與模型、行程 id 與記錄路徑、所屬的對話以及任何工單或管線執行,另外還有兩個承載大部分真相的分類欄位。
- 狀態是粗略的:
pending、running、completed、error。 - 存活狀態是更細緻的讀法:
alive、productive、completed、blocked、empty、looping、failed、stalled、dead。 - 錯誤類別把失敗有效地歸類:
transientUpstream、sandboxInfrastructure、budgetExceeded、processLost、silentRun、unknown。
關閉執行會發佈 AgentRunCompleted,而有很多東西掛在它上面:管線成本彙總、恢復某個正在等待該次執行的管線步驟、完成背後那張工單、把一次編排對應到終止狀態、目標監督器的繼續或停止決定、檢查者角色,以及執行後的預算評估。線上狀態名冊則另行跟隨,靠觀察最近的執行記錄,而不是該事件。「代理已完成」通知不在這張清單上:該事件在程序串流結束時觸發,那時回覆尚未寫入,因此這則通知其實是該回合的 MessageReceived,在訊息持久化之後才發佈。
事後結算的預算
標題為「事後結算的預算」的章節預算執行是一種反應,不是一道閘門。當一次執行完成,評估器會把代理本月至今日的支出與它的有效上限比較(若有連結的預算政策就用它,否則用代理自己的每月數字;零代表無上限)。越過軟性門檻會記錄一宗警告事故;用盡預算會記錄一宗硬性事故,並在組織架構圖上把代理的生命週期狀態切換為 paused。派發仍然接受來自該代理的工作。BudgetThresholdCrossed 管線觸發器可以由同一個事件啟動跟進工作。
重試譜系
標題為「重試譜系」的章節每一份執行記錄都可以帶重試譜系——一個父執行 id、一個嘗試次數計數器,以及一份續接摘要。對話執行樹會在嘗試次數不為零時顯示該數字。從聊天按「再試一次」就是一次新的派發,並有一份全新的執行記錄。