v2 · 2026-05-10 · OpenClaw Context Engineering

上下文管理九层塔
OpenClaw Agent 的长期记忆、主动召回与自我进化架构

一个真正长期运行的 AI Agent,需要的不是更大的上下文窗口,而是一套完整的上下文治理体系。

引言:大窗口的幻觉#

上下文窗口从 4K 到 128K 再到 1M+,很多人以为"窗口够大就不需要记忆管理了"。

这是一个危险的幻觉。

窗口变大解决的是"能放多少",但没有解决:

  • 放什么进去?
  • 什么时候放?
  • 过期的怎么清?
  • 跨会话怎么延续?
  • 多 Agent 怎么共享又隔离?
  • 错误记忆怎么修正?
  • 经验怎么沉淀成能力?

这些问题,不是靠"更大的窗口"能解决的。它们需要的是 Context Engineering——对上下文的工程化治理。

本文介绍一套在 OpenClaw 多 Agent 环境中运行三个多月、并在近一个多月集中升级整理出的上下文管理架构。我们称之为"九层塔"。

从三层到九层:为什么简单记忆不够#

最基础的记忆架构分三层:

  • Layer 0:身份与规范(静态,低频修改)
  • Layer 1:知识积累与检索(持续增长)
  • Layer 2:驱动行动(实时运转)

三层架构能让 Agent "记住东西"。但当你开始长期运行——跨天、跨周、多会话、多 Agent 协作——你会发现三层不够:

  1. 记忆膨胀:文件越来越多,bootstrap 注入被截断
  2. 噪声累积:系统日志、heartbeat、maintenance 消息混入记忆
  3. 召回失败:记了但找不到,或找到的不是最相关的
  4. 压缩丢失:长会话被 compaction 后,关键决策丢了
  5. 重复劳动:同样的任务做了十次,每次从零开始

九层塔就是为了解决这些问题而逐步演化出来的。

三层记忆架构九层塔
回答问题如何开始让 Agent 记住东西如何让 Agent 在长期运行中持续治理上下文
核心抽象身份 / 知识 / 行动基础 / 运行时 / 进化(每组 3 层)
适用场景单轮 - 几轮对话内的记忆跨天 / 跨周 / 多会话 / 多 Agent 协作
关注重点"记得住""记什么、何时召回、如何压缩、怎样进化"
侧重设计正确的入门记忆模型把上下文相关功能纳入可治理系统

九层塔不是替代三层架构,而是在三层之上回答了"系统化治理"这个新问题。两者读起来可对比,但本文不依赖你读过前文。

九层塔总览#

点击任一层跳到详细说明 · ⚠ 数字 为常见坑数 · 🚨 数字 为高严重度坑数

三组,每组三层:

  • 基础层(L1-L3):定义 Agent 是谁、该怎么做、记住了什么
  • 运行时层(L4-L6):让记忆在对话中真正发挥作用
  • 进化层(L7-L9):让系统随时间变得更好

L1身份注入层:Agent 是谁#

解决的问题:Agent 需要一个稳定的身份锚点,否则在长对话或多 Agent 场景中会"人格漂移"。

OpenClaw 中的实现

  • SOUL.md — 定义人格、语气、行为边界
  • IDENTITY.md — 基本信息:名字、角色、emoji
  • USER.md — 用户画像:偏好、沟通风格、技术栈

关键设计:这些文件在每次 session 启动时自动注入 context window,不依赖 Agent 主动读取。

常见坑

  • 身份文件写得太长,挤占有效上下文空间
  • 多 Agent 场景中,从 chat history 推断身份而非从配置文件确认
  • persona 写得太强,压过任务目标

L2规则治理层:Agent 该怎么行动#

解决的问题:Agent 需要明确的操作边界——什么能做、什么不能做、怎么做。

OpenClaw 中的实现

  • AGENTS.md — 操作手册:读写边界、协作协议、安全规则
  • TOOLS.md — 工具使用规范:什么场景用什么工具
  • Bootstrap 配置 — 启动时的行为指令

关键设计:规则分层——身份规则 > 安全规则 > 任务协议 > 工具偏好。优先级明确,冲突时高优先级覆盖。

