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 prompt | OpenClaw 构建的规则、工具、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.md | Agent 名称和身份 |
USER.md | 用户资料 |
HEARTBEAT.md | 心跳提示,满足条件才注入 |
BOOTSTRAP.md | 只在 brand-new workspace 首次使用 |
MEMORY.md | 存在时注入长期记忆 |
大文件会被截断。官方当前默认值是:agents.defaults.bootstrapMaxChars 为 12000 chars,控制单个 bootstrap 文件最大注入字符数;agents.defaults.bootstrapTotalMaxChars 为 60000 chars,控制所有 bootstrap 文件合计注入上限;agents.defaults.bootstrapPromptTruncationWarning 为 once,控制截断时是否在 Project Context 注入警告。
这就是为什么 TOOLS.md、MEMORY.md、AGENTS.md 不能无限写。它们越长,越容易导致:
- 本轮可用窗口变小。
- 关键内容被截断。
- compaction 更频繁。
/context list中 Project Context 占比异常高。
Bootstrap 文件不是越全越好。它们每轮都可能进入 Project Context,写太长会直接挤压模型可用窗口。
5. Daily memory 不等于普通 bootstrap
上一篇讲过 memory/YYYY-MM-DD.md。这里补一个重要边界:
memory/*.mddaily files are not part of the normal bootstrap Project Context.
普通回合里,daily notes 通过 memory_search 和 memory_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 解决的是会话历史太长的问题。
官方定义:
- 旧 conversation turns 被摘要成 compact entry。
- 摘要保存在 session transcript。
- 最近消息保持原样。
关键点:
- 完整历史仍在磁盘上。
- 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 decisionsCompaction 质量取决于摘要模型。可以设置 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 的区别
这张表必须记住:
| 维度 | Compaction | Pruning |
|---|---|---|
| 处理对象 | 旧 conversation turns | old tool results |
| 方式 | 摘要成 compact entry | soft-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. 本章自检
读完这一篇,你应该能回答:
- Context 和 Memory 的区别是什么?
/context list和/context detail分别看什么?- 为什么 workspace bootstrap 文件太长会导致截断?
- Skill 为什么是列表注入、说明按需读取?
- Tool schema 为什么是隐藏但真实的上下文成本?
- Compaction 和 Pruning 的持久化差异是什么?
- Context engine 的四个生命周期点是什么?
能回答这些问题,再进入 Workspace 篇,你就能理解为什么 OpenClaw 把 AGENTS.md、SOUL.md、TOOLS.md、USER.md 这类文件作为长期工作容器。
17. 接下来去哪
06 · Workspace
继续看 workspace 文件如何决定 Agent 身份、边界、工具习惯和长期协作方式。
04 · 记忆系统
回到 Memory 篇,对照 Context 和 Memory 的持久化边界。
官方教程:Agents
对照官方 Agents 页继续核对 Agent runtime、workspace 和运行边界。