Skip to content

功能规格说明:支持 AskUserQuestion 工具 ​

创建日期:2026-01-19

用户场景与测试 (必填) ​

用户故事:澄清模糊指令(优先级:P1) ​

作为 AI agent,当我收到用户的模糊指令时,我希望使用结构化的多选界面提出澄清问题,以便我可以在正确理解用户意图的情况下继续。

为什么是这个优先级:这是工具的核心价值。它防止 agent 做出错误假设并提高交互质量。

独立测试:可以通过给 agent 一个模糊任务(如"重构这个函数")并验证它使用 AskUserQuestion 工具询问期望的重构模式而不是猜测来测试。

验收场景:

  1. 假设 agent 正在处理任务,当遇到模糊性时,则它必须调用 AskUserQuestion 工具并提供相关选项。
  2. 假设用户看到问题,当用户选择选项时,则 agent 必须收到答案并基于该选择继续任务。

用户故事:在实现方案之间选择(优先级:P2) ​

作为 AI agent,当有多种有效方式实现功能时,我希望向用户展示这些选项,以便他们可以决定哪种方案最适合其需求。

为什么是这个优先级:使用户能够在不必自己编写代码的情况下做出架构或设计决策。

独立测试:可以通过要求 agent "添加认证" 并验证它询问是使用 JWT、OAuth2 还是基于 Session 的认证来测试。

验收场景:

  1. 假设 agent 处于规划或实施阶段,当识别出多种方案时,则它应该使用 AskUserQuestion 让用户选择。
  2. 假设选项中包含推荐项,则 agent 应该在标签中标记为 "(Recommended)"。

用户故事:在计划模式中收集需求(优先级:P2) ​

作为计划模式中的 AI agent,我希望在最终确定计划之前向用户询问缺失的需求,确保计划准确并获得批准。

为什么是这个优先级:确保规划阶段是交互式的并产生高质量计划。

独立测试:可以通过带着模糊请求进入计划模式并验证 agent 在调用 ExitPlanMode 之前提出问题来测试。

验收场景:

  1. 假设 agent 处于计划模式,当需求缺失时,则它必须使用 AskUserQuestion 来收集。
  2. 假设 agent 准备最终确定计划,则它不得将 AskUserQuestion 用于计划批准(必须使用 ExitPlanMode 代替)。

用户故事:选项组键盘可达(优先级:P1) ​

作为用户,当回答 agent 的提问时,我希望选项(单选/多选)逐个成为 Tab 可达的焦点目标、用空格选中、全部答完后用 Enter 提交,以便纯键盘用户无需鼠标即可选择任意选项并提交回答。

为什么是这个优先级:对齐 Claude IDE/桌面端的 AskUserQuestion 实际交互(permissionRequestContainer 选项每个 tabIndex={0},选项只响应 Enter/Space,方向键不参与选项导航,输入框内按键 stopPropagation 保持文本编辑语义)。曾实现 roving tabindex(组内单一 Tab stop + 方向键移动),与 CC 不一致,且方向键导航与「其他」输入框内左右键编辑光标冲突(输入框里按左右键会跳走焦点)。改后选项间用 Tab 遍历,输入框内方向键回归光标语义。Enter 键分工按交互设计师裁决(2026-08-27 a4466e21):Enter 仅用于全部题目答完后的提交、由空格负责选中选项——焦点在任意选项上时同样生效(答完按 Enter 即提交、未答完无动作),不把 Enter 当作选中键,避免与提交语义冲突(单选答完后重复按 Enter 若只做「选中」会变成无意义的 no-op,见场景 8/10 与「多问题循环轮播」)。

独立测试:触发 AskUserQuestion 弹窗,Tab 依次经过每个选项(含「其他」)、空格选中;在「其他」输入框内按方向键/空格确认光标移动与文本输入不受影响、不改变选中状态;Enter 仅用于提交(全部题目答完时提交,未答完无动作,见「多问题循环轮播」)。

