Sherry's Blog


  • 首页

  • 关于我

  • 标签

  • 文章列表

2026年 Agent 上下文管理生态全景:从源码到架构决策

发表于 2026-04-04 | 分类于 技术

2026年Agent上下文管理生态全景:从源码到架构决策

我花了点时间调研agent上下文/记忆/任务状态管理领域,读了OpenClaw核心源码、lossless-claw全部实现、Headroom架构、Claude Code泄露源码分析,以及十几篇学术论文。这篇文章把所有发现整理出来,包括每个方向为什么不值得做——因为“为什么不做”往往比“做了什么”更有价值。


一、问题定义:Agent为什么需要上下文管理?

LLM有context window限制。当agent执行长任务——调试一个跨20个文件的bug、做一份需要50次搜索的研究报告——对话历史会持续膨胀,直到撞上token上限。

朴素的解决方案是截断旧消息。但截断意味着遗忘:第3步读取的那个API响应,到第47步可能是定位bug的唯一线索。

所以这个领域的核心问题是:如何在有限的context window里,让agent记住它需要记住的东西?

看起来是个清晰的工程问题。实际上,2026年的现状是——每个子方向都有人在做,但没有人做得足够好。


二、生态全景:谁在做什么

开源Agent框架的上下文管理

框架 上下文管理策略 核心问题
Hermes Agent(27k星) 结构化摘要+迭代更新,压缩前LLM记忆刷新,可插拔记忆provider 压缩需要两次额外LLM调用,13.9k token固定开销,9432行上帝类
OpenClaw(350k+星) ContextEngine可插拔接口(v2026.3.7),默认实现是空壳 默认行为是“塞满了再摘要”,用户日均消耗50-100美元
Claude Code(闭源) 三层自愈记忆+Tasks任务状态+autoDream记忆整合+KAIROS后台agent 工业级最佳实践,但锁在Anthropic生态内

记忆框架

框架 定位 状态
Mem0(48k星) 轻量记忆存储,向量+图+键值混合 AWS Agent SDK独家记忆provider
Letta/MemGPT OS级记忆管理,三层架构(core/archival/recall) 跟DeepLearning.AI出了课程
Zep 企业级时序知识图谱 Deep Memory Retrieval基准最高
MemoryOS(BAI-LAB) 四模块架构,EMNLP 2025 Oral LoCoMo基准F1提升49%

OpenClaw ContextEngine插件生态

这是当前最活跃的战场。v2026.3.7引入了可插拔的ContextEngine接口后,多个团队在这个接口上竞争:

插件 做什么 核心能力
lossless-claw DAG无损压缩,每条消息变图节点,agent可按需展开 OOLONG基准74.8,超过Claude Code的70.3
Headroom 内容感知压缩(JSON/代码/日志分路由),CCR可逆压缩 13万行成熟代码,40-90% token reduction
context-mode tool output沙盒化,跨12个平台 98% reduction on tool outputs
OpenViking(字节跳动) 长期记忆+会话归档+记忆提取 实现了完整的assemble/afterTurn/compact生命周期
ContextVault 外部markdown持久化,/ctx-bootstrap扫描代码库 session交接,跨工具兼容

压缩工具

工具 方法 特点
Headroom 内容感知路由(SmartCrusher/CodeCompressor/Kompress)+ CCR可逆压缩 最成熟的独立压缩方案,Python生态
LLMLingua(微软) prompt压缩,最高20x 学术出品,可嵌入预处理步骤

三、OpenClaw源码级诊断:5个架构缺陷

我读了OpenClaw的核心源码(不是文档,是代码)。以下是发现的5个架构级问题。

缺陷1:压缩是纯reactive的,没有proactive能力

run.ts里的auto-compaction只在API返回context overflow error之后才触发。tool-use循环中没有pre-prompt的context size检查。

