AI 编程教程中文版
从原理到实战

05 · Context 管理:为什么 AI 会忘记、截断和压缩

理解 OpenClaw 如何组装上下文、统计 token、注入 workspace 文件,并通过 compaction 与 pruning 控制窗口压力。

上一篇讲 Memory:信息保存到磁盘,未来才有机会找回。本篇讲 Context:本轮真正发送给模型的内容。

这两件事必须分开:

Memory 是可持久化的材料;Context 是模型这一次运行时实际看到的窗口。

很多“AI 忘了”的问题,根因不是记忆没写,而是它没有进入本轮 context;很多“上下文爆了”的问题,也不是聊天太长,而是系统提示、工具 schema、workspace 文件和工具结果一起把窗口吃满了。

1. Context 到底是什么

官方定义很清楚:

Context is everything OpenClaw sends to the model for a run.

它受模型 context window,也就是 token limit 限制。初学者可以把它分成三块:

部分包含什么
System promptOpenClaw 构建的规则、工具、skills list、时间、运行时信息、注入的 workspace 文件
Conversation history当前 session 里的用户消息和 assistant 消息
Tool calls/results + attachments命令输出、文件读取、搜索结果、图片、音频、文件等
flowchart TD
  A[System prompt] --> C[Context window]
  B[Conversation history] --> C
  D[Tool calls and results] --> C
  E[Attachments] --> C
  F[Compaction summaries] --> C
  G[Provider wrappers] --> C
  C --> M[Model run]

这也解释了为什么你只发一句短消息,模型实际处理的 token 仍然很多。你的消息只是 context 里的最后一块。

Context window 不是聊天窗口长度。system prompt、workspace、tools、schemas、history 和附件都在抢同一块预算。

2. 先用命令看见上下文

OpenClaw 提供了几个直接观察 context 的命令:

命令用途
/status快速看窗口占用和 session 设置
/context list看注入了什么,以及粗略大小
/context detail看每个文件、tool schema、skill entry、system prompt 的更细分大小
/usage tokens在普通回复后追加 token 使用信息
/compact把旧历史摘要成 compact entry,释放窗口空间

从排障角度,第一步不是猜,而是跑 /context list

官方示例里,/context list 会显示类似信息:

Context breakdown
Workspace: <workspaceDir>
Bootstrap max/file: 12,000 chars
System prompt (run): 38,412 chars (~9,603 tok)

Injected workspace files:
- AGENTS.md: OK | raw 1,742 chars | injected 1,742 chars
- TOOLS.md: TRUNCATED | raw 54,210 chars | injected 20,962 chars

Skills list: 2,184 chars
Tool schemas: 31,988 chars
Session tokens: 14,250 total / ctx=32,000

这些数字会随模型、provider、tool policy、workspace 内容而变。不要背数字,要学会看哪个部分最大。

3. System prompt 每次运行都会重建

OpenClaw 的 system prompt 是 OpenClaw-owned,每次 Agent run 都会组装并注入。它不是 pi-coding-agent 的默认 prompt。

它通常包含:

  • Tooling:工具使用规则和当前工具能力。
  • Execution Bias:可执行请求要在本轮推进,阻塞时说明。
  • Safety:基础安全约束。
  • Skills:可用技能列表和按需读取规则。
  • OpenClaw Self-Update:如何安全查看和修改配置。
  • Workspace:工作目录。
  • Documentation:本地或公开文档路径。
  • Workspace Files:注入的项目上下文。
  • Sandbox:沙箱状态。
  • Current Date & Time:用户时区相关信息。
  • Heartbeats:心跳相关上下文。
  • Runtime:host、OS、model、thinking 等。
flowchart LR
  A[OpenClaw runtime] --> B[Build system prompt]
  C[Workspace files] --> B
  D[Tools and schemas] --> B
  E[Skills list] --> B
  F[Runtime metadata] --> B
  B --> G[Model context]

这里有一个关键判断:system prompt 里的安全约束是 advisory,指导模型行为;真正的硬边界要靠 tool policy、exec approvals、sandboxing、channel allowlists。

4. Workspace 文件会进入 Project Context

OpenClaw 会把一组 bootstrap files 修剪后注入 Project Context,让模型不用显式读取文件,也能看到身份、用户和工作规则。

默认注入的文件包括:

文件作用
AGENTS.md操作规则和项目说明
SOUL.md人格、边界、语气
TOOLS.md工具使用习惯
IDENTITY.mdAgent 名称和身份
USER.md用户资料
HEARTBEAT.md心跳提示,满足条件才注入
BOOTSTRAP.md只在 brand-new workspace 首次使用
MEMORY.md存在时注入长期记忆

大文件会被截断。官方当前默认值是:agents.defaults.bootstrapMaxChars12000 chars,控制单个 bootstrap 文件最大注入字符数;agents.defaults.bootstrapTotalMaxChars60000 chars,控制所有 bootstrap 文件合计注入上限;agents.defaults.bootstrapPromptTruncationWarningonce,控制截断时是否在 Project Context 注入警告。

