AskUserQuestion 工具)时。两者都会触发您的 canUseTool 回调,该回调会暂停执行,直到您返回响应。这与普通对话轮次不同,在普通对话轮次中 Claude 完成后等待您的下一条消息。
对于澄清问题,Claude 生成问题和选项。您的角色是向用户呈现这些问题,并返回他们的选择。您不能向此流程添加自己的问题;如果您需要自己询问用户某些内容,请在应用程序逻辑中单独进行。
回调可以无限期地保持待处理状态。执行保持暂停状态,直到您的回调返回,SDK 仅在查询本身被取消时才取消等待。如果用户可能需要比您的进程能够合理保持运行的时间更长的时间来响应,请返回 defer hook 决定,它允许进程退出并稍后从持久化会话恢复。
本指南向您展示如何检测每种类型的请求并做出适当的响应。
检测 Claude 何时需要输入
在您的查询选项中传递canUseTool 回调。每当 Claude 需要用户输入时,回调就会触发,接收工具名称和输入作为参数:
- 工具需要批准:Claude 想要使用不被权限规则或模式自动批准的工具。检查
tool_name以获取工具(例如"Bash"、"Write")。 - Claude 提出问题:Claude 调用
AskUserQuestion工具。检查tool_name == "AskUserQuestion"以不同方式处理它。如果您指定tools数组,请包含AskUserQuestion以使其工作。有关详细信息,请参阅处理澄清问题。
要自动允许或拒绝工具而不提示用户,请改用 hooks。Hooks 在
canUseTool 之前执行,可以根据您自己的逻辑允许、拒绝或修改请求。您还可以使用 PermissionRequest hook 在 Claude 等待批准时发送外部通知(Slack、电子邮件、推送)。处理工具批准请求
一旦您在查询选项中传递了canUseTool 回调,当 Claude 想要使用不被自动批准的工具时,它就会触发。您的回调接收三个参数:
| 参数 | 描述 |
|---|---|
toolName | Claude 想要使用的工具的名称(例如 "Bash"、"Write"、"Edit") |
input | Claude 传递给工具的参数。内容因工具而异。 |
options (TS) / context (Python) | 附加上下文,包括可选的 suggestions(建议的 PermissionUpdate 条目以避免重新提示)和取消信号。在 TypeScript 中,signal 是 AbortSignal;在 Python 中,信号字段保留供将来使用。有关 Python,请参阅 ToolPermissionContext。 |
input 对象包含工具特定的参数。常见示例:
| 工具 | 输入字段 |
|---|---|
Bash | command、description、timeout |
Write | file_path、content |
Edit | file_path、old_string、new_string |
Read | file_path、offset、limit |
在 Python 中,
can_use_tool 需要流模式和返回 {"continue_": True} 的 PreToolUse hook 以保持流打开。没有此 hook,流会在权限回调被调用之前关闭。y 之外的任何输入都被视为拒绝。在实践中,您可能会构建一个更丰富的 UI,让用户修改请求、提供反馈或完全重定向 Claude。有关所有响应方式,请参阅响应工具请求。
响应工具请求
您的回调返回两种响应类型之一:| 响应 | Python | TypeScript |
|---|---|---|
| 允许 | PermissionResultAllow(updated_input=...) | { behavior: "allow", updatedInput } |
| 拒绝 | PermissionResultDeny(message=...) | { behavior: "deny", message } |
- 批准:让工具按 Claude 请求的方式执行
- 批准并进行更改:在执行前修改输入(例如,清理路径、添加约束)
- 批准并记住:回显建议的权限规则,以便匹配的调用在下次跳过提示
- 拒绝:阻止工具并告诉 Claude 原因
- 建议替代方案:阻止但指导 Claude 朝向用户想要的方向
- 完全重定向:使用流输入向 Claude 发送全新指令
- 批准
- 批准并进行更改
- 批准并记住
- 拒绝
- 建议替代方案
- 完全重定向
用户按原样批准该操作。从您的回调中传递
input 不变,工具完全按 Claude 请求的方式执行。处理澄清问题
当 Claude 需要在具有多个有效方法的任务上获得更多指导时,它会调用AskUserQuestion 工具。这会触发您的 canUseTool 回调,其中 toolName 设置为 AskUserQuestion。输入包含 Claude 的问题作为多选选项,您向用户显示这些问题并返回他们的选择。
以下步骤显示如何处理澄清问题:
传递 canUseTool 回调
在您的查询选项中传递
canUseTool 回调。默认情况下,AskUserQuestion 可用。如果您指定 tools 数组来限制 Claude 的功能(例如,仅具有 Read、Glob 和 Grep 的只读代理),请在该数组中包含 AskUserQuestion。否则,Claude 将无法提出澄清问题:解析问题输入
输入包含 Claude 在 有关完整字段描述,请参阅问题格式。
questions 数组中的问题。每个问题都有 question(要显示的文本)、options(选择)和 multiSelect(是否允许多个选择):将答案返回给 Claude
将
对于多选问题,传递标签数组或用
answers 对象构建为记录,其中每个键是 question 文本,每个值是所选选项的 label:| 来自问题对象 | 用作 |
|---|---|
question 字段(例如 "How should I format the output?") | 键 |
所选选项的 label 字段(例如 "Summary") | 值 |
", " 连接它们。如果您支持自由文本输入,使用用户的自定义文本作为值。问题格式
输入包含 Claude 在questions 数组中生成的问题。每个问题都有这些字段:
| 字段 | 描述 |
|---|---|
question | 要显示的完整问题文本 |
header | 问题的短标签(最多 12 个字符) |
options | 2-4 个选择的数组,每个都有 label 和 description。TypeScript:可选 preview(请参阅下文) |
multiSelect | 如果为 true,用户可以选择多个选项 |
选项预览 (TypeScript)
toolConfig.askUserQuestion.previewFormat 向每个选项添加 preview 字段,以便您的应用可以在标签旁显示视觉模型。没有此设置,Claude 不会生成预览,该字段不存在。
previewFormat | preview 包含 |
|---|---|
| 未设置(默认) | 字段不存在。Claude 不会生成预览。 |
"markdown" | ASCII 艺术和围栏代码块 |
"html" | 样式的 <div> 片段(SDK 在您的回调运行前拒绝 <script>、<style> 和 <!DOCTYPE>) |
preview(布局选择、配色方案),并在不会的地方省略它(是/否确认、仅文本选择)。在呈现前检查 undefined。
响应格式
返回answers 对象,将每个问题的 question 字段映射到所选选项的 label:
| 字段 | 描述 |
|---|---|
questions | 传递原始问题数组(工具处理需要) |
answers | 对象,其中键是问题文本,值是所选标签 |
response | 可选的自由格式回复,用户输入的而不是回答结构化问题 |
", " 连接它们。对于按问题的自由文本,例如”其他”选项,将用户的文本放在 answers[question] 中,如支持自由文本输入中所示。仅当您的 UI 让用户关闭问题卡并输入不是任何特定问题答案的一般回复时,才设置 response。当设置 response 时,Claude 会收到”用户回复:…”而不是按问题答案列表。
支持自由文本输入
Claude 的预定义选项并不总是涵盖用户想要的内容。要让用户输入自己的答案:- 在 Claude 的选项后显示额外的”其他”选择,接受文本输入
- 使用用户的自定义文本作为答案值(不是单词”其他”)
完整示例
当 Claude 需要用户输入来继续时,它会提出澄清问题。例如,当被要求帮助为移动应用程序决定技术栈时,Claude 可能会询问跨平台与原生、后端偏好或目标平台。这些问题帮助 Claude 做出与用户偏好相匹配的决定,而不是猜测。 此示例在终端应用程序中处理这些问题。以下是每个步骤发生的情况:- 路由请求:
canUseTool回调检查工具名称是否为"AskUserQuestion"并路由到专用处理程序 - 显示问题:处理程序循环遍历
questions数组并打印每个问题及编号选项 - 收集输入:用户可以输入数字来选择选项,或直接输入自由文本(例如”jquery”、“i don’t know”)
- 映射答案:代码检查输入是数字(使用选项的标签)还是自由文本(使用文本直接)
- 返回给 Claude:响应包括原始
questions数组和answers映射
限制
- 子代理:
AskUserQuestion目前在通过 Agent 工具生成的子代理中不可用 - 问题限制:每个
AskUserQuestion调用支持 1-4 个问题,每个 2-4 个选项
获取用户输入的其他方式
canUseTool 回调和 AskUserQuestion 工具涵盖了大多数批准和澄清场景,但 SDK 提供了其他从用户获取输入的方式:
流输入
当您需要以下情况时,使用流输入:- 在任务中断代理:在 Claude 工作时发送取消信号或改变方向
- 提供额外上下文:添加 Claude 需要的信息而无需等待它提出问题
- 构建聊天界面:让用户在长时间运行的操作期间发送后续消息
自定义工具
当您需要以下情况时,使用自定义工具:- 收集结构化输入:构建超越
AskUserQuestion多选格式的表单、向导或多步工作流 - 集成外部批准系统:连接到现有的票务、工作流或批准平台
- 实现特定领域的交互:创建针对您的应用程序需求定制的工具,如代码审查界面或部署清单
canUseTool 回调更多的实现工作。
相关资源
- 配置权限:设置权限模式和规则
- 使用 hooks 控制执行:在代理生命周期的关键点运行自定义代码
- TypeScript SDK 参考:完整的 canUseTool API 文档