從問 AI 到用 Agent · 架構補充

Harness:把模型變成「值得信任的 Agent」的那層

同一顆模型,為什麼有人用起來又穩又可靠,有人卻一直失憶、亂跑、燒錢?差別常常在「Harness」——包在模型外面的執行框架,像廚房的水電,平常看不見,卻決定了整間店跑不跑得動。它不讓 AI 更聰明,而是讓 AI 值得信任。

🏗️ 它在五層堆疊的哪一層

flowchart TB
  L5["🧠 Brain / 模型 —— 負責推理(Claude · GPT · 本地)"]
  L4["🤖 Agent —— 真正在做事的(Claude Code · aider)"]
  L3["🔄 Workflow —— 編排與品質驗證"]
  L2["🔧 Harness —— 不失憶 · 自動帶規則 · 接管工具層"]
  L1["📋 SPEC —— 把需求變成可驗證的規則"]
  L5 --- L4
  L4 --- L3
  L3 --- L2
  L2 --- L1
  style L5 fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87
  style L4 fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
  style L3 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#17335e
  style L2 fill:#0ea5e9,stroke:#0369a1,stroke-width:3px,color:#04121f
  style L1 fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f
    

Harness 夾在「Agent 要用的工具」和「Workflow 的編排」之間。上面幾層決定「要做什麼」,Harness 管的是「做的時候不出事」。

🔧 Harness 在做什麼:一次工具呼叫,被它接管

Hook / 步驟 模型 攔截判斷 工具執行 擋下 / 結果
flowchart TB
  H1["① 對話開始 · SessionStart
自動載入規則 + 過去踩過的坑"]:::proc BRAIN{{"🧠 模型
帶著規則做決定"}}:::model DECIDE["Agent 決定要用工具
例如 npm test"]:::proc PRE{"② PreToolUse
這指令要改寫或擋下嗎?"} REWRITE["橋接腳本改寫
npm test → 只留 FAIL 那幾行"]:::proc BLOCK(["危險動作 → 直接擋下"]):::result TOOL["③ 實際執行工具"]:::infra POST["④ PostToolUse
記錄教訓 + 記帳 + 稽核"]:::proc H1 --> BRAIN --> DECIDE --> PRE PRE -->|一般指令 · 改寫瘦身| REWRITE --> TOOL PRE -.->|太危險 · 不放行| BLOCK TOOL --> POST --> BRAIN class PRE decision classDef model fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87 classDef proc fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#17335e classDef decision fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#4c1d95 classDef result fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d classDef infra fill:#e5e9f0,stroke:#475569,stroke-width:2px,color:#1e293b

關鍵在中間那道 PreToolUse:模型想跑什麼,先被攔下來。該瘦身的瘦身(例如一個測試吐一萬行,只留失敗那幾行,省 token 又不洗版),該擋的擋。原則:只動會洗版的噪音指令,一般讀寫別亂改,免得把 AI 真正需要的資料也砍掉。

🧱 三個職責

1記憶保存:不失憶SessionStart
每次對話開始,自動把「該守的規則 + 以前踩過的坑」注入模型的視野,不用你每次重講。把「天才但會失憶的實習生」變成記得住事情的人。
2規則自動生效:不用每次叮嚀紀律
公司/個人的做事規矩自動套用,不靠你每次重新交代。規則不會在對話中途被忘掉。
3接管工具層:攔截與改寫橋接腳本
在指令「真正執行之前」攔下來:改寫吵雜輸出、擋掉危險動作、記錄成本。工具怎麼被呼叫,由 Harness 說了算。

🪝 通用 Agent 的 Hook 點(照生命週期)

剛剛只放大看 PreToolUse 一個。實際上一個通用 Agent 框架,在整條生命週期處處都留了 hook 點——Harness 就是靠掛在這些點上接管一切。照 agent 從開機到關機的順序看:

Hook 點 模型思考 工具執行 Session 起訖
flowchart TB
  A(["▶ Session 開始"]):::result --> SS["SessionStart
載入規則 · 記憶 · 過去的坑"]:::hook SS --> UPS["UserPromptSubmit
你每送一則訊息 · 處理前"]:::hook UPS --> TH{{"模型思考
決定要不要用工具"}}:::model TH --> PRE["PreToolUse
工具執行前"]:::hook PRE --> TL["工具執行"]:::infra TL --> POST["PostToolUse
工具執行後"]:::hook POST -->|還要用更多工具| TH TH -->|這一輪回完| STOP["Stop · SubagentStop
主 / 子 agent 回完"]:::hook TH -.要權限或通知.-> NOTI["Notification"]:::hook STOP -->|下一則訊息 · 再一輪| UPS STOP --> PC["PreCompact
上下文壓縮前 · 存檔"]:::hook PC --> SE["SessionEnd
收尾 · 記帳 · 稽核"]:::hook SE --> EN(["■ Session 結束"]):::result classDef hook fill:#ccfbf1,stroke:#0d9488,stroke-width:2px,color:#134e4a classDef model fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87 classDef infra fill:#e5e9f0,stroke:#475569,stroke-width:2px,color:#1e293b classDef result fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
Hook何時觸發Harness 常做的事
SessionStart開一個新對話 / session載入規則、記憶、過去踩過的坑
UserPromptSubmit你每送出一則訊息(處理前)補上下文、擋不該問的、加提醒
PreToolUse每次工具執行前改寫吵雜指令、擋危險動作、記成本
PostToolUse每次工具執行後記錄教訓、檢查結果、格式化輸出
Notificationagent 要通知你時(要權限 / 要你注意)轉發到手機 / Slack、決定要不要打擾你
Stop主 agent 回完一輪驗收、稽核有沒有守規則、決定要不要繼續
SubagentStop子 agent 回完收子代理結果、彙整
PreCompact上下文要壓縮前把進度存檔,免得壓縮後失憶
SessionEndsession 結束記帳、稽核、把學到的寫回去

不同 Agent 框架的 hook 名稱會略有出入,但邏輯一樣:開場 → 每輪對話 → 每次工具 → 通知 → 收尾,每個轉折都留一個掛勾。你掛得越準,Harness 就越能在對的時機接管,而不用改動 Agent 或模型本身。

🎯 為什麼重要

1沒有 Harness 會怎樣失控
AI 表面「做好了」其實悄悄降級了安全設定;一個測試吐一萬行把 token 燒爆;五分鐘前交代的規則中途就忘;出事沒有紀錄可查。
2有 Harness 之後可信
不失憶、自動帶規則、接管工具層、每個動作有帳可查。Harness 不是讓 AI 變聰明,是讓它從「聰明但靠不住」變成「可以放進正式工作」。
3它跟前面幾塊的關係底層基建
MCP 給 Agent 工具、Skill 固化流程、記憶讓它記得住——這些能穩定運作,底下都靠 Harness 這層水電在撐。它是把單次能用,變成「天天可靠」的地基。