
界面没有收到新内容,是Agent还在工作,还是客户端把一条空值事件丢掉了?企业把智能体接进网页和后台任务后,这种细节会影响进度显示与恢复判断。LangGraph Python SDK 0.4.11修正了SSE流式解析和重连游标的一组边界,让“值为空”“没有事件”和“清空续接位置”不再被简单混在一起。
快速看点:正式版本发布于10月30日22时17分UTC,即北京时间31日早晨;同步和异步客户端都涉及修改;这不是把所有业务请求自动重跑,也不等于升级后每个断线任务都能无损恢复。LangGraph核心1.2.19与Python SDK 0.4.11是不同包版本。
SSE可以把运行状态持续送给客户端,但网络收到的一块字节,不一定正好是一行或一条事件。换行还可能使用不同表示。若一段内容以回车结束,下一段才出现换行,解析器必须记住两者的关系;否则,应用看到的边界就可能取决于传输怎样切块,而不是服务端怎样组织事件。
此次修正调整了增量行解码:回车结尾的完整行可以及时交付,后续配对换行不会重复生成边界。多行data字段仍保留应有的换行。官方测试用分开的字节片段检查这些场景,说明被覆盖的是协议解析条件,不是某条真实企业网络的性能实测。
更容易被忽视的是data值为null,或data字段为空。两者在解析后的数据值都可能是None,但并不代表服务端什么也没发。新版通过单独记录这一块是否含有data字段,决定是否向上交付;不能只凭“解析结果不为空”筛选,否则一条有意义的事件就可能消失。
续接通常靠Last-Event-ID告诉服务端:客户端已经推进到哪里。这里至少有三种状态:尚未收到ID、收到一个非空ID,以及收到明确的空id字段。最后一种意味着清空游标,不是继续沿用旧值。即使这个控制块没有业务数据,也需要更新内部状态。
例如调用方最初带着游标5,流中随后发来id:1,后续请求应以1为准,不能同时夹带大小写不同的旧请求头。若再收到空id,重连请求就不应把5或1重新带回去。正式版本会在流端明确更新ID后,先移除原有同名头,再按当前非空值生成请求头;若流尚未给过ID,调用方原有值仍可保留。
重连后创建的解析器也会继承已有游标。于是新连接中某条事件即使没再写ID,也不会仅因为换了连接就失去先前的位置。另一方面,单纯心跳注释和没有待交付内容的刷新,不应反复冒充业务事件。位置记忆与消息交付是两件事,需要分别处理。
正式代码在重连时发现没有有效Last-Event-ID,会发出警告:断线期间发出的事件不会因此自动重放;创建运行时启用stream_resumable,才有可供续接的事件ID。客户端记住一个字符串,不等于服务端一定保存了对应历史,更不能把没有游标的重新连上写成零丢失。
自动续接还依赖响应提供的Location。已有续接位置时,客户端可用GET去接后续流,而不是重新提交原始POST。没有拿到续接地址前发生失败,不能靠这条路径自动恢复。代码对连续重连失败设置上限,有新事件进展会重置计数,因此它也不是整个任务的全局次数或耗时硬封顶。
本轮核对了正式标签的SSE解码器、同步/异步stream方法,以及相应PR测试差异和正式测试中的相关用例。用例包含null与空数据、独立空ID、调用方请求头大小写、重连后继承ID及无游标警告。本站未运行上游测试,未启动服务、调用模型或模拟真实断网,不把源码与测试存在写成现场可用性保证。
这组改动改善的是客户端协议处理,不负责证明Agent决策正确、工具写入只发生一次,或服务端永远保留事件。界面收到的进度与实际业务状态仍需对账。取消、等待、退避及其他同版变化也有各自调用路径,不能将本文的解析结论扩展成全SDK、JavaScript客户端或任意代理链路的认证。
企业集成值得补上的验收,不只是“断网后能继续打印”。应检查空值事件是否交付,空ID是否真正清掉旧头,新连接是否接住最新位置,以及界面进度能否对应服务端运行状态。对于发消息、写订单或改数据等有副作用的动作,还要依靠业务幂等与结果核对。连接层少犯错很重要,但它不能替业务层承担一次性执行的责任。
