本文整理自 OpenClaw 代码库中与"上下文压缩与预算管理"相关的全部实现,覆盖压缩框架、核心算法、关键机制、阈值常量与配置项。所有内容基于实际源码探索,文件路径可点击跳转。


在这里插入图片描述

一、总述:上下文压缩的整体定位

OpenClaw 是一个支持长对话的个人 AI 助手平台。长对话面临一个根本矛盾:LLM 的上下文窗口有限(4K–200K tokens),而真实任务对话可能持续上百轮。若不压缩,上下文会撑爆窗口,触发"Lost in the Middle"问题——相关信息位于上下文中间时性能显著下降(Liu et al., 2023)。

OpenClaw 的解法是一个多层防御系统:从底层的提示缓存保留,到中层的延迟轮次维护,再到上层的 compaction(上下文压缩)与工具结果截断,每一层都是一道防线,共同保证对话可持续、上下文不丢失关键信息、且不会陷入死循环。

图 1 说明:上下文压缩多层防御架构总览。从底到顶四层,每层职责清晰,共同对抗"上下文撑爆"与"Lost in the Middle"。

顶层 · Tool Result Truncation 工具结果截断

char budget 截断

头部 + 尾部保留

cache-ttl 过期修剪

上层 · Compaction 上下文压缩

token 估算 + 阈值判断

分块摘要 + 自适应分块

历史裁剪 + 保留最近轮次

hook pipeline + 安全超时

中层 · Deferred Maintenance 延迟轮次维护

后台 lane 异步执行

context-engine maintain

turnMaintenanceMode: background

底层 · Cache Retention 缓存保留

none / short / long 三档

按 provider family 配置

Anthropic / Google / OpenAI 兼容

派发 LLM 安全上下文


二、压缩框架:分层架构与职责

2.1 四层防御体系

