源码我是从https://github.com/alex000kim/claude-code/tree/main/src下载的上下文压缩的实现位置如下先来说说为什么需要上下文压缩。 核心原因很简单所有大语言模型都有最大上下文 Token 限制Context Window。如果用户在同一个会话里长时间调试、执行大量命令、读取冗余内容对话总 Token 很容易超限最终触发Prompt Too Long错误。这个目录下的代码正是为解决这类问题而设计通过智能判断对历史消息进行压缩或局部截断让 AI 能在有限的上下文窗口内持续工作同时尽可能不丢失关键信息。接下来我们先看上下文压缩的触发位置。 我个人倾向于只要对输出内容做了精简处理都可以算作广义上的压缩如果范围再放宽一些这类操作更适合统称为上下文处理。 因此在后续讲解中我会把相关逻辑拆成两部分来讲上下文处理与上下文压缩大家可以自行判断哪些属于压缩、哪些属于更通用的上下文管理。上下文什么样子呢大概是这个样子let state: State { messages: params.messages, // 当前对话所有消息 toolUseContext: params.toolUseContext, // 工具调用上下文 maxOutputTokensOverride: params.maxOutputTokensOverride, // 输出Token覆盖配置 autoCompactTracking: undefined, // 自动压缩追踪状态 stopHookActive: undefined, // 停止钩子状态 maxOutputTokensRecoveryCount: 0, // Token恢复重试次数 hasAttemptedReactiveCompact: false, // 是否尝试过响应式压缩 turnCount: 1, // 当前对话轮次 pendingToolUseSummary: undefined, // 待处理工具调用摘要 transition: undefined // 循环过渡状态用于测试/恢复}哪里会调用这个上下文的处理上下文相关处理逻辑的入口位于src/query.ts文件的核心循环函数queryLoop内部。本节我们重点关注主循环中对上下文的各类处理流程暂时不纠结这些操作到底算不算 “压缩”也不提前给它们贴标签。 上下文处理的具体调度顺序如下与源码执行逻辑完全一致所有操作均围绕上下文内容管理展开具体包含哪些行为、是否属于压缩大家可以结合后续细节自行判断。1. 触发源头queryLoop持续循环在 Claude 处理用户请求的每一轮对话Loop开始时它都会在发送 API 请求之前通过一系列“拦截器”来检查和压缩上下文状态。2. 核心调用链条 (按执行顺序)如上图所示在src/query.ts的while(true)循环中你可以看到以下关键入口逐个依次执行入口 A工具输出结果预算硬性裁剪 (applyToolResultBudget)代码位置src/query.ts第 379 行左右。函数await applyToolResultBudget(messagesForQuery, ...)触发条件无条件执行。遍历发给 API 之前的消息体。作用对每一次单条的消息实行强制拦截与预算管理。由于某些工具没有配置上限或者其输出可能极其庞大这步会在进入真正的高级压缩处理池前确保工具运行产生的原始文字负荷不会直接溢出单条上限。入口 B局部信息修剪模块 (snipCompactIfNeeded)代码位置src/query.ts第 403 行左右。函数snipModule!.snipCompactIfNeeded(messagesForQuery)触发条件处于feature(HISTORY_SNIP)特性开启状态下。作用根据特定规则去把大块不再紧密关联的局部对话进行“硬切除”Snip并在本次切除完毕后算出“释放了多少 TokensnipTokensFreed”留给后续判断步骤使用。注意这里虽然是函数但是我们没有找到对应的ts文件也就是或这个源码还是有遗漏的。# 各位可以看看能不能找到snipCompact这个文件/* eslint-disable typescript-eslint/no-require-imports */const snipModule feature(HISTORY_SNIP) ? (require(./services/compact/snipCompact.js) as typeof import(./services/compact/snipCompact.js)) : null入口 C微压缩清理 (Micro-compaction)代码位置src/query.ts第 414 行左右。函数await deps.microcompact(...)触发条件无条件执行但在其内部会自动根据“冷热缓存”与“时间阈值”进行旁路决策。作用在发起主请求前清理不再需要的历史大尺寸工具执行结果记录。如果判断上下文由于闲置过久已经变成了“冷缓存”会直接清空历史 grep/cat 等工具打印结果的内容区以释放空间若是“热缓存”则会排队等候向 API 发布“清空旧节点”的指令从而保全其它缓存命中率。入口 D局部上下文折叠 (contextCollapse)代码位置src/query.ts第 441 行左右。函数await contextCollapse.applyCollapsesIfNeeded(...)触发条件当系统带有CONTEXT_COLLAPSE标识并且上下文折叠功能被启用。作用该模块会在真正的“暴力合并压缩AutoCompact”发生之前抢跑。它检查历史记录中可以被折叠、归档合并的工作流并将其转化为本地短文本节点。通过它的提前抢答和瘦身系统上下文会大量释放从而极有可能避免接下来的暴力合并。入口 E全局红线自动压缩 (autoCompact)代码位置src/query.ts第 454 行左右。函数await deps.autocompact(...)触发条件通过估算目前的令牌消耗量并在评估时聪明地减掉刚刚第 B 步里snipTokensFreed省下的令牌。如果发现将要超过API 安全上限 - Buffer预留空间则强制触发。作用全局防爆兜底机制。一旦触发它在内部会首选把对话写入长期记忆流中Session Memory 模式进行保存。若是走投无路就会正式冻结界面并新建子任务给原生 Claude 下发指令“彻底读一遍上面这几十轮对话给出一段核心 Summary”并把所有老的几十轮消息无情抛弃换成一句总结实现重新续航。上面是5个小模块对吧这里我们分开来说首先说的是2个处理模块的一些细节。先说下2处理模块的介绍和细节处理模块我认为有两个分别是applyToolResultBudget和contextCollapse1.applyToolResultBudget单次工具输出预算管理该机制的核心作用是大内容本地保存 原文替换为短摘要避免单个工具返回超长内容如读取超大文件、爬取超长网页把大模型的上下文撑满。代码位置实现逻辑在src/utils/toolResultStorage.ts核心调用由applyToolResultBudget内部调用算法enforceToolResultBudget触发时机在每轮对话发送给大模型 API 前自动检查messages列表控制阈值由MAX_TOOL_RESULTS_PER_MESSAGE_CHARS决定上限也可通过动态参数tengu_hawthorn_window覆盖工作流程1.采集待处理工具结果从消息里把所有工具返回内容抽出来按消息分组。 例消息1里有cat package.json、grep两个工具结果消息2里有curl一个工具结果2.读取配置与过滤规则拿到单条消息最大长度限制比如 50KB并跳过某些工具比如 Read 工具不处理。 例限制 50KB跳过Read工具其他都要检查。3.按历史状态拆分内容根据之前处理记录把每条消息的结果分成三类 mustReapply之前已经被截断过的 frozen之前处理过但没超限正常保留 fresh本轮新出现的还没检查过 例消息1里的grep是之前截过的 → mustReapplycat package.json是新的 → fresh4.重新应用历史替换之前截过的内容直接用上次一模一样的短文本保证缓存不炸。 例grep上次截成了预览文本这次直接再用一遍一字不差。5.对新内容算总大小把本轮新内容 历史没超限的内容加起来看超不超 50KB。 例历史冻结 10KB 新的cat结果 60KB 70KB 50KB → 超限6.筛选超长内容去落盘超限就挑最新、最大的工具结果处理。 例选中这个 60KB 的cat结果准备存本地。7.安全标记已处理ID不需要替换的先标记“已见过” 要存盘的等存完再标记防止状态错乱。 例grep直接标记已处理cat先不标记等存好文件再说。8.落盘 生成短预览把大内容存到本地文件生成一段短预览。 例60KB 内容存到session123/tool-results/abc.txt替换成persisted-output太大了存到xxx预览前2000字.../persisted-output9.替换并返回结果把原消息里的大文本换成短预览返回新消息列表。例最终发给模型的是短文本原大内容留在本地。2.contextCollapse局部动作链条折叠该机制的本质是对局部对话做高压缩归档。 它比applyToolToolResultBudget覆盖范围更广又比全局强制总结autoCompact更精细、更温和。代码位置src/services/contextCollapse/index.js按需加载核心调用contextCollapse.applyCollapsesIfNeeded(...)内部依赖projectView()及恢复逻辑开关控制由特性开关feature(CONTEXT_COLLAPSE)启用但是兄弟们没有找到这个代码位置啊你们找到的话对我说下# query.ts中的19行const contextCollapse feature(CONTEXT_COLLAPSE) ? (require(./services/contextCollapse/index.js) as typeof import(./services/contextCollapse/index.js)) : null/* eslint-enable typescript-eslint/no-require-imports */下面的工作流程就看看得了不保熟…工作流程1.优先优化避免全局压缩: 该函数会在破坏性最强的全局总结autoCompact之前执行目标是只要折叠后能把 Token 降下来就不触发全局强总结。2.不修改原始消息: 不会直接删除或改动state.messages里的真实历史而是维护一套 - 折叠中心Collapse store - 提交日志Commit log 实现“无损折叠”。3.自动识别可折叠的动作链: 自动扫描历史对话找到冗长、重复、只为完成一个小目标的对话段例如连续5次调试只为改一个拼写错误。4.生成局部摘要只发送精简版给模型: 把一长串消息“折叠”成一句精简摘要只将摘要发给大模型。这种折叠方式让对话具备层级化、可伸缩的能力保留核心逻辑隐藏冗余细节。各个压缩模块的文件介绍和整体流程我们在src/services/compact下面真compact就是压缩的意思可以看到其主要的实现方式compact 文件夹是 Claude Code 中负责管理对话上下文与消耗Token limits最核心的模块即“上下文压缩Compaction”系统总共有apiMicrocompact.ts、 autoCompact.ts、 compact.ts、 compactWarningHook.ts、 compactWarningState.ts、 grouping.ts、 microCompact.ts、 postCompactCleanup.ts、 prompt.ts、 sessionMemoryCompact.ts、 timeBasedMCConfig.ts这个几个文件。但是注意哈我们只能看到这几个文件其实从主循环里面来看的话应该还是有其它文件的。注意这里我说的是核心的压缩模块哈是压缩不是处理哈。其中各个核心模块的作用与原理如下各个核心模块的作用与原理1. 核心压缩引擎compact.ts执行全局对话“压缩”的主文件。当需要压缩时它会取出当前聊天记录的最老部分调用 LLM 对其进行高质量“总结Summarize”生成一份概要记录并舍弃原有的庞大对话节点。同时它还负责重新插入重要的状态如当时用过的 Tool、计划Plan附件以及仍旧打开的文件状态。prompt.ts里面定义了多套精心设计的系统提示词Prompt。这些 Prompt 专门用来教导 LLM “如何给自己做压缩总结”。例如里面有极其严格的指示让 LLM 做总结时切勿调用任何工具NO_TOOLS_PREAMBLE而且必须关注用户过去的根本意图、已修复的 Bug、以及代码架构等等。2. 自动化触发机制Proactive CompactingautoCompact.ts自动化压缩守护进程。它会根据当前使用的模型精确计算其允许的 Token 上限并留出缓冲区Buffer。每次工具执行或者回合结束时它都会计算评估一旦触及警告阈值Auto Compact Threshold它就会在后台自动触发压缩。用户感受到的就是“对话一直在继续不需要我自己去开新会话”。timeBasedMCConfig.ts基于时间的评估配置方案。3. 微压缩与策略缓存Micro CompactionmicroCompact.ts/apiMicrocompact.ts微压缩策略Micro Compaction。不同于把所有对话生成总结微压缩主要是把繁重的工具返回结果Tool Result清理掉。比如你用grep搜出了几百行结果或猫了一个大文件这其实很快就会失去时效性并且占据极大 Token微压缩就会针对这种特定的 Tool Result 截掉其内容替换成[Old tool result content cleared]。sessionMemoryCompact.ts该文件实现了另一种维度的压缩逻辑。也就是将一些旧状态压缩进入一种更加“长期的记忆Session Memory”片段中进行存储而不是单纯作为聊天流水账。4. 状态预警与维护杂项compactWarningHook.ts/compactWarningState.ts用来处理“Token 报警”时的状态管理比如决定什么时候该给用户弹警告告诉用户当前上下文正在变得很重马上要进行压缩了。postCompactCleanup.ts它主要承担“后事处理”。当完成一次完整的 Context 压缩后它负责清空某些过时的缓存树比如之前残留的旧消息 ID、重置一些上下文环境从而保证压缩后的会话纯净且不发生内部 ID 错换或报错。grouping.ts协助将庞大的消息队列依据 API 的回合Round规则进行分类和聚合以防压缩时割裂了 “User - Assistant” 这个成对出现的消息结构导致请求格式报错。这几个模块在 Claude Code 里的执行调度顺序是有明确优先级的它们主要卡在“向大模型发起请求前”的执行 Loop 中。整个拦截和清理机制的先后顺序可以总结为一个漏斗先剔除冗余片段 - 算账报警 - 尝试智能记忆归档 - 没办法了才做暴力总结。好了说完了每个ts的功能我们再看下整理的流程将先后顺序拉齐流程的入口是autocompact.ts文件我们在query.ts中就可以看出来// src/query.ts 中的 queryLoop 函数片段// ... 步骤 1: 预算裁剪 (applyToolResultBudget)// ... 步骤 2: 历史片段剪枝 (snipCompactIfNeeded - HISTORY_SNIP 特性)// ... 步骤 3: 微清理 (microcompact - 清理旧的工具输出)queryCheckpoint(query_autocompact_start)// 核心调用点这里通过依赖注入调用了 services/compact/autoCompact.ts 中的 autoCompactIfNeededconst { compactionResult, consecutiveFailures } await deps.autocompact( messagesForQuery,)queryCheckpoint(query_autocompact_end)if (compactionResult) { // 如果触发了压缩则在此处应用压缩结果并更新消息序列 const postCompactMessages buildPostCompactMessages(compactionResult) // ... messagesForQuery postCompactMessages}所有的其它ts文件主要是通过通过query.ts里面的loop串起来自动压缩详细解释焦于autocompact.ts文件看它里面的流程如下代码在services/compact/autoCompact.ts-Line241的autoCompactIfNeeded主要逻辑包含以下几个关键判定点1.安全守门员阶段 (Guard Clauses) 流程图最左侧展示了两个前置判定环境禁用首先读取环境变量如果用户显式禁用了压缩DISABLE_COMPACT后续所有逻辑都不会跑直接返回。熔断保护 (Circuit Breaker)检查最近连续失败的次数。如果已经连续失败 3 次系统会认为当前上下文状态可能存在“不可救药”的问题例如某条消息过于巨大导致总结接口始终崩溃此时会主动停止尝试防止无谓的 API 消耗。2.压力评估阶段 (Should Compact?)调用shouldAutoCompact函数进行计算。逻辑先排除掉各种不能触发自动压缩的场景比如递归调用、上下文折叠已生效、仅响应式压缩模式等避免冲突或死锁然后计算当前消息的实际 Token 数量判断是否超出模型设定的压缩阈值最后返回是否需要执行全局自动压缩。3.第一优先级会话记忆压缩 (SM Compact - 策略1) 这是图中第一个核心分支做啥把长的会话记忆文本压缩成短摘要同时保留关键信息并标记被截断的部分。输入这个部分输入是message、session_memory,不压message做法记录压缩前 token 数用于统计、 创建边界标记标记从哪里开始压缩记录使用了哪些工具、 截断过长的 session memory防止占满 token 预算、 生成摘要内容如果被截断会提示完整内容路径、 包装成特殊消息不显示给用户只作为上下文给 AI、 返回压缩结果包含摘要、保留的消息、token 统计等。举个例子假设对话已经进行很久原始对话5000 tokens、保留最近 10 条消息1000 tokens、压缩之前的 4000 tokens → 生成 500 tokens 的摘要、最终上下文摘要(500) 保留消息(1000) 1500 tokens。代码上是通过自己定义的规则来实现的。具体在utils/messages.ts-Line460代码services/compact/sessionMemoryCompact.ts-Line5144.兜底策略总结压缩 (Full Compact - 策略2) 如果策略 1 失败通常是因为后台提取器还没来得及生成一致的总结系统会进入这个兜底环节原理调用专门的总结 Prompt 让 LLM 对当前历史进行重写。逻辑图中 Simplified1.暂停 UI 和加载 Hooks (executePreCompactHooks)界面会进入“Compacting…”等待状态暂停处理你的新需求。2.构建 Prompt (使用prompt.ts)获取你先前的会话记录并给 Claude 添加极度严厉的指令参数类似要求必须以包含summary、analysis的格式去浓缩整段历史且绝对禁止在此总结期间使用任何工具。3.触发隐式 AI 请求发送一次幕后请求拿回浓缩结论Summary String。如果这一步连发要求总结的请求都报 prompt-too-long 的错即CC-1180问题系统甚至会用truncateHeadForPTLRetry无脑切掉头部的几个轮回硬试。4.截断与状态重建拿到生成的短文本摘要后用它替换掉旧对话序列的最开头插入边界标志SystemCompactBoundaryMessage。然后系统会将你在压缩前正开着的文件、计划列表Plan等重要附件重新挂载回去免得大模型失忆。5.完成后一切恢复带着瘦身后的上下文去回答你的初始提问。输入message压缩的是这个不是记忆哦代码services/compact/autoCompact.ts-Line387的compactConversation5.状态平滑复位与收尾 (Post-Process) 图的最右侧展示了压缩成功后的必要动作ID 重置因为压缩会改变消息的 UUID所以必须重置lastSummarizedMessageId否则下一轮循环会找不到锚点。钩子执行调用runPostCompactCleanup触发如PROMPT_CACHE_BREAK_DETECTION通知缓存检测系统Token 下降是正常的压缩行为不是缓存断档。计数归零如果压缩成功会将“连续失败计次”重置为 0解除熔断状态。轻量级微清理 (Micro-Compacting)详细解释代码位于services/compact/microCompact.ts-Line253的microcompactMessages函数。在每次向外发送消息之前会先走microCompact.ts或者原生的apiMicrocompact.ts。系统不想一上来就动大手术所以先看看能不能把没用的“胖子资源”删掉。1.基于时间的判断 (evaluateTimeBasedTrigger)如果距离上一次调用时间已经过去很久代表缓存早已失效、变冷直接本地扫一遍对话把之前老旧工具的输出结果比如好几个长长的被猫cat出来的文件文本或是 grep 结果替换为缩写提示[Old tool result content cleared]从而立刻腾出空间。2.基于热缓存编辑 (cachedMicrocompactPath)就算对话很频密如果累计调用了太多的 Shell、FileRead它也会打个标签并排队Pending Cache Edits去告诉大模型 API “这几个之前的结果你从上下文里删掉”。3.调用apiMicrocompact.ts构建原生 API 请求策略正如你打开的代码如果没有采用客户端清理就会去配置 Anthropic API 的原生清空策略ContextEditStrategy比如让后端大模型自动clear_thinking(剔除旧的思维链内容) 或者clear_tool_uses。Snip裁剪这个流程我放到处理里面去了在这里不展示了Context Collapse这个流程我放到处理里面去了在这里不展示了所以整体上是 Snip - Microcompact - Context Collapse - AutoCompact。其中Snip和Context Collapse没有源码只能猜怎么做的了。总结基于源码分析Claude Code 的上下文压缩机制按以下顺序执行五个入口依次触发applyToolResultBudget工具输出裁剪→snipCompactIfNeeded硬切除→microcompact清理旧工具输出→contextCollapse局部折叠→autoCompact全局压缩两种核心压缩策略优先使用会话记忆压缩本地规则压缩sessionMemory不调 API失败后降级为LLM 总结压缩调用 AI 生成对话摘要消耗 token辅助清理机制applyToolResultBudget将超大工具输出存本地文件并替换为短摘要microcompact按时间或缓存状态清理旧工具结果安全保护包含熔断机制连续失败 3 次后停止尝试和环境变量禁用开关学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】