跳至主要內容

human in the loop AI agent guardrails approval

實作

人工審查:把核准內容保存下來,再恢復工作

規則檢查放在外部操作邊界,保存待審資料包;授權審查者決定後,只能恢復原本那個精確執行。

難度
進階
預估時間
105 分鐘
更新日期
2026-10-02
文案複核
speak-human-tw
兩輪
本課內容
  1. 01先把定義說清楚
  2. 02現場情境
  3. 03實作範例
  4. 04照著做,每一步都有檢查點
  5. 05實務脈絡
  6. 06動手實作
  7. 07故障診間
  8. 08正式上線前的邊界
  9. 09資料來源與主張限制

這一課會完成什麼

  • 模型提出操作前,先依風險分類
  • 審查資料包可跨程序重啟與延遲的決策保存
  • 核准綁定精確參數、規則版本、執行者與到期時間
  • 測提示注入、過期核准、重複恢復與審查者拒絕

開始前先準備

  • • 模組 2 的有型別的工具執行器
  • • 模組 3 的正式可信的執行/操作效果紀錄
  • • 操作人員與已授權預算核准者的測試身分

先把定義說清楚

人工審查與防護規則

人工介入(人工介入)是在應用程式狀態機中保存待審工作的中斷點。系統記下提議的操作、完整參數與當時的規則,交給有權限的審查者;恢復時再次驗身分、期限與資料是否一致,只執行同一筆待審工作。防護規則(防護規則)負責特定格式或政策檢查。周邊系統仍需要各自的權限與復原設計,不能因某項防護通過,就省略其他檢查。

只顯示『這個動作可以嗎』的對話框,證據很弱。模型若能在核准後換參數,或重試能執行兩次,審查就和真正操作效果脫鉤。

提示注入同時是不受信任資料問題。已檢索的文字、工具結果或使用者內容不會因模型重述,就取得更高權限來源。權限與規則必須由模型外的程式碼決定。

審查者處理量有限。低風險讀取應自動通過,禁止操作確定性的阻擋;只有人類判斷真的會改變風險決定的操作,才送精簡證據資料包。

現場情境

Beacon campaign budget review

具名合成情境。Beacon Mobility、行銷活動、身分、門檻與紀錄都是教學測試資料,不是已部署的系統或客戶端結果。

負責人
你是付費媒體操作團隊的應用程式工程師。
要做的決策
逐一決定提議的操作要阻擋、請求審查或執行,並證明已核准的執行綁在已審查的傳送資料。
目前狀態
研究 agent 可讀行銷活動成效。新工具能提案每日預算變更,但廣告轉接層保持模擬。測試資料有正常提案、70% 增加、含注入的指令的請求,以及等待審查時證據改變的提案。
預期成果
正常讀取照常;預算提案全部以可持久保存的資料包暫停;禁止/注入的請求拒絕執行;只有不同已授權審查者的未過期核准能恢復 1 個匹配的模擬操作效果。

限制條件

  • • 所有預算寫入都留在模擬轉接層;實作無權呼叫廣告平台。
  • • 最多 10% 的變更可以提出,但仍要具名審查者;更大變更在本練習直接阻擋。
  • • 核准 30 分鐘後失效,只對已審查的參數與證據 ID 的標準化雜湊有效。
  • • 審查者不能批准自己建立的請求;單一核准 token 只能使用 1 次。
  • • 已檢索的內容只是資料,無法修改工具權限、核准規則或系統指令。

實作範例

核准後傳送資料被改,Beacon 直接拒絕

證據類型: 具名模擬情境

執行 beacon-014 提案將行銷活動 cmp_42 的每日預算從 USD 1,000 改為 USD 1,080。應用程式驗行銷活動 ID、算出 8% 變化量、記證據 ev_7/ev_9,按標準化鍵值順序序列化參數,再以規則 budget-v3 存 SHA-256 摘要值。Agent 只收到 pending_review。

