Azure SRE Agent のエージェント フック

フックは、重要な時点でエージェントの動作をインターセプトして制御するカスタム チェックポイントです。 フックを使用して、エージェントの応答に品質ゲートを適用し、ツールの使用状況を監査および制御し、ポリシーを適用して危険な操作をブロックし、エージェントの出力を検証してタスクの早期完了を防ぎます。

問題

エージェントは、インシデントの調査、ツールの実行、応答の生成などのタスクを自律的に実行します。 しかし、見落としのない自律性はリスクを生み出します。

  • 不完全な応答: エージェントは、要求したすべての内容に対処する前に "完了" と表示されます。
  • 監査されていないツールの使用状況: エージェントが呼び出すツールや、その結果を把握することはできません。
  • ポリシーが施行されていない: 危険な操作 (破壊的コマンド、未承認の変更) は確認なしで進行します。
  • 品質ギャップ: 検証手順がないため、応答は重要な情報を見逃します。

エージェントの動作を遅くしたり、その自律性を完全に削除したりすることなく、重要な瞬間にエージェントの動作をインターセプトする方法が必要です。

エージェント フックのしくみ

フックは、特定のエージェント イベントにアタッチするカスタム チェックポイントです。 イベントが発生すると、フックは状況を評価し、アクションを許可するかブロックするかを決定します。

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

現在、次の 2 つのフック イベントがサポートされています。

イベント 次の場合にトリガーされます。 実行可能事項
止める エージェントが最終的な応答を返す 完全性を検証し、拒否して、エージェントに続行させるように強制する
PostToolUse ツールの実行が正常に完了する 使用状況の監査、結果のブロック、追加のコンテキストの挿入

2つのレベルのフック

フックは次の 2 つのレベルで動作します。

レベル 構成する場所 Scope
エージェント レベル ポータル内のビルダー → フック すべてのスレッドとすべてのカスタム エージェントを含むエージェント全体に適用されます
カスタム エージェント レベル Agent Canvas → カスタム エージェント →フックの管理、または REST API v2 経由 特定のカスタム エージェントが実行されている場合にのみ適用されます

両方のレベルが共存できます。 エージェント レベルのフックとカスタム エージェント レベルのフックの両方が同じイベントと一致する場合は、 両方とも実行されます。 エージェント レベルのフックが最初に起動します。

実行の種類

フックは、LLM またはシェル スクリプトを使用して実装できます。

タイプ どのように機能するのか 最適な用途
プロンプト LLM はプロンプトを評価し、JSON の決定を返します 微妙な検証 ("この応答は完了しましたか?")
命令 bash または Python スクリプトがサンドボックス環境で実行される 決定論的チェック、ポリシーの適用、監査

プロンプト フック は、応答がすべてのユーザーの懸念に対処しているかどうかを確認したり、調査が十分に行われたかどうかを確認したりするなど、主観的な評価に強力です。 $ARGUMENTS プレースホルダーを使用して、完全なフック コンテキストを受け取ります。 $ARGUMENTSがプロンプトに存在しない場合、コンテキストは自動的に追加されます。 会話のトランスクリプトが使用可能になると、プロンプトフックも ReadFile および GrepSearch のツールを受け取り、LLM は完全な会話履歴について理由をつけることができます。

コマンド フック は、応答に必要なマーカーが含まれていることの検証、危険なコマンドのブロック、外部システムへのツールの使用状況のログ記録など、決定的なチェックに適しています。

このアプローチの違い

次の表では、フックの有無に関するエージェントの動作を比較します。

フックなし フック付き
エージェントが "完了" するタイミングを決定する "完了" の意味を定義する
ツールの使用状況が表示されない すべてのツール呼び出しを監査できます
危険なコマンドは警告なしで続行されます ポリシーの適用によって自動的にブロックされる
品質はプロンプト エンジニアリングにだけ依存している 自動化された品質ゲートが欠陥を検出する

フックは実行モードの安全コントロールを置き換えるのではなく、補完します。 実行モードは、エージェントが 実行できる操作 を制御します。 フックは、それが どれだけうまく 機能し、結果で 何が起こるかを 制御します。

前と後

シナリオ の前に 後の
応答の品質 エージェントが完了したと判断すると停止する Stop フックは、応答がユーザーに到達する前に完全性を検証します
ツールの可視性 ツール実行の監査証跡なし PostToolUse はログをフックし、すべてのツール呼び出しを確認します
ポリシーの適用 危険なコマンドが無検査で実行される スクリプトは、 rm -rfsudo、およびその他の危険なパターンを自動的にブロックします
品質保証 プロンプトエンジニアリングはあなたの唯一のレバーです LLMベースのフックは微妙な差異を評価します。スクリプトは決定論的なルールを強制します。

フックの構成

フックを作成する最も簡単な方法は、ポータル UI を使用することです。

  1. エージェント レベルのフック:[BuilderHooks] に移動→、[フックの作成] を選択します。
  2. カスタム エージェント レベルのフック:[エージェント キャンバス] に移動→、カスタム エージェント→フックの管理を選択します。

