MCP 缺参数时如何向用户补问
文章介绍 MCP 的 Elicitation 机制:工具执行中发现缺少用户决策时,通过客户端收集答案后继续调用。它适用于环境选择等必要决策,不应用来弥补输入模式缺陷或索取应由网关处理的密钥。
AI 深度解读
MCP 工具执行到一半,才发现缺少一个必须由用户决定的值,该报错、猜一个默认值,还是停下来问?原文给出的答案是 Elicitation:让服务端通过客户端收集答案,再继续当前调用。
但作者更想强调的是它的边界:固定必填参数应该进入输入 schema,凭证应该交给网关或环境管理。只有真正需要用户当场选择的值,才适合在执行中追问。这套区分,能帮我们审查 AI 生成的 MCP 服务,避免把一次工具调用做成连续填表。
缺值时,为什么不直接报错或填默认值
作者把工具执行中缺值的处理分成三条路:返回错误、静默使用默认值,以及通过 Elicitation 补齐信息。
前两条路各有代价。报错会打断正在进行的任务,用户需要补充信息并重新发起;静默使用默认值则把决策权交给了工具。以部署目标为例,工具能够执行部署,不代表它有依据替用户选择环境。
Elicitation 增加了一轮结构化交互:服务端暂停当前调用,描述需要收集什么;客户端展示请求,用户作答;服务端拿到结果后,继续原来的操作。已经建立的任务上下文可以保留下来。
它与确认操作也有区别。确认是在问用户是否批准某个计划,Elicitation 则是在收集后续执行需要的数据。两者都可能暂停调用,但后者返回的是结构化答案,而不只是简单的是或否。
需要用户作出的选择,应该显式交还给用户。
哪些值值得追问,哪些应该提前拦住
判断标准不是「现在有没有这个值」,而是「这个值为什么到现在还不知道」。
如果每次调用都需要某个参数,而且调用前就能提供,就应该把它声明为输入 schema 的必填字段,让客户端在工具运行前校验。服务端执行后才发现它不存在,再弹出问题,是把输入契约的漏洞转嫁给用户。
适合 Elicitation 的,是执行时才显露出来的真实选择。例如工具找到多个有效匹配,需要用户确定目标;或者部署操作的上下文仍有歧义,需要用户决定目标环境。
这也解释了原文中部署环境例子的前提:如果每次部署都必须先指定环境,它就应当是必填输入;只有运行时仍存在需要用户消除的歧义,才有理由中途询问。
请求本身还要限制答案范围。作者建议使用受约束的枚举(enum),让用户从合法选项中选择,避免补回来的值仍然无法使用。原文提到了这一做法,但没有附上具体请求代码或字段定义,不能据此直接拼出一份协议实现。
凭证则有明确边界。API keys 和 tokens 应由网关或环境注入,不应通过交互提示收集,因为提示及回答可能进入日志。
真正难做对的是拒绝、取消和继续执行
一个完整实现必须处理三种结果:
- accept 携带用户提供的答案,工具使用它继续执行。
- decline 表示用户选择不提供信息,服务端需要明确处理。
- cancel 表示放弃这次请求,需要干净地终止相关操作。
作者提醒,如果服务端默认每次询问都能拿到答案,拒绝路径就可能崩溃。取消时,如果上游工作已经启动,还需要清理,不能让调用悬在那里,也不能带着 undefined 参数继续执行。
问题文案同样属于实现的一部分。只写「请输入一个值」,用户无法判断该填什么。有效的问题需要说明受影响的资源、为什么必须选择,以及各选项会带来什么结果。用户看得懂,才有条件作出可靠决定。
测试也应覆盖整轮往返,而不只是检查请求对象。测试夹具(harness)可以代替客户端,接收询问、返回指定答案,再断言工具确实使用该答案完成后续操作;拒绝与取消则分别验证操作能否退出、是否需要清理。
作者还提出一个实用检查:如果测试夹具都必须猜测 schema 才能回答,约束很可能不够清楚。这个检查能暴露设计问题,但不能代替真实客户端的交互验证。
我的判断
这篇最有用的地方,是把输入校验、用户决策、凭证管理分开了。AI 生成服务端代码时,很容易用一种办法处理所有缺值:要么不断追问,要么统一补默认值。作者给出的分类,有助于逐个审查这些选择是否合理。
但它是一篇设计建议,没有给出可运行实现、实测记录或对照数据,也没有说明具体客户端的支持情况。因此,不能把「保留上下文」进一步理解成已经证明能减少多少重试或缩短多少操作时间。
作者对报错路径的描述也偏绝对。工具返回缺参错误,并不必然要求用户重启整段对话;调用方可能保留上下文,补齐参数后重试。原文没有比较这种方案与 Elicitation 的实际成本。
我的取舍是:固定输入优先靠严格 schema;运行时出现真实歧义,再考虑 Elicitation。它能让决策发生在合适的位置,同时也增加了等待、分支处理和清理责任,不能只实现一个漂亮的提问框。
能拿来做什么
- 编写或审查 Node MCP 服务时,把缺失字段逐个归类:调用前可知的参数设为必填,运行时需要用户选择的值才进入 Elicitation,API keys 和 tokens 交给网关或环境。
- 给部署、资源选择等工具设计问题时,写清具体资源、选择原因和选项后果,并用枚举限制合法答案,避免用户回答后再次被校验拒绝。
- 为 Elicitation 补齐 accept、decline、cancel 三条测试路径,重点断言答案是否用于后续执行,以及终止时是否留下未清理的工作。
- 审查 AI 生成的工具代码时,检查每个交互提示和默认值的依据,找出被追问掩盖的必填参数,以及未经用户决定就继续执行的分支。