news 2026/10/2 1:38:08

Gajae-Code Compaction压缩机制详解:长会话如何不丢上下文?分支摘要原理剖析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gajae-Code Compaction压缩机制详解:长会话如何不丢上下文?分支摘要原理剖析

Gajae-Code Compaction压缩机制详解:长会话如何不丢上下文?分支摘要原理剖析

【免费下载链接】gajae-codeGajae Code MVP项目地址: https://gitcode.com/gh_mirrors/ga/gajae-code

Gajae-Code 是一个开源的 AI 编程助手,长会话中上下文窗口会被对话与工具输出不断填满,一旦超出模型上下文上限,之前的工作进度就会"失忆"。Gajae-Code 通过Compaction 压缩与分支摘要(Branch Summary)两大机制解决这个问题:Compaction 把当前分支的旧历史改写为一份结构化摘要,分支摘要则在/tree导航时归档被放弃分支的上下文,两者都会持久化为会话条目,并在重建 LLM 输入时还原为上下文消息,让长会话永不丢上下文。

为什么长会话会"记不住"?

LLM 的每一轮请求都要携带完整历史:你让 AI 读文件、跑命令、改代码,read、search、bash的工具输出会持续累积。真实的会话统计曲线能直观看到这种增长——下图是各工具调用累计消耗的 token 量,read与search是绝对大头:

更麻烦的是,真实工作流往往横跨多个阶段。下图的"需求澄清 → 实施计划 → 执行验证"多阶段流程,每一步都会产生大量轮次:

当上下文超出窗口,模型直接报错;粗暴地删掉最旧消息又会打断因果链(比如孤立的工具结果)。Gajae-Code 的解法不是"删",而是"压缩 + 归档"。

Compaction 压缩:把旧历史改写成语义摘要

核心实现位于 compaction.ts,整体流程在 docs/compaction.md 中有完整描述。

压缩何时触发:4 种入口

  1. 手动压缩:输入/compact [指令],立即对当前分支执行压缩,你还可以附带定制指令;
  2. 溢出自动恢复:模型返回上下文溢出错误时,先尝试"上下文晋升"(切换到更大窗口的模型重试),不可用时才执行压缩,压缩成功后自动继续;
  3. 阈值维护:正常回合结束后,若上下文 token 数超过阈值(默认约为min(上下文窗口 - max(15%, 保留token), 300000)),自动压缩;
  4. 空闲维护:可选开启,空闲时用reason: "idle"重写历史,且不会自动续跑。

压缩长什么样:切割点的"硬规则"

压缩不是截断,而是在历史中选一个切割点(cut point),把切割点之前的消息交给 LLM 生成摘要,切割点之后的"近期消息"原样保留(默认保留约 20000 token,配置项compaction.keepRecentTokens):

  • 边界记为firstKeptEntryId,之后的消息照常发给模型,之前的旧消息不再随请求发送;
  • 硬规则:永远不在工具结果(toolResult)处切割,避免产生孤立的因果链碎片;
  • 切割点若落在某个回合中间(split turn),会生成两份摘要——历史摘要 + 当前回合前缀摘要,用分隔线合并存储;
  • 第二次压缩时不再从零总结,而是基于上一份摘要增量更新(对应模板 compaction-update-summary.md)。

压缩完成后,模型实际看到的是:系统提示 + 一份摘要消息 + 切割点之后的近期消息——篇幅小得多,语义完整度几乎不降。

摘要里都有什么:不止"几句话"

摘要由专门的结构化提示词(compaction-summary.md)驱动,强制包含:目标、约束与偏好、进度(已完成/进行中/被阻塞)、关键决策、下一步行动、关键上下文,并要求精确保留文件路径、函数名、报错信息。除此之外,系统还会自动附加两类"确定性信息",不依赖总结模型自己猜:

  • 文件活动标签:全程统计read/write/edit工具调用,摘要尾部追加<read-files>与<modified-files>清单;
  • 在途状态注入:当前活跃目标、至多 5 个进行中的工作流技能(含阶段)、至多 10 条未完成 todo,被写进摘要请求的附加上下文。

这正是"长会话不丢上下文"的关键——工作进行到一半时压缩,模型能精确知道"做到哪了、还差什么"。

先修剪后压缩:工具输出裁剪(Pruning)

