
早期的程式碼 Agent 揭露了一件出乎意料強大的事:只要給 Agent Bash 的存取權,它幾乎什麼都能做——從寫程式碼、蒐集情境資訊,到管理完整的 Git 工作流程。
這個洞察,助長了一股邁向 CLI 優先軟體的更大趨勢。命令列介面開始看起來像是讓 AI Agent 能存取複雜應用程式的標準做法,也催生了一句耳熟能詳的口號:
有 CLI 就夠了。
但這裡有個隱藏成本。Agent 使用終端機的方式常常跟人類很像:執行一段簡短指令、檢查結果、再決定下一步該做什麼。任務一旦變複雜,模型和工具之間的來回就會增加,代表更多 LLM 呼叫、更多情境浪費,還有更多等待時間。
與其要求 Agent 拼湊複雜的 shell 腳本,我們更希望它們用自己已經熟悉的程式語言來統籌任務。這帶出了一個略有不同的架構:
保留 CLI 作為通用入口,但實際跟軟體互動的方式改用程式碼。
Agent 送出一段程式碼,裡面包含了原本得分散在好幾輪互動中的操作、決策和資料處理。本機執行環境接著執行整個工作流程。
ego-browser was built around this idea. Its CLI launches a programmable environment, the browser exposes its capabilities through a small set of functions, and the agent uses its existing programming skills to compose those functions and 統籌調度它們.
在這篇文章中,我們比較 heredoc 和 REPL,這是兩種透過 CLI 執行程式碼的方式,並分享來自 ego-browser 的實驗結果。用 heredoc,Agent 完成同樣的任務時,執行輪次減少 44%,工具呼叫次數減少 35.5%,成本降低 21.6%。
「有 CLI 就夠了」——然後呢?
「有 CLI 就夠了」這個說法,前提是模型早就知道怎麼使用那個 CLI。
對 Git、Docker、FFmpeg 這類知名工具來說,這通常不是問題。模型在訓練過程中看過無數的指令、教學、腳本和錯誤訊息,早就知道各種參數,也知道指令怎麼組合在一起。
但當我們要為 Agent 打造一個全新的 CLI,情況就不一樣了。每個 CLI 都有自己的子指令、參數、輸出格式和錯誤語意。 對模型來說,這基本上就是一種新的迷你語言。 就算文件寫得再完整,模型還是得先學會規則,再透過反覆呼叫,摸索出各個指令怎麼組合在一起。
改用 JavaScript API(或任何其他語言的 API)來提供同樣的能力,模型還是得學新的領域知識,但不需要重新學控制流程、資料結構或組合方式。迴圈、條件判斷、例外處理和資料處理,全部都留在它已經熟悉的程式語言中。
以一個簡單任務為例:打開一個網頁,讀取它的主標題。如果 ego-browser 提供的是傳統的指令式介面,Agent 可能得花好幾個步驟才能完成:
# First call: open the page
ego-browser open https://example.com
# Tool response: the page is open
# Second call: locate the main heading
ego-browser find --role heading
# Tool response: a heading was found
# Third call: read the heading
ego-browser read --role heading每完成一步,Agent 都得等工具回應、讀取結果,再決定下一步該做什麼。
ego-browser 實際採用的程式碼介面,能讓它一次表達整個工作流程:
await taskSpaces.useOrCreate("read example page");
await browser.openOrReuseTab("https://example.com", { wait: true });
const heading = await page.getByRole("heading").textContent();
console.log(heading);兩種做法都能完成同樣的事。指令式介面把流程拆成好幾輪模型與工具的互動;程式碼介面則讓 Agent 一次寫出完整流程,再交給本機執行環境處理。
這正好呼應前面提到的設計理念:保留 CLI 作為通用入口,但實際跟軟體互動的介面改用程式碼。這樣既保留了 CLI 容易呼叫、容易整合的優勢,又能讓模型運用自己已經具備的程式設計能力來組合與統籌。
當 CLI 變成通往程式碼的入口
一旦 CLI 開始接受程式碼,下一個問題就是:Agent 該怎麼把程式碼交給執行環境?
嚴格來說,heredoc 是 shell 的輸入語法,REPL 是直譯器的執行模式,兩者並不在同一個抽象層次上。這篇文章實際比較的,是透過 ego-browser 中的 heredoc 一次性輸入程式碼執行,對比建立在 REPL 之上的持續互動連線階段。為了行文簡潔,之後就統一稱為 heredoc 和 REPL。
其中一個做法是 heredoc。在 ego-browser 中,Agent 會一次送出一整段 JavaScript 程式碼:
ego-browser nodejs <<'EOF'
await taskSpaces.useOrCreate("read example page");
await browser.openOrReuseTab("https://example.com", { wait: true });
const heading = await page.getByRole("heading").textContent();
console.log(heading);
EOFshell 把程式碼傳給 ego-browser,等待執行完成,接收結果,然後結束。對 Agent 來說,這的行為就跟一般的工具呼叫一樣:
Submit command → wait for process → receive resultREPL 的運作方式不同。直譯器持續存活,讓 Agent 能反覆輸入程式碼,同時保留變數和連線階段狀態:
> await browser.openOrReuseTab("https://example.com", { wait: true })
< Tab {...}
> await page.getByRole("heading").textContent()
< "Example Domain"就表達能力來說,兩者本質上是對等的。REPL 能一次執行包含迴圈、條件判斷和例外處理的完整程式,heredoc 也能只送出一行程式碼。
明顯的差別在於程序的生命週期。用 heredoc,程式碼一跑完,程序就結束;REPL 則讓直譯器程序持續存活,等待進一步的輸入。這也代表兩者對 Agent 工具的要求不同。heredoc 直接運作在大家熟悉的請求—回應模型上:
submit the command → wait for the process to exit → get the resultREPL 對工具的要求更高:持續存活的程序、連線階段管理、持續輸入、中斷與復原。多數 Agent 內建的 Bash 工具都不具備這些能力。在目前的主流產品中,只有 Codex 算是支援得還不錯。而工具支援只是使用 REPL 的必要條件,並不能決定模型實際上會怎麼使用它。就算兩種環境都能執行同樣的程式碼,模型在兩邊寫出來的程式碼還是可能不一樣。
模型在不同環境中怎麼寫程式碼
理論上,模型在兩種環境中的程式設計能力應該一樣。但實務上,我們觀察到一致的行為差異:
- 在 REPL 環境中,模型傾向逐步輸入程式碼。
- 在 heredoc 環境中,模型更傾向一次生成完整的程式。
給人類用的軟體必須考慮人體工學。給 Agent 用的軟體也需要類似的紀律,可以稱之為 模型體驗工程。介面設計應該順應模型在訓練過程中養成的行為模式。
REPL 和 heredoc 之間的差異,反映的正是它們訓練資料的分布狀況。
REPL 的範例通常來自教學文件、除錯過程和問答交流,典型模式是探索性的:
> Get the page
< Return page information
> Find an element
< Return element information
> Read its contents
< Return the textheredoc 程式碼區塊看起來更像腳本或原始碼檔案,有明確的開始與結束邊界,這會促使模型產生連貫的工作流程:
const page = await openPage();
const element = await findElement(page);
const text = await readText(element);
console.log(text);這不代表 REPL 沒有能力執行完整的程式。模型其實也能一步就把同一段程式碼送進 REPL 執行。
差別在於情境。REPL 鼓勵的是一種 執行、觀察、繼續 模式。而 heredoc 鼓勵的是一種 先規劃,再執行 模式。
這種傾向也決定了控制流程放在哪裡。在 REPL 中,模型更傾向把任務拆成好幾個階段,每次拿到結果後才決定下一步。在 heredoc 中,模型則更傾向直接把迴圈、條件判斷、篩選和資料處理寫進程式裡,交給本機執行環境處理。
實驗結果顯示了什麼
在我們能穩定整合的主流 Agent 工具中,Codex 提供了持續執行的 REPL 所需要的執行能力。所以我們在 Codex SDK 上打造了一套自動化效能實測:同一個 Agent 分別用 REPL 和 heredoc 完成四種真實瀏覽器任務,我們彙整多次執行的結果來做比較。
任務內容如下:
- X trending-post analysis (a typical social media scraping workload): 蒐集 OpenAI 過去七天的原創貼文,排除置頂、轉發和回覆,依觀看次數排出前五名,並計算它們的互動率和整體平均值。
- OpenAI 職缺申請: 找到舊金山正確的雲端基礎設施職缺,上傳履歷,填完整份申請表,在最終送出前停下來。
- Redfin 房貸試算: 在 Austin 依房型和價格篩選物件,排序後開啟第一筆結果,把頭期款改成 20%,取得更新後的預估月付金額。
- Expedia 機票搜尋: 搜尋從 JFK 到 MIA 的單程直飛航班,從指定航空公司中挑最便宜的選項,輸入乘客資料,在付款前停下來。