ヒント

を使用して PUT /api/v2/extendedAgent/agents/{agentName} を使用してフックを構成することもできます。 次のセクションの YAML 形式は、完全な構成スキーマを示しています。 詳細については、 API チュートリアルを参照してください。

[Agent Canvas YAML] タブには v1 形式が表示され、フックは表示されません。 [ビルダー] の [フック] ページを使用して、フックを表示および管理します。

次の例は、完全なフック構成を示しています。

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 を出力する必要があります。 2 つの形式がサポートされています。

単純な形式 (プロンプト フックに推奨):

{"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設定 (allowまたはblock) を使用します

注意事項

停止フックの場合、 理由のない 拒否は承認として扱われ、エージェントは正常に停止します。 拒否するときは、常に reason フィールドを指定します。

同じイベントに対して複数のフックを定義できます。 PostToolUse の場合、一致する matcher パターンを持つ各フックは個別に実行されます。 複数のフックが additionalContextを提供する場合、最後のフックのコンテキストが会話に挿入されます。

構成のリファレンス

次の表では、使用可能なすべてのフック構成オプションについて説明します。

オプション タイプ デフォルト 説明
type 文字列 prompt prompt または command
prompt 文字列 LLM プロンプト テキスト (プロンプト フックに必要)。 コンテキスト挿入には $ARGUMENTS を使用します。
command 文字列 インライン シェル コマンド (コマンド フックの場合、 scriptと相互に排他的)。
script 文字列 複数行スクリプト (コマンド フックの場合、 commandと相互に排他的)。
matcher 文字列 ツール名の正規表現パターン (PostToolUse フックに必要)。 * は、すべてのツールと一致します。 パターンは ^(pattern)$ としてアンカーされ、大文字と小文字が区別されます。 空または null は何も一致しません。
timeout int 30 実行タイムアウトは秒単位で設定します(正の値である必要があります。300 を超える値には CLI 検証中に警告が出ます)。
failMode 文字列 allow フック エラーの処理方法: allow または block
model 文字列 ReasoningFast プロンプトフック用モデル(シナリオ名またはデプロイ名)。
maxRejections int 3 (エージェントの既定値) 強制停止前の最大拒否数。 範囲: 1 ~ 25。 prompt-type Stop hooks にのみ適用されます。 コマンドタイプのストップフックには暗黙的な制限はありません。 複数のプロンプト フックで異なる値が指定されている場合は、最大値が使用されます。

フック コンテキスト スキーマ

フックは、現在のイベントに関する構造化された JSON コンテキストを受け取ります。 プロンプト フックは、プロンプト テキストの $ARGUMENTS プレースホルダーを介してコンテキストを受信します。 コマンド フックは、stdinの JSON としてコンテキストを受け取ります。

どちらの種類のフックでも、 execution_summary フィールドには、(インライン コンテンツではなく) 会話トランスクリプトへの ファイル パス が含まれます。 プロンプト フックの場合、LLM は、このファイルにアクセスするための ReadFile および GrepSearch ツールを受け取ります。 コマンド フックの場合、ファイルはサンドボックス内の指定されたパスで使用できます。

共通フィールド

すべてのフックは、次のフィールドを受け取ります。

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

フック フィールドを停止する

ストップ フックは、エージェントの最終的な出力に関する追加のフィールドを受け取ります。

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

PostToolUse フック フィールド

PostToolUse フックは、ツールの実行に関する追加のフィールドを受け取ります。

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

制限

エージェント フックには、次の制限が適用されます。

制限 価値
スクリプト サイズ 最大 64 KB
Timeout 1 ~ 300 秒
最大拒否数 (プロンプト停止フック) 1 ~ 25 (既定値: 3)
サポートされているスクリプト shebangs #!/bin/bash#!/usr/bin/env python3
スクリプト実行環境 サンドボックス コード インタープリター

例: すべてのツールの使用状況を監査する

次の PostToolUse フックは、すべてのツール呼び出しをログに記録し、監査コンテキスト メッセージを追加します。

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. stderr にログを記録する: 出力のデバッグに stderr を使用します。 システムは、フックの結果として stdout を解析します。

実際に試してみる

次のスクリーンショットは、停止フックの動作を示しています。 エージェントは最初は "4" だけで応答しますが、完了マーカーがないため、フックは応答を拒否します。 エージェントは続行し、マーカーを追加します。

フックの拒否後にエージェントの応答が完了マーカーで修飾されている[Stop hook in action]\(フックの停止\) を示すスクリーンショット。

概要

資源 学習する内容
エージェント フックの構成 (API) REST API v2 と YAML を使用してフックを設定する
能力 関連付け方法
実行モード フックは、実行モードの安全制御を補完します。 モード は実行内容 を制御し、フックは実行 の程度を 制御します。
Python ツール フックによって監査と検証が可能なカスタムツールを作成します。