AX 提示 3 — 子代理回報限 300 字,依據寫進檔案

發布

  • AX 提示
  • Claude Code
  • 開發環境自動化
  • 子代理

子代理的最終回報會原封不動地堆進主要對話的上下文,所以在指示文末尾加上「最終回報 300 字以內,詳細依據寫進檔案、只給路徑」,是最便宜的節省方法。如果靠人每次手寫,很容易漏掉,所以讓 Claude Code 的 PreToolUse hook 接收 Agent 呼叫的 prompt,回傳附加了那句話的輸入(updatedInput)就行了。不過,光靠一句話並不會讓回報立刻變短,所以必須一邊量測實際的回報長度一邊處理。

這篇文章是連載的第三篇,連載內容是把一個人使用的開發環境改成以 AI 代理為中心(AX,AI 轉型)的過程中,每天整理一個我做出來的機制。上一篇是把修改過的檔案自動用 Orca 分頁打開的 hook。

為什麼子代理的結果會佔滿主要上下文?

需要讀很多檔案的調查或審查,我會交給子代理。子代理在自己專屬的上下文裡工作,所以它在裡面讀的檔案內容不會傳到主要對話。但是,完成工作後回傳的最終回報是唯一的例外。回報的文字會一個字不少地進入主要對話,之後每次主代理呼叫工具時,又會被重新讀一次。

有一天,我看到一個審查代理的一份回報,因為表格與依據清單,讓畫面捲動了好幾次,才發現這些累積起來,把工作交給子代理的意義就變小了。工作是在外面交辦的,結果卻是在裡面很長地接收。

為什麼只在指示文裡寫「300 字」還不夠?

一開始我想用規則來解決。我在指引中寫下一條規則:把工作交給子代理時,一律在指示文末尾放入「最終回報 300 字以內 — 詳細依據寫進檔案,只給路徑」。

規則放進去之後,我量測了回報長度(2026-10-19),300 字以內的回報在 37 筆中只有 1 筆,中位數是 650 字。找原因時發現,我使用的幾個代理定義檔,另外規定了「結果要附依據表格詳細回報」的輸出格式。當指示文末尾的一行與定義檔的輸出格式衝突時,代理多半是依照定義那一邊。

hook 怎麼修改指示文?

所以我改了兩件事。一是不要期待人去寫,而是由 hook 來附加;二是在句子裡寫明順序:「這個上限優先於代理定義的輸出格式」。

PreToolUse hook 在工具執行之前接收輸入,如果回傳 updatedInput,就會換成那個輸入來執行。把 Agent 呼叫時在 prompt 末尾附加句子的部分縮短,大概是這樣。

CAP = "(這個上限優先於代理定義的輸出格式 — 最終回報 300 字以內,詳細依據寫進檔案,只給路徑)"

def report_cap_input(tool_name, tool_input):
    if tool_name not in ("Agent", "Task") or tool_input.get("subagent_type") == "fork":
        return None                      # 不是委派,或是 fork,就不動它
    prompt = tool_input.get("prompt")
    if not isinstance(prompt, str) or CAP in prompt:
        return None                      # 已經附上就維持原樣(冪等)
    return {**tool_input, "prompt": prompt.rstrip("\n") + "\n" + CAP}

fork 是原封不動延續目前對話的分支,沒有另外的指示文規約,所以排除了。如果句子已經存在就不再附加,因此即使同一個呼叫多次通過 hook,句子也不會重複。實際的 hook 在處理中發生例外時,會回傳 None,讓它以原本的輸入執行。與其因為修改指示文失敗而讓委派本身被擋下,不如讓它在缺少那句話的情況下照常進行。

hook 的輸出是下面的樣子。同時輸出給模型的提示(additionalContext)與變更後的輸入。

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "additionalContext": "收到結果後,用一行輸出收到的要點",
    "permissionDecision": "allow",
    "updatedInput": { "subagent_type": "general-purpose", "prompt": "調查一下\n(這個上限 … 只給路徑)" }
  }
}

加入這個功能的那天,我同時加上了 7 個自我測試。檢查的是:句子會不會附在沒有該句子的指示文末尾、其他輸入值是否維持原樣、已經有句子時是否不改動、對訊息傳送與 fork 是否不動它。

直到委派指示文附上回報上限為止主代理呼叫 Agent → PreToolUse hook 接收輸入; PreToolUse hook 接收輸入 → 是委派、不是 fork、還沒有句子?; 是委派、不是 fork、還沒有句子? → 在 prompt 末尾加上限制句子 (是); 是委派、不是 fork、還沒有句子? → 以原本的輸入執行 (否); 在 prompt 末尾加上限制句子 → 以變更後的輸入執行子代理是否主代理呼叫 AgentPreToolUse hook接收輸入是委派、不是fork、還沒有句子?以原本的輸入執行在 prompt末尾加上限制句子以變更後的輸入執行子代理
直到委派指示文附上回報上限為止 — 即使人不寫,hook 也會把最後一行補齊

數字改變了多少?

老實說,距離目標還很遠。2026-10-21 重新量測最近 7 天,指示文裡含有 300 字用語的委派,在 198 筆中有 179 筆(90.4%),靠人手寫的那一步幾乎已經補齊。但是實際以 300 字以內回來的回報,在 143 筆中只有 4 筆(2.8%),中位數是 574 字。

第一次量測的值(37 筆,中位數 650 字)與這次的值,量測期間與筆數不同,所以無法直接比較。只能確認中位數往下降的方向。即便如此,因為我每天都看這個數字,所以不再誤以為「加了規則就解決了」。句子只是撐住底線,下一步是縮減代理定義本身的輸出格式,這一點也是數字告訴我的。

回報長度的中位數目標上限: 300字; 2026-10-19(37 筆): 650字; 2026-10-21(143 筆): 574字0200400600目標上限300字2026-10-19(37筆)650字2026-10-21(143筆)574字
回報長度的中位數

現在的一天有什麼不同?

委派時,我不再操心指示文的結尾。不管交給哪個代理,最後一行都由 hook 補齊。回報短短地回來時,我在主要對話裡只讀結論,需要依據時才打開回報裡寫的檔案路徑。如果回來的是很長的回報,會直接記在當天的指標上,成為找出哪個代理定義仍在讓它寫很長的線索。

常見問題

使用子代理,主要上下文會減少嗎?

子代理工作時讀取的檔案與工具結果,不會傳到主要對話。但最終回報會原樣進來,所以回報如果很長,省下的部分又會花回去。最好另外規定回報長度。

permissionDecision 輸出 allow 沒問題嗎?

要使用 updatedInput 就必須一起輸出,而 allow 會跳過該次呼叫的權限確認。我的模式本來就不使用確認視窗,所以沒有新放寬的權限。如果你使用的是有確認視窗的環境,請先考慮這一點。

300 字不會太短嗎?

用來放結論與檔案路徑是足夠的。依據表格或長清單寫進檔案,主代理只在需要時打開那個檔案。不過這個數字是我在自己的環境裡定的值,請依用途調整。

要不要一起打造您的網站?

免費諮詢