上下文处理(context management)指 agent 运行时在对话历史接近模型上下文窗口上限时,对历史消息进行摘要、裁剪、外部化或重置,使会话得以继续的一整套机制。它是 agent 可用性的第一决定因素:处理不好会丢失关键决策、产生重复问答、或因缓存失效导致成本与延迟飙升。评测一个方案的优劣,通常看六个维度:
沿用前序行业报告的 9 个 harness;其中 Kiro 产品闭源、公开仓库无上下文处理代码,故本报告的源码级分析覆盖其余 8 个。所有路径相对各仓库根目录(均在 repos/<name> 下),所有提交哈希为 2026-05-01 后窗口内提交。
| harness | 语言 | 核心机制 | 触发 | 摘要形态 | 状态载体 | 标志性设计 |
|---|---|---|---|---|---|---|
| DSH | TS | 四件套:basic 摘要 + 命令 + 工具结果裁剪 + 图片 offload | 压力比 0.8 + 余量 65536 | 8 段结构化 Markdown | SessionEvent 日志(事务性提交) | 摘要请求是末次路由请求的前缀扩展,直接复用 KV 缓存 |
| codex | Rust | 三模式:本地摘要 / 服务端原生压缩 / token 预算窗口重置 | token 上限(默认窗口×9/10)、回合末比例、65% 后台、provider 溢出 | handoff 摘要(可自定义 prompt) | Rollout 事件(CompactedItem 含完整替换历史) | retained tool outputs 整条保留/丢弃;媒体按消息边界计费;压缩失败保留原历史 |
| pi | TS | 轮次边界切分 + split-turn 双摘要 + 分支摘要 | contextTokens > window − 16384 | 6 段固定结构 + 文件聚合附录 | jsonl 会话条目(compaction entry) | 切点绝不落在 toolResult;尾部超大工具结果回退到前一 assistant 边界 |
| ZCode | TS | microcompact(工具结果清理)→ 完整压缩 双层 + 四阶段 | 有效窗口−13k buffer;micro 为完整阈值 90% 或 idle 60min | 9 段式(含反归属声明) | append-only 事件(CompactBoundary 等) | 四阶段模型(manual/pre_request/mid_turn/reactive);连续失败 3 次熔断;rapid-refill 熔断 |
| opencode | TS | 拒绝恢复阶梯 + 后台预压缩 + native 通道 | estimate ≥ ceiling;拒绝后 overflow 一次性恢复 | 7 段 Markdown | compaction 消息行 + keepID 引用 | 被拒请求按 [0.85,0.7,0.5,0.35] 逐级降尺寸重截;后台摘要到期直接换入复用缓存 |
| goose | Rust | 结构化 JSON 摘要 + 双可见性冻结 | min(0.8, 225k/窗口) —— 价格护栏 | <analysis> 草稿 + 10 字段 JSON | 消息行(user_visible/agent_visible 标记) | 225k 刻意低于 OpenAI 272k 长上下文价格档;摘要模板可被用户覆盖 |
| gemini-cli | TS | 新旧双路径 + 工具输出三件套(masking/distillation/归一化) | 0.5×tokenLimit(旧);150k/65k profile(新);工具 token 80k 批量掩码 | XML state_snapshot + probe 自校验 | compression_state.json 文件缓存(contentHash 失效) | 增量/热启动/屏障三模式管线;掩码产物落盘换预览 |
| mcode | TS | 分层阶梯:归档 → 裁剪 → LLM checkpoint(h0→hmin 六档) | 输入上限 95% 单调触发;provider 拒绝无条件恢复 | 8 段 Markdown + recentUserQueries 逐字附录 | canonical history 替换 + v5 appendix | 工具结果 artifact receipt(可恢复);准入要求实测 footprint 真减小 |
每节按“模块地图 → 触发 → 算法 → 状态与持久化 → 配置 → 近期更新”展开,全部结论可回溯到文件与提交。
packages/compaction/ 下五个可独立发布的包:compaction(核心类型:checkpoint、tool-pairing)、compaction-basic(摘要引擎)、command-compact(/compact 命令)、compaction-tool-result-pruner(工具结果裁剪)、compaction-image-offload(图片预算)。另有 packages/context/ 注入族:agent-instructions(指令摘要 digest)、file-reference(文件引用语法)、time-context(请求时区)、session-reference。
thresholdRatio 默认 0.8(请求压力占上下文窗口比例);余量 headroomTokens 默认 65,536(同时作为 maxTokens 上限);逐字保留尾部比例 retainRatio 默认 0.16(compaction-basic/src/config.ts)。modelPolicies):不同模型可配不同的摘要 provider、模型、重试次数(compactionRetries、maxOverflowRetries)。region.ts,600 行):selectCompactableRange 选范围 → validateSurfaceRegion 校验 → prepareCompaction/summarizeCompaction 摘要 → assertWholeSurfaceUnchanged 乐观并发断言(整个界面区间在摘要期间未被改动)→ commitCompactionBody 提交 → completeCompaction。任何阶段失败可整体回滚。summarizer.ts,标志性设计):摘要指令不是独立的系统提示,而是作为回放对话之后的最后一条 user 消息发出——前置的 system prompt、工具 schema、消息前缀逐字复现末次路由请求,使辅助调用成为该请求的真正前缀,直接命中 provider 的 KV 缓存而非重建。<compacted-summary> 旧检查点,则合并而非复制(保留仍属实的事实、丢弃过时信息)。thresholdChars=8192 的结果只保留头 headChars=4096 + 尾 tailChars=1024,中间替换为标记 [... tool result middle pruned ...];按 codePoint 长度计算(Unicode 安全)。压缩作为 SessionEvent 日志中的条目落地(append-only 事件溯源),压缩后由 deriveMessages 从日志派生消息视图;replay/fork 用旧日志播种。快照覆盖全 profile:snapshots/session/compaction-output-reserve、snapshots/sdk/manual-compact、snapshots/acp/image-compaction。
compaction.basic.{thresholdRatio, headroomTokens, retainRatio, retainTokens, summarizationProvider, summarizationModel, maxTokens, compactionRetries, maxOverflowRetries, auto, modelPolicies}。
cf7229e72a(10-22)超大摘要用更小前缀重试 → 10-23 被 3081c71bab revert,随后补文档说明重试成本与溢出恢复契约(dd87277afa、595f5a65f3)。eb1713f856(#7754)修复 checkpoint 中 released units 的保留问题。cd6187f901、7ee39638b2)。core/src/:compact.rs(930 行,本地摘要主流程)、compact_token_budget.rs(窗口重置)、compact_remote_v2*.rs(服务端原生压缩,含 attempt/installation/media)、compact_retained_tool_outputs.rs、compact_model_fallback.rs、context/、context_manager/;独立 crate context-fragments(可注入片段体系)、rollout/src/compression(会话文件压缩);prompts/templates/compact/{prompt.md, summary_prefix.md}。
model_auto_compact_token_limit:无显式配置时取模型目录值且被 min 到上下文窗口×9/10;作用域可选 total 或 body_after_prefix(只计压缩窗口 prefix 之后的新增 token)。model_post_turn_compact_threshold_percent(缺省禁用)。remote_compaction:OpenAI/Azure、Bedrock、GCP 为 V2(服务端原生压缩),其余 Unsupported → 本地摘要。async_compaction)在窗口 65% 即启动后台摘要;TokenBudget feature 开启时改为直接开新窗口不摘要。/compact 与自动共用 CompactTask 三分支;PreTurn 在模型切换致缩窗时触发(reason=ModelDownshift)。prompt.md:为接手模型写 handoff summary,含进展与关键决策、重要上下文/约束/用户偏好、剩余工作、关键数据)发给模型;prompt 可经 compact_prompt 配置替换。COMPACT_USER_MESSAGE_MAX_TOKENS=20,000,超出转带标记的截断);客户端标记的 retained tool outputs;canonical 初始上下文重新注入到最后一条真实用户/摘要消息之前;World State 基线。SUMMARY_PREFIX(“Another language model started to solve this problem…”)编码为 user 角色的 CompactionSummary。400f2356d)。CompactionTrigger,服务端必须返回恰好一个 Compaction item,客户端只安装 checkpoint(prefix 策略)。RETAINED_MESSAGE_TOKEN_BUDGET=64,000:user 消息、hook prompt、≤10,000 token 的 agent 消息、客户端 developer 消息、retained tool outputs;newest-first 截断。FunctionCallOutput{call_id:None, name:Some}),整体保留或整条丢弃;超窗工具输出被替换为 “Output exceeded the available model context and was truncated”。codex.compaction.model_fallback);压缩请求 reasoning effort=Compaction。9e03960cf 接入 turn 生命周期);安装时校验 prefix 的 history_version/auth_owner_generation,拼接 live suffix,拒绝则回退前台。replace_compacted_history 原子替换内存历史并写 RolloutItem::Compacted:message、完整 replacement_history、guardian_history、retained_context、window_number/ids、compaction_response_id、latest_token_usage_record、resume_metadata(拒绝音频文件、动态工具、多 agent 版本等)。不可逆(原始历史被替换)但 replacement_history 整体留存,resume 时选最新可回放的压缩作为基线;fork/resume 继承压缩窗口并保留 reasoning token 计数(c62e9df39)。全程有 pre/post compact hooks 与 ContextCompaction turn item,保证分析事件一致。
model_auto_compact_token_limit(+scope)、model_post_turn_compact_threshold_percent、compact_prompt、experimental_compact_prompt_file;features:token_budget、async_compaction(默认 65%)、CompactionImageBudget、RetainClientToolOutputs、RetainClientDeveloperMessages。
19438adcb 专用 context window ID 类型;1685f2d62 上传音频按实测时长计费。3780a5f75 压缩中给保留文件音频计费;f1b0721c8 上传音频持久化拒绝恢复。446044992);压缩后允许 volatile World State section 刷新(2fa67f03f)。c62e9df39);10-27 不可用图片引用替换(cb66dbecf)。400f2356d 压缩失败保留会话历史;10-20 改善压缩 rollout 读取失败诊断。9e03960cf)+ 推测性 remote v2 基础设施(1a69ad323)。6c0c6759d);08-12 远程压缩后丢弃 descendant progress 更新、保留 client developer messages(bff03ecce)。packages/coding-agent/src/core/compaction/:compaction.ts(1104 行,主逻辑)、branch-summarization.ts(会话树分支摘要)、utils.ts(序列化/文件聚合);token 计数在 packages/ai(catalog 提供模型窗口)。durable 会话的压缩状态迁至 pi-durable(原 packages/agent/src/harness/compaction 已于 10-01 7fd478a2 移除)。
contextTokens > model.contextWindow − reserveTokens;reserveTokens 默认 16,384,逐字保留 keepRecentTokens 默认 20,000(settings-defaults.ts)。usage.totalTokens(含 cache 计数),尾部新增消息用 chars/4 保守估算。_exceedsCompactionThreshold);轮次结束后(_checkCompaction,含溢出恢复:上下文溢出错误 → 省略式恢复 → 按 “overflow” 压缩)。手动 AgentSession.compact() 先中止当前操作且不重试。compaction.modelOverrides["provider/id"] 逐模型覆盖(含压缩专用模型)。8bdcd449 #9740)。/compact 自定义指令同时作用于两段(adfc1446)。<read-files>/<modified-files> 附录(utils.ts)。压缩结果作为 compaction 条目 append 进 jsonl 会话文件:summary、firstKeptEntryId、tokensBefore、details{readFiles,modifiedFiles}、usage、边界处完整 systemMessage。投影规则:上下文 = [最新 compaction 条目,firstKeptEntryId 起原文,之后全部条目]。fork 复制全部条目(含 compaction)→ 压缩在 fork 后存活。生成失败(stopReason=length/error)拒绝落盘(97fa14e3)。扩展钩子:session_before_compact(可取消/供结果)、session_compact、session_compact_failed。
compaction.{enabled, reserveTokens, keepRecentTokens, modelOverrides};branchSummary.{reserveTokens, skipPrompt}。
d0fe2130(#11680)context edits 进分支摘要输入;269afc66(#11482)分支摘要传 thinking level。6fcb4867(#11036)摘要请求去除固定输出上限;90305d90摘要期禁用工具;15e7bdc1摘要省略 thinking。cff1cf52,8-18)已被 8dab7028 revert——缓存对齐的收益不足以抵消复杂度(行业里少见的“加了又退”样本)。apps/zcode-cli/packages/core/src/compact/:policy.ts(触发策略)、microcompact.ts(轻量层)、rounds.ts(轮次分组)、manual.ts(手动流程)、prompt.ts(摘要 prompt)、compact-active.ts(运行时编排);契约在 contracts/src/compact/;事件在 contracts/src/events/session.events.ts;设计文档 docs/design/v2/compact/ + rewind-compact.md。
microcompact_boundary 观测事件、不产生完整 boundary。standalone_turn+user_requested(手动 /compact);pre_request+context_limit(turn 首个 model 请求前);mid_turn+context_limit(同 turn 工具批次后的下一次请求前);reactive+provider_overflow(主请求溢出后的压缩重试,成功后原请求重放)。groupByAssistantStartedRounds 按 assistant 消息 id 变化切轮次;自动/响应式保留最近若干组原文(基础 1 组),其余进摘要;minimumGroupsToPreserve 可配。append-only 会话事件:CompactStarted / CompactCompleted / CompactBoundary / MicrocompactBoundary;boundary payload 含 trigger/phase/reason/压缩前后 token 计数/preservedSegment/summaryMessageIds。原子写 bundle(摘要消息 user 角色 + compaction part,顺序=请求前公告→summary→附件),仅摘要成功才写;resume 从最近 boundary 后水合;事件存储对 turn-window 淘汰(封存 turn 的 model_request 瘦身为只留 messageCount)。
active chain 从 compact boundary 开始;conversation rewind 只在 boundary 之后合法;compact 前的 file checkpoint 可做 file-only rewind 并标 covered_by_compact;回到 compact 前的对话点用 fork(append-only 分支切割);partial compact 记 preservedSegment{head/anchor/tailMessageId} 且不得拆 tool_use/result 对。
AgentRuntimeConfig.compact.{enabled, contextWindow, maxOutputTokens, modelContextBudgetStrategy(legacy|preflight-v1), summaryReserveTokens, bufferTokens, thresholdPercentOverride, maxConsecutiveFailures, microcompact{enabled, thresholdTokens, idleThresholdMinutes, keepRecentToolResults, compactableToolNames, clearErrorResults, minTokenSavings}}。
a9fe401e(v3.17.2,11-03):子会话不再收到主会话的五阶段 plan 提醒(compact-active 调整)。0a1fc56d(10-19):摘要请求的工具候选按 ToolSearch/registry 能力过滤,防 MCP schema 撑爆摘要请求;compact-persistence 重写。a60ba6a7(10-30):rewind-compact 文档 + session-store compact bundle 测试;aac47556(v3.15.1):compact/README、plan、e2e 文档与 e2e 用例(断言 manual=standalone_turn/toolCount=0、auto=mid_turn、microcompact 占位符且不产生 full boundary、reactive 带 reason=provider_overflow)。packages/core/src/session/compaction.ts(1246 行,核心);触发点在 session/runner/llm.ts;配置在 config/plugin/compaction.ts;测试 test/session-runner.test.ts。
estimatePrompt ≥ ceiling)、overflow(provider 拒绝后一次性恢复)、manual(/compact)。compaction.buffer 支持百分比("1%"–"99%",6700dd87b)或整数 token(旧键 reserved 经 normalize 迁移),默认留 max(15% 窗口, 16k);窗口未知 → ceiling=Infinity,auto 永不触发(只靠 overflow 恢复)。experimental.background_compaction):达 ceiling×0.85(PRECOMPUTE_RATIO)且实测 ≥64k 时在后台摘要 anchor 前全部历史;压缩到期直接换入以复用 prompt 缓存;每 session 一份,失败 2 次停止到下次压缩。splitConversation 按 keep(默认 15k tokens)切出逐字尾部,其余整段发模型;7 段模板(Objective / Requirements / Decisions / Work State / Next Move / Relevant Files / Important Context);instruction 类内容(AGENTS.md 等)明确排除、下轮单独给。6597f6cd6):被拒请求按 SHRINK_STEPS [0.85, 0.7, 0.5, 0.35] 对首次被拒尺寸逐级降 target 并从零重截;measured 请求被拒后只以纯文本重发;payload-too-large 转文本一次不计步。model.compaction.type==="native" 走 provider 原生压缩机制,保留最近 keep 的整条 user 消息;native 窗口仅原 provider 可回放。结果持久化为 type=compaction 消息(completed/failed + text + metadata.keepID);历史从最新 compaction 加载,previousCompaction 恒为第一条;进程重启靠 settleStaleCompactions 结算孤儿 running 行。后台摘要存内存 Map(firstID/keepID/tailLimit/failures),模型或指令变化即失效。事件 Compaction.Started/Delta/Ended/Failed 广播;失败/中断照常计费(spent map)。
compaction.auto(默认 true)、compaction.keep.tokens(15k)、compaction.buffer、experimental.background_compaction;旧键 tail_turns/prune 被拒绝。
6700dd87b buffer 支持百分比配置;cb1e58fe4 prompt 大小封顶(fitOutput 压 maxTokens,floor 32k)。6a5973d26(后改名 f523f7713)后台预压缩上线。6597f6cd6 拒绝后不原样重发、逐级降尺寸重截。独立 crate crates/goose-context-management/:lib.rs(三层 API)、summarize.rs、structured.rs(484 行,结构化解析)、format.rs、provider.rs(CompactingProvider)、model.rs(CompactionModel/TokenEstimator)、templates.rs、prompts/compaction.md;触发在 crates/goose/src/context_mgmt/mod.rs 与 agents/state_machine/proactive_compaction.rs。
session.usage.total_tokens(+未上报工具结果)或全量估算 / context_limit > threshold;assistant 结尾(无后续推理)跳过。GOOSE_AUTO_COMPACT_THRESHOLD 默认 0.8, GOOSE_AUTO_COMPACT_TOKEN_LIMIT 225,000 / context_limit)。225k 是价格护栏:刻意低于 OpenAI 272k 长上下文价格档(cd1da62a),是成本边界不是请求上限。manages_own_context 的 provider(claude_code/gemini_cli)整体跳过。format_message_for_compacting 扁平为 [role]: 文本(图片/文档/工具调用降级为短标记,Thinking 丢弃)。[0,10,20,50,100] 从中间向外删 tool response 重试;无 tool response 直接 fast-fail 报错。原消息 → user_visible=false & agent_visible=false(冻结);摘要消息 agent-only + compaction_summary 标记;追加 assistant continuation(“Your context was compacted…”,普通/工具循环/手动三文案)。保留最近一条纯文本 user 消息逐字(手动压缩不保留);当前 turn 的 turn-context 事件 carry 到最后且 created 时间戳重置(防持久化重排)。可见性投影:用户可见存档保留原 audience 注释,agent 回放去掉 user-only 内容。
GOOSE_AUTO_COMPACT_THRESHOLD(0.8)、GOOSE_AUTO_COMPACT_TOKEN_LIMIT(225,000)、GOOSE_TOOL_PAIR_SUMMARIZATION(默认 false)、GOOSE_TOOL_CALL_CUTOFF;摘要模板可被用户 ~/.config/goose/prompts/ 覆盖;Python/Kotlin 经 uniffi 复用。
cd1da62a 225k 封顶(价格护栏落地);0aa212e6 可选 context relevance 操作;c85a58d7 ACP 手动压缩失败上报;7f57d569 不向模型暴露压缩倒计时。packages/core/src/context/:传统路径 chatCompressionService.ts(721 行);新架构 contextManager.ts + pipeline 图 + profiles;工具输出三件套 toolOutputMaskingService.ts、toolDistillationService.ts、agentHistoryProvider.ts;状态缓存 compression_state.json 配套 contextCompressionService.ts。
compressionThreshold 默认 0.5×tokenLimit(model);findCompressSplitPoint 按 JSON 字符占比 0.7 找切点(1−COMPRESSION_PRESERVE_THRESHOLD 0.3,保护最近 30%);上次失败后只做截断不再调 LLM。tool-outputs/session-*/ 文件,原位换 <tool_output_masked> 预览(shell 保留 Error/Exit Code 段);EXEMPT_TOOLS 永不掩码。compression_state.json 按文件路径缓存 FileRecord(level FULL/PARTIAL/SUMMARY/EXCLUDED + contentHash,内容变即失效),批量一次路由调用(chat-compression-2.5-flash-lite)决策;掩码产物按 session 隔离落盘;压缩 telemetry 事件记录 tokens/masked_count。
compressionThreshold;contextManagement.{enabled, historyWindow.{maxTokens,retainedTokens}, messageLimits, tools.distillation.{maxOutputTokens,summarizationThresholdTokens}, tools.outputMasking.*}。
e6f92d6 大简化;01635dd loose boundary(屏障 backstop);bedef96 工具输出体积上界;055e5f6 跨会话快照恢复;07792f9 自适应 token 计算器。packages/local-runtime-v2/src/service/turn-system/compaction/:automatic-context-compactor.ts(507 行,触发)、contracts.ts;algorithm/:compact-context.ts(991 行)、history-reduction.ts、tool-result-archiver.ts(783 行)、tool-trim-admission.ts、checkpoint-protocol.ts、checkpoint-format.ts、assistant-iteration-cadence.ts、todo-cadence.py、background-cadence.ts;execution/request-media-projection.ts;状态在 agent-host/compaction/。
probeBeforeLlm 每次 LLM 调用前执行;footprint=本地估算(inputTokens + 序列化字节,usageAnchor 进程级缓存最近实测,压缩后 invalidate 防旧值误导)。contextManagement.compactionTriggerAt(a79348f #493):(0,1] 比例或 >1 整数 token,每次调用读取,只能降低内置触发(单调语义);非法值 warn 一次后忽略。压缩 = canonical history replaceMessages 操作(attemptId/compactionId 幂等,克隆消息);结果附 CompactionCompatibility v5 appendix(summary + recentUserQueries + todoState + cadence + subagents)。session-id 恢复(c460f08 #466):session_identity_reminder 在压缩丢 id 后重新注入;近期提交移除了拒绝后强制重发(绕过 before-LLM 管线导致截图上限/session-id 未重放)。
contextManagement.{compactionTriggerAt, disableSystemReminderModels, cuMaxScreenshotsInContext: 2};toolResultCompaction.{enabled, maxInlineKiB: 64, mcpDetailsMaxInlineKiB: 32, watermarkKiB: 256, minSavingsKiB: 256, minCandidateKiB: 2, keepRecentRounds: 5};requestMedia.*。
a79348f compactionTriggerAt 单调语义;c460f08 session-id 恢复 + 移除强制溢出压缩。5b4e0a4 oversized 重发改走正常恢复;1852771 图片上限与恢复;3123293 用量失效防误导;698a986 同步 MiniMax 0.7.2。| harness | 阈值基数 | 默认值 | 自适应 | 后台/预执行 | 响应式恢复 |
|---|---|---|---|---|---|
| codex | token 上限 / 窗口比例 | 窗口×9/10(可配 scope) | 模型目录值兜底 | 65% 后台摘要;TokenBudget 窗口重置 | provider 溢出;PreTurn 缩窗 |
| ZCode | 有效窗口−buffer | 200k−输出预留−13k | preflight-v1 用 provider usage | microcompact(90%/idle 60min) | reactive 重放原请求 |
| DSH | 请求压力比 | 0.8 + 余量 65536 | 按路由模型覆盖 | — | overflow 重试(可配次数) |
| pi | window − reserve | reserve 16384 / keep 20000 | 模型 catalog 窗口 | — | 溢出错误专项压缩 |
| opencode | window − buffer | max(15%, 16k) | Percent 可配 | 85% 后台预压缩换入 | SHRINK_STEPS 四级降尺寸 |
| goose | 比例 + 绝对上限 | min(0.8, 225k/limit) | 绝对上限=价格档护栏 | — | 同错误 >2 次熔断 |
| gemini-cli | 0.5×limit / profile 65k | 0.5(旧)/ 65k retained(新) | hotstart 真实计数校准 | 增量管线持续 GC | barrier 同步 backstop |
| mcode | 输入上限 95% | 0.95×providerInputLimit | 单调 compactionTriggerAt 下调 | — | 拒绝无条件压缩 + 专属图片归档 |
| 原型 | 含义 | 采用者 |
|---|---|---|
| 本地 LLM 摘要 | 把历史发给模型生成摘要,替换原历史 | DSH、pi、ZCode、opencode、goose、gemini-cli、mcode、codex(本地模式) |
| 服务端原生压缩 | provider 端压缩,客户端只安装 checkpoint | codex remote v2、opencode native |
| 启发式裁剪/外部化 | 不调 LLM,直接截断/掩码/归档工具输出 | DSH pruner、gemini-cli masking/distillation、mcode tool archive、codex retained outputs |
| 窗口重置 | 跳过摘要,直接安装新上下文窗口 | codex TokenBudget feature |
| 分层组合 | 上述手段按强度分层,逐档加码直到装下 | ZCode(micro→full)、mcode(archive→trim→h0..hmin)、gemini-cli(mask→distill→summarize)、codex(retained→local→remote) |
| harness | 逐字尾部 | 工具输出处理 | 用户原话 | 迭代合并 | 其他特色保留 |
|---|---|---|---|---|---|
| DSH | retainRatio 0.16 | 裁剪头 4096+尾 1024,中间标记 | 预算内 newest-first | 旧检查点合并不复制 | 图片 offload 占位;最近单位保留 |
| codex | 20k token 预算 | retained 整条保留/丢弃;超窗截断占位 | 真实用户消息 newest-first | — | 初始上下文重注入;World State 基线;agent 消息 ≤10k |
| pi | keepRecentTokens 20k | 切点绝不落 toolResult;超大回退 | 含在最近段 | UPDATE prompt 合并 | 文件操作聚合附录;分支摘要 |
| ZCode | 最近 ≥1 组轮次 | microcompact 保最近 5 条 | 9 段含全部用户消息+反归属 | — | preservedSegment;session memory |
| opencode | keep 15k | 截断工具输出(可恢复源) | 最新 exchange 永不省略 | previousCompaction 首条 | instruction 下轮单独给 |
| goose | 最近纯文本 user 消息 | 摘要器溢出时按 0-100% 删 | user_messages 字段逐字 | — | 结构化 JSON 10 字段;turn-context carry |
| gemini-cli | 保护最近 30% | 掩码落盘换预览 / 蒸馏截断+摘要 | state_snapshot 整合 | anchor 整合 | 文件级压缩缓存(contentHash) |
| mcode | hmin=最近真实 user query | 归档 receipt(可恢复)/ 控制工具豁免 | recentUserQueries 逐字附录 | — | todoState/cadence/subagents 随附录存活 |
| harness | 结构 | 段数 | 缓存对齐 | 特殊纪律 |
|---|---|---|---|---|
| DSH | 固定 Markdown 段 | 8 | 摘要请求=末次路由请求的前缀扩展(复现 system+tools+前缀) | 不得提及压缩、不得调工具;空段写 (none) |
| codex | handoff 摘要 | 4 主题(进展/约束/下一步/数据) | — | 可自定义 compact_prompt;压缩用独立 reasoning effort |
| pi | 固定结构 + 文件附录 | 6 | — | 工具结果截断 2000 字符、thinking 省略 |
| ZCode | <analysis>+<summary> | 9 | 工具段字节稳定契约 | 反归属声明;安全约束逐字保留;纯文本输出强制 |
| opencode | Markdown 段 | 7 | 能原样发就原样发(保 cache);后台换入 | instruction 排除;头尾 clip 2000 字符 |
| goose | <analysis> 草稿 + JSON block | 10 字段 | — | 逐字引用错误/panic;不编造;模板可用户覆盖 |
| gemini-cli | XML state_snapshot | 两阶段(生成+probe) | 批量路由调用决策 | probe 自校验;膨胀即放弃 |
| mcode | Markdown 段 | 8 | — | 历史视为不可信数据;标题从 prompt 尾部解析防漂移 |
观察:DSH 与 opencode 把缓存对齐做进摘要协议(前缀复用 / 原样发送 / 后台换入);goose 与 ZCode 用“<analysis> 丢弃 + 结构化产物”两段式;mcode 明确“历史不可信”的 prompt 纪律;各家摘要段数收敛在 6–10 段。
| harness | 载体 | 压缩记录内容 | 可回放/分叉 | 可逆性 |
|---|---|---|---|---|
| DSH | SessionEvent 日志(事务提交) | 压缩条目;快照多 profile | replay/fork 用旧日志播种 | 事务失败整体回滚 |
| codex | Rollout 事件 | CompactedItem:完整 replacement_history + window ids + resume_metadata | resume 回放;fork 继承压缩窗口 | 不可逆但留全量替换历史;失败保留原历史 |
| pi | jsonl 条目 | summary + firstKeptEntryId + details + usage | 投影重建;fork 存活 | 生成失败拒绝落盘 |
| ZCode | append-only 事件 | boundary:trigger/phase/tokens/preservedSegment/summaryMessageIds | boundary 后水合;rewind 仅限 boundary 后;fork 回退点 | 仅摘要成功才写;rapid-refill 熔断 |
| opencode | compaction 消息行 | text + metadata.keepID;孤儿 running 行结算 | 从最新 compaction 加载 | 被拒阶梯重截;后台 Map 失效控制 |
| goose | 消息行(可见性标记) | 双冻结 + compaction_summary 标记 + continuation | agent 回放投影 | 解析失败无损保留原文 |
| gemini-cli | compression_state.json + 落盘文件 | FileRecord(level + contentHash) | 跨会话快照恢复 | 内容变即失效;膨胀即放弃 |
| mcode | canonical history 替换 + v5 appendix | summary + recentUserQueries + todoState + cadence | 幂等 attemptId;session-id 恢复 | 准入实测;无 read 工具时破坏性替换 |
| harness | 失败处理 | 熔断/节流 | 并发保护 | 特殊机制 |
|---|---|---|---|---|
| DSH | 事务回滚;overflow 重试可配 | — | assertWholeSurfaceUnchanged 乐观并发断言 | released units 保留修复 |
| codex | 失败保留原历史(400f2356d);超窗从头删保前缀缓存重试 | 模型回退链 | hook pre/post;installation 校验 history_version | 便宜模型回退压缩;遥测完整 |
| pi | 生成失败拒绝落盘 | 手动不重试 | — | 摘要期禁用工具 |
| ZCode | 自动最多 3 次尝试 + 时间线事件 | 连续失败 3 次熔断;rapid-refill 熔断 | 单写者生命周期 | reactive 重放原请求 |
| opencode | SHRINK_STEPS 四级降尺寸重截 | 后台失败 2 次停 | — | 失败/中断照常计费 |
| goose | 解析失败无损保留;无 tool response fast-fail | 同上下文错误 >2 次停 | — | 摘要器自身溢出按 0-100% 删重试 |
| gemini-cli | 失败后只截断不调 LLM;膨胀即放弃 | 迟滞防抖;批量阈值 | 屏障同步 | hotstart 一次性校准 |
| mcode | provider error 原地重试一次 | — | 幂等 attemptId | 准入要求实测 footprint 真减小 |
| harness | 摘要成本意识 | 缓存策略 | 价格护栏 |
|---|---|---|---|
| DSH | maxTokens 独立配置;重试成本文档化 | 摘要请求复现前缀直吃 KV 缓存 | — |
| codex | 独立 reasoning effort;媒体按字节计费 | 保留 reasoning token;前缀保形重试 | — |
| pi | 去除固定输出上限 | cache-friendly 原语(曾加入后 revert) | — |
| ZCode | 摘要输出上限 20k | 工具段字节稳定契约 | — |
| opencode | 失败也计费(诚实计费) | 能原样发就原样发;后台预压缩到期换入复用缓存 | — |
| goose | — | — | 225k = OpenAI 272k 价格档护栏 |
| gemini-cli | 批量路由调用(2.5-flash-lite)做决策 | 文件级压缩缓存跨轮次复用 | — |
| mcode | 实测 footprint 后才准入 | prefixCached 模型保图不动 | 触发点单调下调 |
| harness | 近期更新主线 | 代表提交/版本 |
|---|---|---|
| codex | 后台压缩接入 turn 生命周期、推测性 remote v2、音频/媒体预算、跨压缩保留 reasoning token 与 world state、失败回滚 | 9e03960cf、1a69ad323、1685f2d62、c62e9df39、2fa67f03f、400f2356d |
| opencode | buffer 百分比化、后台预压缩、拒绝恢复阶梯 | 6700dd87b、f523f7713、6597f6cd6、cb1e58fe4 |
| ZCode | 摘要请求工具候选按能力过滤(防 MCP schema 撑爆)、persistence 重写、子会话 plan 提醒隔离(随同步流 v3.15.1→v3.17.2) | 0a1fc56d、a9fe401e、a60ba6a7 |
| pi | 分支摘要增强(context edits/thinking level 进输入)、摘要去固定上限与工具禁用、cache-friendly 原语加了又退 | d0fe2130、269afc66、6fcb4867、90305d90、cff1cf52/8dab7028 |
| goose | 225k 价格护栏、可选 context relevance 操作、失败上报、不向模型暴露倒计时 | cd1da62a、0aa212e6、c85a58d7、7f57d569 |
| gemini-cli | 大简化、屏障 backstop、工具输出体积上界、跨会话快照恢复、自适应 token 计算器 | e6f92d6、01635dd、bedef96、055e5f6、07792f9 |
| mcode | compactionTriggerAt 单调语义、session-id 恢复、图片上限与恢复专属归档、用量失效防误导 | a79348f、c460f08、5b4e0a4、1852771、3123293 |
| DSH | 超大摘要前缀重试(加后 revert + 文档化契约)、checkpoint released units 修复、多轮溢出恢复契约文档 | cf7229e72a/3081c71bab、eb1713f856、dd87277afa |
| 优先级 | 建议 | 参照 |
|---|---|---|
| P0 | 先建“分层”骨架:触发探测 → 启发式裁剪(带 receipt)→ LLM 摘要(带 prompt 模板)→ 兜底(窗口重置或拒绝恢复)。不要一上来就只做摘要。 | mcode 六档阶梯、ZCode micro→full |
| P0 | 触发探测优先用 provider 真实 usage(含 cache 计数),本地估算只补尾部;阈值 = 有效窗口(扣输出预留)− buffer。 | codex body_after_prefix、ZCode preflight-v1、goose 225k 护栏 |
| P0 | 摘要 prompt 采用“<analysis> 丢弃 + 结构化产物”两段式,段数 6–10,空段显式占位,历史视为不可信数据;模板可配置。 | goose compaction.md、ZCode prompt.ts、mcode checkpoint-protocol |
| P1 | 工具输出外部化:超阈值落盘 + 原位占位 + 可恢复 receipt(工具名+来源+artifact 引用);控制类工具豁免。 | mcode tool-result-archiver、gemini-cli masking、codex retained outputs |
| P1 | 压缩事件进会话事件流(trigger/phase/reason/前后 token),支持 resume 回放与 fork 继承;压缩失败保留原历史。 | ZCode boundary、codex CompactedItem、pi compaction entry |
| P1 | 缓存对齐:摘要请求复用主请求前缀;预算允许时后台预压缩并在到期时换入。 | DSH summarizer、opencode background compaction |
| P2 | 媒体预算:图片按消息边界保留/丢弃、按字节计费;非 prefixCached 模型才换占位。 | codex media budget、mcode request-media-projection、DSH image-offload |
| P2 | 切点纪律 + 熔断:toolResult 不切、连续失败 3 次熔断、rapid-refill 检测、同错误计数上限。 | pi 8bdcd449、ZCode circuit breaker、goose >2 |
| harness | 上下文处理核心文件 |
|---|---|
| DSH | packages/compaction/compaction-basic/src/{config.ts,region.ts,summarizer.ts}、compaction-tool-result-pruner/src/config.ts、compaction-image-offload/src/image-offload.ts、command-compact/src/index.ts、context/agent-instructions/src/digest.ts |
| codex | core/src/{compact.rs, compact_token_budget.rs, compact_remote_v2*.rs, compact_retained_tool_outputs.rs, compact_model_fallback.rs}、context-fragments/src/*、rollout/src/compression.rs、prompts/templates/compact/{prompt.md, summary_prefix.md} |
| pi | packages/coding-agent/src/core/compaction/{compaction.ts, branch-summarization.ts, utils.ts}、core/settings-defaults.ts |
| ZCode | apps/zcode-cli/packages/core/src/compact/{policy.ts, microcompact.ts, rounds.ts, manual.ts, prompt.ts, compact-active.ts}、contracts/src/compact/index.ts、docs/design/v2/compact/ |
| opencode | packages/core/src/session/compaction.ts、session/runner/llm.ts、config/plugin/compaction.ts |
| goose | crates/goose-context-management/src/{lib.rs, summarize.rs, structured.rs, format.rs, provider.rs, prompts/compaction.md}、crates/goose/src/context_mgmt/mod.rs |
| gemini-cli | packages/core/src/context/{chatCompressionService.ts, contextManager.ts, toolOutputMaskingService.ts, toolDistillationService.ts, agentHistoryProvider.ts, compression_state.json 配套服务} |
| mcode | packages/local-runtime-v2/src/service/turn-system/compaction/{automatic-context-compactor.ts, algorithm/*}、agent-host/compaction/、execution/request-media-projection.ts |
--shallow-since=2026-05-01)。git show 核对 diff 与提交说明一致。