news 2026/9/12 7:25:37

Roo Code ask_followup_question 工具完全指南:交互式澄清机制的原理与实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Roo Code ask_followup_question 工具完全指南:交互式澄清机制的原理与实践

Roo Code ask_followup_question 工具完全指南:交互式澄清机制的原理与实践

【免费下载链接】Roo-CodeRoo Code gives you a whole dev team of AI agents in your code editor.项目地址: https://gitcode.com/GitHub_Trending/ro/Roo-Code

ask_followup_question是 Roo Code 内置的交互式提问工具,它让 AI 代理在信息缺失、需求模糊或面临多方案选型时,能以结构化方式向用户提问并获取决策依据。本文基于官方文档与仓库源码,系统讲解该工具的参数格式、触发时机、完整工作原理、错误处理机制与实际使用范例,帮助你理解并善用这一"始终可用"的人机协作通道。


工具定位:Roo Code 中的人机对话桥梁

在 Roo Code 的默认工作流程中,AI 代理被设计为尽量自主地使用工具完成任务。但在真实开发场景里,任务请求往往存在信息缺口——例如用户只说"做一个博客网站",却没说明技术栈、样式方案或数据库选型。此时盲目行动可能带来大量返工。

ask_followup_question正是为此而生:它通过向用户提出具体问题,收集完成任务所需的补充信息,在"自主执行"与"用户决策"之间建立一条结构化的对话通道。从仓库源码 src/core/prompts/responses.ts 可以看到,系统提示词明确要求:"If you require additional information from the user, use the ask_followup_question tool."

与随意输出一段文字等待用户回复不同,该工具具备完整的参数校验、建议选项注入、流式渲染与错误计数机制,是一条经过工程化设计、可被测试验证的正式工具调用路径。


参数详解

工具接受两个参数:

参数必填说明
question要向用户提出的具体、清晰的问题
follow_up2-4 条建议答案的列表,用于引导用户快速回复;在 UI 中以可选按钮形式展示

注意:官方文档 ask-followup-question.md 中将follow_up标注为可选,但从当前仓库源码看,src/core/prompts/tools/native-tools/ask_followup_question.ts 的 JSON Schema 已将其声明为required,并要求数组长度为 1-4;src/core/tools/AskFollowupQuestionTool.ts 在运行时也会对缺失或非数组的follow_up报出缺少参数错误。因此实际使用时应始终提供建议答案。

在原生(native)工具协议中,follow_up数组的每个元素是一个对象,包含两个字段:

  • text(必填):用户可直接选中的建议答案,必须是完整、可执行的答案,不能是留有占位符的残缺内容;
  • mode(可选):若用户选中该选项,代理将切换到的模式 slug(如codearchitectdebug等),允许"提问即触发模式切换"的联动效果。

该模式切换能力的示例在 native-tools/ask_followup_question.ts 的注释中给出:

{ "question": "Would you like me to implement this feature?", "follow_up": [{ "text": "Yes, implement it now", "mode": "code" }, { "text": "No, just plan it out", "mode": "architect" }] }

何时使用该工具

Roo Code 只在下列情况下调用ask_followup_question

  • 原始请求中缺失关键信息,无法推断出合理的默认值;
  • 存在多种可行的实现方案,需要用户决策(如技术栈、认证方式选型);
  • 缺少继续执行所需的技术细节或用户偏好;
  • 遇到必须澄清的需求歧义;
  • 额外上下文能够显著提升方案质量时。

同时,系统提示词在 src/core/prompts/sections/rules.ts 中设定了两条重要约束:

  1. 工具优先原则:如果能用list_filesread_file等现有工具自行查明信息,就应当直接去做,而不是发问。例如用户提到 Desktop 上的某个文件时,应先列出目录确认,而不是询问文件路径;
  2. 提问下限原则:"Do not ask for more information than necessary"——提问应克制、聚焦,能自证的信息绝不打扰用户。

也就是说,该工具是信息获取的"最后手段",其使用频率受系统提示词纪律约束,避免破坏代理的自主性与任务完成效率。


核心特性

  • 提供结构化的信息收集方式,不打断整体工作流;
  • 内置建议答案,减少用户输入量、引导回复方向;
  • 跨交互保持对话历史与上下文连贯;
  • 用户回复支持携带图片与代码片段;
  • 作为always available工具集成员,对所有模式(mode)开放——在 src/shared/tools.ts 的ALWAYS_AVAILABLE_TOOLS列表中,ask_followup_questionattempt_completionswitch_modenew_task等并列,无需在模式配置中单独声明;
  • 允许用户直接指导代理的实施方案决策;
  • 用户回复统一以<answer>标签包裹,与普通对话内容清晰区分;
  • 工具成功执行时重置连续错误计数器,作为代理自我纠错状态的一部分。