常见坑

  • 规则堆太多,Agent 遵循率下降
  • 规则没有分层,任务协议和人格描述混在一起
  • 缺少"完成后必须汇报 / 落盘"的闭环要求

L3文件记忆层:长期事实载体#

解决的问题:Agent 需要一个持久化的、可人工修正的知识库。

OpenClaw 中的实现

memory/
  shared/        ← 所有 Agent 可读写:项目、偏好、决策
  daily/         ← 每日共享日志
  private/       ← 各 Agent 私有记忆
  self-improving/ ← 行为改进记录

关键设计

  • Markdown 格式:可读、可 diff、可版本控制、可人工修正
  • shared / private 分区:多 Agent 协作时既共享又隔离
  • 写入规则明确:什么信息写哪里,由 AGENTS.md 定义

常见坑

  • MEMORY.md 变成垃圾桶,什么都往里塞,导致 bootstrap 截断
  • shared 区被某个 Agent 意外覆盖
  • 短期日志和长期事实混在一起,信噪比下降

L4语义检索层:从记忆中找上下文#

解决的问题:记忆文件越来越多,不可能全部塞进 prompt。需要按需召回。

OpenClaw 中的实现

  • 向量索引(embedding)+ 混合搜索(BM25 + semantic)
  • 多源检索:memory 文件 + session transcript
  • Fallback 机制:primary backend 超时时降级到 builtin index

关键设计

  • 不只是"向量相似度",还有 temporal decay(时间衰减)和 MMR(多样性)
  • 索引定期更新(扫描 + embedding)
  • 搜索结果有质量阈值,不是"找到就注入"

工程 Insight

搜索 timeout 从 15s 提到 60s 只解决了配置层问题。真正的瓶颈在 query expansion + LLM rerank 路径。搜索系统需要区分:索引是否更新、embedding 是否覆盖、query path 是否稳定、ranking 是否符合预期。

常见坑

  • 只看"文件已索引",忽略 embedding 覆盖率
  • Fallback 静默工作,掩盖 primary backend 的性能问题
  • exact query 被日志文件排在源文件前面(rerank 偏差)
  • 检索 CLI 的 stdout 不是干净 JSON——遇到 collection 不存在 / 参数异常时会先打印 Warning:Usage: 文本再给 JSON。下游 parser 必须容错地跳过非 JSON 前缀,抛错会让多 collection 路径整体退化到慢 fallback
  • per-agent 索引会累积大量 orphan 向量(content 已删但 vector 留着),需要周期性 cleanup;orphan 占比 > 50% 是 sqlite 体积膨胀的常见原因

L5主动召回层:消息前自动带上下文#

解决的问题:用户不应该每次都说"帮我查一下记忆"。系统应该自动判断需要什么上下文。

OpenClaw 中的实现

  • Active Memory 插件:在用户消息进入 Agent 前,自动搜索相关记忆
  • 将召回结果压缩为短摘要注入 prompt
  • 结果标记为 untrusted context:明确告知 Agent 这部分内容来自自动召回而非用户原话,可质疑、可忽略、可反向校验,不作为权威事实直接采用

关键设计

  • 主动召回 ≠ 无脑注入。有质量阈值、空结果过滤、相关性判断
  • 注入内容明确标记来源,Agent 可以选择忽略
  • 对慢 query 可以选择更轻的搜索模式

常见坑

  • 低质量摘要污染当前对话
  • Active memory 输出被误当作 trusted fact
  • 召回 subagent timeout 太短,导致频繁空结果
  • 检索后端单点失败传染整条召回链:active memory 调底层多 collection 检索时,任一子查询抛错会让整条召回退化到 builtin slow path(>10s / 0 hits)。L4 parser 必须 fail-soft(warn + 返回空数组),主动召回层才能稳定

L6会话生存层:长会话不丢上下文#

L6 是九层塔最复杂、也最容易"安静吃亏"的一层——本节多数 critical 标注集中在这里,建议慢读。

解决的问题:长对话会超过模型上下文窗口。只靠简单截断或一次性 compaction,会让早期约定、任务状态和关键决策从当前对话里消失。

