MCP 多轮往返请求怎样让工具调用继续执行
MCP 工具调用返回 input_required 时,不要重新发起一条新的工具请求,也不要把服务器返回的状态值改成自定义字符串。正确做法是保存本轮的输入请求和不透明 request_state,由客户端处理 sampling、elicitation 或 roots,再携带原状态重试原始调用,直到工具给出最终结果。
官方地址:https://modelcontextprotocol.io/
把这类调用看成“暂停—补充输入—继续”的同一条请求链:工具负责声明还缺什么,客户端负责提供答案,重试时原样带回状态。
先区分普通结果与 input_required
普通的 tools/call 可以直接返回内容;多轮往返请求则表示工具执行过程中需要客户端参与。现代 MCP 规范把这类结果包装成输入需求,客户端完成处理后再重试原始请求。它不是新的会话,也不是让客户端猜测服务器内部状态。
排查时先看三个字段:结果是否标记为需要输入、输入请求的类型是什么、服务器给出的状态值是否被原样保存。如果把 request_state 解析后再重新序列化或自行拼接,服务端可能无法识别下一轮请求。

保存 request state 与输入请求
客户端收到工具结果后,先把它当作协议对象读取,不要只保留一段文本。下面用 Go 写一个简化的处理骨架,重点是把服务端返回的状态当作不透明字节保存,并让后续重试继续使用原始调用标识。
type InputRequired struct {
// Requests 描述客户端还需要处理的请求,键名由服务端定义。
Requests map[string]json.RawMessage `json:"inputRequests"`
// RequestState 只保存和回传,不在业务层解释或改写它。
RequestState json.RawMessage `json:"requestState"`
}
func savePending(result []byte) (InputRequired, error) {
var pending InputRequired
// 先解析协议外壳,解析失败要停止重试,避免发送不完整状态。
if err := json.Unmarshal(result, &pending); err != nil {
return InputRequired{}, fmt.Errorf("解析 input_required 失败: %w", err)
}
if len(pending.RequestState) == 0 {
return InputRequired{}, errors.New("缺少 requestState,不能安全重试")
}
return pending, nil
}
真实 SDK 会把这些字段封装成更具体的类型,但判断原则不变:状态只负责回到同一条请求链,输入请求才交给相应处理器。若响应中没有状态,宁可记录明确错误,也不要用空对象“补齐”。
按 capability 处理三类输入
输入请求可能要求客户端调用 sampling,让客户端模型生成一段结果;也可能要求 elicitation,让用户确认或填写字段;roots 则用于取得客户端声明的工作区范围。客户端必须先声明对应能力,并对拒绝、超时和能力缺失分别处理。
func answerRequest(ctx context.Context, kind string, body json.RawMessage) (json.RawMessage, error) {
switch kind {
case "sampling":
// sampling 由客户端的模型处理,应用仍应保留人工审核或拒绝分支。
return samplingHandler(ctx, body)
case "elicitation":
// elicitation 的答案来自用户,取消不能伪装成空字符串。
return elicitationHandler(ctx, body)
case "roots":
// roots 只返回客户端已声明的根,不能把它当成服务器权限授予。
return rootsHandler(ctx, body)
default:
return nil, fmt.Errorf("不支持的输入请求类型: %s", kind)
}
}
这里的函数名是应用层适配器示意。关键是把每个答案放回服务端给出的请求键中,并保留错误原因。用户拒绝 elicitation、客户端不支持 sampling、或者 roots 不可用,都应该结束当前重试链并返回可诊断错误。
带回 inputResponses 重试原始请求
答案准备好后,构造下一次请求时至少要保留三件事:原始工具调用的上下文、服务端返回的 requestState、按照请求键组织的 inputResponses。不要为了“简化参数”只发送答案。
type ContinueRequest struct {
// RequestState 必须原样回传,客户端不负责生成替代值。
RequestState json.RawMessage `json:"requestState"`
// InputResponses 的键必须和 inputRequests 一一对应。
InputResponses map[string]json.RawMessage `json:"inputResponses"`
}
func continueTool(ctx context.Context, pending InputRequired) ([]byte, error) {
answers := make(map[string]json.RawMessage, len(pending.Requests))
for key, requestBody := range pending.Requests {
kind, err := requestKind(requestBody)
if err != nil {
return nil, err
}
answer, err := answerRequest(ctx, kind, requestBody)
if err != nil {
return nil, fmt.Errorf("请求 %s 未完成: %w", key, err)
}
answers[key] = answer
}
// 仍然调用同一条工具请求的 continuation 入口,而不是创建新任务。
return retryToolCall(ctx, ContinueRequest{
RequestState: pending.RequestState,
InputResponses: answers,
})
}
如果重试后仍然返回 input_required,继续进入同一处理循环;如果返回工具结果,则结束。应用可以设置次数和总耗时上限,但上限触发后应记录当前请求键和错误类型,方便判断是能力不足还是工具本身反复索取输入。