審查者 rev_mina 不是申請者,她先批准畫面上的傳送資料。恢復前測試資料把 daily_budget 改成 USD 1,120,核准 ID 不變。執行器重算摘要值發現不一致,標核准不合法,不寫操作效果。另一個未變測試資料取得全新核准,產出 1 張模擬驗收憑證;重複恢復回既有驗收憑證,不做第 2 次寫入。

合法執行的事件依序為 proposed、pending_review、approved、effect_started、effect_succeeded。參數遭竄改時以 approval_invalid 結束,記錄預期與實際摘要值;拒絕則以 denied 結束,不能重新開啟。驗證只找到 1 張綁定有效冪等鍵的回執。

主張限制

門檻、身分、行銷活動資料與操作效果全是合成。實作只證明模擬轉接層的狀態機性質,不代表真實媒體平台授權正確。OpenAI 文件描述核准中斷與可恢復的狀態;精確 SDK 型別可能變動,串接前須查目前說明文件。

做法

照著做,每一步都有檢查點

核准狀態機:提議的、待處理審查、已核准的/denied、摘要值驗證、單一操作效果與已使用;到期時間/竄改全拒絕執行。

現場情境

逐一決定提議的操作要阻擋、請求審查或執行,並證明已核准的執行綁在已審查的傳送資料。

  1. 01每個工具操作先分類
  2. 02保存不可變的資料包
  3. 03授權並恢復

驗收條件

報告有 1 個已核准的/已使用操作、1 個拒絕、4 條 blocked 對抗性路徑。唯一操作效果是綁已審查的摘要值的 1 張模擬驗收憑證;每個終止狀態都指出決定它的規則檢查。

這張圖要幫你看懂什麼確定性的狀態圖解必須列出所有可恢復的/終止狀態轉移,並顯示傳送資料、決策與操作效果如何綁定。
  1. 01

    每個工具操作先分類

    建立允許、審查、禁止表。核准欄位的讀取可自動執行;預算提案進審查;直接發布、憑證 access 與允許清單外請求在模型重新解讀前就禁止。

    檢查點 · 依表格驅動的測試將每個已登錄的工具映射到唯一規則類型;新工具沒分類就 fail。

  2. 02

    保存不可變的資料包

    驗有型別的參數、排序證據 ID、雜湊標準化傳送資料,存申請者、規則版本、到期時間與執行 ID。迴圈只拿待審參考,核准狀態不得只放在對話。

    檢查點 · 停止並重啟測試程序,待處理資料包仍以相同摘要值載入,也不能原地修改。

  3. 03

    授權並恢復

    檢查審查者角色與職責分離,核准/拒絕寫成只新增不覆寫的事件;恢復重查到期時間、摘要值、規則版本與已使用狀態,轉接層使用執行操作效果冪等鍵。

    檢查點 · 合法測試資料寫 1 張模擬驗收憑證;拒絕 0 張;第 2 次恢復回原驗收憑證。

  4. 04

    對抗測試邊界

    放一份要求繞過審查的已檢索的文件,再測金額遭修改、已到期項目、跨次執行 token 重用與自行核准。每種都要明確停止原因。

    檢查點 · 5 個對抗性測試資料全拒絕執行、保留稽核事件,模擬行銷活動紀錄完全不變。

  5. 05

    檢查審查者使用體驗

    畫面列目前/提議的值、相對變更、證據連結、規則版本、申請者、到期時間與不受信任來源警告。請審查者只用資料包做決定。

    檢查點 · 審查者只看資料包就能核對範圍、幅度、證據和到期時間;畫面不顯示模型隱藏推理。

實務脈絡

展示版之後

G1

實作拆解

待審資料包要能獨立於聊天介面保存。記下執行 ID、工具、標準化參數、證據 ID、資料摘要值、規則版本、申請者、審查資格、建立及到期時間與目前決策。審查畫面直接呈現資料包中的目前值和提議值,不能再請模型摘要。決策以新增事件保存,不改原資料;參數、證據或規則版本一變,就建立新請求,舊核准失效。