These tasks covered more than opening pages and reading text. They included structured extraction, conditional filtering, navigation across pages, file uploads, form completion, page-state changes, and calculations, covering most of the common operations performed by browser agents.
兩種做法都完成了大部分任務。heredoc 的成功率是 77.5%,REPL 是 75.0%,穩定度差異不大。
更大的差異在於效率:
- 平均完成時間減少了 35.0%.
- 完成時間中位數減少了 30.7%.
- 工具呼叫次數減少了 35.5%.
- Token 消耗減少了 29.8%.
- 平均成本降低了 21.6%.
雖然 REPL 能重複使用執行階段狀態,但這個優勢並沒有換來更少的互動次數。實際測試中,heredoc 的 Agent 呼叫工具的次數反而更少。
結果跟我們先前的觀察一致。一旦進入 REPL,Agent 常常只跑一小段程式碼、檢查結果,再決定下一步。原本可以在單一程式裡處理完的迴圈、篩選和決策,卻被分散到好幾輪模型與工具的交流中。
兩種環境提供的表達能力相近,效率上的差異主要來自互動模式如何形塑 Agent 的行為。至少就這四項瀏覽器 Agent 任務來說,heredoc 更一致地促使模型組織出完整的程式,把迴圈、篩選和決策都寫進程式碼裡,避免逐步決策帶來的額外來回。
我們也在 Odysseys 資料集上,拿 ego-browser 對比一款類似的 REPL 式瀏覽器自動化產品,檢視同樣的模式在更大規模下是否成立。跟上面的對照實驗不同,這次比較涉及兩款完整的產品,而不是同一個模型透過兩種介面操作,因此適合作為整體效率的比較參考,但差異不能完全歸因於 heredoc 對比 REPL。

