給 Agent 開發者的

Harness + Loop Engineering

2026/6/26
ihower @ 生成式 AI 開發者年會

我是誰

張文鈿,網路暱稱 ihower

Agenda

  1. Recap: 什麼是 Deep Agent
  2. 什麼是 Harness Engineering 🎯
  3. 時機 ①: 工具執行內
  4. 時機 ②: request 之間注入
  5. 時機 ③: 單輪結束(stop hook)
  6. 時機 ④: 外層 Loop
  7. 進階: 自我改進的 Harness
  8. 收尾: 會過期的 Harness
  9. 番外: 自建 Agent 的框架選型

📚 搭配有 9 篇的 blog 系列《給 Agent 開發者的駕馭工程》長篇文章 👉 blog.aihao.tw

👥 預期聽眾

多數談 Harness Engineering 是在講 Claude Code、Codex 來做軟體開發流程。

本場不是這個角度,而是站在「自行開發 AI Agent」的切入點。你要做的可能是 Text-to-SQL Agent、知識庫 RAG Agent,場景各式各樣,用途不一定是軟體開發。

Harness Engineering 可以適用於開發任何場景的 AI Agent

PART 1

Recap:
什麼是 Deep Agent

複習 Agent 1.0 迴圈

Agent 迴圈: Input → LLM 挑選工具 → Tools → 執行得到 Tool Result → 觀察結果回到 LLM,呼叫工具 N 次後輸出 Output

呼叫工具 N 次、每次都把結果讀回來,直到沒有工具要呼叫才輸出

Agent 2.0 (Deep Agent) 的六項能力

這些能力讓 Agent 應付更大更複雜的任務,技術上都是用到 Function Calling 來實現的

能力 做什麼
Plan & Todos 拆解大任務,依序執行
Filesystem & Bash 操作檔案、執行程式(搭配 sandbox)
Sub-Agent 把耗 token 的任務分給子代理人,隔離 context
Memory 跨 session 記得使用者與專案的長期資訊
Skills 按需動態載入的技能 prompt
更多工具 MCP、Browser、Computer Use
代表產品: Claude CodeCodexGemini CLI、LangChain Deep Agents

Deep Agent 內建能力 ①: Plan & Todos

🎯 它解決什麼問題

  • 只靠 in-context 規劃,思路容易被中間步驟干擾、遺失
  • 改用工具維護外部 todo list,不會忘記沒做完的事

🔧 技術上怎麼辦到

透過 Function Calling 提供工具:

  • TaskCreate 建立任務項目
  • TaskGet 取得任務詳情
  • TaskUpdate 更新任務狀態
  • TaskList 列出所有任務

Deep Agent 內建能力 ②: Filesystem & Bash

🎯 它解決什麼問題

  • Filesystem 讀寫改檔,Bash 執行任意 shell 指令
  • 讓 Agent 真的動手做事:編譯、跑測試、git、裝套件

🔧 技術上怎麼辦到

透過 Function Calling 提供工具:

  • ReadEditWrite 讀寫檔案
  • Bash 執行 CLI 指令
  • GlobGrep 搜尋檔案

Deep Agent 內建能力 ③: Sub-Agent