真正執行外部操作前,再驗角色、職責分離、期限、決策、摘要值、規則版本、核准使用狀態與冪等鍵,全部通過才呼叫模擬轉接層。若外部操作已發生、回執尚未保存時程序崩潰,先核對供應商正式狀態;結果未知時不能盲目重試。練習只使用模擬預算寫入,也要先處理這種交易缺口。

按操作類型看佇列數量、等待時間、修改率、拒絕、到期、繞過嘗試與事故,再調審查規則。低風險讀取若幾乎都原樣核准,可改由程式驗證;本案例超過 10% 的預算變更則直接禁止,省去無效審查。人工判斷留給證據與脈絡真會改變決定的提案。任何自動化調整先補回歸測試,避免縮短佇列時擴大權限。

G2

營運檢查

審查畫面要讓決定者看見真正要授權的效果。以預算提案為例,畫面直接顯示活動識別碼、目前與提案金額、相對變動、支援證據、政策版本、提出者、到期時間與不受信任內容警告。批准按鈕提交的是封包識別碼與決定,不重新傳一份可被修改的參數。後端在效果旁重算摘要值;任何差異都使原決定無效。這樣即使前端快取、模型文字或攻擊者改了顯示以外欄位,也不能把舊批准套到新效果。

人工關卡也要有服務目標與失敗處理。待辦過期後不能預設批准;拒絕要成為終止狀態,若要重提就建立新封包;審查者權限在等待期間被收回,恢復時必須重新驗證。佇列監控要區分等待、批准、修改後重提、拒絕、過期與繞過嘗試,並抽查批准是否真的改變風險判斷。若某類讀取每次都原樣通過,可將固定規則移回程式;若某類寫入超出允許範圍,直接禁止比要求人員不斷按拒絕更可靠。

G3

驗證與上線

政策表由程式載入並帶版本。每個工具只有允許、需審查或禁止三種明確類別;未列出的新工具預設禁止。分類可依動作、資源、變動幅度與使用者角色組合,但模型不能用自然語言覆寫。政策更新要重新評估等待中的封包;若規則已改,舊核准不得沿用。這避免一次長時間等待跨過政策變更,卻仍執行以前允許、現在已禁止的效果。

封包顯示的證據也要鎖版本。若等待期間績效資料更新、來源被刪除或權限改變,恢復前檢查證據摘要值與存取權;有差異就失效並要求新審查。審查者批准的是當時看見的資訊,不是未來任何同名提案。對需要時效的證據,政策可設定比三十分鐘更短的有效期;實際數值由業務與風險負責人決定,不能沿用課程示例。

對抗測試除了提示注入,還要含前端與流程攻擊:交換活動識別碼、改金額、移除一個證據、把核准套到另一個工作、重放已使用 token、讓提出者自我批准、在過期邊界同時點擊、於效果完成後中斷。每個案例都查資料庫事件與假介面呼叫數。模型回一句拒絕不算控制;只有應用程式沒有產生不該有的效果,才算通過。

人工審查紀錄要能回答誰在何時根據哪個版本做了什麼決定,也要保存拒絕理由的結構化分類,避免後續只能讀自由文字。這些資料可轉成評測與政策調整,但不得用來訓練未經授權的內容。每月抽查核准後是否真的只執行一次、拒絕是否被其他路徑繞過,以及過期項目是否還能恢復;任何例外都新增回歸案例。

G4

補強練習

審查權限也要定期重驗。角色名單、代理人與職務分離規則版本化;待辦顯示審查者當下資格,恢復時後端再查一次。帳號被停用或角色移除後,即使手上還有舊連結,也不能提交或恢復任何效果。

核准介面的證據連結要遵守相同存取政策。審查者能看摘要,不代表能取得受限原文;後端按身分解析來源,失去權限就使封包失效。畫面不可把秘密、完整工具輸出或模型隱藏推理當成說服審查者的材料。

效果完成後保存實際回條、執行時間、參數摘要值與外部版本。之後有人問『批准的和執行的是否相同』,可直接比對,不依賴前端截圖。對帳發現外部狀態不同時,先停新執行,再由負責人處理。

