# ADKの便利で実践的な使い方
## 🎛️ エージェントの振る舞いを自在に制御!ADKのCallbacks機能
LLM呼び出しの前にガードレールをかけたい、ツール実行前にバリデーションしたい…そんな要望、ADKの **Callbacks** なら全部叶います!🔧
## 📌 タイトル
Callbacks(コールバック)
## 🔗 URL
## 🧩 概要
Callbacksは、エージェントの実行フローの重要なポイントにフックを仕掛け、振る舞いを観察・カスタマイズ・制御するための仕組みです。フレームワークのコアを変更することなく、6種類のコールバックで柔軟な制御が可能です。
- **before_agent / after_agent**:エージェント実行の前後
- **before_model / after_model**:LLM呼び出しの前後
- **before_tool / after_tool**:ツール実行の前後
最大のポイントは **戻り値によるフロー制御**。`None` を返せば通常続行、特定のオブジェクトを返せばその先の処理をスキップできます。
## 🛠 使い方
**LLM呼び出しをスキップする(入力ガードレール/キャッシュ):**
`before_model_callback` を定義し、引数として `CallbackContext` と `LlmRequest` を受け取り、戻り値を `Optional[LlmResponse]` とします。`llm_request.contents[-1].parts[0].text` からユーザーの最後のメッセージを取得し、禁止ワードが含まれていれば `LlmResponse` に `Content(role="model")` と拒否メッセージを詰めて返すことでLLM呼び出しをスキップします。問題なければ `None` を返して通常のLLM呼び出しを続行します。
**ツール実行をスキップする(バリデーション/モック):**
`before_tool_callback` を定義し、`context`、`tool`、`args` を受け取ります。戻り値は `Optional[Dict]` です。`validate_args(args)` で引数を検証し、不正であれば `{"error": "引数が不正です"}` という辞書を返してツール実行をスキップします。正常であれば `None` を返して通常実行を続行します。
**エージェント実行をスキップする:**
`before_agent_callback` を定義し、`context` を受け取り、戻り値を `Optional[Content]` とします。`is_authorized(context)` で権限チェックを行い、権限がなければ `Content(role="model", parts=[Part(text="権限がありません")])` を返してエージェント実行をスキップします。認可済みであれば `None` を返して通常続行します。
## 🏗 実践的な使い方
**入力ガードレール + レスポンスキャッシュの組み合わせ:**
`smart_before_model` 関数を定義し、`ctx` と `req` を受け取り `Optional[LlmResponse]` を返します。まず Step 1 として `req.contents[-1].parts[0].text` からユーザー入力を取得し、`contains_pii()` で個人情報を検出した場合は拒否メッセージ入りの `LlmResponse` を返してLLM呼び出しをスキップします。次に Step 2 として `hash(user_input)` でキャッシュキーを生成し、`ctx.state.get(f"cache:{cache_key}")` でキャッシュを検索します。キャッシュがあればそのテキストを `LlmResponse` に詰めて返し、なければ `None` を返してLLM呼び出しに進みます。最後に `LlmAgent` を作成する際、`name="SecureAgent"`、`model="gemini-2.0-flash"` を指定し、`before_model_callback=smart_before_model` でこのコールバックを登録します。
## 💡 ユースケース
- 🛡️ **入力ガードレール**:不適切な入力やプロンプトインジェクションをLLM呼び出し前にブロック
- 💾 **レスポンスキャッシュ**:同じ質問にはキャッシュから即座に応答しコスト削減
- 🔍 **デバッグ・ログ**:各実行ポイントでリクエスト/レスポンスを記録
- ✅ **ツールバリデーション**:ツール引数の事前検証でエラーを未然に防止
- 🧪 **テスト用モック**:本番ツールの代わりにモックレスポンスを返す
## ⚠️ 注意点
- コールバックは同期的に実行されるため、重い処理(外部API呼び出し等)は避けてください
- `before_*` で値を返すと後続処理が完全にスキップされるため、意図しないスキップに注意
- セキュリティガードレールをエージェント横断で適用したい場合は、Callbacksよりも **Plugins** の利用を検討してください
- エラーハンドリングは必ず try-except で囲み、コールバックのエラーがエージェント全体をクラッシュさせないようにしましょう
## ✨ まとめ
ADKのCallbacksは、エージェントの実行フローに対する「外科手術的な制御」を可能にします。ガードレール、キャッシュ、ログ、バリデーション…あらゆるクロスカッティングな関心事を、コアロジックを汚さずに実装できます。まずは `before_model_callback` から始めてみましょう!
#
ADK# #
AIAgent#