OpenClaw 中的实现

  • Lossless Context Engine(lossless-claw):作为 plugins.slots.contextEngine 的运行时上下文引擎,实时摄入消息,并用 DAG / 摘要 / 分层压缩来组装下一轮模型上下文
  • Session Memory hook:实时保存会话 transcript,保留可审计的原始时间线
  • Compaction Memory Flush:压缩前自动将重要信息写入 durable memory,作为最后一道持久化防线
  • Session transcript 被索引,可供 L4 语义检索和后续 Dreaming 使用

关键设计

  • L6 的中心不是单纯 flush,而是"运行时上下文生存":谁负责摄入、压缩、组装当前会话
  • 检索层回答"该找回什么长期记忆",context engine 回答"当前这条长会话怎样继续保持连贯"——两者互补,不互相替代
  • memoryFlush / safeguard compaction 是 fallback safety rail,不是替代 context engine 的主机制
  • 长任务应该外化 plan 到文件,而不是只存在 context 里
  • 必须显式绑定 plugins.slots.contextEngine:不绑不会报错,只会悄悄退化到 legacy 截断引擎(详见 坑 #6
  • 摘要 LLM 调用前必须 regex redact secrets:否则 sk-XXX / token 会经 FTS + vector 持续放大注入(详见 坑 #7
  • 短源 (< 200 tokens) 跳过 summarizer:避免"摘要 = timestamp + 原文"的反向膨胀(详见 坑 #8

工程 Insight

compaction / heartbeat / system prompt 被写入 transcript 后,可能被后台整理层(L7)错误晋升为长期记忆。会话生存层和后台整理层之间需要噪声过滤机制。
Secrets 在 raw 消息里容易识别(grep 一抓一个准),但 LLM 摘要把它换个上下文重新表述后,固定的 grep 规则就不一定 catch 得到了。在源头 redact 比事后 audit 容易得多——这是 L6 必须正视的安全责任。

常见坑

  • 只依赖大窗口模型,不做显式 context engine / 持久化治理
  • 把 memoryFlush 当成主机制,而不是 fallback safety rail
  • 长任务没有外化 plan,压缩后目标漂移
  • 系统消息混入 transcript,污染下游

L7后台整理层:Dreaming 消化上下文#

解决的问题:短期记忆和 session transcript 会无限增长。需要定期整理、去重、提炼。

OpenClaw 中的实现

  • Memory Core Dreaming:每日自动运行
    • Deep sleep:修复 recall store
    • Light sleep:从 session corpus 中提炼候选记忆
    • REM:生成摘要和关联
  • Post-sweep watchdog:检查 Dreaming 产物、清理噪声、统计健康指标

关键设计

  • Dreaming 不是简单的"把所有东西都记住",而是有选择地晋升
  • Promotion threshold:只有高价值内容才会从短期进入长期
  • 噪声清理是 Dreaming 的必要后置步骤
  • L7 还要监控 L6 引擎本身:context engine 是个安静失败的组件(不写入即等于沉默)。L7 应当包含一个周度健康监控 cron,监控 lcm.db 增长、DAG leaf / condensed 比例、WAL 状态。否则一次配置回归可能要 40 天才被发现

工程 Insight

Dreaming 会把 heartbeat、maintenance、compaction 通知等系统噪声纳入候选。因此需要 post-sweep watchdog:每天 Dreaming 完成后自动清理噪声、统计 promotion ratio、报告异常。典型数据:每天清理 200+ 行噪声,promotion 率约 4-6%。
健康监控阈值要分级——🔴 才告警(ingest 沉默 / lcm 停摆 / WAL 损坏),🟡 只写报告不打扰(DAG 浅 / WAL 滞后),🟢 静默通过。否则告警疲劳会让真问题被淹没。

常见坑

  • 后台任务成功但报告投递失败,无人知道结果
  • 噪声进入 corpus 后被长期污染
  • Promotion threshold 太宽,低价值内容晋升

L8自我迭代层:从错误中改进行为#

解决的问题:Agent 会犯错。同样的错误不应该犯第二次。

OpenClaw 中的实现

memory/self-improving/
  hot/           ← 当前活跃的行为信号
  corrections/   ← 被纠正的错误记录
  signals/       ← 观察到的行为模式
  shared-rules/  ← 晋升为稳定规则的条目

关键设计

  • 错误记录 → 信号积累 → 规则晋升:不是一次犯错就改规则,而是重复出现才晋升
  • shared-rules 跨 Agent 共享:一个 Agent 的教训,所有 Agent 受益
  • 有 reviewer 和 threshold,防止规则膨胀
  • agent identity 用唯一规范:自我迭代目录用 agent id(agent-A / agent-B / ...),不用 persona name(Persona-A / Persona-B 这类用户自定义显示名)。所有跨进程协作(cron、patrol、promotion)用同一份 mapping
  • cron payload 用绝对路径:周期性自反思任务里写 memory/self-improving/X/hot.md 这种相对路径会被不同 cwd 解析到不同 workspace,造成同一 agent 的内容分裂到多处。统一用 /root/.openclaw/workspace/memory/self-improving/<id>/... 的绝对路径
  • patrol 用枚举白名单KNOWN_AGENTS + KNOWN_FILES 列表化,扫到不在白名单的就报警。这能在第 1 周内发现命名漂移、拼写错误(如 corrrections.md 多打一个 r)、persona vs agent-id 大小写分裂

常见坑

  • 把一次性偏好过早晋升为全局规则
  • 没有 deprecation 机制,过时规则永远存在
  • 目录命名不一致,导致扫描漏项
  • persona name vs agent id 双轨命名不统一,cron 跟 patrol 各走各的写出多份目录
  • cron payload 用相对路径,cwd 一漂全军覆没

L9能力进化层:把经验变成技能#

解决的问题:Agent 反复做同样的事情,每次从零开始。经验应该固化为可复用能力。

OpenClaw 中的实现

  • Skill Evolution:从历史任务中 harvest → synthesize → review → promote
  • 产出的 skill 存入 shared-skills 目录,所有 Agent 可调用
  • 定期审计:清理过窄、过时、重复的 skill

关键设计

  • 技能不是手动写的,而是从实际任务中自动提炼
  • 有 review 环节:不是所有 workflow 都值得变成 skill
  • 技能有生命周期:创建 → 使用 → 验证 → 可能 deprecate

常见坑

  • 技能过窄,只适用于特定场景
  • 命名差,其他 Agent 找不到
  • 私有上下文被错误抽象成 shared skill

九层之间的数据流#

九层塔数据流:从用户消息到下一轮对话的闭环 用户消息 L1 / L2身份 + 规则(自动注入) L5主动召回(自动搜索) L4语义检索(按需查找) Agent 回答 / 执行 L6会话生存(lossless-claw) L3文件记忆(durable) L7Dreaming(整理) L8自我迭代(纠错→规则) L9技能进化(→ skill) 下一轮对话继续使用

点击任一节点跳到对应章节 · 虚线表示跨轮闭环

这不是线性流程,而是一个闭环。每一层的输出都是其他层的输入。

搭建路径建议#

不需要一次性搭建九层。建议分阶段:

第一阶段:基础可用(L1-L3)

  • 写好 SOUL.md、IDENTITY.md、USER.md
  • 建立 memory/ 目录结构
  • 定义 AGENTS.md 中的读写规则

第二阶段:检索与召回(L4-L6)

  • 启用 memory search + embedding
  • 配置 Active Memory 插件
  • 启用 session memory 和 compaction flush

第三阶段:自动进化(L7-L9)

  • 启用 Dreaming + post-sweep watchdog
  • 建立 self-improving 目录和晋升机制
  • 启用 Skill Evolution
你已搭到 0/9 项 · 第 0/3 阶段

每个阶段都可以独立运行。但完整的九层塔才能形成真正的闭环。

源码层的小修整:把开源组件做成"工程资产"#

诚实地说,把九层塔落到生产时,光配置是不够的。前文 L4(parser fail-soft)和 L6(摘要前 redact secrets / 短源跳过 LLM)提到的几处问题,都需要在开源组件源码上做小幅适配。

这一节不再重复"改什么",重点谈"怎样让这种修改活下去"——临时 hotfix 会随着 npm 升级或上游 git pull 失效;只有做成可观测、可重启自愈的工程资产,才能真正成为架构的一部分。最佳实践是:

要素做法
sentinel在 patched 区域留 // PATCH:<name> 注释,apply 脚本据此判断幂等
apply script单一 idempotent shell / node 脚本,能反复跑
boot 集成gateway 启动时 ExecStartPre 自动跑 apply 脚本——上游覆盖目标后下次重启自动重打
backup 文件apply 前 timestamp 备份,rollback 路径明确
descriptor 入版控.patch 文件(unified diff + 解释)入 git,编译产物 gitignore
fail-closedsentinel anchor 找不到(上游改了函数体)就 fail,主流程容错继续,日志留 trace

让对开源组件的小修整可被持续维护,而不是"换台机器就丢"。

运维真心话:14 个最容易踩的坑#

九层塔架构清单容易看,但落地时会反复踩一些坑。以下是从实际运行里整理出的高频陷阱,按层归类:

#出现层一句话提醒
1bootstrap 注入文件超阈值被截断L1 / L2 / L3MEMORY.md 严格限制为"规则 + 索引",自动 promotion 内容拆出去
2embedding 覆盖率 ≠ 索引完成率L4"files indexed" 是文件级,"embedded chunks" 是向量级,两者可以差几个数量级
3检索 CLI stdout 非 JSON 噪声L4qmd 类 CLI 在 collection 异常时往 stdout 写 warning,下游 parser 必须 fail-soft
4多 collection 路径单点失败传染L4 / L5一个 collection 的子查询抛错不应让整条 active-memory 退化到 builtin
5active-memory 注入低质量摘要L5加 minRelevanceScore + 模板化 fallback 过滤 + untrusted context 标记
6context engine slot 没绑定 = 安静失败L6plugins.slots.contextEngine 缺失时系统不报错,只是 lcm.db 永不增长——必须有 L7 健康监控
7LLM 摘要把 secrets 经 FTS 放大L6摘要器原样保留 sk-XXX / token,进 summaries 后 lcm_grep 命中、vector embedding 收录、下次组装再注入 prompt——必须在调 LLM 前 redact
8短源做 summary 反而变长L6源 < 200 tokens 直接 return 原文,避免"摘要 = timestamp + 原文"的反向膨胀
9session 内部消息(cron / subagent)污染 corpusL6 / L7ignoreSessionPatterns 在源头排除,比在 Dreaming 后清理高效
10post-sweep watchdog 投递失败 → 无人知L7watchdog 自身也要监控;delivery 失败要降级到 local log + 告警
11persona 名 vs agent id 双轨写入造成目录分裂L8全局只用 agent id(agent-A / agent-B / ...);persona name 不进文件系统
12cron payload 用相对路径在不同 cwd 下落到不同 workspaceL8自反思 cron 一律用绝对路径
13per-agent 索引累积 orphan 向量L4周期性 cleanup,否则 sqlite 体积膨胀(实测可达 80%+ 都是 orphan)
14sudoers 文件名带 . 被默认忽略运维/etc/sudoers.d/X.tmp 不生效;要用 X 不带后缀
没有匹配的坑。换一个筛选条件试试。

其中 #6 和 #7 是这套架构最容易"安静吃亏"的两点:context engine 不绑 slot,整个 L6 等于没装;摘要器没做 secrets redaction,secrets 会经 FTS 持续放大。这两条强烈建议在搭建 L6 时就一次到位。

结语#

九层塔不是为了复杂而复杂——长期运行的 Agent 面临的问题天然分布在九个不同维度(身份 / 规则 / 记忆 / 检索 / 召回 / 会话生存 / 整理 / 自我迭代 / 技能化),缺一层就会在某个时刻"漏出来"。

好的 Agent 不是"记得更多",而是知道什么该记、什么时候召回、何时压缩、如何清噪、怎样从经验中进化。

这就是 Context Engineering 的本质:不是管理上下文的大小,而是把上下文的整个生命周期做成 可观测、可修复、可进化 的工程闭环。