每次政策變更用既有對抗固定資料重跑,特別看邊界值、到期同時操作與重放。若允許幅度從示例的 10% 改變,新的數值要由業務風險負責人簽核並更新版本;課程門檻不能自動成為真實投放政策。

G5

交付前最後檢查

值班手冊另列審查服務不可用的處理:新提案保持等待或直接拒絕,絕不因佇列故障自動放行;既有核准仍須通過所有恢復檢查。恢復服務後,過期項目不批次補執行,而是逐筆重新評估。

審查紀錄與效果回條使用相同關聯碼,事後才能確認每個決定只對應一個效果。

每次抽查都同時看批准、拒絕與過期樣本,不能只驗成功路徑。

G6

延伸實作

審查政策的變更要回看歷史封包。用新規則重播批准、拒絕、過期、內容變更與重放案例,確認哪些決定會不同,再由風險負責人批准政策版本。等待中的封包若受影響,標記需要重新審查,不自動套用較寬規則。政策上線後監控拒絕、過期與人工修改是否異常,必要時回退。這讓人工關卡的嚴格度有證據可查,不會在佇列壓力下靠口頭決定逐步放寬。

動手實作

實作可持久保存的核准資料包

擴充 Beacon 模擬預算工具,讓提案變成不可變的審查資料包,再測核准、拒絕、竄改、到期時間與重複恢復。

準備項目

  • • 廣告轉接層僅用記憶體中的模擬資料,把 cmp_42 的每日預算設為 USD 1,000。
  • • 使用固定時鐘與身分,讓到期及職責分離測試可重現。
  • • 原始已檢索的文字與有型別的操作參數分開保存。

本課產出

TypeScript 核准儲存區、模擬執行器、6 個測試案例、1 份審查畫面,以及各案例的核准狀態軌跡。

起始模板: 核准規則與紀錄

TypeScript
type Decision = "pending" | "approved" | "denied" | "expired" | "consumed";

type BudgetArgs = {
  campaignId: string;
  currentDailyUsd: number;
  proposedDailyUsd: number;
  evidenceIds: string[];
};

type Approval = {
  id: string;
  runId: string;
  tool: "propose_budget_change";
  argsDigest: string;
  policyVersion: "budget-v3";
  requestedBy: string;
  decidedBy?: string;
  decision: Decision;
  expiresAt: string;
  consumedAt?: string;
};

const policy = {
  allowedCampaign: /^cmp_[a-z0-9]+$/,
  maxRelativeChange: 0.10,
  approvalTtlMs: 30 * 60 * 1000,
  rolesAllowedToApprove: new Set(["media-approver"]),
};

function canonicalBudgetArgs(args: BudgetArgs): string {
  return JSON.stringify({
    campaignId: args.campaignId,
    currentDailyUsd: args.currentDailyUsd,
    proposedDailyUsd: args.proposedDailyUsd,
    evidenceIds: [...args.evidenceIds].sort(),
  });
}

// Implement with node:crypto createHash("sha256"), then persist this digest.
function assertReviewable(args: BudgetArgs): void {
  if (!policy.allowedCampaign.test(args.campaignId)) throw new Error("CAMPAIGN_DENIED");
  const delta = Math.abs(args.proposedDailyUsd - args.currentDailyUsd) / args.currentDailyUsd;
  if (!Number.isFinite(delta) || delta > policy.maxRelativeChange) throw new Error("POLICY_LIMIT");
  if (args.evidenceIds.length < 2) throw new Error("EVIDENCE_REQUIRED");
}

// resume() must revalidate role, different reviewer, TTL, decision, digest,
// policy version, and idempotency key before calling the fake adapter once.

預期結果

報告有 1 個已核准的/已使用操作、1 個拒絕、4 條 blocked 對抗性路徑。唯一操作效果是綁已審查的摘要值的 1 張模擬驗收憑證;每個終止狀態都指出決定它的規則檢查。

留給下一課

保留核准事件、規則結果與對抗案例。下一模組將它們納入回歸測試,上線審查再檢查拒絕比率和人工處理時間。