這並不代表 heredoc 就此永久勝出
我們不認為 heredoc 天生就優於 REPL。
我們的結論取決於模型的能力、訓練資料的分布,以及截至 2026 年 Agent 工具的設計方式。
現在的 Agent 普遍更擅長一次生成一整段完整的程式碼,它們的 shell 工具設計也圍繞著一個簡單的生命週期:送出指令、等待結束、回傳結果。在這樣的前提下,heredoc 更容易減少互動輪次,並把控制流程搬進本機執行的程式碼中。
這些前提條件可能很快就會改變。
未來的 Agent 工具或許能提供穩定的持續連線階段、結構化輸出,以及強健的狀態復原機制。Agent 或許就不再需要自己處理 REPL 提示、程序狀態和中斷的連線階段。針對性的訓練,也可能教會模型主動在 REPL 中送出完整程式,而不是落入不必要的逐步互動。
如果真的發生,REPL 就能在不需要更多模型呼叫的情況下,保留狀態重複使用和即時回饋的優勢。對於初始化成本高、狀態存續時間長,或真正屬於探索性質的工作流程,REPL 甚至可能成為更好的選擇。
這正是標題特別指出 2026。我們並不是宣稱發現了什麼永恆不變的定律。這只是根據現有模型和 Agent 工具,在此時此刻做出的工程判斷。