iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
AI Security

我也希望安全第一——然後我們看看這些鎖是怎麼一個個被撬開的系列 第 5

第 5 篇|Harness 實際能管什麼——工作指引、工具邊界與驗證流程

  • 分享至 

  • xImage
  •  

Harness 實際能管什麼——工作指引、工具邊界與驗證流程

[[我也希望安全第一]]|第 5/30 天

每次都問「可以嗎」,不一定比較安全

Claude Code 在 2026 年把 auto mode 設為部分付費方案的預設值時,Anthropic 公布了一組很反直覺的數字:在 1,053 名測試者的研究裡,自動防護攔下 89% 的有害動作,人工審查只攔下 13.6%。使用者批准了 97% 的權限提示。

實際看到這組數字的第一個反應是,人怎麼可能比自動檢查差這麼多。再想一下每天跳出的 cookie、手機權限和公司 VPN 警告,其實不難理解。確認視窗如果一天出現幾十次,很快就會變成通往下一步的按鈕。

這些比例來自 Anthropic 自己的研究,公開報導沒有完整交代測試設計,不能拿來證明 auto mode 在所有情況都比人安全。比較值得注意的是:把決策交給人,不等於已經設計好控制。

三個地方,管的是不同問題

沿用修程式的例子。Agent 收到「清掉舊的測試資料,讓測試通過」,接著準備刪除檔案。Harness 至少有三個介入點:

控制面 可以做的事 不能獨自保證的事
工作指引 要求先讀檔、避免碰 production、遇到歧義先停 模型一定會遵守,或不被後來的內容帶走
工具與權限 只提供 delete_test_fixture,限制路徑、帳號與動作 被允許的操作一定符合使用者實際意圖
驗證與流程 檢查 diff、跑測試、要求證據,高風險動作送審 Evaluator 自己不會誤判,或人工不會疲乏

三層放在一起,才比較像一套安全設計。

工作指引最便宜,也最容易修改。專案裡的 AGENTS.mdCLAUDE.md 可以要求「修改前先讀取」「不要碰正式環境」。它適合補工作習慣,卻仍然是送進模型的文字。模型忘了、誤解了,或者讀到另一段互相衝突的指令,檔案系統不會因此自動拒絕它。

工具邊界硬得多。如果 agent 只有一個會產生草稿的 invoice.create_draft,就不能直接呼叫 invoice.pay。ChatGPT Health 接上 Epic 電子病歷時採用唯讀存取,也是同一個思路:先讓模型讀取病歷、整理時間線,不讓生成內容直接寫回正式病歷。這會少掉一些自動化能力,卻也拿掉一整類寫錯資料的事故。

最後是驗證流程。模型說「完成」以前,Harness 可以要求它附上測試結果、diff 或 API 回應;Planner、Generator 與 Evaluator 也可以先約定完成條件,再開始執行。這對品質很有用。碰到付款、刪除或公開發布時,我不會讓另一個模型的「看起來沒問題」成為唯一授權。

決策點要放在模型外面

一個常見的誤會,是替 tool 寫了 JSON Schema,便以為權限問題也解決了。Schema 可以拒絕缺欄位或型別錯誤,卻不知道登入者能不能刪這筆資料,也不知道這筆資料現在是不是 production。

比較穩的路徑是讓模型只能提出請求,最後的允許或拒絕由外部程式決定:

Model proposes tool call
          ↓
Schema validation
          ↓
Policy decision ── deny/require approval ──→ Audit log
          ↓ allow
Tool adapter(使用受限身分)
          ↓
Downstream API/filesystem/database
          ↓
Result + evidence → Evaluator → User

這裡的 policy engine 可以是自己的幾個明確判斷,也可以是 Open Policy Agent(OPA)這類通用引擎。重點不是採用哪個 repo,而是 policy decision 和 enforcement 必須在模型無法改寫的位置。OPA 官方文件描述的分工也是服務先詢問政策,取得 allow/deny 後,再由服務本身執行決定;OPA 不會替呼叫端自動擋住請求。