🎯 它解決什麼問題

  • 主 agent 派子代理去研究、查找、驗證
  • 子 agent 是獨立 context 跑,只回精簡摘要(context 隔離
  • 平行化:多個子 agent 同時工作

🔧 技術上怎麼辦到

透過 Function Calling 提供工具:

  • 一個叫做 Agent 的工具
  • 工具內就是呼叫另一個 Agent 執行,把子 agent 輸出回傳給主 agent

Deep Agent 內建能力 ④: Memory

🎯 它解決什麼問題

  • 重要資訊存起來,下次再開 agent,它還記得
  • 例:Claude Code 的 CLAUDE.md、Codex 的 AGENTS.md、長期 memory 儲存

🔧 技術上怎麼辦到

  • Agent 一啟動就預設載入 AGENTS.md
  • 使用者可以自己要求更新 AGENTS.md
  • 可自行設計記憶行為:記什麼、存在哪些目錄檔案、什麼時候回憶哪些內容

Deep Agent 內建能力 ⑤: Skills

🎯 它解決什麼問題

  • 為特定任務打包的 prompt +工具配置+程式碼
  • 不全部塞進 context,用到才載入;寫 markdown 就能新增
  • 例:翻譯 skill、寫部落格 skill、處理 PDF skill

🔧 技術上怎麼辦到

  • 預設 system prompt 只載入 skills 列表
  • 使用者需要某個 skill 時,Agent 才用讀檔工具載入完整 skill 內容

Deep Agent 內建能力 ⑥: 更多工具

🎯 它解決什麼問題

  • MCP: 接外部 Slack、Gmail、Notion、自建 API…
  • Browser: 瀏覽網頁、填表單、點按鈕,能上網做事或用網頁驗證自己的產出
  • Computer Use: 直接操作桌面 GUI(看螢幕、移動滑鼠、敲鍵盤)

🔧 技術上怎麼辦到

  • Browser 與 Computer Use 需要多模態模型:讓 AI 看截圖判斷下一步該點哪裡
  • MCP 標準化工具協議

但有能力 ≠ 把事情做好

✓ 能力給了你能不能做

能讀檔、跑指令、開子代理、記憶、用工具。

? 但是做得對不對 · 做完了沒

這一步的產出對嗎?整個任務做完了沒?怎麼穩定地做好、做完?

PART 2

什麼是
Harness Engineering

「做完了」誰說了算?

  • Agent 自信地宣稱完成,但東西是壞的
  • 測試沒跑、需求沒做完,它說「已全部完成 ✅
  • 你指出問題,它道歉,然後再犯

這不是個案

Anthropic 整理長時間執行 agent 的失敗模式,第一名就是「過早宣告完成」

什麼是 Harness? ➡️ Agent = Model + Harness

這是網路上常見的定義

模型以外的一切(system prompt、工具、編排、hooks)都算 harness。

小小吐槽 🤷

這定義有點偷懶

就像說「整體 = 核心 + 其他」

這個其他到底是什麼,我們需要更可以操作的技術拆解!

定義出自: The Anatomy of an Agent Harness(Viv Trivedy)

首先,harness 不只是技術功能列表

❌ 不是這個

Skills、Sub-Agent、Hooks、Filesystem、worktree

這些都只是手段,不是 Harness Engineering 的思維核心。

✅ 真正的主軸

是如何讓 agent 在執行過程能被約束、檢查、動態修正

回顧 Prompt、Context、Harness 三層

常被講成一條「演進」之路,但其實技術累加的都會用上,只是各自凸顯一個新的工程焦點:

核心問題 技術功能
Prompt Engineering 怎麼讓模型這一次答得更好 system prompt、few-shot、evals
Context Engineering 在 context window 限制下選擇該放的資訊 RAG、memory、compaction、tool offload
Harness Engineering 怎麼在執行過程中約束、檢查、動態修正 skills、filesystem、hooks

並沒有「XXX 已死」這回事,後者是基於前者的發展之上,而非取而代之。

Harness 核心策略: 先 generate,再 verify

核心策略就是: 驗證 (verification),廣義的說就是 回饋(feedback)

常見失敗

agent 輸出答案 → agent 覺得「看起來沒問題」→ 就停了。

解法: generate → verify → fix

模型有自我修正的能力,但我們需要讓 Agent 順利觸發進入「輸出 → 回饋驗證 → 修正」這個流程。

那工程上怎麼確保 verify「真的會發生」?

兩個軸把 harness 拆解

Thoughtworks 用兩個軸拆解 harness 作法: 方向×型態:

運算式 Computational(確定性、程式工具) 推論式 Inferential(LLM 生成)
前饋 Feedforward
引導器 Guides(行動前引導)
用程式工具產生的 code metadata 與約束:LSP、Codemod/ast-grep、架構規則(ArchUnit 等) system prompt、AGENTS.md、Skills、bootstrap instructions、how-to 文件
回饋 Feedback
感測器 Sensors(行動後修正)
測試、linter、type checker、靜態分析(eslint、semgrep)、pre-commit hook LLM as Judge、AI code review、Review Skills
原文是針對 coding agent 場景,但此框架被我延伸到非 coding agent 上
參考:Birgitta Böckeler(Thoughtworks)Harness engineering for coding agent users

好的 Harness 做兩件事

🧭 Guides 前饋

提高「一次做對」的機率

文件、skills、範例、架構約束。

軟性引導,做不做最後還是要看 agent

📡 Sensors 回饋

輸出之後,感測提供回饋,引導 Agent 自我修正

測試、linter、judge、AI review。

用程式自動觸發,不靠 Agent 自覺。

好的 harness 同時做兩件事: 提高「一次做對」的機率,並在出錯時能自我修正。

前饋 Guides

你的 system/developer prompt,要把「什麼是好的結果」以及「驗證流程」寫清楚。
例如 AGENTS.md/CLAUDE.md 都會要求 Agent 要去做驗證

Claude Code

非常重要:完成任務時你必須執行 lint 和 typecheck(npm run lint、ruff…),確保程式碼正確。」

Codex

「如果 AGENTS.md 裡有可程式化的檢查,你必須全部執行並盡力驗證通過。即使只是改文件也一樣。」

前饋的限制

前饋終究是軟性、機率性的引導

你在 AGENTS.md 寫十遍「一定要驗證」,模型還是有可能跳過 😢

回饋 Sensors: 把 verify 變成自動執行

前饋是軟性引導;回饋則用程式自動執行,不靠模型自覺

這可以插在 Agent lifecycle 的不同位置,來給 Agent 回饋。

本場將深入講解回饋的四個時機點

① 工具執行內(Part 3)

② request 之間注入(Part 4)

③ 單輪結束 · Stop hook(Part 5)

④ 外層 Loop(Part 6)

當然,前饋和回饋缺一不可

若只有回饋、沒有前饋

agent 寫 code → 測試失敗 → 改 → 再失敗,跑好幾輪還是超時。

通常不是回饋不夠,是 agent 從頭就不知道「好的執行過程跟結果」該有的樣子。

若只有前饋、沒有回饋

Agent 可能跳過驗證流程,可能沒有確實做好驗證。不知道做的對不對、不確定做完了沒

Agent 需要前饋一開始走對方向,也需要回饋負責把關修正。兩者缺一不可。
Harness Engineering:
讓 Agent 依目標持續、正確地動作的工程。

本場將重點講「回饋訊號」:要有東西能判斷做得好不好、做得對不對、做完了沒

回饋的四個時機點

把 agent 的迴圈由內而外拆解,回饋有四個時機點:

時機 多久觸發一次 成本 修正粒度 對應的 hook
① 工具執行內 每次 tool call 毫秒,最便宜 單一動作 Pre/PostToolUse
② request 之間注入 使用者或程式想注入時 趨近零 當前這一輪的方向 無專屬 hook
③ 單輪結束 每一輪 秒級 整輪的產出 Stop hook
④ 外層 Loop 每個 session 分鐘到小時 整個任務 排程/外迴圈

回饋的四個時機 ①②③④

④ 外層 Loop · 每個 session · 分鐘~小時 · 修正整個任務 ③ 一輪 Turn · 秒級 使用者輸入 模型 request 1 🔧 tool calls 模型 request 2 🔧 tool calls 模型 輸出答案 ② request 之間注入 (人 steer 或程式) ① 工具執行內 · 修正單一動作 Stop hook 沒過 → 同份 context 再跑一輪 一輪 (Turn) = 多次「模型 request → tool calls」反覆,直到模型輸出答案 ④ 通過後這個 session 收掉,換上全新 context 再跑一圈

PART 3 · 時機 ①

在工具執行內

Tool Call 裡面

工具呼叫內,有三個可以設計的地方:

執行前: 驗證輸入

確定性檢查參數與內容,
擋掉危險或無效的呼叫

執行後: 檢查結果

對結果做品質檢查,
必要時就地修復或重試

工具回傳值+夾帶指引

tool response 不只回資料,還夾帶指示與 metadata,引導 Agent 的下一步

工具輸出不只是 function output,
是你寫給 Agent 的回饋

寫程式習慣把回傳值當「資料」: 查到什麼回什麼,出錯就回傳 error code

但對 Agent 來說,tool response 也是一個對話訊息:
你可以在裡面夾帶指示、更多資訊 metadata,
甚至告訴 Agent 下一步怎麼做。

案例: Text-to-SQL Agent

場景

使用者用自然語言問財務數據,

Agent 基於 DB schema 產生 SQL

execute_sql(sql_query) 工具查詢。

LLM 生成 SQL 的風險

  • 幻覺不存在的表格和欄位
  • 生成查詢以外的危險語法
  • 忘記分頁,回傳爆量資料
  • SQL dialect 語法不同
我們會在 system prompt 插入 table schema 說明有哪些 tables/columns,以及各種 SQL 限制,這是前饋要先寫好。

在工具內: 把 SQL 解析成語法樹(AST),做確定性的檢查和改寫

import sqlglot
from sqlglot import exp

tree = sqlglot.parse_one(sql_query, dialect="postgres")

# 1. 只允許 SELECT(擋下來)
if not isinstance(tree, exp.Select):
    return "只允許 SELECT 查詢"

# 2. 資料表白名單(擋下來)
for table in tree.find_all(exp.Table):
    if table.name not in ALLOWED_TABLES:
        return f"資料表 {table.name} 不在允許範圍,可用:{ALLOWED_TABLES}"

# 3. 沒 LIMIT 就補安全上限(補強)
if tree.args.get("limit") is None:
    tree = tree.limit(200)

safe_sql = tree.sql(dialect="postgres") # 確保輸出 postgres 語法

工具回饋的設計

驗證沒過時,tool response 的品質決定 Agent 自我修正的能力

❌ 爛 error

ERROR: column "revenue_growth"
does not exist

Agent 只能瞎猜重試,越改越歪。

✅ 好 error

欄位 revenue_growth 不存在。
financial_metrics table 可用欄位有:
revenue, revenue_yoy, gross_margin…
和 revenue_growth 最相似的欄位有 revenue_yoy, revenue_qoq

下一步直接被導正。

每個失敗訊息都是引導模型再次做對的好機會

連「成功」都可以回傳更多狀態資訊

❌ 陽春的成功 flag

{"success": true}{"count": 0}

  • 查詢成功但 0 筆,是真的沒有結果,還是查詢不正確?
  • 是改了幾筆,也看不出來

✅ 回傳更多狀態資訊

把規模與範圍寫清楚:

  • 影響幾筆、動了哪些欄位或區塊
  • 有沒有碰到不該碰的

更多資訊,Agent 才有依據判斷「這次結果合不合理」,是否要修正

錯誤要設計,成功也要設計。一個陽春的成功 flag,也可能是「假完成」的訊號

工具回傳的引導訊息

各種純運算式(Computational)的檢查,回傳的是對應的固定訊息:

def collect_feedback(output, source):
    # 純運算式檢查:規則直接判定,不靠 LLM,沒過就回寫死的固定訊息
    msgs = []
    if count_words(output) > 500:
        msgs.append("摘要超過 500 字,請縮短")
    if missing_required_terms(output):
        msgs.append("漏掉必留的專有名詞,請補回")
    if cosine_similarity(output, source) < 0.8:
        msgs.append("與原文語意偏離,請貼近來源重寫")
    return msgs

運算式檢查(固定訊息)

事先寫死的固定字串:又快又穩又可重現。

語意 judge(當場生成)

若沒辦法用純運算式的檢查,也可用 LLM 當 judge,附上回饋的 reasoning 理由。

設計回傳值的另一個重點: 需要有意識地控制 context window

注意控制別塞滿 context。context 過了某個門檻,模型會變笨(context rot)

別忘了 Context Engineering 的整套策略,各種縮減 context 的技術:

Context Offloading

硬性工具輸出上限頭尾保留 (切頭切尾)、卸載到檔案 (只留預覽 + 路徑,有需要 Agent 再打開看)

檢索技術

關鍵字、向量檢索、reranker 等,只挑選相關的 context

Sub-Agent

龐大的中間過程交給 sub-agent 在獨立 context 跑,只回傳結論

案例: 知識庫 RAG Agent

知識庫問答 Agent 會配一個 search_knowledge(query) 工具 (關鍵字搜尋+向量搜尋 等)

工具不只回傳搜尋結果,我們還可以回傳以下資訊,回饋給 Agent 更多資訊:

1️⃣ 標註來源與分數

回傳時標上來源和相關度分數,讓 Agent 有依據判斷哪些該引用、哪些該丟

2️⃣ 同源就 load 整頁

好幾個 chunk 都來自同一份文件 → 暗示整份相關。可以指示 Agent 直接把整頁讀回來,比散落片段好用

3️⃣ 看見 top-k 以外的資訊

回傳不只 top-k 搜尋結果,還夾帶整個資料集的統計

工具回傳除了 top-k,還夾帶統計與指示

<results query="API timeout issues">
  <ticket id="LIN-1247" status="Done"></ticket>
  <ticket id="LIN-1189" status="Done"></ticket>
</results>
<facets>
  <status_facet> <value name="Done" count="6"/> <value name="Open" count="5"/> </status_facet>
</facets>
<system-instruction>
  回傳的 2 筆全是 Done。facets 顯示另有 5 筆 Open 沒進 top-k,請改用 search(query, status="Open") 追查進行中的問題。
</system-instruction>

<facets> 揭露隱藏資料

告訴 Agent:符合的不只你看到這 2 筆,還有 5 筆 Open 沒進 top-k

<system-instruction> 額外的指示

直接在工具輸出裡告訴 Agent 下一步該怎麼搜

語意 judge: 把回饋交給另一個模型

呼叫另一個模型做 review,把回饋當 tool response 帶回來。從主迴圈看,這仍是一次普通的 tool call。

@function_tool
async def consult_model(question, files, model):
    """遇到難題、想確認方向、或要 review 產出時呼叫,
    交給另一個模型給獨立回饋。"""
    ...

例如: RAG Agent 生成答案後,用另一個模型檢查有沒有幻覺。

案例: Claude Code + Codex plugin

這種做法在 coding agent 上也蠻常見

/codex:review: Claude 把本地 git 改動交給 Codex(GPT) 做 code review,並說明「只做 review、不准順手改」。一個寫 code、一個分析審查。

這是人工觸發,也可以寫進前饋規則,說明「在流程中何時、遇到哪類情況就呼叫」

工具層 Harness 的設計原則

1️⃣ 能確定性檢查最好

例如 SQL 語法驗證用 SQLGlot,又快又穩

2️⃣ 語意判斷才用 LLM Judge

細緻品質好不好沒有確定性 assert 可寫,
使用 LLM judge 補規則型檢查的不足

3️⃣ 回饋最好可行動

錯誤訊息要附「該怎麼辦」,不是只丟一個程式 error code。

4️⃣ 延遲預算內完成

工具層回饋在 tool call 內發生,要注意 latency,別拖慢整個迴圈。

PART 4 · 時機 ②

兩次 model request 之間,
把訊息注入執行中的 agent

這個時機在哪:兩次 model request 之間

一輪 (Turn) 不是「一問一答」,而是「模型 request → tool calls → 模型 request → …」反覆,直到輸出答案。注入就發生在這個迴圈內部、還沒輸出答案前:

一輪 Turn (agent 還在進行中) ↓ 在這裡注入訊息 (人 steer 或程式) 模型 request 1 🔧 tool calls 模型 request 2 🔧 tool calls 模型 輸出答案 (還沒到) 注入發生在每個「tool calls → 下一個 model request」之間 (圖中標記處) agent 還沒到「輸出答案」這一步,就把新訊息插進這一輪
不是等 agent 執行完才注入(那是時機③單輪結束),而是在它還在迴圈中間、還沒輸出答案時就插進去。來源可以是人 (steer),也可以是程式。

同一個注入點,兩種用途

Agent 還在反覆呼叫工具、還沒輸出答案時,就把新訊息插進去,馬上影響它接下來的動作

🧑 用途一: 人中途 steer

使用者就主動輸入一段話介入,叫做 steering 轉向/引導。

Codex、Claude Code 這類互動式 coding agent 最常見,是內建功能。

⚙️ 用途二: 程式注入

例如背景工具程式跑完送回結果、外部事件 (webhook、告警) 要讓 agent 知道。

目前較少框架實作,少數像 Pydantic AI 做成通用機制。

只能在 requests 之間: 這是 API 後端的限制

已經發出 tool calls 但還沒拿到結果,這時若添加 user message 回傳,API 會錯誤

❌ 不合法

assistant 發了 tool calls → 還沒等到所有工具結果 → 直接加 user message 回傳。下一個 request 送出就 400。

✅ 合法

assistant 發了 tool calls → 每個 call 的結果都補齊 → 再加 user message → 下一個 request。

OpenAI、Anthropic 模型發出的每一個 tool call 都必須先補上對應結果,中間不能插別的訊息。所以必須等當前 tool 全部執行完、湊成 API 合法狀態,才能在下一個 model request 之前注入你的訊息。

用途一: 人中途 steer

最常見的用途是人主動介入。steering 和 interrupt 都是 Codex、Claude Code 的內建功能。這跟 human-in-the-loop 不一樣:

🛑 Human-in-the-loop

刻意設計一個等待點,讓 agent 跑到那裡停下來問你 (最典型: 執行某工具前先請使用者確認)。

agent 停下來問你

🧭 Steering

agent 沒有等待點、也不打算停,是你在它還在執行時主動輸入 (通常因為「需求變了」)。

你主動介入

當用戶中途輸入訊息時,還可以細分兩種: steering 與 interrupt

🧭 不中斷: steering

訊息先排進佇列,等當前 tool calls 結果到齊、正要發下一個 model request 前才注入。

agent 沒中斷,只是下一步多了你的訊息,已建立的 context 全部保留

🛑 強制中斷: interrupt

取消正在執行的工具,沒答完的 tool call 硬塞 tool_result,內容是固定字串 aborted ,維持對話 API 合法。

用途二: 程式注入

用途常見有:

🔧 背景工具結果

長時間工具在背景跑完,把結果送回 agent。

📡 外部事件

webhook、錯誤告警、聊天平台訊息主動送進來。

有提供這個注入點的框架不多: OpenAI Agents SDK、Google ADK 都沒有。少數例外是 Pydantic AI v1.101.0(2026 年 5 月)的 enqueue,兩種模式: asap(盡快插入,就是這篇的時機點)與 when_idle(整輪結束後才插入)。

背景工具結果怎麼送回 agent

它分兩步:

第一步: 當工具被呼叫時

tool call 後不等跑完,馬上回 tool_result,內容是固定的:

Tool 'X' is running in background (task N). You will receive the result automatically when it completes.

第二步: 當背景任務完成時

只能用 user message 插入:

Background tool 'X' (task N) completed. Result: …

注意不能用 tool_result 訊息了,因為 API 的 tool call 跟 tool result 是一對一配對的。

PART 5 · 時機 ③

單輪結束的
Goal 與 Outcomes

單輪結束的時機 ③ Agent 連續呼叫工具後,最後輸出文字答案時

④ 外層 Loop · 每個 session · 分鐘~小時 · 修正整個任務 ③ 一輪 Turn · 秒級 使用者輸入 模型 request 1 🔧 tool calls 模型 request 2 🔧 tool calls 模型 輸出答案 ② request 之間注入 (人 steer 或程式) ① 工具執行內 · 修正單一動作 Stop hook 沒過 → 同份 context 再跑一輪 一輪 (Turn) = 多次「模型 request → tool calls」反覆,直到模型輸出答案 ④ 通過後這個 session 收掉,換上全新 context 再跑一圈

設計 Goal 可驗證的停止條件,強迫模型自動再一輪

給 Agent 一個目標:

  • 希望的最終狀態是什麼
  • 用什麼證據驗證
  • 有哪些限制要遵守

讓 Agent 持續修正,直到通過為止。

這是 Codex 和 Claude Code 的內建功能。

核心精神

不能因為「模型覺得大概做完了」
就算數。

完成與否,要對著停止條件驗證,
沒過就繼續做。

Goal 合約模板

好的 Goal 不一定是更長的 prompt,而是一份精簡的契約:

/goal <desired end state>                 ← 期望的最終狀態
      verified by <specific evidence>     ← 用什麼證據驗證
      while preserving <constraints>.     ← 同時要保住什麼
Use <allowed inputs, tools, boundaries>.  ← 允許的工具與邊界
Between iterations, <how to choose the next best action>.
If blocked or no valid paths remain,
      <what to report and what would unlock progress>.
範例:「將 p95 latency 降到 120ms 以下,用壓力測試做驗證,並保持測試套件都要通過」

🤖 讓 AI 幫你寫:任務夠清楚時,直接 Help me turn this into a strong /goal: <任務描述>

不適合用 Goal 的時候

❌ 完成條件模糊

  • 「把這個變得更好
  • 重構這段程式碼」

沒有可靠的完成條件,

✅ 先定義,再開工

  • 預期的最終狀態
  • 驗證用的測試
  • 要保住的限制

定義不出來?那問題不在工具,
在你還不知道自己要什麼。

使用者的角色轉變: turn → round

藏在 Goal 背後的,是交付物的轉變:

  • 你交付的不再是一句 prompt,而是一份「目標 + 邊界」的契約
  • 然後讓 Agent 持續去跑: prompt → 判斷完成沒 → 再 prompt 讓 agent 繼續做
  • 思考單位,從「一次對話 turn」換成「一輪工作 round/loop

那這迴圈怎麼判斷「做完了沒」?

有各種不同實作,讓我幫你分析。

深入研究三種產品實作,沿著「驗證的 Judge 有多獨立」來看

Codex 的 Goal

主模型自我審計,自己呼叫 update_goal 宣告

Claude Code 的 Gooal

每輪結束,交給獨立的 Haiku 小模型裁決

Claude Managed Agents 的 Outcome

由獨立的 grader agent 拿 rubric 評分標準,去檢查產出物做驗收

實作一: Codex /goal,沒有裁判的自我審計

Codex 沒有第二個模型在做判定,是自我審計

Agent loop 像是確定性狀態機

  • 當判斷完成時,主模型呼叫 update_goal(complete)更新狀態
  • 如果狀態還是 Active,就重新注入同一份 continuation.md prompt 強迫 Agent 繼續跑下一輪

判定者就是主模型自己

  • 完成 = 模型呼叫 update_goal(complete)
  • Agent 帶著完整的對話紀錄和推理脈絡繼續下一輪

Codex /goal:自我審計迴圈

update_goal(complete) ✅ 注入 continuation.md 每輪同一份合約 prompt 主 agent 跑一輪 推理 + 工具呼叫 自我審計 達成目標? 否: 沒呼叫 update_goal → thread idle 且 goal.status = Active → 再注入 判定者就是主 agent 自己, 全程沒有第二個模型

Codex 怎麼防「過早宣告完成」

判定權在主模型手上,Codex 用 prompt 要求以「當前 worktree 與外部狀態」去自查

Tool description

update_goal 的 description 寫好寫滿:

Set status to complete only when the objective has actually been achieved and no required work remains.

每輪注入的 Continuation prompt

要求模型逐項找證據:

"treat completion as unproven and verify it against the actual current state"
"The audit must prove completion, not merely fail to find obvious remaining work"

每輪注入的 prompt 都一樣 (只有 Budget 數字不同)

別只看名字,要看實作

流傳的誤解

有些技術文章寫: Codex 的 Goal「用一個獨立小模型每回合評分」

翻原始碼跟文件才知道

沒有第二個 model、沒有額外的 grader

harness 的實作細節,不能靠幻覺想像那是怎麼做的

實作二: Claude Code 的 Goal,獨立 Haiku 讀刪減 transcript

Claude Code 把判定交給另一個模型。當主迴圈(Opus)輸出答案時,harness 不交還控制權,而是發一個 request 把整段對話交給一個獨立小模型來審計 (類似 fork):

Based on the conversation transcript above,
has the following stopping condition been satisfied?

<stopping condition>

Answer based on transcript evidence only.

⚠️ 注意: 這只會看對話紀錄,審計是不會呼叫工具打開檔案、實際檢查 artifact 產出物

Claude Code /goal 的三個細節

獨立的小模型

預設 Haiku,用另一份 system prompt

transcript 是重組副本

保留對話紀錄、工具呼叫紀錄,移除 thinking、移除整包 claudeMd 環境、tool metadata 等

structured output

回覆 {ok, reason, impossible},包括回饋理由,以及是否不可能辦到(此時應該放行,避免無窮迴圈卡死)。

判「是」

目標完成,把最後答案輸出給你

判「否」

擋下,把 Haiku 寫的 reason 注入主 agent,強迫跑下一輪

Claude Code /goal:Haiku 裁判流程

主 agent 跑一輪 (Opus) 自認達成, 要結束 Stop hook 攔下結束 複製刪減版 transcript (剝除 thinking) 獨立 Haiku 裁判 另一個模型, 只讀 transcript ok: true ok: false 目標完成, 交還控制 ✅ goal 達成 reason 注入回主 thread 針對性診斷 → 主 agent 繼續下一輪

判「沒完成」之後,兩家差在哪

Codex /goal Claude Code /goal
回饋形式 重播同一份 continuation.md,只有 budget 數字在動 Haiku 寫的針對性診斷,指出 transcript 缺了什麼
下一步依據 環境證據(測試失敗、compile error等)+自己保留的 reasoning 外部裁判指出缺口
成本代價 每輪多累積一份 prompt,但會有 prompt cache 每輪多一次 Haiku call,主 thread 只增加一小段 reason
失效模式 模型有盲點時無外部視角打破,可能連錯好幾輪 Haiku 誤判:會被自信的收尾語言騙過

實作三: Claude Managed Agents 的 Outcome

第三種最為獨立,獨立 Agent 拿著 rubric 操作 artifact 做檢查:

  • Grader 在全新 context window:只拿 rubric 與產出物,看不到主 agent 的推理與敘事
  • 不只「看」:而是有工具操作,可以像真實使用者實際操作 artifact 產出物,開檔、點 UI、打 API、查 DB 等
  • Rubric 逐條可評分;沒過就帶著逐條缺失進下一輪
  • max_iterations 預設 3、最多 20

Rubric 評分條件 範例

# Outcome: 研究報告完成
- [ ] 涵蓋 7 項必查數據,各附來源
- [ ] 每個引用 [n] 連到有效 URL,
      且原文逐字支持該主張
- [ ] 財務數字出自 10-K / 10-Q 正式文件

Outcome:獨立 grader 操作 artifact

主 agent (generator) artifact (檔案 / app) 獨立 grader agent 全新 context + rubric 產出 拿 rubric 操作 點 UI / 打 API / 查 DB satisfied needs_revision 交付 ✅ 逐條缺失回饋 主 agent 再改一輪 裁判完全獨立: 不看 transcript, 直接對成品逐條驗收

相比自評,獨立驗收是最準確的

Agent 會自我吹捧

要 agent 評自己做的東西,它傾向自信地稱讚,哪怕在人眼中品質明顯普通。

而且 context 裡的錯誤推理會不斷累積,前面說服了自己「方向對」,後面就一路錯下去。

問題在於「誰來批判」

同一個 agent 較難對自己的產出下得了手,換一個全新 context 獨立評審,比較容易做出準確的 Judge。

「調出一個挑剔的獨立 evaluator,比教會 agent 自我批判容易得多。」

學界研究表示: 越獨立、越會動手,判定越可信

自我評審

  • 純自我修正: 缺乏外部回饋時容易失敗
  • 只讀文字的 judge: 偵測假性完成(false success)能力有限,容易被「自信的收尾語言」帶著走

獨立評審

  • 環境/執行回饋: 看測試與執行結果,不看語言宣稱
  • rubric 分解: 把驗收拆成逐條標準
  • Agent-as-a-Judge: 能讀檔、跑指令的裁判,可靠度接近人類
越往獨立、越會實際操作的那端,判定越可信。

三種實作的總比較

Codex 的 Goal Claude Code 的 Goal Claude Managed Agents Outcomes
誰來判定 主模型自我審計 獨立的 Haiku 全新 context 的 grader agent
harness 角色 不判斷,閒置時重播合約 prompt 每輪結束送 transcript 裁決 自動配置 grader 評估迴圈
看什麼證據 自己 context 裡的一切(含 reasoning) 刪減版 transcript 只看 artifact,實際操作驗收
怎麼宣告完成 主模型呼叫 update_goal yes/no +診斷 reason rubric 逐條 pass/fail
沒完成時的回饋 沒有診斷,只重播同一份模板 一段針對性診斷,指出缺什麼 逐條列出缺失,最具體
獨立性: Codex Goal < Claude Code goal < Managed Agents Outcomes

但是對工程師來說,一切都有 tradeoff: 成本和獨立性的代價

獨立性換來可靠度,但要付出代價。差別不只是「單次評估多少錢」,也要看「錯誤多久才被發現」

獨立性/可靠度 單次評估成本 錯誤多久被發現
Codex 自我審計 低:主模型自評 趨近零:只查狀態 靠模型自己就先發現
Claude Code Haiku 中:獨立小模型讀 transcript 小:約 1-2 秒 每 turn 一次
Outcome grader 高:獨立 agent 操作 artifact 高:數十倍、約 8 分鐘 整個 iteration 做完才抓到
越獨立越可靠,但需要用到更多 tokens 來分析,錯誤也是在整個流程中越晚被發現,導致總成本較貴也較慢

OpenAI Codex goal 為什麼不用獨立裁判?

有兩層可以裁判:

  • harness 層: 用獨立裁判,就像 Claude 作法
  • 模型層: 要靠模型本身的驗證、自我審計能力行不行

我個人推測

  • 我推測 OpenAI 有特別加強 update_goal 的 post-training 模型訓練,強化模型自我審計的能力
  • 比較節省執行 tokens 的總成本
兩家方向不同: OpenAI 偏向加強模型訓練 goal、把自評 prompt 寫好。Claude 則用 harness 層的獨立裁判來做。

如果是自行開發 agent,該怎麼選

自我審計(Codex 式)

調教難度較高。高度依賴模型的自律,一般模型容易過早宣告完成。

適合: 重視 Latency 和成本的中短任務。

Transcript 裁判(Claude Code 式)

折衷做法。小模型判 transcript,好實作、好評估(輸入輸出都是文字)。

適合:中程任務,在 transcript 中就能看到可信的證明。

獨立 verify(Outcome 式)

效果最好,但成本最高、latency 是最大弱點。每次驗收要把 artifact 跑起來操作。

適合:長時間、以交付物為終點,價值高到值得花評估開銷。

綜合案例: 使用者訪談 Agent,結合兩家的做法

需求: 按訪綱逐題訪問用戶

挑戰: 但什麼時候該換下一題?這題問夠了沒?

模型會偏向「覺得差不多了就想往下走」,跟第二篇的過早宣告完成是同一個問題,只是這裏是「這一題問完了沒」。

我的做法

  • Claude Code 的 transcript judge 把關「這題問夠了沒」
  • Codex 每輪重新注入 prompt 的做法,讓訪談持續往前

借 Claude Code 的做法: 提供換題工具,裡面做 transcript judge

agent 想跳下一題時,呼叫 switch_next_question_workflow 工具,裡面是一個獨立 Judge 審核:

@function_tool
async def switch_next_question_workflow(reason: str, user_requested_next: bool) -> str:
    """當你判斷目前這題已取得足夠答案、或使用者要求跳題時呼叫。"""
    # 真正的判定在 server 端,工具只是把請求轉過去
    ...
prompt 寫說:「回傳 Y/已切換才代表進到下一題」、「回傳 N 你 MUST 繼續聚焦同一題,換問法追問」

Judge 看什麼: 每題有不同的 rubric,根據逐字稿判斷

不同題目有不同的完成標準(rubric),用小模型根據逐字稿來判斷:

QUESTION_WORKFLOW = [
  { "title": "最近一次使用情境",
    "completion_criteria":
      "需含最近一次使用的具體情境,"
      "至少提到使用的功能與當時任務。" },
  { "title": "替代方案",
    "completion_criteria":
      "需提到至少一個替代方案,"
      "最好指出最常用者與原因。" },
  # …其餘題目
]
You are a user interview quality reviewer.
Use only the transcript below. Do not infer
facts that are not in the transcript.

Current question: {question}
Completion criteria: {completion_criteria}
Transcript: {transcript}

Return exactly one character:
Y if complete. N if not.

沒過時的回傳值: 還是要可行動

Judge 回 N 時,工具不是只回一個 false,而是回一段可行動的指令,順便附上這是第幾次被退:

N: 仍停留在第 1 題「最近一次使用情境」。這是第一次追問。
請換一種問法追問目前這題,不要切換題目。

借 Codex 的做法: time_control 每輪注入動態狀態

每輪推動 agent 往對的方向走: 「現在過幾分鐘了、第幾題了」的狀態也傳給 Agent

<time_control>已過 7 分鐘 / 共 15 分鐘</time_control>
<current_question>第 2 / 5 題: 題目....</current_question>
每輪動態注入當下狀態,提醒目前在哪一題,以及用這個訊號調節奏:時間充裕就從容追問,時間不夠了就加速減少追問。

訪談 Agent:time_control 推進度,Judge 把關

time_control: 每輪注入動態狀態 (時間 / 題號) Codex 式 · 前饋: 給模型它自己算不出的當下狀態 訪談 agent 跑一輪 逐題問答 · 判斷這題問夠了沒 獨立 Judge · 只讀 transcript + 該題 rubric Claude Code 式 · 回饋: 把關「這題能不能換」 進到下一題 ✅ harness 推進到下一題 留在本題, 換問法追問 回傳可行動指令 + 第幾次被退 影響何時換題 想換題: 呼叫 switch 工具 Y: 切換 N: 留本題 下一輪 退 3 次 / 使用者喊跳 → 強制放行 time_control 推進度, Judge 把關: 一前一後讓限時訪談問得深又跑得完

PART 6 · 時機 ④

外層 Outer Loop

Agent 輸出一輪完整答案之後 ④ 外層 Harness

④ 外層 Loop · 每個 session · 分鐘~小時 · 修正整個任務 ③ 一輪 Turn · 秒級 使用者輸入 模型 request 1 🔧 tool calls 模型 request 2 🔧 tool calls 模型 輸出答案 ② request 之間注入 (人 steer 或程式) ① 工具執行內 · 修正單一動作 Stop hook 沒過 → 同份 context 再跑一輪 一輪 (Turn) = 多次「模型 request → tool calls」反覆,直到模型輸出答案 ④ 通過後這個 session 收掉,換上全新 context 再跑一圈

為什麼需要外層迴圈?

三種情況

  • ① 單一 context 能力有限: 大任務得拆段,每段用乾淨 context 重新開始、表現不受前一段影響(塞滿、失敗推理污染、Goal 跨不過 session)
  • ② 是另一個不相關的新任務: 本來就該各自開乾淨 context,並管理多條平行的 agent
  • ③ 要由外部事件自動觸發: webhook、新郵件、排程、CI 失敗一來就啟動

共同的解法

需要一個在單輪 agent 之外的工程迴圈,也就是 外層 harness

它決定何時觸發、每件事開獨立 agent、多條 agent 怎麼協調。

進度不靠 context 記憶,會寫到檔案系統共享。

思路: 設計提示 Agent 的迴圈

這一層最近在社群很熱門:

  • 龍蝦爸 Peter Steinberger:「你不該再去提示 agent,你該設計提示 agent 的迴圈」講了好幾個月
  • Claude 的 Boris Cherny、Andrej Karpathy 大神也講過類似的話
  • 最近出現 loop engineering 新詞

具體來說

其實就是強調 Outer loop (Outer harness) 這一層,讓我們看具體實作案例,拆解給你看

參考: Peter Steinberger: You should be designing loops that prompt your agents.

外層 Loop 的三種實作案例

🔁 Ralph

bash 蠻力重跑

每圈全新 context,同一份 prompt 反覆送進去直到做完

🎼 OpenAI Symphony

看板協調器

專案管理工具當控制平面,每張開啟的 ticket 配一個 agent

⏰ 自動排程

定時觸發

時間到就跑一輪;依 context 是否沿用,再分「獨立」與「heartbeat」兩種

Ralph:最笨也最有名的 Loop

while :; do
  cat PROMPT.md | claude-code
done
  • 一個 bash 無窮迴圈,每圈把同一份 prompt 再送進去一次
  • 每一圈都是全新的 context:每圈歸零,只從固定幾份檔案重新讀起
  • 完成才跳出:當 AI 認為所有任務都完成,輸出 COMPLETE 代表完成,就脫離無窮迴圈
出處: ghuntley.com/ralph(2025 就有了)

跨圈記憶: 進度全靠外部狀態

Ralph 拆成三個檔案:

📜 git history

完成的工作就是 commit,

新 agent 開圈先看歷史

📝 progress.txt

每圈追加學到的事:

陷阱、模式、決策

☑️ prd.json

任務清單與 passes 狀態:

每圈挑最高優先且未完成的

ralph 的每一圈:

讀 prd.json/progress.txt → 挑最高優先尚未完成的 story → 只實作這一個 → 跑 typecheck 和測試 → 過了 commit 標記完成 → learning 追加進 progress.txt → 下一圈。

Ralph:一圈的樣子

每圈結束 → context 整個丟掉, 開全新一圈 prompt.md 每圈用同一份 全新 context 的 agent 乾淨的 context, 跑一圈 挑一個 story 做 過 typecheck/測試才 commit 檔案狀態 (跨圈不丟) git history · progress.txt · prd.json ① 開圈先讀 ② commit、 記下學到的

Claude Code 的 ralph-wiggum Plugin: 別只看名字,要看內部實作

名字叫 Ralph,但讀完 code,它的機制跟原版不同:

原版 Ralph

bash 外迴圈,每圈整個重來:全新 context、靠檔案傳遞進度。是「換新 context」的設計。

ralph-wiggum plugin

Stop hook同一個 session 內攔住結束,進行完成判定。

「同一條 thread 延續」+「完成與否主模型自己決定」= 其實是 Codex /goal 作法,而不是原版 Ralph。

對 Ralph 的批評

  • 無狀態重跑: prompt 每圈不變,progress.txt 只是軟性筆記、缺結構化記憶
  • 暴力跑,收斂困難: 弱模型的權宜之計,靠大量 token 硬做、可能把關不足
  • 執行成本: 可能卡住一直耗 token
心得: 驗證 (goal) 應該在內層 harness 就要做好,而不能只靠外層一直重跑。只依靠外層既耗 token,也很難對大範圍做好驗證。

OpenAI Symphony: 把專案管理系統變成 Agent 控制系統

OpenAI 開源的 harness 外層系統(以Spec形式): 以任務為中心,將 Linear 當做控制平面,每張開啟的 ticket 都有一個 agent 在自己工作區跑(有新 ticket 就派工)

專案看板就是狀態機

  • ticket 狀態驅動:進 Todo 派 agent、進 Rework 帶 review 重做、進終態收掉
  • 任務 DAG:沒被 block 的就開 agents 平行跑
  • agent 自己開 ticket、交付 proof of work 成果(CI、review、示範影片等)

人管理的是「工作」,不是 code

  • 有些 ticket 純調查分析,從頭到尾不碰 codebase
  • Agent 的目標不只是「寫完 code」,而是要「說服人類把這段程式碼合併」

Symphony:看板就是狀態機

🎼 Symphony: 看板當控制平面, 每張開啟的 ticket 都配一個 agent 在自己的 workspace 跑 Todo In Progress Review Done TICKET-12 待派工 TICKET-13 待派工 TICKET-9 🤖 agent A 實作中 TICKET-10 🤖 agent B 實作中 TICKET-7 PR + 證明影片, 等人審 TICKET-3 ✓ merged ticket 狀態由左往右流動 = 狀態機; 沒被 block 的各配一個 agent 平行跑

自動排程(cron): 最輕量、最通用的觸發

設定觸發條件,條件一到就自動把一段 prompt 丟出去跑一輪。

Claude Code、Codex 都已內建/loop、Routines、Automations),設定就能用,是最容易上手的。

