這是另一個 Fable 5 實驗。我的 LLM 函式庫已經演變成一個更像代理框架的東西,現在是時候看看基於它構建一個簡單的編碼代理會是什麼樣子了。
我使用我的 python-lib-template-repository GitHub 範本儲存庫啟動了一個新的 Python 函式庫,然後執行了這兩個提示詞(這是 Claude Code 的網路轉錄):
「為這個專案編寫一個 spec.md,它將依賴 PyPI 上最新的『llm』alpha 版本,並實作一個 Claude code 風格的編碼代理,配備讀取和編輯檔案以及執行指令的工具。」
然後是:
「提交規格文件,然後使用紅/綠測試驅動開發(TDD)以一系列合理的提交來構建它(每個提交都包含通過的測試和更新的文件),偶爾使用環境中的 OpenAI API 金鑰手動測試它。」
這是規格文件、生成的 README 檔案以及一系列的提交紀錄。我已經將一個初步的 alpha 版本發佈到 PyPI,所以你可以這樣執行新的代理:uvx --prerelease=allow --with llm-coding-agent llm code。
對於第一次嘗試來說,它表現得相當不錯!這是由 Fable 撰寫的 README,其中列出了像 llm code --yolo 和 llm code --allow "pytest" --allow "git diff" 這樣的「食譜」。
它還提供了一個基於 CodingAgent(model="gpt-5.5", root="/path", approve=True).run("Fix the failing test in tests/test_parser.py") 類別的 Python API,這是我沒有要求但很高興看到它實作的功能。
以下是它實作的工具套件,使用 uvx ... llm tools 列出:
CodingTools_edit_file(path: str, old_string: str, new_string: str, replace_all: bool = False) -> str
替換檔案中完全匹配的字串。old_string 必須與檔案內容完全匹配(包括空白),並且必須識別唯一位置,除非 replace_all 為真。返回變更的差異,以便進行驗證。
CodingTools_execute_command(command: str, timeout: int = 120) -> str
在會話根目錄中執行 shell 指令。返回合併的標準輸出和標準錯誤,後面跟著一行結束碼。timeout 以秒為單位(最大 600 秒);超時時,整個程序樹將被終止。
CodingTools_list_files(pattern: str = '**/*', path: str = '.') -> str
列出符合全域匹配模式的檔案,最新者優先。跳過隱藏目錄、node_modules、__pycache__ 以及(在 Git 儲存庫中)任何被 .gitignore 涵蓋的內容。最多返回 200 個相對於搜尋目錄的路徑。
CodingTools_read_file(path: str, offset: int = 0, limit: int = 2000) -> str
讀取文字檔案,返回帶行號的內容,類似於 cat -n。路徑是相對於會話根目錄的。使用 offset(從 0 開始的第一行)和 limit(最大行數)來分頁讀取過大的檔案。
CodingTools_search_files(pattern: str, path: str = '.', glob: str = None, max_results: int = 100) -> str
使用正規表達式搜尋檔案內容。返回匹配項,格式為 path:line_number:line,最多 max_results 個。使用 glob(例如 *.py)來限制搜尋的檔案。
CodingTools_write_file(path: str, content: str) -> str
使用給定內容建立或覆寫檔案。必要時會建立父目錄。修改現有檔案時,建議使用 edit_file。
我嘗試執行 llm code --yolo,然後提示它:
「建立 /tmp/demo 目錄,然後在該資料夾中建立一個簡單的 SwiftUI CLI 應用程式,用於以 ASCII 藝術顯示時間。」
這是轉錄內容,其中 GPT-5.5 的推理筆記指出「SwiftUI 不適合真正的 CLI」,然後構建了一個應用程式,在 swift run AsciiTime 上輸出以下內容:
█ █████ ████ █ █ ███
██ █ █ █ ██ █ ██ █ █
█ ████ ███ █ █ █
█ █ █ █ █ █ █ █
███ ████ ████ ███ ███ █████