验收场景:

  1. 假设 选项组渲染(单选或多选),当 Tab 遍历弹窗时,则 每个选项(含「其他」)都是独立 Tab stop(tabIndex={0}),Tab 依次经过全部选项,不跳过任何一项。
  2. 假设 焦点在某个选项上,当 用户按方向键(↑/↓/←/→)时,则 焦点不移动(方向键不参与选项导航)。
  3. 假设 焦点在某个选项上,当 用户按空格时,则 单选=替换为该选项;多选=切换该选项的勾选状态;当 用户按 Enter 时,则 Enter 仅用于提交(全部题目已答完时提交、未答完无动作),不改变选中状态(见场景 8/10 与「多问题循环轮播」)。
  4. 假设 「其他」选项被空格选中,则 输入框自动聚焦可直接输入(保留现有自动聚焦行为);未选中时提示「输入自定义回答...」照常显示。
  5. 假设 焦点在「其他」输入框内,当 用户按方向键或空格时,则 均为输入框自身的文本编辑行为(光标移动/输入空格),不触发选项选择或任何弹窗级快捷键(输入框内按键不冒泡到弹窗,对齐 CC 的 stopPropagation)。
  6. 假设 焦点在选项或「其他」输入框上,当 用户按 Enter(非 Shift)且非输入法合成中时,则 Enter 仅用于提交——全部题目已答完时提交,未答完时无动作,不负责切换题目、不改变选中状态(见「多问题循环轮播」场景 8/10)。
  7. 假设 用户回答完当前问题后切换到下一题(点击「下一个」或按 →),当 题目切换完成时,则 焦点落在新题目第一个选项(或当前已选中的选项)上,焦点不会因按钮状态变化而丢失到弹窗外。

用户故事:多问题循环轮播(优先级:P1) ​

作为用户,当 agent 在一次 AskUserQuestion 中提出多个问题时,我希望弹窗底部固定三个按钮([上一个] [下一个] [提交回答]),题目可循环轮播切换,以便我随时前后浏览、修改任意一题答案,清楚还剩多少问题要回答,不会因未答完而困惑为什么无法提交。

为什么是这个优先级:固定三按钮 + 循环轮播让多问题问卷的浏览路径不受边界限制(首页可「上一个」回看末题、末题可「下一个」回到首题),进度与答题状态一目了然;替换之前「向导式」(第一题仅「下一个」、中间「上一个/下一个」、最后一题才出现「提交回答」)的阶段性按钮组合——向导式在中间题不显示「提交回答」,用户想提交时还得先走到最后一题,循环轮播固定三按钮把「提交」入口始终可见。

独立测试:触发包含 3 个问题的 AskUserQuestion,逐题观察底部三按钮与启用状态;首页点「上一个」验证跳到末题、末题点「下一个」验证跳回首题;答完部分题目验证进度条对应段着色、提交按钮保持禁用;全部答完后验证「提交回答」可用并回车提交。

验收场景:

  1. 假设 弹窗包含多个问题,当 展示任意一题时,则 底部导航固定显示「上一个」「下一个」「提交回答」三个按钮(「提交回答」为主按钮、最右侧),不随题目位置隐藏或新增按钮。
  2. 假设 用户在第一题,当 点击「上一个」时,则 循环跳转到最后一题,且各题已填答案保留。
  3. 假设 用户在最后一题,当 点击「下一个」时,则 循环跳转到第一题,且各题已填答案保留。
  4. 假设 用户处于任意一题,当 按 ← 或 → 方向键时,则 循环切换上一题 / 下一题(与按钮行为一致)。
  5. 假设 题目进度条显示(每段代表一题),当 用户点击某一段时,则 直接定位到对应题目,不要求逐题翻页。
  6. 假设 用户已答完部分题目,当 查看进度条时,则 已答完的题目段标记为完成状态(着色),与当前浏览到第几题无关;回看已答题目时已答段保持完成色。
  7. 假设 弹窗存在未作答的题目,当 用户点击「提交回答」时,则 按钮保持禁用(不可点击);「上一个」「下一个」不受作答状态影响,始终可点。
  8. 假设 全部题目均已回答,当 用户点击「提交回答」或按 Enter 时,则 一次性提交所有问题的答案并关闭弹窗。
  9. 假设 弹窗只有一个问题,当 查看底部导航时,则 只显示「提交回答」,无「上一个/下一个」按钮。
  10. 假设 用户未答完所有题目,当 按 Enter 时,则 无动作(Enter 仅用于全部答完后的提交,不负责切换题目)。
  11. 假设 主按钮「提交回答」可提交时,则 按钮上显示回车键提示标注(⏎),提示可用回车提交。
  12. 假设 弹窗显示底部导航按钮,当 用户按 Tab 遍历按钮,则 焦点按视觉从左到右顺序遍历:「上一个」→「下一个」→ 主按钮「提交回答」(主按钮最后);Shift+Tab 反向(主按钮最先),Tab 陷阱仍限于弹窗内(与确认操作面板按钮布局一致,见 confirm-ui.md)。

