AskUserQuestion ツール経由)です。どちらも canUseTool コールバックをトリガーし、応答を返すまで実行を一時停止します。これは Claude が終了して次のメッセージを待つ通常の会話ターンとは異なります。
確認質問については、Claude が質問とオプションを生成します。あなたの役割は、それらをユーザーに提示して、ユーザーの選択を返すことです。このフローに独自の質問を追加することはできません。ユーザーに何か尋ねる必要がある場合は、アプリケーションロジックで別途実行してください。
コールバックは無期限に保留中のままにすることができます。実行はコールバックが返されるまで一時停止したままであり、SDK はクエリ自体がキャンセルされた場合にのみ待機をキャンセルします。ユーザーがプロセスが合理的に実行し続けることができるより長く応答するのに時間がかかる可能性がある場合、defer フック決定を返します。これにより、プロセスを終了して、後で永続化されたセッションから再開できます。
このガイドでは、各タイプのリクエストを検出し、適切に応答する方法を示します。
Claude が入力を必要とする場合を検出する
クエリオプションでcanUseTool コールバックを渡します。Claude がユーザー入力を必要とするたびにコールバックが発火し、ツール名と入力を引数として受け取ります。
- ツールが承認を必要とする場合:Claude が 許可ルールまたはモードによって自動承認されていないツールを使用したい場合。
tool_nameでツール(例:"Bash"、"Write")を確認します。 - Claude が質問をする場合:Claude が
AskUserQuestionツールを呼び出します。tool_name == "AskUserQuestion"をチェックして、異なる方法で処理します。tools配列を指定する場合は、これが機能するようにAskUserQuestionを含めます。詳細は 確認質問を処理するを参照してください。
PermissionRequest フックを使用して、Claude が承認を待っているときに外部通知(Slack、メール、プッシュ)を送信することもできます。
ツール承認リクエストを処理する
クエリオプションでcanUseTool コールバックを渡すと、Claude が自動承認されていないツールを使用したい場合に発火します。コールバックは 3 つの引数を受け取ります。
input オブジェクトにはツール固有のパラメーターが含まれます。一般的な例:
完全な入力スキーマについては SDK リファレンスを参照してください。Python | TypeScript。
この情報をユーザーに表示して、アクションを許可するか拒否するかを決定してから、適切な応答を返すことができます。
次の例では、Claude にテストファイルを作成して削除するよう要求します。Claude が各操作を試みるたびに、コールバックはツールリクエストをターミナルに出力し、y/n 承認を求めます。
Python では、
can_use_tool は ストリーミングモードが必要です。有限のメッセージストリームを query(prompt=generator) または ClaudeSDKClient.connect(prompt=async_iterable) を通じて渡すと、登録されたフックまたはプロセス内 MCP サーバーがストリームを開いたままにしていない限り、SDK は最後のメッセージの後、許可コールバックが呼び出される前にストリームを閉じます。上記の例は、{"continue_": True} を返す PreToolUse フックでストリームを開いたままにします。プロンプトなしで接続し、ClaudeSDKClient.query() を通じてメッセージを送信すると、ストリームは自動的に開いたままになり、フックは不要です。y 以外の入力は拒否として扱われます。実際には、ユーザーがリクエストを変更したり、フィードバックを提供したり、Claude を完全にリダイレクトしたりできるより豊富な UI を構築する可能性があります。すべての応答方法については ツールリクエストに応答するを参照してください。
ツールリクエストに応答する
コールバックは 2 つの応答タイプのいずれかを返します。
許可する場合、Claude がリクエストした入力でツールが実行されます。ただし、変更された入力を返す場合は、TypeScript では
updatedInput、Python では updated_input を返すことができます。v2.1.207 より前では、Claude Code は updatedInput を省略した許可結果を拒否し、検証エラーでツール呼び出しを拒否していました。
拒否する場合、理由を説明するメッセージを提供します。Claude はこのメッセージを見て、アプローチを調整する可能性があります。
- 承認:ツールを Claude がリクエストしたとおりに実行させる
- 変更を加えて承認:実行前に入力を変更する(例:パスをサニタイズ、制約を追加)
- 承認して記憶:提案された許可ルールをエコーバックして、一致する呼び出しが次回プロンプトをスキップするようにする
- 拒否:ツールをブロックして Claude に理由を伝える
- 代替案を提案:ブロックするが、ユーザーが望むものに向かって Claude をガイドする
- 完全にリダイレクト:ストリーミング入力を使用して Claude に完全に新しい指示を送信する
- 承認
- 変更を加えて承認
- 承認して記憶
- 拒否
- 代替案を提案
- 完全にリダイレクト
ユーザーはアクションをそのまま承認します。コールバックから
input をそのまま渡し、ツールは Claude がリクエストしたとおりに実行されます。確認質問を処理する
Claude が複数の有効なアプローチを持つタスクについてさらに方向性が必要な場合、AskUserQuestion ツールを呼び出します。これは toolName が AskUserQuestion に設定された canUseTool コールバックをトリガーします。入力には Claude の質問が複数選択肢として含まれており、これらをユーザーに表示して、ユーザーの選択を返します。
次のステップは、確認質問を処理する方法を示しています。
1
canUseTool コールバックを渡す
クエリオプションで
canUseTool コールバックを渡します。デフォルトでは、AskUserQuestion が利用可能です。Claude の機能を制限するために tools 配列を指定する場合(例:Read、Glob、Grep のみを持つ読み取り専用エージェント)、その配列に AskUserQuestion を含めます。そうしないと、Claude は確認質問をすることができません。2
AskUserQuestion を検出する
コールバックで、
toolName が AskUserQuestion と等しいかどうかをチェックして、他のツールとは異なる方法で処理します。3
質問入力を解析する
入力には Claude の質問が 完全なフィールド説明については 質問形式を参照してください。
questions 配列に含まれています。各質問には question(表示するテキスト)、options(選択肢)、multiSelect(複数選択が許可されているかどうか)があります。4
ユーザーから回答を収集する
質問をユーザーに提示して、ユーザーの選択を収集します。これをどのように行うかは、アプリケーションによって異なります。ターミナルプロンプト、Web フォーム、モバイルダイアログなど。
5
Claude に回答を返す
answers オブジェクトをレコードとして構築します。各キーは question テキストで、各値は選択されたオプションの label です。複数選択質問の場合、ラベルの配列を渡すか、
", " で結合します。自由テキスト入力をサポートする場合は、ユーザーのカスタムテキストを値として使用します。質問形式
入力には Claude が生成した質問がquestions 配列に含まれています。各質問には以下のフィールドがあります。
コールバックが受け取る構造:
オプションプレビュー(TypeScript)
toolConfig.askUserQuestion.previewFormat は各オプションに preview フィールドを追加して、アプリがラベルと一緒に視覚的なモックアップを表示できるようにします。この設定がない場合、Claude はプレビューを生成せず、フィールドは存在しません。
形式はセッション内のすべての質問に適用されます。Claude は視覚的な比較が役立つオプション(レイアウト選択、配色)に
preview を含め、役立たないオプション(はい/いいえの確認、テキストのみの選択)では省略します。レンダリング前に undefined をチェックしてください。
応答形式
各質問のquestion フィールドを選択されたオプションの label にマップする answers オブジェクトを返します。
複数選択質問の場合、ラベルの配列を渡すか、
", " で結合します。自由テキスト入力をサポートに示されているような質問ごとの自由テキスト(例:「その他」オプション)の場合は、ユーザーのテキストを answers[question] に入力します。response は、ユーザーが質問カードを閉じて、特定の質問への回答ではない一般的な返信を入力できる UI の場合にのみ設定します。response が設定されている場合、Claude は質問ごとの回答リストではなく「ユーザーが応答しました:…」を受け取ります。
自由テキスト入力をサポートする
Claude の定義済みオプションがユーザーが望むものをカバーしていない場合があります。ユーザーが独自の回答を入力できるようにするには:- Claude のオプションの後に追加の「その他」選択肢を表示して、テキスト入力を受け入れます
- ユーザーのカスタムテキストを回答値として使用します(「その他」という単語ではなく)
完全な例
Claude は、タスクを進めるためにユーザー入力が必要な場合に確認質問をします。たとえば、モバイルアプリのテックスタックを決定するのに役立つよう求められた場合、Claude はクロスプラットフォーム対応 vs ネイティブ、バックエンド設定、またはターゲットプラットフォームについて質問する可能性があります。これらの質問は、Claude がユーザーの設定に合致する決定を下すのに役立ちます。推測ではなく。 この例は、ターミナルアプリケーションでこれらの質問を処理します。各ステップで何が起こるかは以下の通りです。- リクエストをルーティングする:
canUseToolコールバックはツール名が"AskUserQuestion"であるかどうかをチェックし、専用ハンドラーにルーティングします - 質問を表示する:ハンドラーは
questions配列をループして、各質問を番号付きオプションで出力します - 入力を収集する:ユーザーはオプションを選択する番号を入力するか、自由テキストを直接入力できます(例:「jquery」、「i don’t know」)
- 回答をマップする:コードは入力が数値(オプションのラベルを使用)か自由テキスト(テキストを直接使用)かをチェックします
- Claude に返す:応答には元の
questions配列とanswersマッピングの両方が含まれます
ask.ts として保存して npx tsx ask.ts で実行するか、Python バージョンを ask.py として保存して python ask.py で実行してください。
制限事項
- サブエージェント:
AskUserQuestionは現在、Agent ツール経由で生成されたサブエージェントでは利用できません - 質問の制限:各
AskUserQuestion呼び出しは 1~4 個の質問と 2~4 個のオプションをサポートします
ユーザー入力を取得する他の方法
canUseTool コールバックと AskUserQuestion ツールはほとんどの承認と明確化のシナリオをカバーしていますが、SDK はユーザーから入力を取得する他の方法を提供しています。
ストリーミング入力
以下が必要な場合は ストリーミング入力を使用します。- エージェントをタスク途中で中断する:Claude が作業中にキャンセル信号を送信するか、方向を変更する
- 追加コンテキストを提供する:Claude が尋ねるのを待たずに、Claude が必要とする情報を追加する
- チャットインターフェースを構築する:長時間実行される操作中にユーザーがエージェントと対話できるようにする
カスタムツール
以下が必要な場合は カスタムツールを使用します。- 構造化入力を収集する:
AskUserQuestionの複数選択形式を超えたフォーム、ウィザード、または複数ステップのワークフローを構築する - 外部承認システムを統合する:既存のチケット、ワークフロー、または承認プラットフォームに接続する
- ドメイン固有の対話を実装する:コードレビューインターフェースやデプロイメントチェックリストなど、アプリケーションのニーズに合わせたツールを作成する
canUseTool コールバックを使用するよりも実装作業が必要です。
関連リソース
- 権限を設定する:権限モードとルールを設定する
- フックで実行を制御する:エージェントライフサイクルの重要なポイントでカスタムコードを実行する
- TypeScript SDK リファレンス:完全な canUseTool API ドキュメント