系列:「一人艦隊:用一群 AI CLI 打造跨平台代理 mesh」— 第 30 篇(系列 ID:9330)
紀錄日期:2026-09-21
本機草稿,尚未貼到網站。篇次是素材順序。今天完成有界程式修正與本機驗證,沒有部署正式版,也沒有宣稱已完成整個私人 Agent Swarm。
上一篇比較五個免費 LLM gateway 後,我又問:應該直接 import,還是自己重雕?
這次採取的做法是把 FreeLLMAPI 放在獨立、可以替換的供應層,以 Spectyn 已有的 openai_compat 接入。Spectyn 保留任務、記憶、工具、權限與評估;gateway 處理模型 API 的供應與切換。這樣能借用已有成果,也保留日後換供應層的空間。
不過,真正阻擋這個接法的問題在 Spectyn 自己。
上游先送出部分文字,再送 error,最後用 [DONE] 結束串流。原本 Spectyn 仍會回報 done、truncated:false、exit 0。
對人來說,少半段回答可能看得出來;對自動開發迴圈來說,exit 0 可能變成「繼續測試、建立成果、準備部署」的依據。更麻煩的是,串流中可能已經帶了工具參數,錯誤後若還去執行,就把不完整的一輪變成真的副作用。
所以今天先完成這個最小修正,沒有急著接更多模型。
修正後,收到部分文字或工具片段再遇到明確錯誤,就保留失敗狀態。[DONE] 只是串流結束記號,不能把失敗變回成功。
程式先記錄供應商回報的用量,再在儲存本輪回答、從文字補救工具格式、執行工具之前停止。後續文字或工具片段不再採用;後續 usage 仍可入帳。
如果前一輪工具已經執行,系統不假裝回滾,也不自動重播它。這次測試真的先在隔離目錄寫入一個檔案,再讓第二輪失敗:檔案保留,請求沒有額外重試,整個命令仍以失敗退出。這是目前能保證的邊界,還不是跨程序 exactly-once。
同一個錯誤不能在一般模式失敗,到了 JSON 或 quiet 模式卻成功。我們用真正編譯出的 Spectyn CLI,測七種情境,每種跑三種輸出模式:
| 驗證層 | 本輪結果 |
|---|---|
| Rust 回歸:串流錯誤、既有斷線契約、用量 | 12 項通過 |
| 真 CLI:正常、錯誤文字、完整/不完整工具、工具形狀文字、前輪已執行工具、工具後斷線 | 21 組通過 |
| 固定 FreeLLMAPI 的 HTTP/Spectyn 接線 | 15 項判準通過 |
| Rust cargo check | 通過,保留既有警告 |
gateway 固定在 37f07fdc3a2cdf14b2cc804e63ce82ff9a178854。使用真實 router、SQLite 與 adapters,但上游是本機固定回應服務;不是已驗證外部免費 API 額度或完整背景服務啟動。上一篇的 113 項上游測試沒有在這次重跑,不能重複加進今天的成績。
第一版工具副作用測試沒有設定隔離工作目錄的信任,因此工具其實被拒絕。這不能證明「前輪工具執行後還能正確失敗」。補上只限測試目錄的信任後,才拿真正的寫檔結果驗證。
另一個斷線 fixture 用 HTTP/1.0 卻傳 chunked,讓客戶端根本還沒收到工具就失敗。改成 HTTP/1.1,確認先收到工具片段再斷線,才形成有效的情境。
這兩件事都保留原始失敗資料,沒有刪掉重跑成績假裝一次成功。
我的 Big Goal 仍是:由自己的訂閱與電子設備組成 Agent Swarm,越使用越懂我、越能替我做事,也讓我自己變強。
今天做到的是其中一小段:遇到供應層失敗時,開發中的 CLI 能誠實停止,留下其他 CLI 可以檢查的測試、來源與原始證據。Codex 負責整合實作,OpenCode/agy 提供分析與審查,另有 Claude Code 最終審查;審查是否完成以最後的實際結果補記,不以叫過工具就算通過。
下一包要處理 exec 被拒絕工具的三模式計數差異,再建立真實供應商 opt-in 測試與整體重試上限。自我開發迴圈也仍需要穩定版監督候選版、獨立評估、可回復部署,以及使用者掌握主要決策。
本輪未 commit、未覆蓋安裝版、未部署;RC-071 仍是 draft-candidate。PowerShell 契約檢查因缺 pwsh 為 NOT_RUN,不能拿 Rust 測試代替它。系列走到第 30 篇,不等於專案已經全部完成。
審查結果補記:Claude Code 最終 APPROVE with limits;OpenCode 最終 APPROVE,並更正初審的兩段誤讀。兩份非作者審查已齊,agy 無輸出不計入。這是本輪候選修正的審查,不是發布核准。