iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
AI Engineering

Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent系列 第 12 篇

Day12:給 agent 工具越多越好嗎?從 Pi 的預設工具看 Agent 的能力邊界

  • 分享至 

  • xImage
  •  

迴圈的「動手做」那一站

前面幾天都在拆「看現況」:AGENTS.md(Day8)、Skills(Day10)。今天換到迴圈的另一站——動手做。

模型自己不會執行任何東西,它只能說「我要用某個工具、參數是這些」。真正做事的是 harness 提供的那組工具。所以工具集決定了 agent 的行動空間:它能做什麼、做不到什麼、以及做一件事要繞多少路。

Pi 的內建工具一共有八個:read、bash、powershell(僅 Windows)、edit、write、grep、find、ls。但預設只開四個:

// dist/core/system-prompt.js
const tools = selectedTools || ["read", "bash", "edit", "write"];

grep、find、ls 預設是關的。這件事我在 Day7 第一次實跑時才發現,它也直接改寫了 Day13 的題目——原本要問「拿掉搜尋工具會怎樣」,實際上要問的是「加上它們有沒有差」。

工具怎麼自我介紹

每個工具在原始碼裡都帶著兩段給模型看的文字:一行 snippet(出現在 system prompt 的工具清單),還有若干 guidelines(出現在 Guidelines 區)。

工具 snippet guideline
read Read file contents Use read to examine files instead of cat or sed.
bash Execute bash commands (ls, grep, find, etc.) 可以查 PI_* 環境變數取得目前模型與 session 資訊
edit Make precise file edits with exact text replacement, including multiple disjoint edits in one call oldText 必須完全相符;多處修改請用一次呼叫
write Create or overwrite files Use write only for new files or complete rewrites.

這裡有個設計細節值得學:工具清單是動態組出來的,只有「呼叫端有提供 snippet」的工具才會出現在 system prompt 裡。Guidelines 也一樣,會依照當下開了哪些工具調整。沒開的工具,模型連知道都不知道。

先看一下這四個工具實際上怎麼被用。下面是第一輪校準裡,每個任務平均用掉的工具呼叫次數:

每個任務用了哪些工具

任務 read bash edit write 合計
T1 修分頁 bug 2.7 4.3 1.0 0.0 8.0
T2 新增 endpoint 20.0 3.3 4.3 1.0 28.7
T3 修 CI 檢查 9.3 2.7 3.0 0.0 15.0
T4 拆常數 9.0 4.0 8.0 0.0 21.0
T5 資料遷移 19.3 5.7 3.0 1.0 29.0

除了最短的 T1 以外,read 在每個任務都是最大宗——agent 大部分時間在讀,不在寫。T4 是例外中的例外:因為要改六個檔案,edit 的次數幾乎追上 read。write 全部加起來只有兩次,正好對應它的 guideline:只用在新檔案。

read:不是 cat

read 除了路徑,還接受 offset 和 limit 兩個參數,可以只讀某個行數範圍。回傳內容有上限:2000 行或 50KB,超過會被截斷並標示出來。

這解釋了 Day6 那份 session 的一個細節:模型讀 models_generated.py 時帶了 offset: 1, limit: 180——它在控制自己的 context 用量。

為什麼要專門做一個 read,而不是叫模型用 bash 跑 cat?因為工具結果會進 context,harness 需要能控制進來多少。cat 一個一萬行的檔案,整包都會塞進去;read 則會截斷、會標示、會告訴模型「還有更多」。

bash:沒有預設逾時

bash 的 schema 只有兩個參數:command,以及選填的 timeout。原始碼註解寫得很直白:「Timeout in seconds (optional, no default timeout)」——不指定就沒有逾時。

這是一個很重要的 harness 行為。如果模型跑了一個會卡住的指令又沒設逾時,這個 agent loop 就停在那裡了。實務上模型通常會自己帶 timeout(我們的實驗記錄裡,Pi 跑 pytest 和 check.py 時都帶了 timeout: 120),但這是模型的習慣,不是 harness 的保證。

指令的輸出同樣受 2000 行/50KB 限制,結束時會附上 exit code。Day6 看到的 Command exited with code 1 就是這樣來的——而且這種「指令失敗」會被標記成 isError: true 回傳給模型,讓它知道剛剛那步沒成功。

edit:最容易出錯的那一個

edit 是四個工具裡設計最講究的。它接受一個 edits[] 陣列,每一筆有 oldText 和 newText。規則寫在 schema 的 description 裡,模型看得到:

Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.

Each edit is matched against the original file, not incrementally.

兩個關鍵限制:

  1. oldText 必須在檔案裡唯一。 不唯一就沒辦法確定要改哪一處。
  2. 所有 edit 都是對照「原始檔案」比對,不是套用前一個 edit 之後的結果。 所以兩個互相重疊或相鄰的修改不能拆成兩筆,要合併成一筆。

還有一條 guideline 是講效率的:「oldText 在唯一的前提下越短越好,不要填一大段沒改到的內容。」因為 oldText 和 newText 都是模型輸出的 token,填越多付越多。

在我們的實驗記錄裡看得到模型確實照著做:某一輪它同時改了四個檔案,其中兩個檔案各自包含兩處修改,回傳是 Successfully replaced 2 block(s)——一次呼叫、多處修改,而不是拆成四次。

write:會蓋掉,也會自動建目錄

write 最單純:建立或覆寫檔案,父目錄不存在會自動建立。它的 guideline 只有一句——「只用在新檔案或整份重寫」。

這句話其實是在防一種浪費:模型如果用 write 去改一個五百行的檔案裡的一行,它得把整整五百行重新輸出一次。Day14 會看到,這種「輸出 token」在成本裡的比重比想像中高。

這對 harness 設計的意義

把這四個工具擺在一起看,會發現它們其實在回答同一個問題:怎麼讓模型用最少的 token 完成一次動作。

  • read 有 offset/limit 和截斷 → 控制「進來」的量
  • edit 要求最小唯一片段、可一次多處 → 控制「出去」的量
  • write 被明確限制用途 → 避免整檔重寫
  • bash 什麼都能做,但輸出一樣被截斷

工具不只是「能力」,它同時是成本控制的介面。這也是為什麼「加一個工具」不見得總是好事——多一個工具就多一段 schema 常駐在每一次請求裡。

明天

Day13 量這件事:把 grep、find、ls 這三個預設關閉的搜尋工具打開,對一個需要跨檔案搜尋的任務有沒有幫助。我已經先偷看到一個現象——關著的時候,agent 會直接用 bash 跑 rg 和 find 繞過去,所以真正要量的其實是「繞路要付多少代價」。


上一篇
Day11:Skill 沒有增加新知識,為什麼成本卻少了一半?
系列文
Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
justin_log
iT邦新手 4 級 ‧ 2026-09-26 19:44:42

超Pi~~~~~~~~~~~~~~~

我要留言

立即登入留言