代理 CLI 編寫者
代理伸手拿的是命令,而不是手冊。只存在於文件中的規則,只有當代理碰巧讀到它時才會被遵守。這背後的衡量指標位於 references/evidence.md。
規則: 工具的每一條規則都由工具本身在其適用的那一刻陳述。它印出的內容、它拒絕的內容以及它讓事情變得容易的方式,就是手冊。
代理如何使用工具
- 先嘗試命令;只有在不確定時才打開手冊,而且常常是確定但錯誤的。
- 閱讀是為了確認已經制定的計畫:它尋找的是語法,而不是規則。
- 每次會話之間會忘記一切,並在每次使用時重新學習工具。
- 一次發送多個呼叫。
- 在後續的每次請求中,都需為工具先前印出的每個字元再次付費。
- 無法廉價地等待:它會輪詢或休眠,而每次輪詢都是一次付費請求。
- 比起稍早的文件所說的內容,它更可靠地執行眼前答案所指示的動作。
方法
十二項檢查,每項附帶驗證方式。tool 是假設的命令。
- 在使用點教學。 命令的答案會說明剛剛走過的路徑花費了什麼,並指出更好的路徑。
驗證:每個具有已知錯誤用法的動詞,都會在其自身的輸出中說明。$ tool machine new created m-41 (stops by itself in 60 min) note: work started by hand in this machine keeps no run record. for a job you need to follow: tool job start --from <dir> -- <cmd> - 拒絕就是一課。 說明拒絕了什麼、原因,以及填入了呼叫者自己參數的確切下一條命令。一次回答所有問題。永遠不要在沒有說明的狀況下以非零狀態退出。用法錯誤時,僅印出該子命令的正確形式。
驗證:沒有不帶說明的退出路徑;每次拒絕都附帶tool: refused: `job wait j-7` would hold this turn for up to 40 min. next: tool job show j-7 (how it stands now) tool job start … --notify (be told when it ends)next:。 - 將手冊內建於工具中。
tool rules會完整印出操作規則,並以版本碼結尾。由代理手動驅動的動詞,會拒絕一個尚未設定當前版本碼(TOOL_RULES=<code>)的非互動式呼叫者,僅一行說明。作為機器介面的動詞則保持開放。當規則改變時,版本碼也隨之改變。 驗證:一個只知道命令名稱的全新代理,在其首次執行建立、更改或刪除操作的呼叫之前,規則已存在於其上下文中。 - 讓正確的路徑成為容易的路徑。 在撰寫「偏好 X」之前,先讓 X 能完成整個工作:接受代理真正擁有的輸入,立即返回,並保留記錄。代理會繞過一個會阻塞、丟棄歷史記錄或無法接受其輸入的推薦命令。陳述後果,而非偏好:「Y 不保留記錄」比「偏好 X」更有效。 驗證:對於文件中的每一個「偏好」,指出被避開的路徑提供了什麼偏好的路徑所缺乏的,並補上那個差距。
- 一個命令回答「我現在處於什麼狀態,以及為什麼」。
tool status,僅用幾行:我的東西是什麼、正在運行的東西是什麼、上一件事如何結束及其原因、下一步該做什麼。代理直接讀取工具的儲存或日誌,表示 status 遺漏了某個事實。 驗證:在真實的對話記錄中統計這類讀取的次數;最常見的三個問題應屬於 status。 - 長時間工作:啟動、回報、告知。 超過約一分鐘:
start立即返回一個 handle;show <handle>提供時間線、退出碼和最後幾行,即使在 worker 消失或呼叫者死亡後也能查詢;結果會傳遞給呼叫者,包含結果和原因。訊息只有在攜帶代理可以立即採取行動的新資訊時才算合格:沒有定期的「繼續」。 驗證:預設情況下,沒有操作會阻塞超過 60 秒;每個工作都有記錄和包含結果、原因及下一步的結束通知。 - 輸出少量內容。 預設輸出適合一個畫面:約 40 行或 2,000 個字元。更多內容寫入一個檔案,並印出檔案路徑,或跟在
--full後面。沒有橫幅、沒有進度動畫;一次會話中的固定指示。被截斷的輸出會說明情況並指出其餘內容的位置。 驗證:測量一個真實週期中每個命令返回的字元數,並為最大的三個總額設定預算。 - 兩位讀者:人和程式。 在終端機上為文字。透過 pipe,或加上
--json:僅限 JSON lines,穩定的欄位名稱,一個最終摘要。退出碼即代表結果:0 表示完成,並為拒絕、錯誤用法、超時、從未運行設置單獨的退出碼。診斷訊息寫入標準錯誤。 驗證:tool <verb> | cat可解析;--help列出每個退出碼。 - 可安全重複執行,可同時安全執行。 執行兩次命令不會將事情做兩次,或者會說明它已經做過了。來自同一個代理的兩個同時發出的呼叫不會彼此覆蓋寫入:採用鎖定,或者用文字拒絕第二個。破壞性的動詞需要一個明確的旗標,並提供
--dry-run。 驗證:一項測試會讓每個寫入動詞同時執行兩次。 - 設定邊界並留下記錄。 預設時間限制;工具建立的東西會自行過期;
list顯示遺留物;cleanup移除這個呼叫者建立的東西;一件事的成本就是一個命令。每個動作都記錄了誰、何時以及工具的建置版本;tool version會命名它。 驗證:在中間殺死呼叫者;沒有東西會無限制地運行,並且記錄會說明發生了什麼事。 - 一件事用一個名稱。 在命令、其輸出、其錯誤及其文件中使用相同的名詞;一個動詞在不同名詞間表示相同的動作。未知的旗標和多餘的參數會被拒絕,絕不忽略。 驗證:列出工具印出的所有名詞;每個概念恰好有一個。
- 機密資料不曝露。 絕不在命令列上、絕不回顯、絕不在記錄中:來自檔案、標準輸入或環境變數,並在輸出中遮罩。
編寫工具手冊
手冊負責解釋;工具負責強制執行。沒有什麼有約束力的東西只存在於手冊中。
- 描述: 工具做什麼以及何時載入它,使用任務會用的詞彙,並命名動詞。
- 順序: 先寫有約束力的規則,每條附帶其後果;然後是一個目標與命令的簡短表格;接著是失敗情況及應對措施。
- 大小: 最多 150 行,每行不超過 100 個字元。代理會以截斷長行的方式列印檔案,並會遺失每個寬表格行的結尾。
- 表格: 表格儲存格內不要放置有約束力的內容。
在新鮮代理上驗證
一個從未見過該工具或其手冊的新會話,在收到真實任務和命令名稱時:
- 記錄每次呼叫、其輸出及其退出碼。
- 統計:查閱說明的次數、失敗的呼叫次數、重複失敗呼叫的次數、輪詢次數、直接讀取儲存或日誌的次數、返回的字元數。
- 每個大於零的計數都是工具本身的缺陷,而不是代理的缺陷。修正訊息或路徑,然後在另一個全新的會話中再次執行。
- 在載入手冊的情況下再執行一次:任何情況都不能變得更糟,且手冊不得與工具矛盾。
完成目標:全新代理完成任務時,沒有查閱說明、沒有失敗後需猜測如何脫身的呼叫、沒有輪詢、沒有直接讀取儲存。
錯誤模式
僅限手冊的規則(工具從不陳述它) · 無聲的失敗(非零退出,沒有說明) · 有原因但無下一步(給出原因但沒有命令) · 傾倒整個幫助文件 · 推薦但更糟(推薦的路徑缺乏另一條路徑所擁有的) · 狀態缺口(代理讀取儲存) · 阻塞者(命令佔用回合) · 嘮叨(定期發送沒有新資訊的訊息) · 去看日誌的通知(說明發生了一件事,但沒說是什麼) · 文字牆 · 無聲截斷 · 寫入遺失(同時兩個呼叫,一個結果) · 兩個名稱 · 遺留物(沒有東西會過期)。