如果 agent 能跳過 adapter,直接拿到 production token,前面的 policy diagram 只是簡報。

一份 tool contract 應該寫到什麼程度

MCP 的 tool 定義可以用 JSON Schema 描述輸入。現行規格也要求 server 驗證輸入、實作存取控制與 rate limit,client 對敏感操作應提供確認、timeout 和 audit log。Schema 是起點,實際合約還要補上授權、效果與失敗語義。

以刪除測試資料為例,我會讓模型送出這種請求:

{
  "tool": "test_fixture.delete",
  "arguments": {
    "fixture_id": "fx_2048",
    "expected_revision": 17,
    "reason": "replace invalid parser fixture",
    "dry_run": true,
    "idempotency_key": "task-781-fx-2048"
  }
}

工具端另外固定以下規則:

  • fixture_id 必須屬於目前專案與 test 環境,不能接受任意檔案路徑。
  • 先比對 expected_revision;資料已被別人修改就拒絕,不猜新的目標。
  • 預設只跑 dry_run,回傳將受影響的項目。
  • 執行刪除需要一次短效 approval token,而且 token 綁定同一個 fixture、revision 與使用者。
  • 重試相同 idempotency_key 不會再刪一次。
  • 結果回傳刪除筆數、資源 ID、政策版本與 audit ID,不能只有一句 success。

這些欄位有些是模型看的,有些是一般程式執行的。deny 規則、revision 比對和 token 驗證不應交給模型自行判斷。

def dispatch(call, actor, policy, tools):
    validate_schema(call)
    decision = policy.evaluate(actor=actor, call=call)
    audit(call=call, actor=actor, decision=decision)

    if decision == "deny":
        raise PermissionError("policy denied tool call")
    if decision == "require_approval":
        return {"status": "pending_approval"}

    result = tools[call["tool"]](**call["arguments"])
    validate_result(result)
    return result

這段 pseudo code 故意很普通。安全關鍵在於所有執行路徑都經過同一個 decision point,而不是再叫一個 LLM 猜准一點。

人工批准應該留給需要人判斷的地方

人工覆核不是沒用。它適合處理系統無法代替人決定的事,例如「要不要把這份報價寄給客戶」「是否接受這個不可逆的資料轉換」。它不適合拿來確認每一次讀檔、列目錄和重跑測試。

比較實際的做法是先分級:

read + bounded scope                 → 自動執行並記錄
write + 可回復 + 通過 policy         → 自動或批次覆核
外部傳送/權限提升/不可逆操作       → 明確的人類批准
未知工具、未知資源、政策服務失效      → fail closed

這樣做不會讓確認視窗消失,而是讓它重新有意義。半夜值班的人看到「將刪除 production 的 8,421 筆訂單」時,才有理由真的停下來看,而不是把它當成今天第87個 yes/no。

下一篇會把情境反過來:工具沒有被外部攻擊,使用者也沒有要求破壞資料,agent 為了把任務做完,仍然自己換了目標、找了憑證,甚至刪掉沒被點名的機器。那時候,問題就不只是 Harness 有沒有提供按鈕,而是模型如何理解「完成任務」。

本篇的鎖

  • 鎖是什麼:工作指引、工具能力邊界,以及模型外的政策與驗證流程。
  • 想攔什麼:Agent 在資訊不足時直接動手、使用超出任務所需的能力,或沒有證據便宣稱完成。
  • 破口在哪:文字指引可以被忽略;policy engine 若不在所有執行路徑上,或工具仍持有過大權限,規則就能被繞過。
  • 怎麼補:讓模型只提出結構化請求,外部程式統一做 schema、授權、批准與 audit;高風險工具採 dry-run、revision check、短效 token 和 idempotency key。

參考與來源


上一篇
第 4 篇|三個詞的演進:Prompt → Context → Harness Engineering
下一篇
第 6 篇|找不到 VM 1、2、3,它為什麼刪了 5、6、7?
系列文
我也希望安全第一——然後我們看看這些鎖是怎麼一個個被撬開的19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言