正在刊行长文 · Essay
2026-08-30所有内容
随机比特 · Random Bits

MCP 长任务为何可用普通轮询实现断线恢复

2026-08-30AI Engineering / Systemsrbits.uk
MCP 长任务为何可用普通轮询实现断线恢复

一次代码分析需要三分钟,第二分钟连接断了。若任务身份只藏在这条连接里,重连后就无法判断原任务仍在运行、已经完成,还是已经失败;盲目重发 tools/call,还可能再启动一次分析。此时,三分钟的计算可能仍在继续,任务与连接之间的关联却已无法恢复。

MCP 2026-07-28 消灭的不是状态,而是藏在连接里的状态。

状态从连接迁移到任务句柄

MCP 新核心移除了协议级 session,请求改为逐次自描述。长任务由官方可选扩展 io.modelcontextprotocol/tasks 承接;该扩展有 2026-07-28 Stable 快照,却不是核心协议的内建能力,客户端与服务端都要声明支持。当前稳定版只有 tools/call 可以任务化。

服务端先持久化任务,再返回 taskId;客户端保存它,随后用普通 tasks/get 查状态和最终结果。可以把它理解为一个取件号。但 taskId 只是定位真实任务记录的键,不是状态副本。句柄持久保存后,客户端进程重启、传输通道更换,都只是换了查询的起点,不会换掉后台的那份工作。

连接绑定与 taskId 轮询在断线后的恢复差异

tasks/get 一次成功返回的 resultType: "complete" 只说明这次查询 RPC 结束,后台任务是否结束,必须继续读 statuscompleted 携带最终结果;failed 携带 JSON-RPC errorcancelled 是取消终态;working 继续等待,input_required 则需要通过 tasks/update 回填请求的输入。

因此,轮询“够用”只指它已经形成正确性、断线恢复和结果获取的完整路径,不代表它延迟最低或流量最少。对低延迟和高频状态更新,notifications/tasks 推送仍可减少空轮询;断线后仍可回到 tasks/get,重新对齐服务端所持有的真实状态。

轮询构成完整恢复路径

一组本地确定性状态机模拟运行了 15 项断言,结果为 15/15 通过。连接侧是为隔离差异而人为构造的非 MCP 负控,证据分成三层:

层级 观测 能推出的结论
MCP 事实 tasks/gettaskId 查询 轮询是完整的结果获取路径
模拟结果 断线后以新连接查询;共享状态下请求依次落到 B、A、B,执行计数仍为 1 可持久句柄可以恢复原任务查询
负控边界 连接绑定路径盲目重发后执行计数变为 2;本地状态落错副本返回 -32602 句柄既不阻止原调用重发,也不会复制状态

这不是完整 MCP Server 的一致性测试,也没有真实网络、代理或性能数据。它只验证恢复机制,不比较轮询与推送的性能。

taskId 仍需定位真实状态

模拟中的负例更重要:任务只存在副本 A 的内存里时,请求落到 B,即使带有正确的 Mcp-Name: task-local,仍返回 -32602 Task not found。若任务状态放在共享存储或外部作业系统,任意副本都可查询;若保留副本本地状态,网关必须按 Mcp-Name = taskId 定向到状态所有者。

显式句柄也不会自动解决创建响应丢失后的重复提交,更不能替代租户授权。它解决的是“已拿到任务号后如何继续找回工作”,创建端幂等与访问控制仍是另外的设计责任。

共享状态与本地状态下的 taskId 路由边界

实现路径由任务状态的位置决定:

状态位置 服务端与网关 客户端
共享存储或外部作业系统 普通分发,任意副本读取同一记录 保存 taskId,遵守 pollIntervalMs
副本本地内存 Mcp-Name = taskId 定向所有者 同样持久保存句柄,并处理路由失败

两条路径都要先协商 Tasks 能力,在返回句柄前持久化任务,并处理 ttlMsinput_requiredfailed.error 与取消后的继续查询。tasks/cancel 成功只表示服务端接受取消意图,任务可能仍为 working,最终状态也不保证是 cancelled。分钟级、低频长任务可先用轮询;需要高频进度展示时,再叠加 notifications/tasks

协议依据:MCP 2026-07-28 变更说明Tasks 2026-07-28 Stable 规范。最小复现使用虚拟时间,不联网、不读取墙上时钟、不调用随机数;固定任务时长为 2000ms、TTL 为 3000ms,多副本顺序为 B → A → B。脚本与结果位于随稿证据包的 research/ 目录:

python3 research/mcp_long_task_experiment.py
随机比特公众号二维码
公众号 · 随机比特
从 AI 工具热闹里拆工程真相

写边界、控制面、上下文、成本与安全。