本文覆盖:Context Compaction 核心定义、safeguard 安全压缩模式、PI Harness
compact()接口、AgentHarnessCompactParams/AgentHarnessCompactResult类型抽象、Replay-safety / replay-unsafe 标记体系(mutating write 变更写标记规则)、QA 回归验证全链路,承接 Session / Transcript / Harness / Tool / Model Provider 整套架构,面向企业级 Multi-Agent 生产、回放审计、客服质检场景。
一、Context Compaction 基础概念
1.1 定义
Context Compaction(上下文压实/上下文压缩):OpenClaw 用于解决长会话上下文窗口溢出的核心机制。
- Transcript:磁盘持久化、完整原始会话事件日志(JSONL),永远不删除,用于审计、回放、QA回归;
- Context:每次送入 LLM 的内存窗口(messages),受模型 max_tokens 硬限制;
- Compaction:不删除原始 Transcript,把窗口内早期多轮对话、工具交互交由 LLM 摘要合并为一条 compact 摘要条目,替换原始多条历史;保留最近若干轮完整原始消息,从而降低 Token 占用,让会话持续运行。
区分 Compaction vs Pruning(修剪)
- Compaction:摘要合并,原始日志留存,支持回放审计;
- Pruning:直接丢弃工具结果/旧消息,轻量化,回放不可信。
1.2 核心设计约束
- 完整 Transcript 持久层不可篡改;
- 压缩只修改送入模型的运行时 Context 窗口;
- 工具调用
tool_call ↔ tool_result配对不能被拆分; - 支持多模式切换:
safeguard / auto / aggressive / manual; - 强制和回放安全标记联动:mutating write 变更操作后会话标记 replay-unsafe,回放时禁止重执行外部副作用操作。
二、safeguard 压缩模式(compaction.mode = safeguard)
2.1 定位
safeguard 是 OpenClaw 生产默认推荐模式,安全优先、回放一致性优先,区别于激进截断,面向 QA 回归、工单质检、可审计长会话场景。
新版 OpenClaw 默认配置:
agents.defaults.compaction.mode = "safeguard"
2.2 核心规则
- 触发策略:仅在 Token 临近上限、手动调用
/compact、溢出兜底时触发;不会高频自动抢占执行; - 不可破坏约束:默认
allowMutatingEventTruncate = false,不能裁剪、合并、摘要 mutating write 标记的事件(数据库写入、外部API提交、文件修改、发消息等带副作用操作); - 保留完整工具配对、人工审批事件、关键业务标识符;
- 内置摘要质量校验:摘要必须保留关键ID、待办、业务结论,摘要无效时执行内置重试回退;
- 可配置底板预留:
reserveTokensFloor,保证压缩本身有足够 Token 预算执行摘要,避免死循环溢出; - 配套防护插件:
compaction-safeguard.ts护栏,控制可压缩历史占比maxHistoryShare,限制摘要预算。
2.3 模式横向对比
| Mode | 优先级 | Mutating 事件处理 | 适用场景 |
|---|---|---|---|
| safeguard | 回放安全最高 | 禁止裁剪/合并 | QA回归、生产审计、客服工单、需要完整回放 |
| auto | 平衡 | 允许合并只读工具日志 | 通用业务Agent |
| aggressive | Token成本优先 | 可裁剪旧事件,摘要简化 | 高并发、低成本、无需回放场景 |
| manual | 外部控制 | 由入参显式控制 | 定时后台批量压缩、测试脚本 |
2.4 典型配置示例
{
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard",
"reserveTokensFloor": 40000,
"maxHistoryShare": 0.3,
"identifierPolicy": "strict",
"allowMutatingEventTruncate": false
}
}
}
}
三、PI Harness compact() 接口
3.1 架构位置
PI Harness = PI 嵌入式会话标准适配层,封装 AgentSession 生命周期:run / toolCall / compact / replay / abort,向上统一抽象,隔离 PI SDK 内部私有实现,网关、业务层、SessionManager 不依赖 PI 内部结构体。
底层实现入口:compactEmbeddedPiSessionDirect(),对外暴露标准化 compact() 方法。
3.2 完整调用链路
上层业务 /compact API / 上下文溢出回调
↓
PI Harness.compact(params: AgentHarnessCompactParams)
↓
参数校验 + safeguard 策略加载 + replay-safety 预检查
↓
SessionManager 读取全量持久化 Transcript
↓
遍历事件流,识别 mutating write,切分可压缩区间
↓
调用 Compactor + ModelProvider 生成摘要
↓
组装新精简上下文窗口,更新会话 replaySafe 标记
↓
持久化 compaction 事件到 Transcript(追加,不覆盖旧日志)
↓
返回 AgentHarnessCompactResult
3.3 compact() 核心职责
- 加载指定 sessionId 的完整 transcript;
- 根据入参 compaction mode 加载策略(safeguard 加载护栏);
- 扫描所有事件,识别 replay-unsafe mutating 事件,划定不可压缩边界;
- 执行分块摘要,保证 tool_call / tool_result 成对不切割;
- 追加一条 compaction 元事件写入 JSONL transcript;
- 返回压缩统计、回放安全标记、Token 变化、变更事件列表;
- 支持 replayCheck 开关(QA场景强制开启,校验压缩前后行为一致性)。
边界注意:如果业务层开启
ownsCompaction=true(业务自行管理窗口),会旁路内置自动 compact 逻辑,必须手动调用本接口触发压缩。
四、AgentHarnessCompactParams / AgentHarnessCompactResult 抽象契约
4.1 设计目的
跨组件解耦:Harness、PI SDK、SessionManager、Gateway、业务侧、测试框架共用同一套强类型契约,避免各层自定义结构导致兼容性问题,方便扩展自定义压缩器、回放校验器。
4.2 AgentHarnessCompactParams(入参)伪类型定义
interface AgentHarnessCompactParams {
sessionId: string; // 会话唯一标识
sessionFile: string; // transcript持久化文件路径
compactionMode: "safeguard" | "auto" | "aggressive" | "manual";
contextTokens: number; // 模型上下文总上限
reserveTokensFloor: number; // 压缩预留最小底板token
modelProvider: ModelProvider; // 绑定模型抽象,用于生成摘要
replayCheck?: boolean; // QA场景:开启回放一致性校验
forceCompact?: boolean; // 强制触发(手动compact使用)
allowMutatingEventTruncate: boolean; // safeguard默认false
}
4.3 AgentHarnessCompactResult(返回结果)伪类型定义
interface AgentHarnessCompactResult {
success: boolean;
originalTokenCount: number;
compactedTokenCount: number;
tokenSaved: number; // 本次节省token数量
replaySafe: boolean; // 当前会话整体是否可完整回放
mutatedEventIds: string[]; // 命中的mutating write事件ID列表
compactedWindow: Message[]; // 压缩后送入模型的新上下文窗口
compactionEventId: string; // 写入transcript的compact事件唯一ID
summaryText: string; // 生成的摘要原文
error?: Error;
}
五、Replay-safety 标记体系:mutating write → replay-unsafe
5.1 核心目标
解决回放风险:直接重放完整 transcript 时,只读事件可以安全重跑;带副作用的变更写操作不能重复执行(重复下单、重复改库、重复发送消息)。
5.2 事件分类
- Replay-safe(回放安全 / readonly)
用户提问、LLM 思考、只读工具调用(查询数据库、读文件、网页拉取);无外部状态变更,回放可重复执行,safeguard 模式允许摘要合并这类事件。 - Mutating write(变更写事件)
写数据库、提交表单、发送通知、文件写入、创建工单、支付调用等,会修改外部系统状态;事件落地持久化后,整个会话标记 replay-unsafe。
5.3 完整规则
- 每条 transcript 事件携带元标签:
replayMark: "safe" | "unsafe"; - 一旦任意 mutating write 事件追加到会话:
session.replaySafe = false; - safeguard 压缩:不能跨 replay-unsafe 边界做摘要裁剪,mutating 事件及其前后配对tool事件必须完整保留在上下文窗口;
- 回放引擎识别标记:replay-unsafe 会话执行回放时,mutating 工具自动拦截、mock 返回,禁止真实调用下游服务;
- 压缩结果
AgentHarnessCompactResult.replaySafe对外暴露会话回放状态,供 QA 测试框架判断是否允许全链路回放对比。
典型踩坑:aggressive 模式可能误合并 mutating 周边事件,导致回放边界丢失,这也是 QA 回归场景强制选用 safeguard 的根本原因。
六、QA 场景完整验证闭环
6.1 QA验证目标
校验:safeguard compact 执行前后,Agent 业务输出、工具调用序列、决策逻辑保持一致;同时验证 replay-safety 标记正确性,避免回放脏写。
6.2 QA 标准测试流程
- 准备测试用会话 transcript:包含多轮对话、只读工具、mutating 变更工具调用;
- 基线回放:不执行 compact,完整跑原始 transcript,采集基线输出、tool call 序列、返回结果;
- 调用 PI Harness compact(),入参:
compactionMode=safeguard, replayCheck=true; - 使用 compactedWindow 重新运行 Agent,采集压缩后输出;
- 对比校验维度:
- 模型最终业务回答一致性;
- 工具调用顺序、参数是否对齐;
- replaySafe 标记是否符合预期(存在mutating事件 → replaySafe=false);
- mutatedEventIds 是否精准捕获所有变更写事件;
- 原始磁盘 transcript 是否完整保留(无删除历史);
- 异常用例补充:摘要生成失败重试、临近token边界压缩、连续多次compact、子Agent嵌套mutating操作;
- 产出回归报告:Token节省量、行为差异用例、回放安全标记错误case,提交修复。
6.3 QA 专用约束
- QA 回归脚本禁止使用 aggressive;强制 safeguard;
- 开启 replayCheck,框架自动做双链路 diff;
- 任何 mutating write 丢失/边界裁剪,判定为阻断性缺陷。
七、整体数据流总结
长会话持续轮次 → Transcript 不断追加事件
↓
Token 接近上限 / 手动触发
↓
PI Harness.compact(AgentHarnessCompactParams)
↓
safeguard策略扫描mutating write,划定不可压缩边界
↓
LLM生成摘要,组装 compactedWindow
↓
写入compaction事件至原始Transcript(追加)
↓
返回 AgentHarnessCompactResult(携带 replaySafe 标记)
↓
上层:业务继续会话 / QA框架做前后行为比对 / Replay引擎判断是否拦截副作用工具
八、常见生产风险点
ownsCompaction=true旁路自动safeguard,会话持续膨胀超限;- safeguard 只基于内存窗口估算token,不感知磁盘 transcript 文件大小,超大JSONL无法自动触发;
- compact 摘要损坏 thinkingSignature(Anthropic extended thinking)引发后续API拒绝;
- mutating write 标记遗漏,回放时重复调用外部服务产生脏数据;
- 摘要预算不足,压缩产出无效摘要,引发循环重试。

1557

被折叠的 条评论
为什么被折叠?