觸發的節奏

  • 定時: cron 排程,時間到就跑
  • 動態: 讓 agent 自己決定下次何時跑
  • 事件: webhook、新郵件、CI 失敗才觸發

例如

/loop 5m 檢查 deploy 狀態,失敗就修        ← 固定間隔
/loop 盯著 CI,紅了就處理                  ← 動態間隔:模型自己決定

設計重點: 要不要沿用 context ?

每次獨立 context

每次開全新的 agent。乾淨 context、進度靠外部狀態。

例如 Codex 的 standalone automation 模式 、Claude Code 的 Routines 功能

沿用 context: Heartbeat

把 prompt 打到同一個長駐 session。記憶連續、反應快,但 context 會持續變大。

例如 Codex 的 thread automation 模式、Claude Code 的 in-session /loop功能

兩種觸發:獨立 context vs heartbeat

cron 觸發 時間到就跑 開新的 回同一條 每次獨立 context (cron + headless / 雲端排程) t1 全新 run 乾淨的 context t2 全新 run 乾淨的 context t3 全新 run 乾淨的 context 各自了結, 結果送出後 context 就丟掉; 進度靠外部狀態傳遞 Heartbeat: 沿用 context (/loop · thread automation) t1 t2 t3 同一條 session 一直活著 context 每次都更長 →