这就是为什么 TOOLS.mdMEMORY.mdAGENTS.md 不能无限写。它们越长,越容易导致:

  • 本轮可用窗口变小。
  • 关键内容被截断。
  • compaction 更频繁。
  • /context list 中 Project Context 占比异常高。

Bootstrap 文件不是越全越好。它们每轮都可能进入 Project Context,写太长会直接挤压模型可用窗口。

5. Daily memory 不等于普通 bootstrap

上一篇讲过 memory/YYYY-MM-DD.md。这里补一个重要边界:

memory/*.md daily files are not part of the normal bootstrap Project Context.

普通回合里,daily notes 通过 memory_searchmemory_get 按需访问,不会自动吃掉 context window。例外是裸 /new/reset 回合,runtime 可以把最近 daily memory 作为一次性 startup-context block prepend 进去。

这点解释了两个现象:你写了 daily note,但普通回复没引用,通常是因为它没有自动注入,Agent 需要搜索或读取;MEMORY.md 太大会影响上下文,是因为它属于 bootstrap 注入文件,存在时会进入 context。

所以长期稳定信息放 MEMORY.md 要克制;大量工作流水放 daily notes,再靠搜索召回。

6. Skills 有两种上下文成本

Skills 不会默认把完整 SKILL.md 全部塞进 system prompt。

官方当前机制是:

  • system prompt 注入 compact skills list:name、description、location。
  • 具体 skill instructions 不默认注入。
  • 模型需要用某个 skill 时,再用 read 读取对应 SKILL.md

这是一种按需加载设计。

flowchart LR
  A[Skills folder] --> B[Compact skills list]
  B --> C[System prompt]
  C --> D{Need skill?}
  D -- Yes --> E[read SKILL.md]
  D -- No --> F[No full skill text loaded]

如果技能很多,skills list 本身也有成本。不要把 skill description 写成小作文;description 应该让模型判断何时使用,而不是替代完整手册。

7. Tools 的隐藏成本更大

Tools 对 context 有两种成本:Tool list text 可在 system prompt 报告中看到,是简短工具描述;Tool schemas JSON 不作为普通文本展示,但计入 context,用来让模型知道如何调用工具。

官方 /context detail 会列出最大的 tool schemas。这个很重要,因为你可能看不到它们,但它们确实消耗 token。

典型情况:

  • 浏览器工具 schema 很大。
  • exec / process 这类工具参数复杂,也会占空间。
  • 工具越多,模型调用能力越强,但基础上下文成本也越高。

这就是 tool policy 的另一个作用:不只是安全,也是上下文预算治理。

8. Slash command 不一定会进入模型

Context 文档还强调了 slash command 的三种行为:

  • Standalone commands:消息只有 /...,由 Gateway 作为命令执行。
  • Directives:/think/verbose/trace/reasoning/elevated/model/queue 等会在模型前被剥离。
  • Inline shortcuts:允许的发送者在普通消息里触发某些 /...,执行后再剥离。

这说明 /status/context list/compact 这类操作不等同于“告诉模型一句话”。它们先被 Gateway 处理。

排障时要分清:

  • 是用户消息进了模型,但模型没理解。
  • 还是 slash command 被 Gateway 提前处理,根本不是普通 prompt。

Slash command 先由 Gateway 处理,不要把 /status/context list/compact 当成普通用户 prompt。

9. Compaction 是摘要旧历史

Compaction 解决的是会话历史太长的问题。

官方定义:

  1. 旧 conversation turns 被摘要成 compact entry。
  2. 摘要保存在 session transcript。
  3. 最近消息保持原样。

关键点:

  • 完整历史仍在磁盘上。
  • Compaction 只改变下一轮模型看到什么。
  • Auto-compaction 默认开启。
  • 当接近 context limit,或 provider 返回 context-overflow error 时触发。
  • /compact 可以手动触发,并可附加指导语。
flowchart TD
  A[Long session history] --> B[Older turns]
  A --> C[Recent turns]
  B --> D[Compaction summary]
  D --> E[Session transcript]
  C --> F[Kept intact]
  E --> G[Next model context]
  F --> G

手动例子:

/compact Focus on the API design decisions

Compaction 质量取决于摘要模型。可以设置 agents.defaults.compaction.model 使用专门模型;未设置时从 active session model 开始,并可能走现有 fallback chain。显式 compaction model override 是精确值。

10. Memory flush 发生在 compaction 前

Before compacting,OpenClaw can run a silent memory flush turn to store durable notes to disk。

这一步的目的不是压缩上下文本身,而是在压缩前抢救值得长期保存的信息。

flowchart LR
  A[Near overflow] --> B[Memory flush]
  B --> C[Write durable notes]
  C --> D[Compaction]
  D --> E[Compact context]

所以它和上一篇的 Memory 形成闭环:Memory flush 写入 memory files,避免重要内容只留在即将被摘要的历史里;Compaction 写入 session transcript summary,减少下一轮模型看到的历史长度。

不要把 memory flush 当成普通自动记忆系统。它是 compaction 前的 silent housekeeping。

11. Pruning 是修剪旧工具结果

Pruning 解决的是工具输出过大,而不是普通聊天过长。

官方定义:

Session pruning trims old tool results from the context before each LLM call.

它有几个硬边界:

  • 只修剪 old tool results。
  • 不重写普通 conversation text。
  • in-memory only。
  • 不修改 on-disk session transcript。
  • full history 仍然保存在磁盘上。
flowchart TD
  A[Session transcript on disk] --> B[Build prompt view]
  B --> C{Old tool result too large?}
  C -- Yes --> D[Soft trim head and tail]
  D --> E[Hard clear remaining old results]
  C -- No --> F[Keep as is]
  E --> G[LLM call]
  F --> G

Pruning 默认对 Anthropic profiles 自动启用;非 Anthropic providers 默认 off,可通过 contextPruning 开启。

12. Compaction 和 Pruning 的区别

这张表必须记住:

维度CompactionPruning
处理对象旧 conversation turnsold tool results
方式摘要成 compact entrysoft-trim 或 hard-clear
是否写回 transcript是,summary 存进 transcript否,只影响本轮 prompt view
是否保留完整历史原始历史仍在磁盘上原始 transcript 不改
解决问题对话历史太长工具输出膨胀

两者互补。Pruning 让工具结果不那么容易把窗口顶满;Compaction 在历史整体接近上限时创建摘要。

13. Context Engine 决定如何组装上下文

大多数用户用默认 legacy engine 就够了。官方说:OpenClaw ships with a built-in legacy engine and uses it by default。

Context engine 的职责是:

  • 选哪些 messages 进入模型。
  • 如何摘要旧历史。
  • 如何跨 subagent 边界管理 context。

每次 OpenClaw 运行 model prompt,context engine 参与四个生命周期点:

  • Ingest:新消息进入 session 时,engine 可存储或索引。
  • Assemble:模型运行前,返回适配 token budget 的有序 messages。
  • Compact:窗口满或用户 /compact 时,摘要旧历史。
  • After turn:运行结束后,持久化状态、触发后台压缩或更新索引。

Legacy engine 的行为:

  • Ingest:no-op。
  • Assemble:由现有 runtime pipeline 处理。
  • Compact:委托内置 summarization compaction。
  • After turn:no-op。

只有当你需要不同的 assembly、compaction 或 cross-session recall 策略,才考虑插件化 context engine。

14. 常见误解

常见误解可以按这组边界校正:

  • 记忆写了不等于本轮一定可见。只有被注入、加载或搜索回来才在 context 里。
  • 200K window 不等于 200K 聊天空间。system prompt、tools、schemas、workspace、history 都占窗口。
  • memory/*.md 不是每轮都会自动加载。普通回合按需搜索或读取,裸 /new/reset 有例外。
  • Skill 不是安装越多越好。skills list 有成本,完整说明按需读取。
  • Tool schema 不可见也占 token。schema 计入 context,只是不作为普通文本展示。
  • Pruning 不会删历史。pruning 只影响 in-memory prompt,不改 transcript。
  • /compact 不是清空会话。compaction 写摘要并保留 recent messages,不是 /new

15. 给 Agent 的实践任务

把下面任务交给你的 OpenClaw Agent:

请检查当前会话上下文:
1. 执行 /context list,指出最大的 3 个上下文来源。
2. 执行 /context detail,说明 tool schemas 和 skills list 的大致占比。
3. 判断是否有 bootstrap 文件被 TRUNCATED。
4. 说明 MEMORY.md 和 memory/*.md 在本轮上下文里的差异。
5. 如果上下文压力很大,给出 pruning、compaction、缩短 bootstrap 文件、收紧 tool policy 的处理顺序。

你要看的不是它有没有给一堆泛泛建议,而是能不能用 /context 的实际输出定位最大成本。

16. 本章自检

读完这一篇,你应该能回答:

  1. Context 和 Memory 的区别是什么?
  2. /context list/context detail 分别看什么?
  3. 为什么 workspace bootstrap 文件太长会导致截断?
  4. Skill 为什么是列表注入、说明按需读取?
  5. Tool schema 为什么是隐藏但真实的上下文成本?
  6. Compaction 和 Pruning 的持久化差异是什么?
  7. Context engine 的四个生命周期点是什么?

能回答这些问题,再进入 Workspace 篇,你就能理解为什么 OpenClaw 把 AGENTS.mdSOUL.mdTOOLS.mdUSER.md 这类文件作为长期工作容器。

17. 接下来去哪

18. 官方资料

本页目录