调用卡住时按四层清单排查
第一层看协议版本:客户端和服务器是否协商了同一代多轮往返机制。第二层看 capability:客户端是否声明了工具实际需要的 sampling、elicitation 或 roots。第三层看数据:请求键是否完整、状态是否原样保存、答案是否放在 inputResponses。第四层看重试:是否重试原始调用、是否在每轮保留上下文、是否把拒绝和超时误当成成功答案。
| 现象 | 优先检查 | 处理方向 |
|---|---|---|
| 一直停在 input_required | 请求键和答案是否一一匹配 | 记录键名,逐个生成响应,不发送空占位 |
| 服务端提示状态无效 | requestState 是否被解析后改写 | 使用原始字节或 SDK 的不透明字段 |
| 调用立即失败 | 客户端 capability 与协议版本 | 补齐能力声明,或明确返回不支持 |
| 用户取消后仍继续执行 | elicitation 的拒绝分支 | 把取消作为当前链路的终止结果 |
常见问题
requestState 可以保存到数据库后再继续吗?
可以把它作为不透明数据持久化,但要同时保存请求上下文、过期策略和安全边界;恢复时仍应原样交给协议客户端,不要把它当成业务字段修改。
roots 返回的目录就是安全权限吗?
不是。roots 表示客户端提供的工作区范围,工具实际访问文件时仍应执行自己的权限、路径和资源控制。
为什么不直接重新调用工具并把答案放进参数?
因为多轮往返的状态由协议管理。重新创建调用会丢失服务端上下文,也可能造成重复副作用;应沿原始请求链继续。
参考地址:https://blog.modelcontextprotocol.io/posts/2026-07-28/
Go SDK 参考:https://go.sdk.modelcontextprotocol.io/client/
Gemini API context caching怎样复用长文档上下文
- 上一篇
- Gemini API context caching怎样复用长文档上下文
- 下一篇
- vLLM prefix caching怎样减少重复提示词延迟
-
- 科技周边 · 人工智能 | 37分钟前 | 性能优化 · 人工智能 · 深度学习 · PyTorch CUDA SDPA scaled_dot_product_attention Flash Attention
- PyTorch scaled dot product attention怎样选择高效注意力后端
- 214浏览 收藏
-
- 科技周边 · 人工智能 | 38分钟前 | 性能优化 · python · ONNX Runtime InferenceSession SessionOptions 图优化 Execution Provider
- ONNX Runtime怎样为推理启用图优化
- 281浏览 收藏
-
- 科技周边 · 人工智能 | 43分钟前 |
- OpenTelemetry GenAI怎样记录模型调用 token 属性
- 414浏览 收藏
-
- 科技周边 · 人工智能 | 44分钟前 | 向量数据库 · RAG 向量检索 LlamaIndex metadata filters
- LlamaIndex metadata filters怎样按元数据筛选检索节点
- 157浏览 收藏
-
- 科技周边 · 人工智能 | 45分钟前 |
- MLflow prompt registry怎样给提示词版本做回滚管理
- 234浏览 收藏
-
- 科技周边 · 人工智能 | 46分钟前 |
- LangChain structured output怎样把工具结果映射到数据模型
- 135浏览 收藏
-
- 科技周边 · 人工智能 | 48分钟前 |
- Ollama embeddings怎样为本地文档生成向量
- 230浏览 收藏
-
- 科技周边 · 人工智能 | 51分钟前 |
- Transformers Trainer怎样保留自定义字段传入模型
- 344浏览 收藏
-
- 科技周边 · 人工智能 | 53分钟前 |
- vLLM prefix caching怎样减少重复提示词延迟
- 312浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Gemini API context caching怎样复用长文档上下文
- 394浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | python · 人工智能 · gemini · 结构化输出 · Pydantic JSON Schema Gemini API google-genai structured output
- Gemini API structured output怎样约束返回 JSON Schema
- 136浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 | python · 异步任务 · gemini · 批处理 · JSONL Batch API Gemini API 离线生成 google-genai
- Gemini API Batch 怎样处理大量离线生成请求
- 486浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 880次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 876次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 960次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 941次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 768次使用
-
- 量化模型本地推理的显存估算方法
- 2026-10-17 501浏览
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览