Loop 和 Goal 可以一起用

管什麼 回答的問題
外層 Loop scheduling 排程 什麼時候跑、多久跑一次
Goal termination 終止 做到什麼程度才能停

作法一

排程內的 Agent 就直接用上 Goal 把事情做完

作法二

在排程內,把工作丟到某個 queue 就結束。另外有真正做事帶 goal 的 Agent 去執行

案例: 龍蝦爸爸的 Loop 自動維護 Repo

Steinberger 開源的 maintainer-orchestrator skill 每隔 5 分鐘醒來執行

🕰️ Cron + Orchestrator 協調分配任務

  • orchestrator 本身只當控制平面:定時檢查、派工、監控、需要時問人決策
  • 每 5 分鐘 heartbeat 醒來讀各 worker 現況
  • 實作全部下放給平行跑的 worker thread;worker 不准再往下委派

🗂️ 先過一道 triage 分類

github-project-triage 把進來的 queue 分三類:

  • Autonomous:可重現、有界、可驗證 → 直接派工
  • Needs owner:產品決策、安全、缺權限
  • Defer/close:過期、重複 → 附證據處置
出處:@steipete(2026/6),skills 開源於 agent-scripts

外層 Loop 核心三個問題

1️⃣ 怎麼被觸發

固定 cron、動態間隔,還是事件(webhook、新郵件、CI 失敗、看板多一張 ticket)?

