MCP 走向无状态,Agent 循环要重新管理状态章节1×0:08事件播报1:03先把协议说清楚1:49对 Agent Loop 的影响3:07团队怎么迁移4:19工程判断0:005:040:08主持人过去二十四小时里,没有足够扎实、又能支撑单主题深挖的 Agent 工程新发布。所以今天回看近一周的一条协议更新。七月二十三日,GitHub 宣布,官方 GitHub MCP Server 已经提前支持下一版 MCP 规范。0:24主持人关键变化不是多了几个工具,而是 MCP 的核心生命周期准备从有状态转向无状态。官方给出的时间点是七月二十八日。GitHub 的实现已经先行:移除了 Redis 会话,初始化时不再写数据库,每次调用也不再读数据库。0:41主持人它还不再为了日志和密钥扫描,提前深度检查每个请求的消息体,而是改为读取协议保证存在的 HTTP 请求头。对于 elicitation,也就是服务端在执行中向用户请求补充信息,新的实现把每一步拆成独立 HTTP 请求,再用 Go SDK 的兼容包装支持新旧机制。1:03主持人过去一次 MCP 连接通常要先走 initialize 握手,协商版本和能力,再带着会话继续调用工具。会话让服务端容易记住上下文,也让服务端可以把连接和状态绑定起来。1:16主持人无状态的思路相反:每个请求尽量自包含,能力按请求协商,服务端不依赖某个长期存在的会话才能处理下一次调用。MCP 官方草案把它列为基础协议的关键细节,同时保留 Tasks 扩展,用来处理轮询、执行中的输入和可持久化任务句柄。1:35主持人这不是把状态消灭了,而是把状态从协议连接里拿出来。模型目标、已完成步骤、工具返回、审批结果、重试次数和预算仍然要保存,只是不能再默认藏在一个 MCP session 里。1:49主持人第一,连接层和任务层要分开。很多系统把「连接还在」当成「任务还在」。在本地开发时这不明显,到了远程服务、自动扩缩容和网络抖动环境里,就会变成脆弱的假设。2:04主持人新的设计应该让每次工具调用都能回答:它属于哪一次任务,当前是第几步,输入是否执行过,结果能不能安全重放。任务标识、步骤序号、幂等键和 trace 标识,都应该进入自己的执行状态,而不是寄托在 MCP session 上。2:20主持人第二,用户交互会进入循环的控制面。工具调用可能暂停,等待用户补充登录信息、选择范围,或者批准下一步。既然每一步都是独立请求,系统就必须保存等待原因、可恢复位置和授权上下文。Tasks 能提供异步接口,但不会替你设计业务状态,也不会替你决定超时、取消、重试和副作用边界。2:45主持人第三,协议升级要进入测试循环。官方 conformance 仓库提供客户端和服务端测试,捕获协议交互后按规范执行检查,覆盖核心、扩展、兼容性、认证、元数据和草案版本。它还支持预期失败基线,但可以只豁免一个具体检查,不能把整套场景一行写进白名单就算通过。3:07主持人如果你维护客户端,先全局搜索 initialize、session、重连和连接池。把「协议握手成功」和「Agent 任务可继续」拆成两个状态,迁移期间按协议版本分支,不要把新旧生命周期混在一个默认路径里。3:24主持人如果你维护服务端,做一次无状态重放测试:把同一个请求发到不同实例,检查认证、能力协商、工具执行和错误返回是否一致;再模拟超时重试,确认有副作用的工具不会重复写入。3:40主持人如果你维护长循环 Agent,先画一张状态表,列出目标、计划、当前步骤、工具输入、工具结果、人工审批、预算、取消信号和最后一次 trace,分别由谁保存、什么时候提交、失败后从哪里恢复。表里如果出现「由 MCP 会话保存」,就该重新设计了。4:00主持人最后,把 conformance 测试放进客户端和服务端各自的持续集成,再加两类 Agent 回归测试:请求被路由到不同实例后能否继续,用户中途补充信息后能否回到正确步骤。协议通过,只能说明连接行为符合规范,不能证明业务循环真的能收敛。4:19主持人GitHub 这次更新看起来像一次底层协议瘦身,实际改变的是责任边界。服务端少保存一点连接状态,换来更容易扩展的部署形态;Agent 宿主则必须把任务状态、身份、重试和恢复写得更明白。4:36主持人所以今天可以带走一个判断:无状态 MCP 不会让 Agent 自动可靠,它只是把「可靠性应该放在哪里」摊到了桌面上。下一次检查自己的 Agent 循环,可以先问一句:如果 MCP 服务端现在重启,上一轮工具调用的结果,究竟从哪里恢复?