2026 年 Agent 上下文管理:源码实证与架构建议

2026 年 Agent 上下文管理:源码实证与架构建议

  • 结论先行(TL;DR)
    • 把“省 token”当目标会南辕北辙;目标应是“在长任务中少犯错”,token 节省只是副产品。
    • 现成方案最易落地的组合是“语义组装 + 算法压缩”:先用 LCM(lossless-claw)挑对上下文,再用 Headroom 压冗余工具输出。但要把可逆取回(CCR)与结构化任务状态贯穿,否则准确率会掉。
    • OpenClaw 默认 Legacy 引擎确实是“壳”,但内置了一套守护与补救机制;生态里已有 Headroom、context‑mode、LCM 的插件化路径,无需 fork 重写。
    • Hermes 的压缩不是“固定 13.9k + 双调用”,而是一次结构化摘要,预算随上下文规模动态调整。

问题刻画

  • 约束:模型上下文上限;工具输出与检索回流导致会话爆炸;跨会话/跨子任务串联要求“记得住状态而不是记得住过程”。
  • 错位:把“最高压缩比/最少 token”当 KPI 会牺牲可用性(缺关键行、断工具结果配对、遗漏标识符等),更好的目标是“正确率、重试次数、任务完成率、返工率”。

生态速写(源代码为证)

  • OpenClaw(默认)
    • Legacy 引擎是“兼容壳”:
      • openclaw/src/context-engine/legacy.ts:28 ingest() 返回 { ingested: false }
      • openclaw/src/context-engine/legacy.ts:38 assemble() 原样透传、estimatedTokens: 0
      • openclaw/src/context-engine/legacy.ts:79 compact() 委托给运行时 delegateCompactionToRuntime
    • 压缩“固定比例 + 护栏”并存:
      • openclaw/src/agents/compaction.ts:16 BASE_CHUNK_RATIO=0.4
      • openclaw/src/agents/compaction.ts:17 MIN_CHUNK_RATIO=0.15
      • openclaw/src/agents/compaction.ts:18 SAFETY_MARGIN=1.2
      • 同文件包含“按 token 份额切块、成对保留 tool 调用/结果、摘要开销预算”等逻辑与重试补救
    • 插件“排他 slot”:
      • openclaw/src/plugins/slots.ts:12 kind→slot 映射(memory / context-engine)
      • openclaw/src/plugins/slots.ts:76 applyExclusiveSlotSelection(…) 切换 slot 并禁用同类插件
    • 任务状态不是“纯内存”:
      • 运行时 Map:openclaw/src/tasks/task-registry.ts:50
      • 可插拔持久化(默认 SQLite):openclaw/src/tasks/task-registry.store.ts:31
  • lossless‑claw(LCM)
    • 架构解耦(SQLite/FTS5 存储 + 语义组装 + 可扩展摘要),通过插件契约接入 OpenClaw:
      • lossless-claw/src/engine.ts:1199 LcmContextEngine implements ContextEngine
      • 依赖的是 openclaw/plugin-sdk 契约而非零依赖:lossless-claw/src/engine.ts:19
      • 会话存储:lossless-claw/src/store/conversation-store.ts:263
      • 语义检索:lossless-claw/src/retrieval.ts:124
  • Headroom
    • JSON 工具输出智能压缩(SmartCrusher)、文本压缩(Kompress,可选 ML)、可逆取回(CCR):
      • 非 JSON 直通(不压):headroom/tests/test_text_compressors.py:289
      • CCR 工具名:headroom/headroom/ccr/mcp_server.py:64
    • 已有 OpenClaw 引擎插件(零 LLM、调用 compress()):
      • headroom/plugins/openclaw/src/engine.ts:1
  • Hermes Agent
    • 压缩预算动态,不是“固定 13.9k + 双调用”:
      • 下限/比例/上限:hermes-agent/agent/context_compressor.py:39, :41, :43
      • 预算计算与上限约束:hermes-agent/agent/context_compressor.py:220–:225
      • 唯一 LLM 调用(结构化摘要,支持迭代更新):hermes-agent/agent/context_compressor.py:404, :287
      • 低成本预处理(裁剪旧工具输出):hermes-agent/agent/context_compressor.py:155
    • 记忆 provider 可插拔,但“是否调用 LLM”取决于 provider 实现:
      • hermes-agent/agent/memory_provider.py:164
  • context‑mode
    • 以“会话简历”跨压缩注入、计数与可观测:
      • 计数:context-mode/src/session/db.ts:84, :194
      • before/after_compaction 钩子 + resume 注入:context-mode/src/pi-extension.ts:297, :307, :265

发现与补正

  • “OpenClaw 等于‘塞满再摘要’”并不全面
    • 确有固定比例与 Legacy 默认,但生产路径包含分块、工具配对修复、摘要质量守卫、标识符保护、重试/超时治理与“预压缩记忆冲洗”等演进;判词宜改为“默认策略偏朴素,但配备成体系护栏,可通过插件替换/接管”。
  • “任务状态在内存 Map,测试强耦合”偏颇
    • TaskRegistry 提供持久化与 Observer 注入点,可替换为轻量 store,隔离测试(见上)。
  • “Headroom 压不动自然语言摘要”要加限定
    • SmartCrusher 针对 JSON,文本默认直通;但 Kompress 可对文本压缩(需 [ml] 额外依赖)。并且 CCR 让“可逆检索”成为安全阀。
  • “LCM 零 OpenClaw 依赖”应更严谨
    • 是“契约依赖、实现解耦”,能在 OpenClaw 外独立复用,但仍以 plugin-sdk 类型做编译时契约绑定。