2️⃣ 醒來看什麼

要讀哪些 context 之外的狀態,才知道進度到哪、有沒有新工作?

例如 Ralph 讀 git/progress.txt、Symphony 讀專案看板等等

3️⃣ 結果送去哪

開 PR、寄一封簡報、丟進 triage 收件匣,還是安靜歸檔?

loopcraft: 由內到外五層巢狀迴圈,從 token 到開放探索

出自 Shawn "swyx" Wang 電子報,其中 loop engineering 最想強調的是第 ④ 層 MetaLoop(生迴圈的迴圈)

PART 7 · 進階

自我改進的
Harness

把「改 harness」這件事交給 agent

連 harness 本身,都讓 agent 自己改。 讓 agent 根據自己跑出來的 trace 與 eval,回頭改自己的 harness,包括 system prompt, skills 甚至 code 。

自我改進不是讓 agent 想改什麼就改什麼

需要在 eval、trace、版本控制、regression test 的限制下,提出可驗證的變更。

不然,「自我改進」和「把 harness 改壞」就分不出來了。

📡 方法一: 讀 Production Traces

🔧 方法二: 用 Agent 當優化器改 code

📚 方法三: Self-Improving 改 Skills

💡 詳見 blog.aihao.tw 文章: 自我改進 Harness, Meta-Harness 與爬坡

