信号要有消息边界
Agent 的“信号”一旦进入长线程,就不能再被当成附着在上下文旁边的小纸条;它必须有稳定的消息边界、消息 ID 和可定向恢复路径。Mastra 1.45.0 连续修了两个看起来很细、但对 Agent 平台很关键的问题:pending signals 过去可能挂到上一个 assistant response 下面,长线程恢复 state signals 时还可能全量扫描 thread history。
这里的工程含义是:signal 和 message 不是简单的父子关系,而是同一条执行时间线里的两类事件。比如浏览器 snapshot、task-list delta、后台状态更新如果在 assistant response 没有“收口”前直接写入 transcript,恢复时就会变成“assistant final answer 后面跟着一串 state”,模型下一轮看到的因果顺序就错了。Mastra 的修复是让 signal drain 走 canonical signal transcript path,并在写 follow-up signal 前 rotate response message id,让 stream order 和 persisted transcript order 对齐。
另一个修复更像性能边界:恢复 state signals 不再扫完整线程,而是根据 tracked signal message IDs 做 listMessagesById;如果 ID 不可用,就退回本地内存状态,而不是做无界历史扫描。这说明 durable Agent 的状态恢复不能依赖“从聊天记录里重新考古”,否则线程越长、信号越多,恢复成本和出错面都会随时间增长。
做 OPC 或内部 Agent 平台时,可以把这条规则落成一个简单设计约束:任何脱离普通对话的状态更新,都要同时回答三个问题——它属于哪个 response boundary?它的 stable id 是什么?重放/恢复时能不能按 id 精确取回而不是扫全量历史?如果今天的任务、浏览器、审批和后台队列都变成 signal,我们现在的 transcript schema 还撑得住吗?