在压缩判断之前,系统会先做一轮工具输出裁剪(pruning.ts),很多场景下光靠它就不必动用摘要。默认策略非常保守:

  • 保护最近 40000 token 的工具输出,最近 2 轮真实用户对话内的输出完全不动;
  • 预期节省不足 20000 token 时直接放弃裁剪;
  • skill与read的结果默认受保护,仅当后续读取被证明覆盖了旧结果时才允许裁剪;
  • 被裁剪的输出替换为一行高信号摘要(退出码、报错行、路径提示);若会话 artifact 管理可用,完整输出会外溢为 artifact 文件——裁剪是可逆的,模型可以用artifact://地址随时读回原文,而无需重跑工具。

下图是每次调用平均 token 的趋势(7 日滑动平均),可以看到单次read常在 1000+ token 量级,裁剪这类重复输出收益显著:

分支摘要:给"被放弃的分支"写归档备忘

Compaction 解决的是"时间轴太长",分支摘要解决的是"空间轴分叉"。Gajae-Code 的会话是一棵树:用/tree(见 docs/tree.md)回退到历史节点、换一条路线继续时,原来的分支就被"放弃"了。

当branchSummary.enabled开启时,导航流程会:

  1. 找出旧叶子到新叶子的公共祖先,收集被放弃路径上的全部条目(如 B、C、D 三条消息);
  2. 按预算模型上下文窗口 - branchSummary.reserveTokens,从新到旧挑选要总结的消息(优先保留近期上下文);
  3. 用 branch-summary.md 提示词生成摘要,同样附上读/改文件清单;
  4. 把摘要以BranchSummaryEntry持久化到导航目标位置(实现见 branch-summarization.ts)。

之后无论从哪个分支重建上下文,被放弃分支的探索过程都会以一条摘要消息的形式回归——你回退重做时,AI 依然记得"方案 A 为什么失败",不用把走过的弯路再走一遍。整个过程支持按 Escape 取消。

快速上手:关键配置一览

相关默认值定义在 settings-schema.ts 中,概念与调优指南见 docs/concepts/context-compaction.md:

配置项默认值说明
compaction.enabledtrue压缩总开关
compaction.strategycontext-full可选handoff(新开会话交接,见 docs/handoff-generation-pipeline.md)或off
compaction.thresholdPercent-1(哨兵值)自动压缩阈值百分比,gjc config set compaction.thresholdPercent 70即可提前压缩
compaction.keepRecentTokens20000切割点之后原样保留的近期 token 数
compaction.autoContinuetrue压缩后若检测到未完成工作才自动续跑,已完成则跳过
compaction.adaptive.enabledfalse自适应压缩:长会话高频调用时自动下调阈值
branchSummary.enabledfalse开启/tree导航时的分支摘要

对工具调用密集、会话动辄上十万 token 的长任务,可参考文档推荐的自适应起步配置(baseThresholdPercent: 75、aggression: 0.2),避免大上下文被反复整包重发。

扩展点:用 Hooks 定制压缩行为

压缩管线对扩展完全开放(hooks/types.ts):

  • session_before_compact:压缩前介入,可取消压缩或提供自定义摘要;
  • session.compacting:覆盖摘要提示词、注入额外上下文、附加保留数据;
  • session_compact:压缩完成后的通知事件;
  • session_before_tree/session_tree:分支摘要的前置与后置钩子。

总结

Gajae-Code 用三层防线保证长会话"不丢上下文":工具输出裁剪先回收可逆的冗余输出,Compaction 压缩把旧历史固化为带进度、决策与文件清单的结构化摘要,分支摘要则在会话树分叉时给放弃的路线留下归档备忘。三者都以一等会话条目持久化,重建上下文时自动还原——这就是长会话可以无限延续、随时回退而不失忆的底层原理。更多实现细节可查阅 docs/compaction.md。

【免费下载链接】gajae-codeGajae Code MVP项目地址: https://gitcode.com/gh_mirrors/ga/gajae-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 1:35:54

从PCB走线到天线:用史密斯圆图搞定2.4GHz频段的阻抗匹配陷阱

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 1:34:58

Matrix-Client摄像头调试与3D视图配置:从环境准备到避坑实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 1:34:27

Spring Boot 轻量级大数据方案:共享单车实时分析实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 1:32:51

IT66220硬件HDCP引擎:从合规成本到视频流水线的重构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 1:32:11

Python串口直驱睿尔曼机械臂实战教程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华