工作原理:从调用到回显的完整链路

1. 参数校验

工具入口 src/core/tools/AskFollowupQuestionTool.ts 首先校验参数:

  • question缺失(空字符串)时,调用recordMissingParamError记录错误;
  • follow_up缺失、为null或非数组时同样报错,且不会继续执行task.ask

该校验逻辑在测试 src/core/tools/tests/askFollowupQuestionTool.spec.ts 中针对 missing / null / 非数组三种异常输入均有覆盖,确认了"缺参即终止"的安全行为。

2. JSON 标准化转换

源码将传入的follow_up列表映射为 UI 层可消费的标准 JSON 结构:

{ question: "User's question here", suggest: [ { answer: "Suggestion 1", mode: undefined }, { answer: "Suggestion 2", mode: "code" } ] }

对应实现见 src/core/tools/AskFollowupQuestionTool.ts:follow_up.map((s) => ({ answer: s.text, mode: s.mode }))。测试 askFollowupQuestionTool.spec.ts 验证了最终传给 UI 的 JSON 中包含"suggest":[{"answer":"Option 1"},{"answer":"Option 2"}]这样的标准化结构。

3. UI 集成

标准化后的 JSON 通过task.ask("followup", ...)方法(src/core/task/Task.ts)传递给 Webview UI 层。用户在界面中看到的是可点击的建议按钮,也可以自由输入自定义回答,形成"点选 + 键入"双通道的交互体验。

值得说明的是流式场景的处理:handlePartial方法在代理流式输出尚未结束时,只传递question文本而暂不发送 JSON(AskFollowupQuestionTool.ts),避免把未完成的原始 JSON 暴露给用户界面;待工具调用完整后再一次性渲染含建议选项的最终内容。对应行为由 askFollowupQuestionTool.spec.ts 验证。

4. 响应收集与处理

用户回复后,流程继续:

  1. 捕获用户输入的文本以及回复中携带的任何图片;
  2. 将回复以<answer>标签包裹后回传给代理;
  3. 保留回复中附带的图片;
  4. 通过task.say("user_feedback", text, images)将反馈写入对话历史,维持上下文连续(AskFollowupQuestionTool.ts);
  5. 成功完成后将task.consecutiveMistakeCount重置为 0。

5. 错误处理与连续错误计数

错误处理机制围绕consecutiveMistakeCount计数器展开(AskFollowupQuestionTool.ts):

  • 参数缺失时consecutiveMistakeCount自增,调用recordToolError("ask_followup_question")记录错误,并将didToolFailInCurrentTurn置为true,同时向用户返回格式化的缺少参数错误提示;
  • 成功时:计数器归零,表示代理已从错误状态恢复;
  • 执行异常时:统一交由handleError处理,生成 "asking question" 场景的错误信息。

这套计数机制是代理自我纠错系统的一部分,用于防止连续失败后仍盲目重复同一操作。测试文件 askFollowupQuestionTool.spec.ts 对错误分支的计数器行为有明确断言(错误后计数为 1、且不再调用task.ask)。


提问-回答工作流时序

一个完整的问答周期遵循如下顺序:

  1. 信息缺口识别:代理判断当前缺少继续执行所需的信息;
  2. 问题拟定:将缺口转化为清晰、具体、可回答的问题;
  3. 建议设计:为每个问题准备 2-4 条相关建议答案(推荐提供,非强制但建议);
  4. 工具调用:代理携带questionfollow_up调用工具;
  5. UI 呈现:问题与建议按钮展示给用户;
  6. 用户回复:用户点选建议或输入自定义回答;
  7. 消息处理:系统分别处理流式(partial)与完整消息——流式响应按到达的分块逐段处理,完整消息则一次性处理,无论消息如何分块都保持状态一致;
  8. 回复加工:回复以<answer>标签包裹并保留图片;
  9. 上下文整合:回复写入对话历史;
  10. 任务继续:代理基于新信息推进任务。

其中第 7 步的"状态一致性"由 Task.ts 中的 partial 消息更新逻辑保障:流式渲染时先以partial: true建立占位消息,完整内容到达后原位更新而非重建消息,从而避免界面闪烁与状态错乱。


响应格式:<answer>标签

用户对问题的回答会以<answer>标签包裹,确保与普通对话元素清晰区分:

<answer> Use Tailwind CSS for utility-first styling with maximum flexibility </answer>

该格式具备以下特征:

  • <answer>标签包围;
  • 保留原始回复的格式(含换行与长文本);
  • 若回复附带图片则一并保留;
  • 即使是长回复,也完整返回全部文本。