真实案例(issue #24800):session从196K涨到200K,连续5次API调用逼近极限,最后一次爆了。compaction本身也需要API调用,也因为context满了而失败。session永久卡死,Compactions: 0,Context: 200k/200k (100%)。

社区提出的修复方案:

1
2
3
4
5
6
7
// 在每次tool-call迭代前检查context是否接近上限
const currentTokens = attempt.usage?.input ?? 0;
const compactionThreshold = ctxInfo.tokens - reserveTokensFloor;
if (currentTokens > compactionThreshold && !proactiveCompactionAttempted) {
proactiveCompactionAttempted = true;
await compactEmbeddedPiSessionDirect({...});
}

这段代码至今没有合并。

缺陷2:safeguard模式默认开启但静默失败

所有新安装默认使用safeguard模式(src/config/defaults.ts第460行)。180K+ token时产生"Summary unavailable due to context limits"——上下文直接丢失,没有任何警告。

更讽刺的是,文档写的是默认模式是“default”,但代码里实际设的是“safeguard”。setup wizard里甚至没有compaction设置选项。

缺陷3:两套hook系统不互通

src/hooks/internal-hooks.ts的triggerInternalHook()和src/plugins/hooks.ts的hookRunner.runSessionEnd()是两个独立系统。

session-memory hook只监听command:new和command:reset(内部事件),不监听session_end(插件事件)。结果:每天4点的daily session reset时,对话被归档但记忆没有flush。你以为agent记住了昨天的对话,其实什么都没保存。

缺陷4:compaction后token计数归零

clearStaleAssistantUsageOnSessionMessages()清除了所有assistant message的usage数据,而不是只清除compaction之前的。Google provider路径(src/agents/pi-embedded-runner/google.ts)有一个正确实现stripStaleAssistantUsageBeforeLatestCompaction(),但通用路径是错的。

用户看到的现象:TUI里永远显示0/1.0m (0%),完全失去对context使用情况的可见性。

缺陷5:LegacyContextEngine是空壳

src/context-engine/legacy.ts的实现:

  • ingest() → 返回{ ingested: false },纯no-op
  • assemble() → 原样透传,estimatedTokens: 0
  • compact() → 丢给delegateCompactionToRuntime()

真正的压缩逻辑在src/agents/compaction.ts,hardcode了BASE_CHUNK_RATIO = 0.4、MIN_CHUNK_RATIO = 0.15、SAFETY_MARGIN = 1.2——不可配置、不可组合。

这意味着350K+ star的项目,默认的上下文管理策略就是“塞满了就用固定比例摘要一下”。


四、更深层的架构问题

排他性slot设计

src/plugins/slots.ts中,memory和contextEngine都是排他slot——只能有一个winner。applyExclusiveSlotSelection(第76-162行)负责这个逻辑。

这意味着lossless-claw + Headroom + context-mode无法作为三个独立的contextEngine插件同时工作。你想组合它们?必须自己写一个meta-engine占住slot,内部编排子引擎——但这就不是“编排现有插件”了,而是“吸收现有插件的逻辑写一个超级引擎”。

历史持久化和上下文组装耦合

三个关键组件没有统一数据模型:

  • SessionManager(Pi外部依赖)负责写磁盘
  • ContextEngine负责读并截断
  • Task state在src/tasks/task-registry.ts的内存Map里

测试任何一个都拖着另外两个。

Registry是God Object

src/plugins/registry.ts管理20+种注册类型:工具、hooks、CLI、HTTP路由、speech、实时转录、媒体生成、web抓取、channel、gateway、memory、contextEngine、安全收集器……单文件混合认证、slot分配、provider冲突解决。


五、lossless-claw源码分析:DI做对了

在所有ContextEngine插件中,lossless-claw的架构设计是最干净的。

核心发现:engine.ts零OpenClaw import

LcmContextEngine(engine.ts第1199行)的构造函数接受一个LcmDependencies接口,通过依赖注入获取所有外部能力:

1
2
3
4
5
6
7
8
export interface LcmDependencies {
config: LcmConfig;
complete: CompleteFn; // LLM调用
callGateway: CallGatewayFn; // Gateway RPC
resolveModel: ResolveModelFn; // 模型解析
getApiKey: GetApiKeyFn; // 密钥获取
log: { info, warn, error, debug };
}

核心逻辑链完全独立:

  • 存储层:conversation-store.ts、summary-store.ts——纯SQLite,零OpenClaw依赖
  • 压缩引擎:compaction.ts——接受CompactionConfig + SummarizeFn,不知道OpenClaw的存在
  • 组装器:assembler.ts——唯一的OpenClaw import是type推导
  • 检索:retrieval.ts——纯SQLite FTS5查询

真正的耦合只在src/plugin/index.ts:390行胶水代码处理api.registerContextEngine()、api.registerTool()等注册逻辑。

这意味着:你可以直接import { LcmContextEngine },自己构造LcmDependencies,完全绕过plugin层。大约100-150行adapter代码。


六、Headroom分析:Python生态的天花板

Headroom是最成熟的通用压缩方案(13万行代码),但它是Python生态。OpenClaw plugin只是通过本地HTTP proxy调用Python进程。

核心压缩能力:

  • SmartCrusher:JSON数组压缩——从500项中挑出统计上“有代表性”的K项(首尾、异常值、变化点),丢弃正常项
  • ToolCrusher:固定规则——截断长字符串、限制数组条目数、限制嵌套深度
  • Kompress:ModernBERT文本压缩

关键局限:SmartCrusher明确声明“Non-JSON content passes through UNCHANGED”。对LLM生成的自然语言摘要,Headroom基本没有压缩能力。


七、Meta-Engine可行性推导:为什么最终放弃

假设

既然lossless-claw做语义层DAG摘要(需LLM调用),Headroom做算法层token压缩(零LLM调用),两者正交,理论上可以串联:LCM先组装最相关的上下文,Headroom再压缩其中的冗余token。

技术上可行——500行代码,不fork任何项目:

  • ~150行LcmDependencies adapter
  • ~50行Headroom proxy生命周期管理
  • ~200行meta-engine编排逻辑
  • ~100行工具代理注册

推翻

LCM的assembler输出包含两类内容:

  1. 摘要(summaries)——LLM生成的精炼文本,Headroom压不动
  2. 原始消息(fresh tail的最近64条)——包含tool output,这是Headroom的目标

在coding agent的tool-heavy场景中,fresh tail的tool output占50-70% token,Headroom能压掉其中60-80%,总体节省30-40%。听起来不错。

但OpenClaw不是一个coding agent工具。它的channel列表——Telegram、Discord、WhatsApp、Signal、iMessage、Voice Call、Web——说明它是一个多渠道聊天机器人平台。大量用户的场景是纯对话,几乎没有tool output。对这类用户,Headroom没有目标可压。

加上压缩的质量风险:grep返回200行匹配结果,SmartCrusher只保留20行——如果LLM需要第87行来定位bug,压缩直接破坏推理链。LCM有lcm_expand_query让LLM按需取回原文,Headroom有CCR做类似的事,但LLM不知道自己丢了什么,不会主动retrieve被压掉的内容。

结论:meta-engine的价值主张只对tool-heavy场景成立,而OpenClaw的用户画像远比这宽。通用性不够,不值得做成独立产品。


八、七个核心洞察

调研过程中形成的判断,按重要性排序:

  1. “省token当目标本身就错了”——真正目标是让agent在长任务中不犯错,省token是副产品。但所有开源方案都在优化压缩比,没人在优化任务完成率。

  2. “不是压缩对话历史,是维护结构化任务状态”——过程不重要,状态才重要。Claude Code的做法是对的:任务状态独立于对话历史,压缩后重新注入,跨会话持久化。

  3. “分层方案假设内容是静态的”——第3步不重要的API响应到第47步可能是解bug的唯一线索。静态重要性排序在复杂任务里经常错。

  4. “CCR把责任转嫁给模型”——模型不知道自己不知道什么。被压缩掉的内容如果摘要不够好,模型不会想到去retrieve。ResonantOS团队实测发现:lossless storage means nothing if the retrieval pipeline is lossy。

  5. “通用agent没办法针对场景做定制化优化”——harness工程的本质是根据场景优化。Claude Code可以针对编码场景深度优化,通用agent只能用通用策略。但通用策略永远打不过专用方案。

  6. “学术论文的激励是发表不是落地”——TME(Task Memory Engine)等方案在paper上表现很好,但没有工业验证。EMNLP Oral ≠ 生产可用。

  7. “编码场景被赢者通吃了”——Claude Code定义了体验天花板。做得不如它没人用,做得跟它一样好大厂直接抄。中间没有生存空间。唯一的缝隙是本地部署/国产模型场景,但这需要完整的benchmark验证。


九、为什么最终放弃找独立项目方向

排除过程:

方向 为什么不做
通用压缩中间件 Headroom已做,13万行,Apache 2.0
记忆存储框架 Mem0/MemOS/OpenViking/Letta已做
独立任务状态管理 天生跟框架深度耦合,做不成独立中间件
三者打包的中间件 各家都在框架内部做
OpenClaw ContextEngine实现 lossless-claw/Headroom/context-mode已做
Memory OS MemOS/MemoryOS/Letta概念和实现已有
编码agent特化 Claude Code定义了天花板,赢者通吃
Meta-engine(LCM+Headroom) 只对tool-heavy场景有价值,通用性不够

最终判断:这个领域在2026年4月已经进入“改进型创新”阶段——剩下的都是增量优化,不是从0到1的机会。每个子方向都有人做了,没做的要么价值不够大要么需要特定场景支撑。方向还是harness工程。


十、资源索引

源码与文档

  • OpenClaw ContextEngine文档:https://docs.openclaw.ai/concepts/context-engine
  • OpenClaw Context文档:https://docs.openclaw.ai/concepts/context
  • lossless-claw:https://github.com/Martian-Engineering/lossless-claw
  • Headroom:https://github.com/chopratejas/headroom
  • context-mode:https://github.com/mksglu/context-mode
  • ContextVault:https://ctx-vault.com/
  • OpenViking(字节跳动):https://github.com/volcengine/OpenViking
  • Hermes Agent:https://github.com/NousResearch/hermes-agent

架构分析

  • Claude Code泄露分析(最详细):https://claudefa.st/blog/guide/mechanics/claude-code-source-leak
  • Claude Code架构深度分析:https://wavespeed.ai/blog/posts/claude-code-architecture-leaked-source-deep-dive/
  • Anthropic长任务harness最佳实践:https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
  • Spotify Context Engineering实践:https://engineering.atspotify.com/2025/11/context-engineering-background-coding-agents-part-2
  • Five CLIs Walk Into a Context Window(context composition对比):https://theredbeard.io/blog/five-clis-walk-into-a-context-window/
  • State of Context Engineering in 2026:https://www.newsletter.swirlai.com/p/state-of-context-engineering-in-2026

学术论文

  • TME(Task Memory Engine):https://arxiv.org/abs/2504.08525
  • ICLR 2026 MemAgents Workshop:https://openreview.net/pdf?id=U51WxL382H
  • Context Engineering for AI Agents in OSS:https://arxiv.org/html/2510.21413v1

社区讨论

  • OpenClaw Issue #24800:auto-compaction在tool-use循环中不触发
  • OpenClaw Issue #7477:safeguard模式静默失败
  • OpenClaw Issue #56072:daily reset丢失context
  • OpenClaw Issue #50795:compaction后token计数归零
  • OpenClaw PR #22201:ContextEngine插件接口的引入
  • Cline Discussion #3248:compact功能的用户反馈
  • awesome-harness-engineering:https://github.com/ai-boost/awesome-harness-engineering

关于预测和决策的思考

发表于 2026-04-03

读过《反脆弱》和一些关于预测的著作后,我意识到一件事:预测本质上是很难的,也许是不可能的。

历史经验的局限性

历史经验看起来有用,但很难真正指导未来。单个事件的发生概率确实可能是 50%——我们无法预知。但统计结果表明某事件发生概率是 99% 或 1% 时,问题出现了。

在做决策时,我们不能只看概率。一个 1% 的事件,如果真的发生,在这个单一的世界里,对你的影响是 100%。所以很多时候,历史经验有可能有用,有可能没用。

复杂性的悖论

我回测过很多模型。一个规律是:简单的模型未必会被复杂的模型击败,但复杂的模型更容易出问题。

当你把一维的东西变成二维,把二维变成三维,把简单变成复杂时,需要考虑的因素成倍增加。任何一个维度出错,整体效果就可能很差。这就是为什么系统性的视角很重要——你要考虑的不只是单个变量,而是它们之间的相互作用。

直觉 vs 模型

杨振宁说过,学东西最高的境界是形成直觉。但这个直觉怎么来?很难量化。

人脑在思考时考虑的因素是难以估量的,但现有的模型无法完全模拟人脑的思维方式。而且,每个人的思维方式都不同。所以用一个通用的复杂模型去指导所有人的决策,本身就有问题。

这也是为什么《Superforecasting》讲的那些预测高手的方法很难完全教会别人——他们依靠的是多年经验形成的直觉和对不确定性的独特理解。但这种东西本质上是个性化的。

市场中的噪音

市场有人操作吗?也许吧。但这不重要。

重要的是,市场中充满了信息——利好、利空、各种消息。但对于个人投资者来说,噪信比很高。大部分消息对决策帮助不大,反而容易被带走。

机构能通过大量数据和算力去过滤信号,识别真正有价值的信息。但散户没有这样的能力。所以散户更容易被市场的波动影响,不知不觉就被带走了。

决策中的不确定性

你不能因为某事件发生概率是 50% 就随意做决策,也不能因为概率很低就完全放弃。

统计概率未必反映真实的情况。你需要有正念——意识到自己的无知。但这不意味着什么都不做。

问题是,没有完全的最优决策。在很多情况下,不存在最优解。你只能在不确定中做出相对更好的选择。

评价决策的标准

评价一个策略的好坏,我们看回撤率、夏普指数这些指标。但最终的成果,是由一个又一个决策累积而成的。

没有任何策略是完美的。最终的结果已经不是完美的。

实力与运气

普通人拿到好结果,很多时候要靠运气。但实力有没有?有。

实力决定了你在不同概率事件中的表现下限,但上限很大程度取决于运气。

实力可能体现在你对回撤的控制、对风险的敏感度、心理的稳定性上。这些能保证你不会特别差。但你最终能拿到多大的结果,很多时候还是运气。

反过来,回撤本身也有运气成分。所以两个方向都既有运气也有努力的因素。

最后的悖论

做决策这件事没有最优解。

如果你去追求最优解,有时候会陷入某个细节的陷阱里,过度优化反而造成问题。

有时候,承认不确定性,保持简单,反而是更好的选择。


在一个充满不确定性的世界里,与其追求完美的预测和决策,不如培养对风险的敏感和承受挫折的能力。

1…456…23

52 日志
2 分类
31 标签
© 2026 Sherry
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4