這一課會完成什麼
- 模型提出操作前,先依風險分類
- 審查資料包可跨程序重啟與延遲的決策保存
- 核准綁定精確參數、規則版本、執行者與到期時間
- 測提示注入、過期核准、重複恢復與審查者拒絕
開始前先準備
- • 模組 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 型別可能變動,串接前須查目前說明文件。
做法
照著做,每一步都有檢查點
現場情境
逐一決定提議的操作要阻擋、請求審查或執行,並證明已核准的執行綁在已審查的傳送資料。
- 01每個工具操作先分類
- 02保存不可變的資料包
- 03授權並恢復
驗收條件
報告有 1 個已核准的/已使用操作、1 個拒絕、4 條 blocked 對抗性路徑。唯一操作效果是綁已審查的摘要值的 1 張模擬驗收憑證;每個終止狀態都指出決定它的規則檢查。
- 01
每個工具操作先分類
建立允許、審查、禁止表。核准欄位的讀取可自動執行;預算提案進審查;直接發布、憑證 access 與允許清單外請求在模型重新解讀前就禁止。
檢查點 · 依表格驅動的測試將每個已登錄的工具映射到唯一規則類型;新工具沒分類就 fail。
- 02
保存不可變的資料包
驗有型別的參數、排序證據 ID、雜湊標準化傳送資料,存申請者、規則版本、到期時間與執行 ID。迴圈只拿待審參考,核准狀態不得只放在對話。
檢查點 · 停止並重啟測試程序,待處理資料包仍以相同摘要值載入,也不能原地修改。
- 03
授權並恢復
檢查審查者角色與職責分離,核准/拒絕寫成只新增不覆寫的事件;恢復重查到期時間、摘要值、規則版本與已使用狀態,轉接層使用執行操作效果冪等鍵。
檢查點 · 合法測試資料寫 1 張模擬驗收憑證;拒絕 0 張;第 2 次恢復回原驗收憑證。
- 04
對抗測試邊界
放一份要求繞過審查的已檢索的文件,再測金額遭修改、已到期項目、跨次執行 token 重用與自行核准。每種都要明確停止原因。
檢查點 · 5 個對抗性測試資料全拒絕執行、保留稽核事件,模擬行銷活動紀錄完全不變。
- 05
檢查審查者使用體驗
畫面列目前/提議的值、相對變更、證據連結、規則版本、申請者、到期時間與不受信任來源警告。請審查者只用資料包做決定。
檢查點 · 審查者只看資料包就能核對範圍、幅度、證據和到期時間;畫面不顯示模型隱藏推理。
實務脈絡
展示版之後
實作拆解
待審資料包要能獨立於聊天介面保存。記下執行 ID、工具、標準化參數、證據 ID、資料摘要值、規則版本、申請者、審查資格、建立及到期時間與目前決策。審查畫面直接呈現資料包中的目前值和提議值,不能再請模型摘要。決策以新增事件保存,不改原資料;參數、證據或規則版本一變,就建立新請求,舊核准失效。
真正執行外部操作前,再驗角色、職責分離、期限、決策、摘要值、規則版本、核准使用狀態與冪等鍵,全部通過才呼叫模擬轉接層。若外部操作已發生、回執尚未保存時程序崩潰,先核對供應商正式狀態;結果未知時不能盲目重試。練習只使用模擬預算寫入,也要先處理這種交易缺口。
按操作類型看佇列數量、等待時間、修改率、拒絕、到期、繞過嘗試與事故,再調審查規則。低風險讀取若幾乎都原樣核准,可改由程式驗證;本案例超過 10% 的預算變更則直接禁止,省去無效審查。人工判斷留給證據與脈絡真會改變決定的提案。任何自動化調整先補回歸測試,避免縮短佇列時擴大權限。
營運檢查
審查畫面要讓決定者看見真正要授權的效果。以預算提案為例,畫面直接顯示活動識別碼、目前與提案金額、相對變動、支援證據、政策版本、提出者、到期時間與不受信任內容警告。批准按鈕提交的是封包識別碼與決定,不重新傳一份可被修改的參數。後端在效果旁重算摘要值;任何差異都使原決定無效。這樣即使前端快取、模型文字或攻擊者改了顯示以外欄位,也不能把舊批准套到新效果。
人工關卡也要有服務目標與失敗處理。待辦過期後不能預設批准;拒絕要成為終止狀態,若要重提就建立新封包;審查者權限在等待期間被收回,恢復時必須重新驗證。佇列監控要區分等待、批准、修改後重提、拒絕、過期與繞過嘗試,並抽查批准是否真的改變風險判斷。若某類讀取每次都原樣通過,可將固定規則移回程式;若某類寫入超出允許範圍,直接禁止比要求人員不斷按拒絕更可靠。
驗證與上線
政策表由程式載入並帶版本。每個工具只有允許、需審查或禁止三種明確類別;未列出的新工具預設禁止。分類可依動作、資源、變動幅度與使用者角色組合,但模型不能用自然語言覆寫。政策更新要重新評估等待中的封包;若規則已改,舊核准不得沿用。這避免一次長時間等待跨過政策變更,卻仍執行以前允許、現在已禁止的效果。
封包顯示的證據也要鎖版本。若等待期間績效資料更新、來源被刪除或權限改變,恢復前檢查證據摘要值與存取權;有差異就失效並要求新審查。審查者批准的是當時看見的資訊,不是未來任何同名提案。對需要時效的證據,政策可設定比三十分鐘更短的有效期;實際數值由業務與風險負責人決定,不能沿用課程示例。
對抗測試除了提示注入,還要含前端與流程攻擊:交換活動識別碼、改金額、移除一個證據、把核准套到另一個工作、重放已使用 token、讓提出者自我批准、在過期邊界同時點擊、於效果完成後中斷。每個案例都查資料庫事件與假介面呼叫數。模型回一句拒絕不算控制;只有應用程式沒有產生不該有的效果,才算通過。
人工審查紀錄要能回答誰在何時根據哪個版本做了什麼決定,也要保存拒絕理由的結構化分類,避免後續只能讀自由文字。這些資料可轉成評測與政策調整,但不得用來訓練未經授權的內容。每月抽查核准後是否真的只執行一次、拒絕是否被其他路徑繞過,以及過期項目是否還能恢復;任何例外都新增回歸案例。
補強練習
審查權限也要定期重驗。角色名單、代理人與職務分離規則版本化;待辦顯示審查者當下資格,恢復時後端再查一次。帳號被停用或角色移除後,即使手上還有舊連結,也不能提交或恢復任何效果。
核准介面的證據連結要遵守相同存取政策。審查者能看摘要,不代表能取得受限原文;後端按身分解析來源,失去權限就使封包失效。畫面不可把秘密、完整工具輸出或模型隱藏推理當成說服審查者的材料。
效果完成後保存實際回條、執行時間、參數摘要值與外部版本。之後有人問『批准的和執行的是否相同』,可直接比對,不依賴前端截圖。對帳發現外部狀態不同時,先停新執行,再由負責人處理。
每次政策變更用既有對抗固定資料重跑,特別看邊界值、到期同時操作與重放。若允許幅度從示例的 10% 改變,新的數值要由業務風險負責人簽核並更新版本;課程門檻不能自動成為真實投放政策。
交付前最後檢查
值班手冊另列審查服務不可用的處理:新提案保持等待或直接拒絕,絕不因佇列故障自動放行;既有核准仍須通過所有恢復檢查。恢復服務後,過期項目不批次補執行,而是逐筆重新評估。
審查紀錄與效果回條使用相同關聯碼,事後才能確認每個決定只對應一個效果。
每次抽查都同時看批准、拒絕與過期樣本,不能只驗成功路徑。
延伸實作
審查政策的變更要回看歷史封包。用新規則重播批准、拒絕、過期、內容變更與重放案例,確認哪些決定會不同,再由風險負責人批准政策版本。等待中的封包若受影響,標記需要重新審查,不自動套用較寬規則。政策上線後監控拒絕、過期與人工修改是否異常,必要時回退。這讓人工關卡的嚴格度有證據可查,不會在佇列壓力下靠口頭決定逐步放寬。
動手實作
實作可持久保存的核准資料包
擴充 Beacon 模擬預算工具,讓提案變成不可變的審查資料包,再測核准、拒絕、竄改、到期時間與重複恢復。
準備項目
- • 廣告轉接層僅用記憶體中的模擬資料,把 cmp_42 的每日預算設為 USD 1,000。
- • 使用固定時鐘與身分,讓到期及職責分離測試可重現。
- • 原始已檢索的文字與有型別的操作參數分開保存。
本課產出
TypeScript 核准儲存區、模擬執行器、6 個測試案例、1 份審查畫面,以及各案例的核准狀態軌跡。
起始模板: 核准規則與紀錄
TypeScripttype 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 張模擬驗收憑證;每個終止狀態都指出決定它的規則檢查。
留給下一課
保留核准事件、規則結果與對抗案例。下一模組將它們納入回歸測試,上線審查再檢查拒絕比率和人工處理時間。
驗收條件
- 01每個非讀取操作已分類;未分類的工具拒絕執行。
- 02核准保存精確參數、證據 ID、規則版本、申請者、審查者、到期時間、決策與資料摘要值。
- 03被竄改的、已到期、自行核准的、跨次執行與重複恢復測試資料無法建立新操作效果。
- 04合法案例在模擬程序重啟後恢復,只產出 1 張可稽核的模擬回執。
常見故障
故障診間
F1核准畫面是安全操作,執行時卻用了別的參數。
- 先檢查
- 比較請求、決策與操作效果 start 的標準化傳送資料/摘要值。
- 可能原因
- 核准只綁工具 name 或對話回合。
- 修復方式
- 決策不合法;核准綁不可變的標準化參數、證據、規則、執行與到期時間。
- 下次怎麼避免
- 外部操作轉接層旁立刻重算並比較摘要值。
F2重試建立 2 張預算變更驗收憑證。
- 先檢查
- 按執行冪等鍵查操作效果紀錄與轉接層呼叫。
- 可能原因
- 外部呼叫後才存已使用狀態,或轉接層忽略冪等鍵。
- 修復方式
- Transactionally 預留操作效果,傳穩定鍵值;重試前先核對實際結果結果未知。
- 下次怎麼避免
- 每次發布測 timeout-after-write 與 duplicate-resume。
F3已檢索的 copy 說不必審查,agent 就跳過。
- 先檢查
- 追來源紀錄,確認不受信任文字是否進規則或系統指令欄位。
- 可能原因
- 應用程式允許模型產生的文字改授權狀態。
- 修復方式
- 恢復有型別的資料邊界,工具規則在模型脈絡外以程式碼執行。
- 下次怎麼避免
- 標不受信任欄位、限制工具輸入,權限決策確定性的。
F4幾乎所有請求都原樣通過,審查佇列仍愈排愈長。
- 先檢查
- 按操作類型拆審查數量、決策時間、修改、拒絕與事故值。
- 可能原因
- 例行低風險讀取與高風險寫入共用同一道未區分風險的驗收門檻。
- 修復方式
- 已驗證的讀取自動化、不允許的操作禁止,人工判斷留給有意義的外部操作。
- 下次怎麼避免
- 每月用事故資料檢查規則矩陣與審查負擔。
展示版之後
正式上線前的邊界
- 01每個工具分成允許、已審查的或禁止;缺漏規則拒絕執行。
- 02授權/參數驗證在操作效果旁的應用程式程式碼執行。
- 03不可變的審查資料包獨立於模型對話狀態保存。
- 04決策綁標準化傳送資料、證據、執行、規則版本、執行者與到期時間。
- 05Material 操作採職責分離,審查者授權留稽核。
- 06Unknown 寫入結果使用冪等鍵、操作台帳與結果核對。
- 07不受信任已檢索的內容不得進指令/權限 channel。
- 08監控核准數量、等待時間、修改/拒絕比率、繞過嘗試與事故。
證據類型
資料來源與主張限制
資料來源只支撐本課標示的主張,不代表換一個系統也會得到相同結果。
- [1]Guardrails 與人工審查審核中斷 · 可恢復狀態 · 工具層 guardrail
OpenAI · 官方文件 · 2026-08-20
- [2]建置 agent 的安全指引prompt injection · 結構化資料邊界 · MCP 核准
OpenAI · 官方文件 · 2026-08-20
- [3]MCP 與 Connectors遠端 MCP 設定 · 核准模式 · 私有伺服器連線
OpenAI · 官方文件 · 2026-08-20
- [4]AI Risk Management Framework風險治理 · 衡量方式 · 營運責任
NIST · 官方文件 · 2026-08-20
延伸的 Tenten 資源