ヒント
ポータル UI を使用しますか? REST API を使用せずに、ポータルでフックを直接作成および管理できるようになりました。 ポータルには、ビジュアル フォームとコード エディターが用意されています。
curlコマンドは必要ありません。
このチュートリアルでは、Stop フックを使用してカスタム エージェントを作成します。このフックにより、エージェントがすべての応答に完了マーカーを強制的に追加します。 REST API を使用してフックを構成し、ポータルのプレイグラウンドでテストします。
推定時間: 15 分
注
エージェント レベルとカスタム エージェント レベルのフック: このチュートリアルでは、 カスタム エージェント (カスタム エージェント レベルのフック) にフックを作成します。 これらのフックは、その特定のカスタム エージェントが実行されている場合にのみ発生します。
エージェント全体 (すべてのスレッド、すべてのカスタム エージェント) に適用されるエージェント レベルのフック を作成するには、ポータルで Builder>Hooks を使用します。
| レベル | 作成する方法 | Scope |
|---|---|---|
| エージェント レベル | ポータル: ビルダー > フック | すべてのスレッドとカスタム エージェントに適用されます |
| カスタム エージェント レベル | REST API (このチュートリアル) またはポータル: Agent Canvas > カスタム エージェント > フックの管理 | 1 つのカスタム エージェントにのみ適用されます |
このチュートリアルでは、以下の内容を学習します。
- REST API を使用して Stop フックを使用してカスタム エージェントを作成する
- ポータルのテストプレイグラウンドでフック動作をテストします
- 監査ツールの使用のための PostToolUse フックを追加する
- ポリシー フックを使用して危険なコマンドをブロックする
前提条件
- 実行中の状態の Azure SRE エージェント
- curl を使用して REST API を呼び出す
-
Azure CLI がログイン (
az login) してアクセス トークンを取得する
フック API 形式を理解する
このチュートリアルでは、 REST API v2 を使用して、カスタム エージェントにフックを作成します。 ポータルの YAML エディター タブには v1 形式が表示され、API を介して構成されたフックは表示されませんが、フックはまだアクティブです。 これらを確認するには、 Builder>Hooks ページまたは テスト プレイグラウンドを使用します。
ヒント
API とポータルを使用する場合:
- ポータル (Builder > Hooks): ビジュアル形式のエージェント レベルのフックに最適です。 コードは必要ありません。
- API (このチュートリアル): カスタム エージェント レベルのフック、CI/CD パイプライン、またはプログラムによる管理に最適です。
エージェントの API URL を見つける
エージェントの API ベース URL は、次のパターンに従います。
https://{agent-name}--{hash}.{hash}.{region}.azuresre.ai
検索するには:
- sre.azure.com を開き、エージェントを選択します。
- 左側のサイドバーで、 Builder>Agent Canvas を選択します。
- ブラウザーの 開発者ツール を開きます (F12キーを押すか、>を右クリックして検証します)。
-
[ネットワーク] タブに移動し、"api" でフィルター処理し、
.azuresre.aiで終わる URL への要求を探します。 - ベース URL は、
/api/...前のすべてです。
または、[src] タブで属性を確認します。<iframe>がsrcで始まるhttps://{agent-name}--を探します。
アクセス トークンを取得する
次のコマンドを実行して、SRE エージェント API のアクセス トークンを取得します。
TOKEN=$(az account get-access-token \
--resource <RESOURCE_ID> \
--query accessToken -o tsv)
Stop フックを使用してカスタム エージェントを作成する
この手順では、応答が my_hooked_agent で終了するかどうかを確認する Stop フックを使用して、=== RESPONSE COMPLETE === というカスタム エージェントを作成します。 マーカーがない場合、フックは応答を拒否し、マーカーを追加するようエージェントに指示します。
AGENT_URL="https://your-agent--xxxxxxxx.yyyyyyyy.region.azuresre.ai"
curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"name": "my_hooked_agent",
"properties": {
"instructions": "You are a helpful assistant. Be concise.",
"handoffDescription": "",
"handoffs": [],
"enableVanillaMode": true,
"hooks": {
"Stop": [
{
"type": "prompt",
"prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
"timeout": 30
}
]
}
}
}
EOF
応答本文に完全なエージェント構成が含まれた状態で HTTP 202 Accepted を受け取ります。
次の例は、参照用の v2 YAML 形式の同じ構成を示しています。
api_version: azuresre.ai/v2
kind: ExtendedAgent
metadata:
name: my_hooked_agent
spec:
instructions: |
You are a helpful assistant. Be concise.
handoffDescription: ""
enableVanillaMode: true
hooks:
Stop:
- type: prompt
prompt: |
Check the agent response below.
$ARGUMENTS
Does it end with === RESPONSE COMPLETE ===?
If yes: {"ok": true}
If no: {"ok": false, "reason": "Add === RESPONSE COMPLETE === at the end."}
timeout: 30
ストップフックのしくみ
Stop フックは、ユーザーに戻る前にエージェントの応答を評価します。
-
$ARGUMENTSをフック コンテキスト JSON に置き換えます。これには、エージェントの最終的な応答が含まれます。 - LLM はプロンプトを評価し、
{"ok": true}または{"ok": false, "reason": "..."}を返します。 - 拒否された場合、エージェントは、理由がユーザー メッセージとして挿入された後も引き続き動作します。
- 3 回の拒否 (既定値) の後、エージェントは停止します。
ポータルでフックをテストする
停止フックをテストするには、次の手順に従います。
ポータルでエージェントに移動し、 Builder>Agent Canvas を選択します。
[ テスト プレイグラウンド ] ラジオ ボタンを選択します。
[サブエージェント/ツール] ドロップダウンを選択し、my_hooked_agentを見つけて、[適用] を選択します。
チャットに「
What is 2+2?」と入力し、[送信] を選択 します。
何が起こるかを見る:
- エージェントは最初に 4 で応答 します。
- Stop フックは応答を評価して拒否します (完了マーカーなし)。
- エージェントが処理を継続する箇所に、思考プロセス手順が表示されます。
- 最後の応答が表示されます: 4 === RESPONSE COMPLETE ===。
フックが機能しました。 停止する前に、エージェントにマーカーの追加を強制しました。
監査用の PostToolUse フックを追加する
エージェントが使用するすべてのツールをログに記録する PostToolUse フックを追加します。 両方のフックを使用して新しい PUT 要求を送信して、同じエージェントを更新します。
curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"name": "my_hooked_agent",
"properties": {
"instructions": "You are a helpful assistant. Be concise.",
"handoffDescription": "",
"handoffs": [],
"enableVanillaMode": true,
"hooks": {
"Stop": [
{
"type": "prompt",
"prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
"timeout": 30
}
],
"PostToolUse": [
{
"type": "command",
"matcher": "*",
"timeout": 30,
"failMode": "allow",
"script": "#!/usr/bin/env python3\nimport sys, json\ncontext = json.load(sys.stdin)\ntool = context.get('tool_name', 'unknown')\nprint(json.dumps({'decision': 'allow', 'hookSpecificOutput': {'additionalContext': f'[AUDIT] {tool} executed.'}}))"
}
]
}
}
}
EOF
matcher: "*" は、このフックがすべてのツール呼び出しに対して実行されます。 このスクリプトは、ツール名をログに記録し、会話に [AUDIT] メッセージを挿入します。
フックをテストするには、ツールをトリガーする質問 (" echo hello実行" など) をエージェントに依頼します。
危険なコマンドをブロックする
rm -rf、sudo、およびchmod 777をブロックする 2 つ目の PostToolUse フックを追加します。
PostToolUse:
# Audit hook (runs for all tools)
- type: command
matcher: "*"
timeout: 30
failMode: allow
script: |
#!/usr/bin/env python3
import sys, json
context = json.load(sys.stdin)
tool = context.get('tool_name', 'unknown')
print(json.dumps({"decision": "allow",
"hookSpecificOutput": {"additionalContext": f"[AUDIT] {tool} executed."}}))
# Policy hook (only for shell tools)
- 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', '')
for pattern in [r'\brm\s+-rf\b', r'\bsudo\b', r'\bchmod\s+777\b']:
if re.search(pattern, command):
print(json.dumps({"decision": "block", "reason": f"Blocked: {pattern}"}))
sys.exit(0)
print(json.dumps({"decision": "allow"}))
監査フックとの主な違い:
-
matcher: "Bash|ExecuteShellCommand"シェル ツールに対してのみ実行されます (パターンは^(Bash|ExecuteShellCommand)$として固定されます)。 -
failMode: blockは、スクリプト自体がクラッシュした場合にツールの結果をブロックします (厳密モード)。 - 危険なパターンが見つかった理由で
"block"を返します。
フック応答形式
プロンプト フックとコマンド フックでは、さまざまな応答形式が使用されます。
プロンプト フック
プロンプト フックは単純な JSON を返します。
{"ok": true}
{"ok": false, "reason": "Please fix X."}
コマンド フック
コマンド フックは、展開された JSON を返します。
{"decision": "allow"}
{"decision": "block", "reason": "Dangerous command."}
{"decision": "allow", "hookSpecificOutput": {"additionalContext": "Audit note."}}
コマンド フックでは、JSON の代わりに終了コードを使用することもできます。
| 終了コード | 行動 |
|---|---|
0 出力なし |
許可する |
0 JSON を使用する |
JSON を解析する |
2 |
ブロック (stderr が原因になります) |
| その他 |
failModeにフォールバックします |
注意事項
理由のない却下は承認として扱われます。 拒否するときは、常に reason を含めます。
確かめる
フックを構成してテストした後、次の条件を確認します。
- カスタム エージェント レベルのフックは、REST API v2 を使用して構成します。 これらは、そのカスタム エージェントにのみ適用されます。
- エージェント レベルのフックは、Builder > Hooks で作成します。 エージェント全体に適用されます。
- 停止フックにより、エージェントは停止する前に
=== RESPONSE COMPLETE ===マーカーを追加します。 - PostToolUse監査フックは、ツール呼び出し時にメッセージを
[AUDIT]に記録します。 - ポリシー フックは、
rm -rfやsudoなどの危険なコマンドをブロックします。
Troubleshooting
次の表に、エージェント フックに関する一般的な問題と解決策を示します。
| 問題 | ソリューション |
|---|---|
| ポータルの [YAML] タブにフックが表示されない | 予期される - [YAML] タブには v1 のみが表示されます。 API を介して作成されたカスタム エージェント レベルのフックはアクティブであり、 Builder>Hooks またはプレイグラウンドに表示されます。 |
Unsupported kind: ExtendedAgent |
v2 エンドポイント ( PUT /api/v2/extendedAgent/agents/{name}) を使用します。 |
Handoffs cannot be null |
JSON ペイロードに "handoffs": [] を追加します。 |
| フックは効果がありません | 拒否時に reason フィールドを含めます。 これを行わないと、拒否は承認として扱われます。 |
| エージェントが無限にループする | 下位 maxRejections (既定値: 3、範囲: 1 ~ 25)。 |