PART 8 · 收尾

會過期的 Harness

Model-Harness-Fit

模型一升級,harness 會怎樣?

🔗 沒有一套 harness 適用所有模型

  • 同一套 harness 換個模型,效果不一樣
  • 小模型要更複雜精巧的 harness,大模型需要的 harness 可以較輕薄

⏳ harness 會過期

模型每次變強,某些當初補強它的元件就不再有用,該被移除。

每次升級時可以檢查之前的 prompt 約束、workflow 還有必要嗎?

Terminal-Bench 2.0 排行榜排的不是「模型」,而是「harness + 模型」的配對。同一個模型配不同 harness,分數差好幾個百分點,差距甚至大過一個模型世代的升級。

設計 Harness 架構時,應考慮模型升級

⏳ 會過期

各種 harness 做法與補強措施

Bitter Lesson: 能隨算力擴大的通用方法,終究勝過手工規則。很多會隨更強的模型逐步不再需要。

♾️ 不會過期

定義「什麼叫做好」+ 驗證

就算模型強到能完美自我驗證,它驗證的,仍然是一個「由你定義的目標」。定義什麼是「好」,是無論模型多強都得自己做的核心。

Harness 應該設計得容易替換元件、更容易測量性能: 模型一變強,你才拆得掉。

💡 詳見 blog.aihao.tw 文章: 會過期的 Harness, Model-Harness-Fit 與 Bitter Lesson