边界情况 ​

  • 用户提供自定义输入:"Other" 选项的自定义输入框在用户选中 "Other" 后才出现;未选中时不显示输入框。
    • 用户选中 "Other" 后,输入框出现,输入的文本作为该问题的答案返回。
    • 用户选中 "Other"(键盘空格/Enter 或鼠标点击)后,输入框自动聚焦,可直接开始输入;切换题目时,若新题目此前已选中 "Other",不抢占输入框焦点(焦点落回选项组的第一个/已选中选项,用户需要时再 Tab 进入输入框)。
    • 未选中 "Other" 时,选项下方以灰色显示「输入自定义回答...」提示(复用普通选项的 description 样式),说明该选项可输入自定义内容;选中后提示由输入框替代。
    • 用户取消选择 "Other"(单选改选其他选项 / 多选取消勾选)时,输入框隐藏,但已输入的内容保留;再次选中 "Other" 时内容恢复,不丢失。
    • 选中 "Other" 但未输入任何内容时,不算有效答案,提交/下一步仍被禁用。
    • 多选模式行为相同:勾选 "Other" 显示输入框,取消勾选隐藏输入框(内容保留)。
  • 多个问题:一次最多 4 个问题。弹窗一次只显示一个问题,底部固定「上一个/下一个/提交回答」三按钮(循环轮播:首页「上一个」跳末题、末题「下一个」回首题,←/→ 方向键等效),顶部显示可点击的分段进度条(每段代表一题,已答段着色为完成状态,点击直接定位到对应题);所有问题都有有效答案后「提交回答」才可用(按钮带 ⏎ 提示),一次性提交全部答案。单问题(仅 1 题)只显示「提交回答」。
  • 键盘导航不改变答案:Tab 聚焦弹窗内任意元素(包括自定义输入框)只应移动焦点,不得改变已选答案;选中/取消选项必须来自明确的用户操作(点击或空格),Enter 只负责全部题目答完后的提交。
  • 多选答案:多个选中选项如何返回?应该以逗号分隔的字符串或类似的结构化格式返回。
  • 工具拒绝:如果用户拒绝回答怎么办?agent 应该被通知并决定是使用假设继续还是再次询问。
  • 选项与内容的关系:选项列表固定在确认 UI 底部始终可见,方向键不参与选项导航(选项间用 Tab 遍历),与上方内容区的滚动完全无关(内容区超高时的 PgUp/PgDn 滚动见 confirm-ui.md「确认详情超高时滚动」)。
  • 选项 Tab 遍历与选中状态:所有选项(含「其他」)均为独立 Tab stop,方向键不改变焦点也不改变已选答案;「其他」选中后输入框自动聚焦;输入框内按键(方向键/空格/Enter 等,除 Meta/Ctrl 组合)不冒泡到弹窗,保持文本编辑语义。

假设 ​

  • 渲染这些问题的 UI 组件已存在或将作为 code 包的一部分实现。
  • AskUserQuestion 工具将被视为需要用户交互的"受限"工具,类似于 Bash 或 Write。
  • "Other" 选项由 UI 自动处理,agent 不需要在工具的输入模式中明确定义。