docs(v2): C07 上下文压缩家族 (YAO-108)#30
Merged
Merged
Conversation
- 在 §3.1 触发流程末尾补充 autoCompact.ts:174-223 三道护栏: marble_origami ctx-agent / REACTIVE_COMPACT / CONTEXT_COLLAPSE 让位逻辑 - 在 §3.4 Compact Prompt 末尾补充 BASE / PARTIAL / PARTIAL_UP_TO 三模板 与 getCompactUserSummaryMessage 的 proactive/KAIROS 续工尾语 - 在 §五 compactWarningState 末尾补充 compactWarningHook.ts 的拆文件理由 (保持 compactWarningState 零 React 依赖,不污染 print-mode 启动路径) - 新增 §七 grouping.ts:groupMessagesByApiRound,解释 CC-1180 拆出的 API-round 边界分组与 import cycle 修复 原 §七 可迁移设计模式顺延为 §八。 YAO-108 Co-authored-by: multica-agent <github@multica.ai>
- 移除新增的 §七 grouping.ts 独立小节,把内容折叠到 §六 末尾 - 恢复 v1 §七 "可迁移的设计模式" 与 §八 编号,满足 C-2 标题保留 - §3.1 把 "约 93%"/"几乎一定" 替换为精确表述 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
OC-R 指出 sessionMemoryCompact 并不调用 getPartialCompactPrompt,而是直接读 Session Memory;改写 §3.4 段落,限定 getPartialCompactPrompt 的唯一调用方为 compact.ts:840 的 partial compact 路径,并补述 microCompact / apiMicrocompact / sessionMemoryCompact 的真实关系。 Co-authored-by: multica-agent <github@multica.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
YAO-108 · C07 上下文压缩家族 迭代重写。在 v1-06 既有骨架与全部一二级标题保留的前提下,往四个位置补了"机制并存如何不互相拆台"维度的散文:
shouldAutoCompact()里针对marble_origami/REACTIVE_COMPACT/CONTEXT_COLLAPSE三道护栏的因果链,以及"谁先点火谁就赢"的共同主题。prompt.ts里BASE / PARTIAL_FROM / PARTIAL_UP_TO三模板的分工,以及getCompactUserSummaryMessage()对 proactive / KAIROS 自治模式的尾语扩展。compactWarningHook.ts被刻意从compactWarningState.ts拆出来以保持状态文件 React-free 的考量。services/compact/grouping.ts(63 行)的groupMessagesByApiRound与"为了打破 import cycle CC-1180 而独立的纯结构性模块"一并收入,避免新开一级标题违反 C-2。源码引用全部回填到
services/compact/当前 commit;中文段落留存率 99.1%,10 个 v1 一/二级标题原样保留。段落统计
保留 ≫ 新增,符合 §0.5.3 迭代重写"增量、不重写"的硬约束。
Manifest diff 摘要
CI 结果
bun run check:docs全部 PASS(含 C-1/C-2/C-3/C-4/C-5/C-6/F),仅一处 fuzzy WARN 命中 v1 原文「几乎零成本」,不阻塞。风格双亲实证
风格双亲:v1-03 状态管理 + v1-05 对话循环
v1 原文摘抄(≥ 200 字 × 2 段)
【摘抄 1,来自 docs/03-状态管理.md】
答案在于 import DAG(依赖有向无环图)的约束。
bootstrap/state.ts处于 import 树的最底部(叶子节点),几乎不 import 其他业务模块。需要澄清的是,state/store.ts和state/AppStateStore.ts本身并不依赖 React —— 真正引入 React 的是state/AppState.tsx。但问题的核心不在于 React 依赖,而在于分层约束:如果 bootstrap/state 反向依赖了更高层的应用状态模块(无论是 Store 还是 AppStateStore),就会破坏 DAG 的叶子节点地位,极易引入循环依赖。源码注释也明确提到这一点。【摘抄 2,来自 docs/05-对话循环.md】
如果把 Claude Code 比作一个人体,那
query.ts就是它的心脏——对话循环的编排入口。当然,心脏需要血管系统才能工作:重试逻辑在services/api/withRetry.ts,工具执行在services/tools/,停止钩子在query/stopHooks.ts,环境配置在query/config.ts。本篇会覆盖这个完整的"循环系统",而不仅仅是query.ts一个文件。每一次用户提问,都会触发这个循环:用户输入 → query() → queryLoop() → API 调用 → 工具执行 → 结果 yield → 等待下一轮。注意transition字段——它记录了上一次迭代为什么continue。这不仅仅用于调试,还用于控制恢复逻辑:比如collapse_drain_retry后如果仍然 413(上下文太长),就不再重复 drain 而是 fall through 到 reactive compact。本章新写正文摘抄(≥ 200 字 × 2 段,覆盖典型叙事段)
【新写 1,来自 docs/06-上下文管理.md §3.1】
除了这两条最直接的递归保护,源码在
shouldAutoCompact()里还排布了几道针对新一代上下文机制的护栏(services/compact/autoCompact.ts:174-223),它们都属于"看似与 compact 无关、一旦同时点火就会互相拆台"那一类隐患:marble_origami这个 ctx-agent——开启了CONTEXT_COLLAPSE之后,contextCollapse 自己也是一个 forked agent(querySource =marble_origami)。如果它在工作过程中又触发 autocompact,runPostCompactCleanup会顺手调用resetContextCollapse(),把主线程那一份模块级 collapse log 全部清掉。源码注释把这个连锁反应讲得很直白——所以这条 querySource 直接被列入"绝不再触发 autocompact"的黑名单。CONTEXT_COLLAPSE启用时的让位——collapse 自己在 90% 触发承诺、95% 触发阻塞生成,而 autocompact 的阈值落在 effective 减去 13K 的位置(200K 模型上即 167K,相当于 93%)——恰好夹在这两条线中间。如果不让位,autocompact 通常会抢在 collapse 之前点火,把 collapse 即将保住的细粒度上下文一刀切掉。这一串护栏背后的共同主题是:当一个进程里同时活着多种上下文管理子系统时,谁先点火谁就赢,而点火顺序错了会发生静默的状态破坏。【新写 2,来自 docs/06-上下文管理.md §六】
与
postCompactCleanup并排坐着的还有一个 63 行的小文件services/compact/grouping.ts,它本身和清理逻辑无关,但属于同一类"为了让 compact 家族跑得动而存在的胶水模块",顺带一提。它只导出一个groupMessagesByApiRound(),把Message[]按"API 往返边界"切组——遇到message.id与上一个 assistant 不同的新 assistant 消息就开新一组。这替换的是早期那套"只在真实用户提示处切分"的人工 turn 分组:那种分组对 REPL 够用,但对 SDK/CCR/eval 这类"整段会话只有一条人类提示、其余全是 agentic loop"的调用方就退化成"只有一组",reactive compact 想压缩中段也无从下刀。改成按 API 往返切分后,单提示词 agent 会话的中间轮次也能被独立摘要。services/compact/grouping.ts:18-21的注释还交代了它为什么会被单拎出来:原本 inline 在compact.ts里时,compact.ts ↔ compactMessages.ts之间形成了 import cycle(CC-1180),在 CI shard-2 上暴露了一个潜伏的ws模块 CJS/ESM 解析竞态——拆出来仅仅是为了改变模块初始化顺序。Test plan
bun run check:docs全绿(一处 fuzzy WARN 命中 v1 原文,非阻塞)services/compact/引用全部回填到 290fdc9🤖 Generated with Claude Code