返回全部文章

工程机制

不用 Compaction,Morphz 如何维护有限的上下文?

随着任务推进,智能体会获得新的信息,并据此更新自己的判断。Morphz 让智能体通过上下文事务维护自己的上下文,在有限空间内持续工作。

长期工作的智能体需要不断修正自己的判断。旧配置可能已经过时,刚才的故障可能已经排除,用户也可能补充新的限制。随着工作推进,上下文也需要随之更新。

在 Morphz 中,智能体通过上下文事务(Context Transaction)修改自己的上下文。它根据新收到的信息决定要保留、修订或退役哪些内容,把这些修改交给运行时检查和提交,然后从更新后的状态继续工作。

可以修改的上下文

上下文里有新收到的观察、已经形成的认知,以及会话和运行状态。这里的观察(Observation)是一条进入上下文的输入记录,比如用户消息、工具返回结果或外部事件。每条记录都有自己的标识,智能体可以引用它、把它作为判断的依据,也可以在处理后将其退役。

判断、知识和约束以认知帧组织,每个帧也有自己的标识。智能体可以引用一条已有认知,修改它的内容,也可以记录这一判断的依据和来源。

这些修改通过 context_tx 提交。一笔事务可以同时创建新认知、标明它替代了哪条旧认知,再退役已经处理的观察记录。运行时检查版本和操作是否合法,要么提交整组修改,要么拒绝这笔事务。

可修改的范围由协议约定。智能体能够维护认知,决定哪些观察记录继续保留在上下文中,以及哪些会话需要持续关注。原始工具结果保持不变,权限和调度由运行时管理。

一次部署判断的更新

假设智能体正在准备一次部署。它之前把部署地区记为杭州,保存在认知帧 deployment/target-v1 中;读到最新的生产配置后,却发现地区应该是上海。这次配置检查的结果作为观察记录 @e42 进入上下文。

智能体可以提交下面这笔事务,更新部署判断,同时让已经处理的配置记录退出活动上下文:

(context-tx
  (base-version 17)
  (reason "current production configuration confirms cn-shanghai")
  (derive deployment/target-v2
    (from @e42 deployment/target-v1)
    (fact (region cn-shanghai)))
  (relate deployment/target-v2 supersedes deployment/target-v1)
  (retire deployment/target-v1)
  (retire @e42))

derive 创建新的认知帧,并把配置结果和旧帧列为来源。relate 声明新帧替代旧帧,最后两个 retire 则分别退役旧帧和已处理的观察记录。提交后的变化如下:

上下文对象 提交前 提交后
旧认知帧 部署地区:杭州 已退役,记录仍可追溯
新认知帧 尚不存在 部署地区:上海,关联旧帧与最新配置
观察记录 @e42 留在活动上下文中 已退役,仍可按引用召回
其他认知 原有内容 不受这笔事务影响

这些操作一起生效。智能体下一次读取上下文时,部署地区已经更新为上海,配置原文则可以在需要时通过 @e42 查阅。

如果只需修改同一条认知,也可以使用 revise。它会替换帧的完整正文,因此新正文需要写全所有应当保留的内容。

为后续工作留出空间

部署还会产生构建日志、健康检查和新的错误信息。模型的输入容量有限,后续步骤往往只会用到其中一部分内容。哪些需要继续留在眼前,哪些可以先放下,是智能体需要反复作出的判断。

一种常见的做法是 compaction:把早期对话压成摘要,后续请求用这份摘要代替原来的长记录。在 Morphz 中,智能体一边执行任务,一边用事务整理上下文。处理一份构建日志后,它可以派生失败诊断、更新阻塞项,再退役日志对应的观察记录。诊断结果留在上下文中,日志占用的空间则被释放。

信息仍然会被提炼,但每条认知都可以单独更新。某个故障排除了,就修改对应的判断;某项约束仍然重要,就用 protect 保留它。以后需要重新检查已经退役的认知,还可以用 restore 恢复。

退役的内容仍然保存在历史中。将一条观察记录退役,会立即释放输入空间;普通认知帧则先进入一个整理窗口,在此期间继续可见,也继续占用容量,留出修订或恢复的机会。前面的部署例子可以立即退役旧帧,是因为新帧既引用了旧帧,又用 supersedes 声明替代关系。受保护的内容需要先解除保护,才能退役。

接近容量上限时

运行时会估算完整模型请求需要多少 token,并把容量压力告知智能体。接近临界值,或者模型接口已经报告输入超限时,Morphz 会暂停新的外部工具动作,进入维护阶段。context_tx 和必要的召回能力仍然可用。

智能体检查积累的观察记录,通过事务保留有用的结论、修订已有认知,并退役不再需要展开的内容。每次提交后,运行时重新测量容量;空间足够时恢复工作,否则继续整理。

