Azure SRE Agent 中的 Agent Hooks

Hook 是自訂檢查點,能在關鍵時刻攔截並控制代理行為。 利用鉤子強制執行代理回應的品質閘門、稽核與控制工具使用、透過執行政策阻擋危險操作,並透過驗證代理輸出來防止任務提前完成。

Agent hooks 解決的問題

您的代理人會自動執行任務,透過調查事件、操作工具並產生回應。 但沒有監督的自主性會帶來風險:

  • 不完整的回應:客服在回答你要求的所有問題前就說「完成」。
  • 未經稽核的工具使用:你無法看到客服人員呼叫哪些工具或得到什麼結果。
  • 無政策執行:危險操作(破壞性指令、未經授權變更)未受監控。
  • 品質缺口:回應會漏掉關鍵資訊,因為沒有驗證步驟。

你需要一種在關鍵時刻攔截代理行為的方法,同時不會拖慢它或完全剝奪其自主性。

代理模組掛勾的運作方式

鉤子是自訂檢查點,附加於特定代理程式事件上。 事件觸發時,您的 Hook 會評估情況,並決定要允許還是封鎖該動作。

Agent about to stop → Stop hook evaluates response → Allow or reject
Agent uses a tool   → PostToolUse hook checks result → Allow, block, or inject context

目前支援兩種 Hook 事件:

事件 觸發時機 您可以採取的方法
停止 特工即將回覆最後的回應 驗證完整性,拒絕並強迫代理人繼續
PostToolUse 工具成功完成執行 審核使用情況、封鎖結果、注入額外脈絡

兩層鉤子

鉤子有兩個層級運作:

等級 設定地點 Scope
代理層級 入口網站中的生產器 → 勾點 適用於整個代理,包括所有執行緒和所有自訂代理
自訂代理層級 Agent Canvas → Custom agent → Manage Hooks,或透過 REST API v2 使用。 只適用於該特定自訂代理執行時

這兩個層級可以共存。 如果一個代理級鉤子和自訂代理級鉤子都匹配到同一事件, 兩者都會執行。 Agent 層級勾點會先觸發。

執行類型

你可以使用 LLM 或 Shell 腳本來實現鉤子:

類型 運作方式 最適合用於
Prompt LLM 模型會評估你的提示並返回一個 JSON 決定 細膩的驗證(「這個回應完整嗎?」)
命令 bash 或 Python 腳本會在沙盒環境中執行 確定性檢查、政策執行、稽核

提示鉤 子對於主觀評估非常有效,例如檢查回應是否涵蓋所有用戶關切,或驗證調查是否足夠徹底。 他們使用 $ARGUMENTS 佔位符來接收完整的鉤子上下文。 如果提示中沒有 $ARGUMENTS,則上下文會自動附加。 有交談記錄可用時,提示詞勾點也會接收 ReadFileGrepSearch 工具,讓 LLM 能針對完整交談歷程記錄進行推斷。

指令鉤 子更適合用於確定性檢查,例如驗證回應是否包含必要標記、阻擋危險指令,或將工具使用記錄到外部系統。

有無 hooks 的 agent 行為差異

下表比較了有鉤子與無鉤子的代理行為。

沒有鉤子 帶鉤子
代理人決定什麼時候「完成」 你定義「完成」的意思
工具使用是隱形的 每一次工具呼叫都可以被稽核
危險指令會悄無聲息地執行 策略執行會自動封鎖它們
品質完全取決於提示詞工程 自動品質閘門捕捉縫隙

掛鉤並不能取代運行模式的安全控制。 相反地,它們是互補的。 執行模式控制代理能做 什麼 。 鉤子控制它的表現如何,以及結果如何發生變化

新增 agent hooks 前後對比

案例 之前 之後
回應品質 Agent 會在它認為已完成時停止 你的停止掛鉤在回應到達用戶之前驗證完整性
工具可見性 工具執行時沒有稽核紀錄 PostToolUse 鉤子會記錄並驗證每一個工具呼叫
政策執行 危險指令未經檢查即執行 腳本會自動封鎖 rm -rfsudo、及其他有風險的模式
品質保證 提示詞工程是您唯一的控制手段 以 LLM 為基礎的 Hook 會評估細微差異;指令碼則會強制執行具決定性的規則

設定代理鉤子

透過入口網站介面建立掛鉤:

  1. 代理層級掛鉤: 請前往 建構者掛鉤 → 選擇 「建立掛鉤」
  2. 自訂代理級掛鉤: 進入 Agent Canvas →選擇自訂代理,→ 管理 Hooks

如需逐步操作說明,請參閱 入口網站中的「建立及管理 Hook」

小提示