PART 9 · 動手做

自建 Agent 的
框架選型

該從哪個開發框架開始?

路線一: 從功能完整的 Deep Agent 開始

起點高: 一開始就有能跑的 agent,但相對不好改。

✅ 優點: 馬上能跑;harness 原廠針對自家模型調過。

⚠️ 缺點: 會帶用不到的 context/工具;可控性/可維護性受限;常綁特定供應商。

路線二: 從基礎構建

起點低: 要自己接的多,但彈性與可控性好,能一步步朝想要的設計走。

✅ 優點: 完全可控,貼著任務分布拿掉無關 context/工具;model 無關、好換供應商、好控成本。

⚠️ 缺點: 前期工程量較大。

框架舉例

路線一: 全套 Deep Agent

路線二: 從基礎構建(opinionated 高 → 低)

那到底該選哪個?

🔹 特定情境/規模大

特定情境,或使用者多 → 從基礎構建。貼近單一任務分布的 vertical agent 更有效率: token 成本低、延遲低,也能換供應商、精算成本。

🔹 自用/內部開發

要打造團隊用的 harness 與 outer loop → 從現成 deep agent

要的本來就是強的通用開發 agent,原廠已調好內層,先有能跑的東西、疊上 outer loop 最快。

🔹 想用訂閱帳號