驗收條件

  1. 01每個非讀取操作已分類;未分類的工具拒絕執行。
  2. 02核准保存精確參數、證據 ID、規則版本、申請者、審查者、到期時間、決策與資料摘要值。
  3. 03被竄改的、已到期、自行核准的、跨次執行與重複恢復測試資料無法建立新操作效果。
  4. 04合法案例在模擬程序重啟後恢復,只產出 1 張可稽核的模擬回執。

常見故障

故障診間

F1核准畫面是安全操作,執行時卻用了別的參數。
先檢查
比較請求、決策與操作效果 start 的標準化傳送資料/摘要值。
可能原因
核准只綁工具 name 或對話回合。
修復方式
決策不合法;核准綁不可變的標準化參數、證據、規則、執行與到期時間。
下次怎麼避免
外部操作轉接層旁立刻重算並比較摘要值。
F2重試建立 2 張預算變更驗收憑證。
先檢查
按執行冪等鍵查操作效果紀錄與轉接層呼叫。
可能原因
外部呼叫後才存已使用狀態,或轉接層忽略冪等鍵。
修復方式
Transactionally 預留操作效果,傳穩定鍵值;重試前先核對實際結果結果未知。
下次怎麼避免
每次發布測 timeout-after-write 與 duplicate-resume。
F3已檢索的 copy 說不必審查,agent 就跳過。
先檢查
追來源紀錄,確認不受信任文字是否進規則或系統指令欄位。
可能原因
應用程式允許模型產生的文字改授權狀態。
修復方式
恢復有型別的資料邊界,工具規則在模型脈絡外以程式碼執行。
下次怎麼避免
標不受信任欄位、限制工具輸入,權限決策確定性的。
F4幾乎所有請求都原樣通過,審查佇列仍愈排愈長。
先檢查
按操作類型拆審查數量、決策時間、修改、拒絕與事故值。
可能原因
例行低風險讀取與高風險寫入共用同一道未區分風險的驗收門檻。
修復方式
已驗證的讀取自動化、不允許的操作禁止,人工判斷留給有意義的外部操作。
下次怎麼避免
每月用事故資料檢查規則矩陣與審查負擔。

展示版之後

正式上線前的邊界

  1. 01每個工具分成允許、已審查的或禁止;缺漏規則拒絕執行。
  2. 02授權/參數驗證在操作效果旁的應用程式程式碼執行。
  3. 03不可變的審查資料包獨立於模型對話狀態保存。
  4. 04決策綁標準化傳送資料、證據、執行、規則版本、執行者與到期時間。
  5. 05Material 操作採職責分離,審查者授權留稽核。
  6. 06Unknown 寫入結果使用冪等鍵、操作台帳與結果核對。
  7. 07不受信任已檢索的內容不得進指令/權限 channel。
  8. 08監控核准數量、等待時間、修改/拒絕比率、繞過嘗試與事故。

證據類型

資料來源與主張限制

資料來源只支撐本課標示的主張,不代表換一個系統也會得到相同結果。

  1. [1]
    Guardrails 與人工審查

    OpenAI · 官方文件 · 2026-08-20

    審核中斷 · 可恢復狀態 · 工具層 guardrail
  2. [2]
    建置 agent 的安全指引

    OpenAI · 官方文件 · 2026-08-20

    prompt injection · 結構化資料邊界 · MCP 核准
  3. [3]
    MCP 與 Connectors

    OpenAI · 官方文件 · 2026-08-20

    遠端 MCP 設定 · 核准模式 · 私有伺服器連線
  4. [4]
    AI Risk Management Framework

    NIST · 官方文件 · 2026-08-20

    風險治理 · 衡量方式 · 營運責任

延伸的 Tenten 資源

實作準備進正式環境時

帶著實作證據來,不用從空白摘要開始。

有效的實作審查,起點應該是任務測試資料、權限地圖、執行軌跡、評測報告、失敗案例與成本上限。Tenten 可以根據這些資料檢查整合與營運缺口,不必把課程裡已經證明過的決策全部重開。