你也可以透過 REST API v2 設定掛鉤,方法是使用 PUT /api/v2/extendedAgent/agents/{agentName}。 以下章節的 YAML 格式顯示完整的配置架構。 想了解更多,請參考 API 教學

Agent Canvas 的 YAML 分頁顯示 v1 格式,且不顯示掛鉤。 請使用建構者(Builder)下的「鉤子」頁面來查看和管理鉤子。

以下範例展示了完整的掛鉤配置:

api_version: azuresre.ai/v2
kind: ExtendedAgent
metadata:
  name: my_hooked_agent
spec:
  instructions: |
    You are a helpful assistant.
  handoffDescription: ""
  enableVanillaMode: true
  hooks:
    Stop:
      - type: prompt
        prompt: |
          Check if the response ends with "Task complete."
          $ARGUMENTS
          Respond with:
          - {"ok": true} if it does
          - {"ok": false, "reason": "End your response with 'Task complete.'"} if not
        timeout: 30

    PostToolUse:
      - type: command
        matcher: "Bash|ExecuteShellCommand"
        timeout: 30
        failMode: block
        script: |
          #!/usr/bin/env python3
          import sys, json, re

          context = json.load(sys.stdin)
          command = context.get('tool_input', {}).get('command', '')

          dangerous = [r'\brm\s+-rf\b', r'\bsudo\b', r'\bchmod\s+777\b']
          for pattern in dangerous:
              if re.search(pattern, command):
                  print(json.dumps({"decision": "block", "reason": f"Blocked: {pattern}"}))
                  sys.exit(0)

          print(json.dumps({"decision": "allow"}))

鉤子回應格式

鉤子必須輸出 JSON。 支援兩種格式:

簡單格式 (建議用於提示鉤子):

{"ok": true}
{"ok": false, "reason": "Please include more details."}

擴充格式 (建議用於指令鉤子):

{"decision": "allow"}
{"decision": "block", "reason": "Dangerous command detected."}
{"decision": "allow", "hookSpecificOutput": {"additionalContext": "Tool audit logged."}}

指令掛鉤也可以使用出口碼取代 JSON 輸出:

