フックは、重要な時点でエージェントの動作をインターセプトして制御するカスタム チェックポイントです。 フックを使用して、エージェントの応答に品質ゲートを適用し、ツールの使用状況を監査および制御し、ポリシーを適用して危険な操作をブロックし、エージェントの出力を検証してタスクの早期完了を防ぎます。
問題
エージェントは、インシデントの調査、ツールの実行、応答の生成などのタスクを自律的に実行します。 しかし、見落としのない自律性はリスクを生み出します。
- 不完全な応答: エージェントは、要求したすべての内容に対処する前に "完了" と表示されます。
- 監査されていないツールの使用状況: エージェントが呼び出すツールや、その結果を把握することはできません。
- ポリシーが施行されていない: 危険な操作 (破壊的コマンド、未承認の変更) は確認なしで進行します。
- 品質ギャップ: 検証手順がないため、応答は重要な情報を見逃します。
エージェントの動作を遅くしたり、その自律性を完全に削除したりすることなく、重要な瞬間にエージェントの動作をインターセプトする方法が必要です。
エージェント フックのしくみ
フックは、特定のエージェント イベントにアタッチするカスタム チェックポイントです。 イベントが発生すると、フックは状況を評価し、アクションを許可するかブロックするかを決定します。
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 -rf、 sudo、およびその他の危険なパターンを自動的にブロックします |
| 品質保証 | プロンプトエンジニアリングはあなたの唯一のレバーです | LLMベースのフックは微妙な差異を評価します。スクリプトは決定論的なルールを強制します。 |
フックの構成
フックを作成する最も簡単な方法は、ポータル UI を使用することです。
- エージェント レベルのフック:[Builder → Hooks] に移動→、[フックの作成] を選択します。
- カスタム エージェント レベルのフック:[エージェント キャンバス] に移動→、カスタム エージェント→フックの管理を選択します。
ヒント
を使用して 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
ベスト プラクティス
エージェント フックを構成するときは、次のガイドラインに従います。
- 拒否する場合は、常に理由を指定してください。 理由なく却下を承認として扱います。
- 適切なタイムアウトを使用する: 実行時間の長いフックにより、エージェントの実行速度が低下します。
-
エラーを適切に処理する: 厳密な強制が必要な場合を除き、
failMode: allowを使用します。 - マッチャーに固有にする: 広範な PostToolUse マッチャーは、パフォーマンスの問題を引き起こす可能性があります。
-
フックを徹底的にテストする: 常に拒否するフックはループを引き起こす可能性があります (
maxRejectionsによって軽減されます)。 - stderr にログを記録する: 出力のデバッグに stderr を使用します。 システムは、フックの結果として stdout を解析します。
実際に試してみる
次のスクリーンショットは、停止フックの動作を示しています。 エージェントは最初は "4" だけで応答しますが、完了マーカーがないため、フックは応答を拒否します。 エージェントは続行し、マーカーを追加します。
概要
| 資源 | 学習する内容 |
|---|---|
| エージェント フックの構成 (API) | REST API v2 と YAML を使用してフックを設定する |
関連するコンテンツ
| 能力 | 関連付け方法 |
|---|---|
| 実行モード | フックは、実行モードの安全制御を補完します。 モード は実行内容 を制御し、フックは実行 の程度を 制御します。 |
| Python ツール | フックによって監査と検証が可能なカスタムツールを作成します。 |