要讓使用者帶自己的 ChatGPT 帳號 → 看 Codex SDK 或 Codex app server

支援訂閱帳號登入,不必 API key 計費;Claude Agent SDK 第三方只能用 API key。

💡 詳見 blog.aihao.tw 文章: 自建 Agent 的框架選型: 全套 Deep Agent 還是從基礎構建?

CONCLUSION

總結

Takeaways

給 Agent 開發者的駕馭工程 系列九篇

  1. Part 1|六項 Deep Agent 能力
  2. Part 2|Harness = 在執行迴圈裡約束、檢查、修正;agent 要回饋迴路,不是完美 prompt
  3. Part 3 · 時機①工具裡閉合最小迴圈: 驗證、改寫、回傳值夾帶指示
  4. Part 4 · 時機②request 之間注入: 人 steer/interrupt,或程式注入背景工具結果
  5. Part 5 · 時機③單輪結束驗收 Goal/Outcomes;三種 judge 不同實作分析
  6. Part 6 · 時機④外層 Loop 跨 session: Ralph/Symphony/cron,把自己移出迴圈
  7. Part 7 · 進階|讓 agent 自己改自己的 harness
  8. Part 8 · 收尾|Harness 綁模型、會過期;不過期的是 Eval 與 Judge
  9. Part 9 · 番外|框架兩條路:全套 Deep Agent/從基礎構建
📚 歡迎到 blog.aihao.tw 看全篇內容。

Thank You

謝謝,請多指教 🙏