如果完整请求已经无法放进窗口,运行时会提供一小批观察记录供智能体处理。当前请求及其因果依赖会优先保留,其余候选按确定性规则从较早、未受保护的记录中选择。智能体据此分批提交事务,逐步整理上下文;这一轮没有选中的记录保留原有状态。

维护本身也需要输入空间。如果连最小的维护请求都放不下,运行时会报告失败。

并发修改与来源追溯

多个执行线程可以共享同一个上下文。假设一个线程正在更新部署地区,另一个正在记录构建失败的原因:只要两笔事务涉及的帧和关系彼此独立,运行时就可以保留两边的修改。每笔事务携带的基础版本,用来检查它所依据的状态是否已经变化。

冲突按具体的帧、关系等边界检查。互不影响的旧版本事务可以安全重放到最新版本;如果相关内容已经被其他线程改过,提交会被拒绝,智能体需要重新读取并处理冲突。

同样的记录也能用来追查判断的由来。有人问起“为什么从杭州改到上海”,智能体可以沿新帧的来源找到旧帧和 @e42,重新读取当时的配置结果。召回结果会作为新的观察记录进入上下文;如果它改变了当前判断,智能体再提交一次修改。

除了沿来源和关系查找,Morphz 还支持关键词、时间范围和标识查询,具体接口见上下文与召回文档

上下文怎样进入模型

事务提交后,修改后的上下文和变更记录会被保存。下一次调用模型时,运行时按当前状态生成上下文编码。认知帧的标识与关系仍然保留,后续事务可以继续修改这些帧。

模型每次能看到多少内容,取决于活动状态、会话工作集和输入预算。很长的工具结果可以先展示预览,并附上原文引用;其他会话可以完整呈现、只保留元数据,或暂时换出。原始事件仍然保存,供后续查询。

跨任务的经验复用

我们用一组跨任务实验,评估了智能体将历史经验用于新任务的表现。实验使用 STATE-Bench 的任务、评分规则和评测提示词,智能体、用户模拟器与评测器统一使用 GPT-5.6 Sol(max reasoning)。在三个领域中,每组分别学习相同的 100 条历史任务轨迹,再完成各领域的 50 项未参与学习的测试任务,合计每组 150 项,每题尝试一次。

任务完成要求同时通过最终状态检查和任务要求评分,运行失败计为未通过:

系统 完成任务 完成率
Morphz 122/150 81.33%
Letta 0.16.8 93/150 62.00%
Mem0 2.0.19 向量检索参考智能体 96/150 64.00%

对 Morphz 的记录复核确认,训练阶段通过上下文事务形成的认知帧实际参与了全部 150 项测试。智能体在历史任务中形成的认知,确实被带到了后续工作中。

这组实验比较的是完整智能体系统,结果包含各自提示、记忆、工具循环和调度的影响。这轮比较中 Morphz 的测试阶段 token 用量更高,并非等成本对照;完整实验报告同时列出了各组的开销统计。更多机制实验见研究论文

前缀缓存

Morphz 的上下文编码为前缀缓存保留了稳定区域:协议和按顺序追加的观察记录在前,变化较多的认知与运行状态在后。更新认知时,前面的观察记录仍保有可复用的前缀。相比只追加内容的线性消息,退役较早的记录会损失一部分缓存复用,未受影响的前缀仍可保留。

实际命中率还取决于模型接口。我们做了一组对照实验,让九个模型分别执行同一个任务,比较各自的缓存命中率。未启用 ContextDelta 时,Kimi K3 和 GLM 5.3 的命中率分别为 85.67%86.46%。这里的命中率均按首轮之后模型服务报告的缓存输入词元占总输入词元的比例统计。

我们测试的 GPT-5.6 Sol 接口,对单消息内部长前缀的自动复用不够稳定。针对这种请求形式,Morphz 的 ContextDelta 编码在连续工具调用之间追加结构化增量,帮助接口复用稳定前缀。同题对照测试中,GPT-5.6 Sol 的命中率从 54.18% 提升到 93.37%。这项实验功能默认关闭,需启用对应编译特性并按模型配置。

成本与边界

上下文维护还会消耗调用、token 和时间,保存原始记录需要存储,召回也会占用输入空间。维护质量取决于模型对任务和信息的判断;事务负责检查修改是否符合规则,版本、来源和检查点则为检查与恢复提供支持。

结语

长期任务会留下大量记录,新得到的信息也可能改变已有的判断。Morphz 让智能体通过上下文事务跟上这些变化:更新需要继续使用的认知,退役已经处理的观察记录,并保留日后查阅的原始记录。

前一篇《从聊天补全到结构化上下文求值》介绍了整体计算模型。项目源码中可以找到本文涉及的事务、容量维护和召回实现。