在 AI 应用中,MCP 工具调用往往涉及数据库检索、文件解析、代码执行或第三方服务访问。如果客户端只能等待最终结果,用户就会面对长时间空白,甚至误以为任务已经卡死。通过流式结果传输与增量响应处理,可以把执行进度、中间状态和阶段性内容及时呈现出来,让工具调用更透明、更稳定,也更容易取消和恢复。🚀
一、先区分“进度通知”与“结果流”
MCP 基于 JSON-RPC 消息模型组织请求、响应和通知。对于耗时操作,客户端可在请求的 _meta 中加入唯一的 progressToken,服务端随后通过 notifications/progress 发送进度值、可选总量和说明信息。规范要求同一任务的进度值持续增加,并在任务完成后停止通知,具体规则可参考 MCP 进度通知规范。
需要注意的是,进度通知不等于业务结果流。进度通知主要表达“执行到哪一步”,而结果流表达“已经产生了哪些可消费内容”。例如,文档分析工具可以先报告“已解析 8 个章节”,再分批返回摘要片段;前者用于状态展示,后者用于增量渲染。把两者混在一起,容易导致客户端无法判断某条消息应该更新进度条,还是追加到正文区域。
二、设计清晰的流式消息结构
实践中可将一次工具调用拆成开始、处理中、增量结果、完成和失败五类事件。每条事件都应带有任务标识、序号、时间信息和事件类型,使客户端能够完成关联、排序与去重。📦
- started:确认服务端已接收任务,并返回任务标识。
- progress:报告当前阶段、已完成数量及可选总量。
- delta:携带新增文本、数据记录或文件片段,不重复发送历史内容。
- completed:给出最终状态、完整性标记和必要的结果摘要。
- failed:提供稳定的错误码、可读说明以及是否允许重试。
增量事件应包含单调递增的 sequence。客户端收到序号 12 后又收到序号 10,可以直接识别为迟到或重复消息;如果序号从 12 跳到 14,则可触发补拉、等待或降级策略。对于多工具并行调用,还应同时携带 requestId、toolCallId 和 streamId,避免不同任务的内容被错误拼接。
三、选择适合的传输方式
本地 MCP 服务常通过标准输入输出传递消息,客户端应按完整消息边界读取,不能把一次底层读取直接视为一条完整响应。远程服务则可以使用支持流式传输的 HTTP 方案。无论底层采用何种方式,应用层都应保持统一事件模型,这样更换传输通道时无需重写业务逻辑。🔄
服务端还要处理背压问题。当生成速度高于客户端消费速度时,如果无限缓存,内存会不断增长。可采用有界队列、批量合并和发送频率限制:高频日志可以合并为阶段摘要,文本增量可以按字符数或短时间窗口聚合,关键状态事件则应立即发送。MCP 官方也建议双方对进度通知实施速率限制,防止消息泛滥。
四、客户端如何处理增量响应
客户端不宜让网络读取线程直接修改界面,而应建立“接收、校验、归并、渲染”四层处理链。接收层解析消息,校验层检查任务标识和序号,归并层维护当前状态,渲染层再按照固定节奏更新页面。这样既能减少界面闪烁,也能避免单条异常消息破坏整个会话。
- 为每次工具调用创建独立状态对象,保存最后序号、已接收片段和完成状态。
- 对重复增量执行幂等处理,不因网络重试而追加两次。
- 对乱序消息设置短暂等待窗口,超过窗口后再请求补偿或标记缺口。
- 收到 completed 后校验完整性,并释放令牌、缓存与监听器。
- 用户取消任务时停止界面更新,同时向服务端发送取消信号。
文本流可以直接追加,但结构化数据更适合按主键合并。例如搜索工具分批返回记录时,客户端应以记录 ID 更新集合,而不是简单拼接数组。对于尚未闭合的 JSON 片段,不要反复尝试整体解析,可以让服务端发送完整的最小数据单元,或采用明确的事件封装。
五、异常、重试与最终一致性
流式连接中断并不一定意味着工具执行失败。客户端应区分“传输中断”和“任务失败”:前者可以携带最后确认序号重新连接,后者则由服务端返回明确错误。若服务端不支持续传,可以重新发起带幂等键的调用,避免重复写入数据库、重复发送消息或重复创建文件。⚠️
增量内容适合提升实时体验,但最终响应应作为任务完成与结果一致性的权威依据。
因此,服务端最好在最终响应中附带完成状态、结果版本、片段数量或摘要校验信息。客户端可将增量内容视为临时视图,收到最终结果后再执行一次轻量校正。如果最终结果与本地拼接内容不一致,应以最终响应为准,并记录差异用于排查。
六、日志与安全边界
调试流式调用时,应记录请求标识、工具名称、事件类型、序号、耗时和结束状态,但不要直接记录访问令牌、用户隐私或完整文件内容。对于超大结果,应限制单次增量大小、总事件数量和任务最长执行时间,防止异常工具持续占用连接与内存。🛡️
此外,进度消息中的说明文字也应视为不可信输入。客户端展示前要进行转义,避免其中夹带 HTML 或脚本。服务端必须验证 progressToken 是否属于仍在执行的请求,任务结束后立即清理令牌,不能让旧通知污染新的工具调用。
总结
MCP 工具调用的流式处理,核心不是把完整响应随意切成小块,而是建立可关联、可排序、可取消、可恢复的事件体系。合理区分进度通知与业务增量,使用唯一令牌和递增序号控制消息顺序,再配合背压、幂等、重试及最终校正机制,就能在不牺牲一致性的前提下显著改善 AI 工具调用体验。对于新项目,建议先实现 progress、delta、completed 和 failed 四类基础事件,再逐步增加续传、补片与并行流管理能力。
微信扫码赞赏
支付宝扫码赞赏