在调用链末端,回复还会进一步封装为<user_message>块作为工具结果返回给模型(AskFollowupQuestionTool.ts),使得后续模型推理能够明确识别"这是用户对提问的反馈"而非普通工具输出。


使用示例

以下示例来自官方文档,展示了该工具在真实开发决策中的典型用法。

询问实现偏好(样式方案选型):

<ask_followup_question> <question>Which styling approach would you prefer for this web application?</question> <follow_up> <suggest>Use Bootstrap for rapid development with consistent components</suggest> <suggest>Use Tailwind CSS for utility-first styling with maximum flexibility</suggest> <suggest>Use vanilla CSS with custom styling for complete control and minimal dependencies</suggest> </follow_up> </ask_followup_question>

请求技术澄清(数据库选型):

<ask_followup_question> <question>What database should this application use for storing user data?</question> <follow_up> <suggest>MongoDB for flexible schema and document-based storage</suggest> <suggest>PostgreSQL for relational data with strong consistency guarantees</suggest> <suggest>Firebase for real-time updates and simplified backend management</suggest> <suggest>SQLite for lightweight local storage without external dependencies</suggest> </follow_up> </ask_followup_question>

化解需求歧义(认证方式决策):

<ask_followup_question> <question>How should the application handle user authentication?</question> <follow_up> <suggest>Implement email/password authentication with account verification</suggest> <suggest>Use social login providers (Google, GitHub, etc.) for quick signup</suggest> <suggest>Implement both email/password and social login options</suggest> </follow_up> </ask_followup_question>

说明:上述为文档层面的 XML 风格展示。在实际的原生工具协议中,模型按 JSON Schema 调用,格式见前文"参数详解"一节(question+follow_up数组,每项含text与可选mode)。


局限性

  • 每次工具调用只能提出一个具体问题,无法一次抛出多个问题;
  • 建议答案在 UI 中以可选项呈现,但用户仍可自由输入任意回复,无法强制其选择;
  • 过度使用会拖慢任务完成速度,并造成碎片化、割裂的交互体验;
  • 建议答案必须是完整内容,不得留有要求用户自行编辑的占位符;
  • 系统不内置对用户回复的校验
  • 没有任何机制能强制用户遵循特定答案格式。

结合 rules.ts 中的系统提示词可知,代理还被要求:建议应"specific, actionable, directly related to the completed task",并按优先级或逻辑顺序排列——遵守这些纪律是发挥该工具价值的前提。


实践建议

  1. 能用工具查证就不提问:文件路径、目录结构等可通过list_files/read_file确认的信息,优先自主获取(rules.ts);
  2. 一个问题配 2-4 条建议:既减少用户输入负担,也引导回复朝可执行方向收敛,并善用mode字段实现"选完即切换模式";
  3. 建议答案要完整可执行:避免"你想怎么实现?"这类开放问题,尽量给出"用 X 技术实现 Y 效果"式的具体选项;
  4. 把提问用在真正的决策点上:技术栈选型、数据库选择、认证方案、性能与可读性权衡、架构设计偏好等,才是该工具的用武之地,而非琐碎的执行细节;
  5. 理解流式渲染行为:流式输出阶段界面只展示问题文本,完整选项在工具调用结束后出现,属正常现象而非缺陷。

通过合理使用ask_followup_question,可以让 Roo Code 在自主执行与关键决策之间取得平衡——既不过度打扰用户,又能在真正需要时获得高质量的方向指引。

【免费下载链接】Roo-CodeRoo Code gives you a whole dev team of AI agents in your code editor.项目地址: https://gitcode.com/GitHub_Trending/ro/Roo-Code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 7:25:33

TensorRT 从 0 到 1 安装教程:pip 一行跑通,再到 trtexec 验证引擎

TensorRT 从 0 到 1 安装教程:pip 一行跑通,再到 trtexec 验证引擎 【免费下载链接】TensorRT NVIDIA TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT. 项目地址: ht…

作者头像 李华
网站建设 2026/9/12 7:24:43

操作系统核心概念与性能优化实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 7:24:03

KV Cache原理与工程实践:大模型推理显存优化核心

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 7:22:56

FPGA UART实战:时序、协议与硬件联调全解析

1. 为什么UART是FPGA工程师绕不开的第一道门FPGA之串口通信&#xff08;UART&#xff09;——这标题看着朴素&#xff0c;甚至有点老派&#xff0c;但在我带过的二十多个FPGA项目里&#xff0c;它几乎永远是新人上手后第一个能“看见反馈”的模块。不是LED闪烁那种抽象的电平变…

作者头像 李华
网站建设 2026/9/12 7:22:13

Rust+Tauri打造的本地无水印视频剪辑器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华