组合方案:Meta‑Engine 编排(LCM → Headroom)

  • 目标:既保留语义相关性(由 LCM 负责),又显著压掉冗长工具输出等结构化内容(由 Headroom 负责);对纯对话场景自动旁路,避免过度压缩。
  • 编排要点
    • 接口所有权:实现一个 ContextEngine,占住 context-engine slot。
    • 生命周期
      • assemble():先调用 LCM assemble(),对输出消息做“工具输出占比估算”;若工具占比>阈值(如 ≥50%),调用 Headroom compress();否则直通 LCM 输出。
      • compact():传入 token 预算给 Headroom(RollingWindow + CCR),并透传/保留 LCM 的摘要(避免对摘要再压缩)。
    • 格式桥接
      • LCM/Headroom 使用的消息格式(Agent/OpenAI)互转:参考 headroom/plugins/openclaw/src/engine.ts:11 转换器思路。
      • 对“工具结果成对”保持:遵循 OpenClaw 分块配对逻辑避免“孤儿调用/结果”(见 openclaw/src/agents/compaction.ts:117)。
    • 可逆性/取回
      • 同步注入 CCR 工具使用说明,或在 system prompt 添加“若需要更多细节,调用 headroom_retrieve”提示,见 headroom/headroom/ccr/mcp_server.py:64。
    • 旁路策略
      • 统计最近 N 条消息文本 token 比例、工具输出 token 比例与 JSON 可压缩度评分(可用样本规则先行),不满足门槛直接返回 LCM 结果。
  • 风险与对策
    • “摘要+压缩”双重丢失风险:禁止对摘要文本做 lossy 压缩;CCR 仅覆盖被压缩的原文,不覆盖摘要。
    • 桥接一致性:保持 tool_call_id/tool_result 成对与顺序稳定,避免模型拒绝或工具注入失配。
    • 观测:记录 tokens_before/after/saved、错配修复次数、CCR 取回次数等,作为回归指标。

评价指标(建议用例)

  • 基础:token 节省(prompt_tokens)、压缩前后 API 错误率、继续对话“重复工作”比率。
  • 任务正确性代理:修 bug 类用例中“首次定位关键错误行”的命中率;代码生成用例中的“路径/标识符保真率”。
  • 稳定性:工具调用-结果配对完整率,CCR 取回命中率与延迟。

我会怎么实现(最小工作量)

  • 新建一个 context-engine 插件(占 slot)
    • 复用 lossless-claw 作为子引擎生产 assemble 结果
    • 条件触发 headroom compress()(沿用 headroom/plugins/openclaw/src/engine.ts:1 里的 compress() 调用方式)
    • 旁路或失败一律回退到 LCM 输出;compact() 仅分发预算与记录观测
  • 工期估计:~300–500 行 TypeScript(含桥接与指标),不改三方仓库

证据清单(可点开核查)

  • OpenClaw
    • openclaw/src/context-engine/legacy.ts:28, openclaw/src/context-engine/legacy.ts:38, openclaw/src/context-engine/legacy.ts:79
    • openclaw/src/agents/compaction.ts:16, openclaw/src/agents/compaction.ts:17, openclaw/src/agents/compaction.ts:18, openclaw/src/agents/compaction.ts:117, openclaw/src/agents/compaction.ts:211
    • openclaw/src/plugins/slots.ts:12, openclaw/src/plugins/slots.ts:76
    • openclaw/src/tasks/task-registry.ts:50, openclaw/src/tasks/task-registry.store.ts:31
  • lossless‑claw
    • lossless-claw/src/engine.ts:1199, lossless-claw/src/engine.ts:19
    • lossless-claw/src/store/conversation-store.ts:263, lossless-claw/src/retrieval.ts:124
  • Headroom
    • headroom/tests/test_text_compressors.py:289
    • headroom/headroom/ccr/mcp_server.py:64
    • headroom/plugins/openclaw/src/engine.ts:1
  • Hermes Agent
    • hermes-agent/agent/context_compressor.py:39, hermes-agent/agent/context_compressor.py:41, hermes-agent/agent/context_compressor.py:43
    • hermes-agent/agent/context_compressor.py:220, hermes-agent/agent/context_compressor.py:225
    • hermes-agent/agent/context_compressor.py:404, hermes-agent/agent/context_compressor.py:287, hermes-agent/agent/context_compressor.py:155
    • hermes-agent/agent/memory_provider.py:164
  • context‑mode
    • context-mode/src/session/db.ts:84, context-mode/src/session/db.ts:194
    • context-mode/src/pi-extension.ts:297, context-mode/src/pi-extension.ts:307, context-mode/src/pi-extension.ts:265