退出代碼 行為
0 無輸出 允許(無異議)
0 與 JSON 一同 解析 JSON 用於決策
2 一律封鎖。 stderr 會成為原因
其他 使用 failMode 設定(allowblock

謹慎

對於 Stop 掛勾,沒有理由 的拒絕會被視為批准,程式代理將正常停止。 拒絕時一定要提供 reason 欄位。

備註

你可以為同一事件定義多個鉤子。 在 PostToolUse 中,每個有相同 matcher 模式的鉤子會獨立執行。 如果多個鉤子提供 additionalContext,最後一個鉤子的上下文會被注入對話中。

設定參考

下表說明所有可用的掛鉤配置選項。

Option 類型 預設值 說明
type 字串 prompt promptcommand
prompt 字串 (無) LLM 提示詞文字 (提示詞 Hook 必要)。 使用 $ARGUMENTS 來進行情境注入。
command 字串 (無) 嵌入式 shell 命令(用於命令掛鉤,與 script互斥)。
script 字串 (無) 多行腳本(用於命令掛勾,與 command互斥)。
matcher 字串 (無) 工具名稱的 Regex 模式 (PostToolUse Hook 必要)。 * 適用於所有工具。 模式會被定位為^(pattern)$,並以區分大小寫的方式匹配。 空或 null 都不匹配。
timeout int 30 執行逾時以秒為單位(必須為正值;值超過 300 會在 CLI 驗證時被標記)。
failMode 字串 allow 如何處理勾子錯誤: allowblock
model 字串 ReasoningFast 提示詞 Hook 的模型 (案例名稱或部署名稱)。
maxRejections int 3 (代理人違約) 強制停機前的最大拒絕次數。 範圍:1 到 25。 僅適用於提示型的停止鉤子。 命令型停止鉤子沒有隱含的限制。 當多個提示符鉤子指定不同值時,會使用最大值。

鉤子上下文結構

Hook 會接收關於當前事件的結構化 JSON 上下文。 提示鉤子 透過提示文字中的 $ARGUMENTS 佔位符接收上下文。 命令 Hook 會透過 stdin 接收 JSON 格式的內容。

對於兩種鉤子類型,欄位 execution_summary 都包含對話逐字稿的 檔案路徑 (非內嵌內容)。 對於提示詞 Hook,LLM 會收到 ReadFileGrepSearch 工具,以便存取此檔案。 對於命令 Hook,該檔案可在 Sandbox 中的指定路徑取得。

一般欄位

所有 Hook 都會收到下列欄位:

{
  "hook_event_name": "Stop",
  "agent_name": "my_agent",
  "current_turn": 5,
  "max_turns": 50,
  "execution_summary": "/path/to/transcript.txt"
}

Stop Hook 欄位

Stop Hook 會收到有關 Agent 最終輸出的額外欄位。

{
  "final_output": "Here is my response...",
  "stop_hook_active": false,
  "stop_rejection_count": 0
}

PostToolUse Hook 欄位

PostToolUse Hook 會收到有關工具執行的額外欄位。

{
  "tool_name": "ExecutePythonCode",
  "tool_input": { "code": "print(2+2)" },
  "tool_result": "4",
  "tool_succeeded": true
}

模型層級

提示鉤子使用人工智慧模型來評估代理行為。 你可以選擇掛鉤使用的模型層級,在評估品質與成本及延遲之間取得平衡。

最適合用於 取捨
Reasoning 複雜的政策執行、多步驟驗證、細緻的合規檢查 最高品質,更高的成本與延遲
快速推理 (預設) 大多數 hooks、回應驗證、稽核檢查、安全性強制執行 低延遲的合理推理
一般用途 簡單的格式檢查、基本合規驗證 精準度、成本與速度的平衡
快速 輕量級檢查、存在驗證、格式驗證 成本最低,反應最快
長篇背景 處理大型輸出、完整文件分析、大量工具結果的 hooks 處理較大的投入,成本較高

小提示

Hook 預設採用 快速推理 ,因為它們會在每個代理回應或工具呼叫時執行,所以低延遲很重要。 Reasoning 僅適用於需要高準確度且強制執行複雜原則的 hooks。

限制

下列限制適用於 Agent Hook。

Limit 價值
劇本大小 最大 64 KB
逾時 1 到 300 秒
最大拒絕次數 (提示詞 Stop Hook) 1 到 25(預設:3)
支援的指令碼 Shebang #!/bin/bash#!/usr/bin/env python3
腳本執行環境 沙盒程式碼直譯器

範例:審核所有工具使用情況

以下 PostToolUse 的 hook 會記錄每個工具呼叫並新增稽核上下文訊息:

hooks:
  PostToolUse:
    - type: command
      matcher: "*"
      timeout: 30
      failMode: allow
      script: |
        #!/usr/bin/env python3
        import sys, json

        context = json.load(sys.stdin)
        tool_name = context.get('tool_name', 'unknown')

        print(f"Tool used: {tool_name}", file=sys.stderr)

        output = {
            "decision": "allow",
            "hookSpecificOutput": {
                "additionalContext": f"[AUDIT] Tool '{tool_name}' was executed."
            }
        }
        print(json.dumps(output))

additionalContext 欄位會以使用者訊息的形式加入對話中,讓客服人員能看到稽核追蹤。

範例:要求完成標記

以下停止鉤子會拒絕未以「任務完成」結尾的回應:

hooks:
  Stop:
    - type: command
      timeout: 30
      failMode: allow
      script: |
        #!/bin/bash
        CONTEXT=$(cat)
        FINAL_OUTPUT=$(echo "$CONTEXT" | jq -r '.final_output // empty')

        if [[ "$FINAL_OUTPUT" == *"Task complete."* ]]; then
          exit 0
        else
          echo "Please end your response with 'Task complete.'" >&2
          exit 2
        fi

最佳做法

當你設定代理掛鉤時:

  1. 拒絕時一定要提供理由。 把沒有理由的拒絕當成批准。
  2. 使用適當的超時:運行時間過長的掛鉤函式會減緩代理執行。
  3. 妥善處理錯誤:除非需要嚴格強制執行,否則請使用 failMode: allow
  4. 具體描述匹配器:過於寬泛的 PostToolUse 匹配器會導致效能問題。
  5. 徹底測試鉤子:總是被拒絕的鉤子可能會導致迴圈(可藉 maxRejections 來緩解)。
  6. Log to stderr:使用 stderr 來輸出除錯資訊。 系統將解析 stdout 結果作為掛鉤結果。

親自試用 agent hooks

以下截圖顯示了停止鉤在運行中的狀態。 智能代理最初只回應「4」,但掛鉤函數因為缺少完成標記而拒絕該回應。 代理人接著繼續並加入標記。

截圖顯示停止掛鉤拒絕代理回應,缺少完成標記,然後代理重新嘗試並新增標記。

開始

資源 您學到什麼
建立與管理掛鉤(入口網站) 在入口網站介面中視覺化建立鉤子,不需要 API 呼叫。
配置代理掛鉤(API) 使用 REST API v2 和 YAML來設定掛鉤。
能力 其關聯
運行模式 鉤子補充了運行模式的安全控制。 模式控制 運行的內容, 鉤子控制其 運行的品質
Python 工具 建立自訂工具,讓掛鉤可以進行稽核與驗證。