层级 名称 职责 触发时机 核心文件
L1 Cache Retention 按 provider family 配置提示缓存策略 每次 prompt 提交 [prompt-cache-retention.ts](file:///workspace/src/agents/embedded-agent-runner/prompt-cache-retention.ts)
L2 Deferred Maintenance 后台异步维护上下文引擎 每轮对话结束 [context-engine-maintenance.ts](file:///workspace/src/agents/embedded-agent-runner/context-engine-maintenance.ts)
L3 Compaction 压缩历史为摘要 token 超阈值 [compact.ts](file:///workspace/src/agents/embedded-agent-runner/compact.ts)
L4 Tool Result Truncation 截断超大工具结果 tool 返回时 [tool-result-truncation.ts](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts)

2.2 Compaction 核心入口与协调链

Compaction 的核心入口是 [compact.ts](file:///workspace/src/agents/embedded-agent-runner/compact.ts) 的 compactEmbeddedAgentSessionDirect(第 118 行)。它协调一个完整的压缩链路:

  1. 解析会话目标与运行时——resolveCompactionRuntimeSelection
  2. 解析压缩目标——resolveEmbeddedCompactionTarget
  3. 解析模型候选链——resolveModelCandidateChain(支持模型回退)
  4. 获取预生成模型运行时租约——acquireAgentRunPreparedModelRuntime
  5. 直接压缩或带回退压缩——compactEmbeddedAgentSessionDirectOnce(有显式压缩模型时)或 runWithModelFallback(回退链)
  6. 分类压缩结果——classifyCompactionFallbackResult

2.3 直接压缩执行流程

[direct-compaction.ts](file:///workspace/src/agents/embedded-agent-runner/direct-compaction.ts) 的 compactEmbeddedAgentSessionDirectOnce 协调一次压缩尝试:

  1. prepareDirectCompactionAttempt——准备
  2. buildPreparedCompactionRuntime——构建运行时
  3. executePreparedCompactionSession——执行([compaction-session-execution.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-session-execution.ts) 第 71 行)

executePreparedCompactionSession 的关键步骤:

  • 获取会话写锁(acquireOwnedSessionTranscriptWriteLock
  • 捕获检查点快照(compactionCheckpointStore.captureSnapshot
  • 应用压缩设置(applyAgentCompactionSettingsFromConfigapplyAgentAutoCompactionGuard
  • 清理会话历史(sanitizeSessionHistoryvalidateReplayTurns
  • 去重用户消息(dedupeDuplicateUserMessagesForCompaction
  • 限制历史轮次(limitHistoryTurns
  • 运行 before/after hooks
  • 执行压缩(compactWithSafetyTimeout,第 426 行)
  • 估算压缩后 token(estimateTokensAfterCompaction
  • 持久化检查点(persistCompactionCheckpoint
  • 运行后压缩副作用(runPostCompactionSideEffects

图 2 说明:Compaction 完整执行流程时序。从入口到副作用,涵盖锁、检查点、hook、超时、估算、持久化全链路。

摘要模型 compaction-safeguard.ts compaction-hooks.ts session-execution.ts direct-compaction.ts compact.ts 调用方 摘要模型 compaction-safeguard.ts compaction-hooks.ts session-execution.ts direct-compaction.ts compact.ts 调用方 compactEmbeddedAgentSessionDirect resolveRuntimeSelection + target resolveModelCandidateChain acquirePreparedModelRuntime compactEmbeddedAgentSessionDirectOnce prepareDirectCompactionAttempt executePreparedCompactionSession acquireSessionWriteLock captureSnapshot 检查点 sanitizeSessionHistory dedupeUserMessages limitHistoryTurns runBeforeCompactionHooks session_before_compact collectToolFailures + fileOps summarize 摘要 摘要文本 buildHistoryPrunePlan qualityGuard 审计 可选 compactWithSafetyTimeout estimateTokensAfterCompaction persistCompactionCheckpoint runAfterCompactionHooks runPostCompactionSideEffects 压缩结果

三、核心算法

3.1 分块摘要算法(Chunked Summarization)

原理:当历史过长无法一次性摘要时,分块独立摘要,再合并。源自 Compressing Context for Effective Long-Doc QA (Jiang et al., 2023) 的思想。

实现位置:[src/agents/compaction.ts](file:///workspace/src/agents/compaction.ts) 的 summarizeChunks(第 116 行),使用 retryAsync 重试(attempts: 3, minDelayMs: 500, maxDelayMs: 5000, jitter: 0.2)。

关键函数链

  • summarizeChunks(params)——分块摘要
  • summarizeWithFallback(params)——带渐进式回退的摘要(第 195 行)
  • summarizeInStages(params)——分阶段摘要
  • buildCompactionSummarizationInstructions(customInstructions, instructions)——构建摘要指令(第 102 行)

摘要指令([compaction.ts](file:///workspace/src/agents/compaction.ts) 第 49-66 行):

  • DEFAULT_SUMMARY_FALLBACK = "No prior history."
  • MERGE_SUMMARIES_INSTRUCTIONS——合并部分摘要的指令
  • IDENTIFIER_PRESERVATION_INSTRUCTIONS——标识符保留指令(压缩时保留关键标识符)

3.2 自适应分块比例算法(Adaptive Chunk Ratio)

原理:根据历史消息平均大小动态调整分块比例,避免单条消息过大导致摘要失败。

实现位置:[src/agents/compaction-planning.ts](file:///workspace/src/agents/compaction-planning.ts) 的 computeAdaptiveChunkRatio(第 208 行)。

关键常量(第 17-28 行):

export const BASE_CHUNK_RATIO = 0.4;        // 默认上下文窗口分块比例
export const MIN_CHUNK_RATIO = 0.15;        // 自适应分块比例下限
export const SAFETY_MARGIN = 1.2;           // estimateTokens 不准确缓冲
export const SUMMARIZATION_OVERHEAD_TOKENS = 4096; // 摘要提示/系统提示开销

算法逻辑

  • estimateMessagesTokens(messages)——先 sanitizeCompactionMessages 去除 toolResult.details 和运行时上下文,再估算
  • computeAdaptiveChunkRatio(messages, contextWindow)——当平均消息 > 上下文 10% 时降低比例
  • isOversizedForSummary(msg, contextWindow)——判断消息是否过大,阈值 contextWindow * 0.5
  • buildSummaryChunks(params)——构建摘要分块(第 232 行)
  • buildOversizedFallbackPlan(params)——过大消息回退计划(第 248 行)

3.3 历史裁剪算法(History Prune Plan)

原理:压缩后仍可能超出预算,按上下文份额裁剪历史,保留摘要 + 最近若干轮原文。

实现位置:[src/agents/compaction-planning.ts](file:///workspace/src/agents/compaction-planning.ts)。

关键函数

  • buildStageSplitPlan(params)——阶段分割计划(第 286 行),minMessagesForSplit 默认 4
  • buildHistoryPrunePlan(params)——历史裁剪计划(第 362 行),当新内容 token > maxHistoryTokens 时触发裁剪
  • pruneHistoryForContextShare(params)——按上下文份额裁剪历史(第 311 行)

3.4 工具结果截断算法(Tool Result Truncation)

原理:工具返回的超大结果按 char budget 截断,保留头部 + 尾部,避免单条结果撑爆上下文。

实现位置:[src/agents/embedded-agent-runner/tool-result-truncation.ts](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts)。

关键函数与逻辑

  1. truncateToolResultText(text, maxChars, options)(第 360 行):

    • hasImportantTail(第 350 行)——检测重要尾部,匹配 error/exception/failed/traceback 等关键词
    • 保留头部 + 中间省略标记 + 尾部(尾部预算 = budget * 0.3,上限 4,000)
  2. resolveLiveToolResultAggregateMaxChars(params)(第 437 行)——解析聚合最大字符数:

    const contextShareChars = Math.floor(contextWindowTokens * 4 * AGGREGATE_TOOL_RESULT_CONTEXT_SHARE);
    return Math.max(perResultMaxChars * PROMPT_TOOL_RESULT_AGGREGATE_CAP_MULTIPLIER, contextShareChars);
    
  3. pruneExpiredCacheTtlToolResults(params)(第 170 行)——修剪过期缓存 TTL 工具结果:

    • 截止点为倒数第 3 个 assistant 消息
    • 软修剪:totalChars / charWindow >= 0.3
    • 硬清除:totalChars / charWindow >= 0.5 且 eligible chars >= 50,000

截断通知([context-truncation-notice.ts](file:///workspace/src/agents/embedded-agent-runner/context-truncation-notice.ts)):

export function formatContextLimitTruncationNotice(truncatedChars: number): string {
  return `[... ${Math.max(1, Math.floor(truncatedChars))} more characters truncated; rerun with narrower args if needed]`;
}

图 3 说明:工具结果截断算法。检测重要尾部 → 头部 + 尾部保留 + 中间省略 → 截断通知。区分单条截断与聚合截断,以及 cache-ttl 过期修剪的软/硬两档。

cache-ttl 过期修剪

软修剪 >= 0.3

硬清除 >= 0.5 且 eligible >= 50000

聚合层

单条截断 perResultMaxChars

聚合截断
max(perResult*4, contextWindow*4*0.5)

工具结果 text

hasImportantTail?
匹配 error/exception/failed

保留头部 budget - tailBudget

中间省略标记

保留尾部
budget * 0.3 上限 4000

截断通知
[... N more chars truncated]

截断后结果

仅头部 budget

3.5 Token 估算算法

原理:压缩前后都需要估算 token 数,决定是否触发压缩、是否压缩成功。

关键函数

  • estimateMessagesTokens(messages)([compaction-planning.ts](file:///workspace/src/agents/compaction-planning.ts) 第 55 行)——压缩规划用,先 sanitize
  • estimateTokensAfterCompaction(params)([compaction-hooks.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-hooks.ts) 第 279 行)——压缩后估算,拒绝不可能的增长
    // 如果 tokensAfter > observedTokenCount 或 > fullSessionTokensBefore * 1.1,返回 undefined
    

投影预算([compaction-planning-projection.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-planning-projection.ts)):

  • TEXT_TRUNCATE_THRESHOLD_CHARS = 32_768
  • TEXT_SAMPLE_CHARS = 8_192
  • PLANNING_MAX_CHARS = 256 * 1024

四、关键机制

4.1 Prompt Cache Retention(提示缓存保留)

原理:稳定前缀可缓存,重复请求命中缓存可降本降延迟(Anthropic Prompt Caching, 2024)。

实现位置:[prompt-cache-retention.ts](file:///workspace/src/agents/embedded-agent-runner/prompt-cache-retention.ts)。

三档策略

type CacheRetention = "none" | "short" | "long";

核心解析函数 resolveCacheRetention(extraParams, provider, modelApi, modelId, supportsPromptCacheKey)(第 24 行):

  1. 检查显式 cacheRetention 或遗留 cacheControlTtl
  2. resolveAnthropicCacheRetentionFamily——解析 Anthropic 缓存家族
  3. isGooglePromptCacheEligible——判断 Google 资格(gemini-2.5*gemini-3*
  4. 检查 supportsPromptCacheKey(OpenAI 兼容后端如 oMLX、llama.cpp)
  5. 遗留 cacheControlTtl 映射:"5m""short""1h""long"
  6. 默认:anthropic-direct 家族返回 "short",其他返回 undefined

相关文件:[cache-ttl.ts](file:///workspace/src/agents/embedded-agent-runner/cache-ttl.ts) 的 isCacheTtlEligibleProvider

4.2 Deferred Turn Maintenance(延迟轮次维护)

原理:每轮对话结束后,在后台 lane 异步维护上下文引擎,不阻塞主流程。

实现位置:[context-engine-maintenance.ts](file:///workspace/src/agents/embedded-agent-runner/context-engine-maintenance.ts)。

关键常量

const TURN_MAINTENANCE_TASK_KIND = "context_engine_turn_maintenance";
const TURN_MAINTENANCE_LANE_PREFIX = "context-engine-turn-maintenance:";
const TURN_MAINTENANCE_LONG_WAIT_MS = 10_000;  // 10 秒后提升为可见任务

核心函数

  • runContextEngineMaintenance(params)(第 536 行)——入口,决定执行模式
  • scheduleDeferredTurnMaintenance(params)(第 415 行)——调度延迟维护,入队到 context-engine-turn-maintenance:{sessionKey} lane
  • runDeferredTurnMaintenanceWorker(params)(第 316 行)——延迟维护工作器
  • executeContextEngineMaintenance(params)(第 281 行)——执行 contextEngine.maintain()
  • waitForDeferredTurnMaintenanceForSession(sessionKey)(第 188 行)——等待完成

关键决策shouldDefer = reason === "turn" && executionMode !== "background" && contextEngine.info.turnMaintenanceMode === "background"——若 turn 维护模式是 background 且原因非 background,则延迟。

4.3 Post-Compaction Loop Guard(防死循环守卫)

原理:压缩后 agent 可能陷入死循环(压缩丢信息 → 重复同一工具调用)。守卫在压缩后窗口内检测"完全相同的工具名 + 参数哈希 + 结果哈希"重复,触发时中止运行。

实现位置:[post-compaction-loop-guard.ts](file:///workspace/src/agents/embedded-agent-runner/post-compaction-loop-guard.ts)。

关键常量与类型

const DEFAULT_WINDOW_SIZE = 3;  // 观察窗口大小

type PostCompactionGuardObservation = {
  toolName: string;
  argsHash: string;
  resultHash: string;
};

type PostCompactionGuardVerdict =
  | { shouldAbort: false; armed: boolean; remainingAttempts: number }
  | {
      shouldAbort: true;
      armed: boolean;
      remainingAttempts: number;
      detector: "compaction_loop_persisted";
      count: number;
      toolName: string;
      message: string;
    };

核心函数 createPostCompactionLoopGuard(options)(第 48 行):

  • armPostCompaction()——武装检测器,设置 remainingAttempts = windowSize,清空历史
  • observe(call)——观察一次工具调用,每次消耗一个剩余尝试;比较完整的 toolName + argsHash + resultHash;匹配数 >= windowSize(3)时触发中止
  • 中止消息:"CRITICAL: tool {toolName} repeated {count} times with identical arguments and identical results within {windowSize} attempts after auto-compaction..."
  • snapshot()——返回当前武装状态
  • PostCompactionLoopPersistedError——自定义错误类(第 113 行),含 detectorcounttoolName

4.4 Compaction Hooks(压缩 Hook 管道)

原理:压缩前后通过 hook 管道注入额外逻辑(安全检查、指令注入、上下文修剪)。

实现位置:[compaction-hooks.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-hooks.ts)。

Hook 列表

Hook 时机 作用 文件
runBeforeCompactionHooks 压缩前 触发 session:compact:before + 插件 before_compaction [compaction-hooks.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-hooks.ts) 第 209 行
runAfterCompactionHooks 压缩后 触发 session:compact:after + 插件 after_compaction,指标含 messageCount/tokens 第 301 行
compaction-safeguard before 压缩 核心安全扩展,收集失败、注入指令、生成摘要 [compaction-safeguard.ts](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 第 850 行
compaction-instructions before 压缩 注入压缩指令(语言、事实、结构保留) [compaction-instructions.ts](file:///workspace/src/agents/agent-hooks/compaction-instructions.ts)
context-pruning 压缩中 修剪不再相关的上下文片段 agent-hooks/

Safeguard 运行时配置([compaction-safeguard-runtime.ts](file:///workspace/src/agents/agent-hooks/compaction-safeguard-runtime.ts) 第 7-36 行):

type CompactionSafeguardRuntimeValue = {
  maxHistoryShare?: number;           // 默认 0.5
  contextWindowTokens?: number;
  identifierPolicy?: AgentCompactionIdentifierPolicy | "custom";
  identifierInstructions?: string;
  customInstructions?: string;
  model?: Model;
  recentTurnsPreserve?: number;       // 默认 3,最大 12
  workspaceDir?: string;
  postCompactionSections?: string[];
  qualityGuardEnabled?: boolean;      // 默认 false
  qualityGuardMaxRetries?: number;    // 默认 1,最大 3
  provider?: string;
  cancelReason?: string;
};

4.5 Safety Timeout(安全超时)

原理:压缩可能因模型慢响应卡住,设 3 分钟超时,超时则中止。

实现位置:[compaction-safety-timeout.ts](file:///workspace/src/agents/embedded-agent-runner/compaction-safety-timeout.ts)。

关键常量

const EMBEDDED_COMPACTION_TIMEOUT_MS = 180_000;  // 3 分钟

关键函数

  • resolveCompactionTimeoutMs(cfg)——从 cfg.agents.defaults.compaction.timeoutSeconds 读取
  • compactWithSafetyTimeout(compact, timeoutMs, opts)——带超时执行压缩
  • compactContextEngineWithSafetyTimeout(...)——插件上下文引擎的安全超时

4.6 Compaction Reasons(压缩原因分类)

实现位置:[compact-reasons.ts](file:///workspace/src/agents/embedded-agent-runner/compact-reasons.ts)。

关键常量

const DEFERRED_CONTEXT_ENGINE_COMPACTION_REASON = "deferred to background context-engine maintenance";
const MAX_COMPACTION_REASON_DETAIL_CHARS = 100;

分类classifyCompactionReason,第 29 行):
no_compactable_entriesbelow_thresholdalready_compacteddeferred_backgroundlive_context_still_exceeds_targetguard_blockedsummary_failedtimeoutprovider_error_4xxprovider_error_5xx

良性跳过判断isBenignCompactionSkipReason / isBenignCompactionSkipResult——区分"正常跳过"与"真正失败"。


五、阈值与常量总览

5.1 核心阈值表

常量 文件位置 说明
EMBEDDED_COMPACTION_TIMEOUT_MS 180,000 [compaction-safety-timeout.ts:10](file:///workspace/src/agents/embedded-agent-runner/compaction-safety-timeout.ts) 压缩超时 3 分钟
DEFAULT_WINDOW_SIZE 3 [post-compaction-loop-guard.ts:14](file:///workspace/src/agents/embedded-agent-runner/post-compaction-loop-guard.ts) 死循环检测窗口
BASE_CHUNK_RATIO 0.4 [compaction-planning.ts:17](file:///workspace/src/agents/compaction-planning.ts) 默认分块比例
MIN_CHUNK_RATIO 0.15 [compaction-planning.ts:19](file:///workspace/src/agents/compaction-planning.ts) 最小分块比例
SAFETY_MARGIN 1.2 [compaction-planning.ts:21](file:///workspace/src/agents/compaction-planning.ts) Token 估算安全边界
SUMMARIZATION_OVERHEAD_TOKENS 4096 [compaction-planning.ts:28](file:///workspace/src/agents/compaction-planning.ts) 摘要开销
DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS 16,000 [tool-result-limits.ts:5](file:///workspace/src/agents/tool-result-limits.ts) 默认工具结果字符上限
LARGE_CONTEXT_MAX_LIVE_TOOL_RESULT_CHARS 32,000 [tool-result-limits.ts](file:///workspace/src/agents/tool-result-limits.ts) 大上下文工具结果上限
XL_CONTEXT_MAX_LIVE_TOOL_RESULT_CHARS 64,000 [tool-result-limits.ts](file:///workspace/src/agents/tool-result-limits.ts) 超大上下文工具结果上限
MAX_TOOL_RESULT_CONTEXT_SHARE 0.3 [tool-result-limits.ts:3](file:///workspace/src/agents/tool-result-limits.ts) 工具结果上下文份额
AGGREGATE_TOOL_RESULT_CONTEXT_SHARE 0.5 [tool-result-truncation.ts:42](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts) 聚合工具结果份额
PROMPT_TOOL_RESULT_AGGREGATE_CAP_MULTIPLIER 4 [tool-result-truncation.ts:41](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts) 聚合上限乘数
MIN_KEEP_CHARS 2,000 [tool-result-truncation.ts:239](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts) 最小保留字符
MAX_COMPACTION_SUMMARY_CHARS 16,000 [compaction-safeguard.ts:69](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 最大摘要字符
DEFAULT_RECENT_TURNS_PRESERVE 3 [compaction-safeguard.ts:73](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 默认保留最近轮次
MAX_RECENT_TURNS_PRESERVE 12 [compaction-safeguard.ts:75](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 最大保留轮次
DEFAULT_QUALITY_GUARD_MAX_RETRIES 1 [compaction-safeguard.ts:74](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 默认质量守卫重试
MAX_QUALITY_GUARD_MAX_RETRIES 3 [compaction-safeguard.ts:76](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 最大质量守卫重试
CONTEXT_WINDOW_HARD_MIN_TOKENS 4,000 [context-window-guard.ts:11](file:///workspace/src/agents/context-window-guard.ts) 上下文窗口硬最小
CONTEXT_WINDOW_WARN_BELOW_TOKENS 8,000 [context-window-guard.ts:12](file:///workspace/src/agents/context-window-guard.ts) 上下文窗口警告阈值
CONTEXT_WINDOW_HARD_MIN_RATIO 0.1 [context-window-guard.ts:13](file:///workspace/src/agents/context-window-guard.ts) 硬最小比例
CONTEXT_WINDOW_WARN_BELOW_RATIO 0.2 [context-window-guard.ts:14](file:///workspace/src/agents/context-window-guard.ts) 警告比例
TURN_MAINTENANCE_LONG_WAIT_MS 10,000 [context-engine-maintenance.ts:44](file:///workspace/src/agents/embedded-agent-runner/context-engine-maintenance.ts) 延迟维护长等待 10 秒
MAX_INSTRUCTION_LENGTH 800 [compaction-instructions.ts:24](file:///workspace/src/agents/agent-hooks/compaction-instructions.ts) 指令最大长度
MAX_TOOL_FAILURES 8 [compaction-safeguard.ts:64](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 最大工具失败数
MAX_TOOL_FAILURE_CHARS 240 [compaction-safeguard.ts:65](file:///workspace/src/agents/agent-hooks/compaction-safeguard.ts) 工具失败字符上限
TEXT_TRUNCATE_THRESHOLD_CHARS 32,768 [compaction-planning-projection.ts:5](file:///workspace/src/agents/embedded-agent-runner/compaction-planning-projection.ts) 文本截断阈值
TEXT_SAMPLE_CHARS 8,192 [compaction-planning-projection.ts:6](file:///workspace/src/agents/embedded-agent-runner/compaction-planning-projection.ts) 文本采样字符
PLANNING_MAX_CHARS 262,144 [compaction-planning-projection.ts:7](file:///workspace/src/agents/embedded-agent-runner/compaction-planning-projection.ts) 规划最大字符 256K

5.2 工具结果上限自适应

[src/agents/tool-result-limits.ts](file:///workspace/src/agents/tool-result-limits.ts) 的 resolveAutoLiveToolResultMaxChars(contextWindowTokens)

  • >= 200K tokens → 64,000 chars(XL 档)
  • >= 100K tokens → 32,000 chars(Large 档)
  • 其他 → 16,000 chars(默认档)

calculateMaxToolResultCharsWithCap(contextWindowTokens, hardCapChars)min(contextWindowTokens * 0.3 * 4, hardCapChars)


六、配置项总览

6.1 核心配置路径

配置路径 默认值 说明
agents.defaults.compaction.model - 压缩专用模型
agents.defaults.compaction.thinkingLevel - 压缩思考级别
agents.defaults.compaction.timeoutSeconds 180 压缩超时(秒)
agents.defaults.compaction.postIndexSync "async" 后压缩索引同步模式(off/async/await)
agents.defaults.contextTokens - Agent 上下文 token 封顶
agents.defaults.context-pruning.mode - 上下文修剪模式(cache-ttl)
agents.defaults.context-pruning.ttl 5m 缓存 TTL
agents.defaults.context-pruning.hardClear.enabled true 硬清除启用
agents.defaults.context-pruning.hardClear.placeholder "[Old tool result content cleared]" 硬清除占位符
agents.defaults.context-pruning.tools.deny - 工具修剪 deny glob
agents.defaults.context-pruning.tools.allow - 工具修剪 allow glob
agents.defaults.compaction.safeguard.recentTurnsPreserve 3 保留最近轮次
agents.defaults.compaction.safeguard.qualityGuardEnabled false 质量守卫启用
agents.defaults.compaction.safeguard.qualityGuardMaxRetries 1 质量守卫重试

6.2 缓存 TTL 修剪设置

[tool-result-truncation.ts](file:///workspace/src/agents/embedded-agent-runner/tool-result-truncation.ts) 的 resolveCacheTtlPruningSettings(config)(第 55 行):

  • ttlMs 默认 5 * 60_000(5 分钟)
  • hardClear 默认 true
  • 支持 tools.deny / tools.allow glob 模式

七、端到端流程

7.1 一次完整压缩的生命周期

图 4 说明:一次 compaction 从触发到完成的完整生命周期决策树。涵盖 token 估算、阈值判断、超时、hook、摘要、裁剪、死循环守卫、副作用全流程。

对话持续 token 增长

estimateMessagesTokens
先 sanitize 去除 details

token > 预算阈值?

跳过 compaction
记录 below_threshold

turn 维护模式 background?

scheduleDeferredTurnMaintenance
入队 context-engine lane

直接进入 compaction

acquireSessionWriteLock

captureSnapshot 检查点

sanitizeSessionHistory
validateReplayTurns

dedupeDuplicateUserMessages

limitHistoryTurns

runBeforeCompactionHooks
session:compact:before

compaction-safeguard
collectToolFailures + fileOps

compaction-instructions
注入语言/事实/结构指令

summarizeChunks
分块摘要 + retryAsync

qualityGuardEnabled?

auditSummaryQuality
可选重试 max 3

buildHistoryPrunePlan
保留摘要 + 最近 N 轮

compactWithSafetyTimeout
3 分钟超时

超时?

abortCompaction 中止

estimateTokensAfterCompaction
拒绝不可能增长

persistCompactionCheckpoint

runAfterCompactionHooks
session:compact:after

runPostCompactionSideEffects
syncPostCompactionSessionMemory

armPostCompactionLoopGuard
武装死循环守卫

压缩完成

7.2 关键决策点

  1. 是否触发estimateMessagesTokens 与预算阈值比较
  2. 延迟还是直接turnMaintenanceMode === "background" 且非 background 执行 → 延迟
  3. 超时中止compactWithSafetyTimeout 在 180s 后中止
  4. 质量审计qualityGuardEnabledauditSummaryQuality 可重试(max 3)
  5. 死循环守卫:压缩后武装,窗口内 3 次相同 tool+args+result 触发中止

八、总结:压缩系统的设计哲学

OpenClaw 的上下文压缩系统体现了三个核心设计哲学:

  1. 多层防御而非单点压缩——Cache Retention → Deferred Maintenance → Compaction → Tool Truncation,每层各司其职,单层失败不致命。这呼应了"记录事实而非推断"的原则:每层都在自己的边界记录状态,而非靠拼凑推断。

  2. 自适应而非固定参数——自适应分块比例(computeAdaptiveChunkRatio)、自适应工具结果上限(resolveAutoLiveToolResultMaxChars)、自适应质量守卫(qualityGuardMaxRetries)。参数随上下文窗口与消息大小动态调整,而非一刀切。

  3. 安全优先而非性能优先——3 分钟超时、死循环守卫、检查点快照、拒绝不可能的 token 增长、质量审计重试。每个关键点都有安全网,宁可慢一点也不让对话陷入死循环或丢失关键信息。

这套系统的本质是:用工程的纪律,让长对话在有限的上下文窗口内可持续、可恢复、不崩溃——这是对抗"Lost in the Middle"问题的诚实回答。

更多推荐