要点速览•上下文不是一个对话框每次请求由系统提示、工具定义、userContext、消息历史、Attachments 五层拼装其中消息历史里的工具结果是 token 膨胀的主要来源•工具结果超限时直接存磁盘单个结果超过 5 万字符、或一轮并行调用合计超过 20 万字符超限部分持久化到本地文件上下文只保留 2000 字节预览 文件路径模型可按需读取完整内容•Prompt Cache 是整个压缩设计的核心约束系统提示 工具定义的缓存前缀命中后费用降至 1/10但前缀一旦被修改就全部失效——所有压缩操作都必须绕开这个约束•压缩还面临信息损失难题把工具调用历史压缩成摘要不可避免地丢失细节模型可能忘记关键约束在任务进行中压缩尤其危险•存量清理分三层代价递进MicroCompact 在每次请求前静默清理旧工具结果零 API 调用Session Memory Compact 在上下文接近阈值时优先用已有记忆文件压缩零额外 API 调用AutoCompact 在前两者都不适用时调用 Claude 生成摘要一次额外 API 调用•AutoCompact 有完整的工程保障结构化九章节摘要防止信息随意丢失、熔断器防止压缩失败时的无限循环、PreCompact Hook 允许注入项目特定的重点保留规则•压缩不等于遗忘AutoCompact 后模型仍能通过状态恢复最近 5 个文件和完整转录文件按需找回细节信息是归档而非删除Claude Code 每次向 API 发起请求发出去的不是一个简单的对话历史而是一个由五个层次拼装而成的结构体。理解这个结构是理解它为什么需要压缩、以及压缩机制为什么要设计成现在这个样子的前提。上下文的构成每次请求包含两个主要字段system系统提示和messages消息列表。但这两个字段的内部结构远比表面复杂。系统提示的四个块系统提示不是一段文字而是一个数组由最多四个块按顺序拼接而成。归因头Attribution Header内容类似x-anthropic-billing-header: cc_version1.2.3; cc_entrypointcli用于服务端识别请求来源。包含版本号等会变化的信息不参与缓存。身份前缀CLI Sysprompt Prefix固定文本例如You are Claude Code, Anthropics official CLI for Claude.。所有请求共享使用org级别缓存。静态指令Static Instructions系统提示的主体包含任务指导、工具使用规范、代码风格要求、安全操作原则等。在一次会话中几乎不变是缓存命中率最高的部分。启用 Global Cache 时使用global级别缓存跨用户共享。动态上下文Dynamic Context包含会话特定信息当前工作目录、Git 状态、CLAUDE.md 内容、今天的日期、语言偏好、MCP 服务器指令等。每次会话都可能不同不参与跨会话缓存。代码中有一个明确的边界标记SYSTEM_PROMPT_DYNAMIC_BOUNDARY将系统提示切分为静态可缓存和动态不可缓存两段// src/constants/prompts.tsexport const SYSTEM_PROMPT_DYNAMIC_BOUNDARY __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__这个边界的意义在于静态指令部分可能有数千 token通过边界标记Claude Code 告诉 API 边界之前的内容可以跨请求复用缓存边界之后的内容每次重新处理。工具定义工具定义作为独立的tools字段传给 API每个工具包含名称、描述和输入 schema。工具列表的最后一个工具会被标记cache_control: { type: ephemeral }缓存点打在工具列表末尾意味着系统提示 所有工具定义这整个前缀都可以被缓存。userContextCLAUDE.md 和当前日期不是放在系统提示里而是作为消息历史的第一条消息注入system-reminderAs you answer the users questions, you can use the following context:# claudeMd...# currentDateTodays date is 2025-04-04./system-reminder为什么不直接放在系统提示里因为 CLAUDE.md 的内容可能在会话中途变化而系统提示在会话开始后就被缓存了。把它放在消息历史开头可以在不破坏系统提示缓存的情况下更新。消息历史消息历史是上下文中增长最快的部分。每一轮对话都会追加用户消息、助手回复、工具调用tool_use块、工具结果tool_result块。文件内容本身会被完整地放入tool_result块这是消息历史膨胀的主要原因。Claude Code 的默认上下文窗口是 200,000 tokens一个中等规模的代码库读取几十个文件后消息历史就可能占满大半个窗口。AttachmentsAttachments 在每次请求前动态生成注入到消息历史末尾。常见内容包括用户 提及的文件、当前 Todo 列表、Plan 文件、从 memdir 检索到的相关记忆片段、与当前任务相关的技能列表、新连接的 MCP 服务器使用说明。设计思路是按需注入——只在需要的时候把信息放进上下文。上下文五层结构上下文管理的必要性与难点为什么必须压缩200,000 tokens 听起来很大但在实际编程任务中消耗极快。读取一个中等规模的源文件大约 1,000–3,000 tokens执行命令的输出可能几千 tokens一次完整的代码审查任务轻松消耗数万 tokens。更关键的是上下文窗口是硬约束——超出就报错任务中断。但不是所有内容都值得保留。模型读取文件是为了理解代码读完之后原始内容就不再需要了执行命令是为了得到输出输出被处理之后原始文本也不再需要了。这些**一次性消费的工具结果**占据了大量空间却不再提供价值。压缩的本质是把这些已经被消费的信息从上下文中清除为新的信息腾出空间。相比之下有些内容绝对不能压缩系统提示和工具定义参与 Prompt Cache在会话中途修改会导致缓存失效代价极高用户消息代表任务的需求和约束是整个任务的需求文档一旦丢失模型可能偏离方向。Prompt Cache压缩绕不开的约束在讲压缩机制之前有必要先理解 Prompt Cache因为它是整个压缩设计的核心约束。LLM 的推理有一个基本特性每次请求模型都要从头处理输入的所有 token计算每个 token 的注意力权重才能生成输出。这意味着即使你的系统提示一个字都没变每次请求仍然要重新处理它。对于 Claude Code 这样的工具系统提示 工具定义可能有数万 token一次会话里要发送几十上百次请求这部分重复计算的成本极高。Prompt Cache 就是为了解决这个问题。它的原理是API 在处理完一个请求后把输入的 KV Cache注意力计算的中间结果保存下来。下次请求如果前缀完全一致就直接复用这份 KV Cache跳过重新计算费用降低到正常处理的 10%。缓存的粒度是**“前缀”**——必须从请求的开头开始连续匹配。这意味着如果你在系统提示的中间插入了一个字符整个系统提示之后的所有内容都无法命中缓存。缓存点通过cache_control: { type: ephemeral }标记来指定打在某个位置意味着从请求开头到这里的所有内容都可以被缓存。Claude Code 的请求结构是这样的[系统提示静态部分] → [工具定义 ← cache_control 打在这里] → [userContext] → [消息历史] → [Attachments]缓存点打在工具定义末尾意味着系统提示静态部分 工具定义这整个前缀可以被缓存。这个前缀可能有数万 token一旦命中缓存每次请求节省的计算量非常可观。Prompt Cache 的 TTL 是 5 分钟——如果超过 5 分钟没有发送新请求缓存就会过期下次请求需要重新处理整个前缀。这个 TTL 对压缩机制的设计有直接影响后面会看到。Prompt Cache 机制压缩的两个核心难点理解了 Prompt Cache就能看清楚压缩面临的两个核心难点。难点一压缩操作本身可能破坏缓存。压缩需要修改消息历史而消息历史紧跟在缓存前缀之后。如果压缩操作改变了消息历史的开头部分就会影响缓存的匹配导致下次请求无法命中缓存。省下的上下文空间可能被增加的 token 处理成本抵消。难点二压缩会导致信息损失影响推理质量。把一段详细的工具调用历史压缩成摘要不可避免地会丢失细节。模型可能忘记某个关键约束在后续推理中犯错。更棘手的是如果压缩发生在任务进行中模型需要在压缩后继续完成任务它必须知道现在文件是什么状态而不只是我之前做了什么。这两个难点决定了压缩机制不能是一个简单的截断历史操作而需要精心设计。上下文管理机制Claude Code 的上下文管理分为两类机制入口管控和存量清理。入口管控在工具结果进入上下文之前就介入阻止大内容进来存量清理在上下文已经积累到一定程度后触发对已有内容做清理或摘要。两类机制分工不同共同构成完整的防线。存量清理部分的核心逻辑是代价递进用最低代价的方案处理最常见的情况只在必要时升级到更高代价的方案。入口管控与存量清理两类机制对比入口管控工具结果持久化工具结果在入库时就会被检查大小超限的直接持久化到磁盘上下文里只保留预览和文件路径。这是最早发生的一道防线代价也最低——只有磁盘写入没有任何 API 调用。// src/constants/toolLimits.tsexport const DEFAULT_MAX_RESULT_SIZE_CHARS 50_000 // 单个工具结果上限5 万字符export const MAX_TOOL_RESULTS_PER_MESSAGE_CHARS 200_000 // 单条消息内所有工具结果合计上限20 万字符触发持久化后上下文里的工具结果会被替换成这样的消息persisted-outputOutput too large (245 KB). Full output saved to: ~/.claude/projects/.../tool-results/abc123.txtPreview (first 2000 B):...前 2000 字节的内容....../persisted-output这里有两层检查。第一层是单个工具结果超过 50,000 字符时触发直接持久化。第二层是消息级预算一轮对话里可能有多个并行工具调用每个单独看都没超限但合计可能超过 20 万字符——这时按大小排序把最大的几个持久化直到总量降到预算以内。持久化机制有一个精心设计的细节替换决策一旦做出就被冻结后续每轮对话都用完全相同的预览字符串重新注入而不是重新读文件生成。这保证了消息历史的前缀字节完全一致Prompt Cache 不会因为同一个工具结果每次预览略有不同而失效。模型如果需要完整内容可以主动用 FileRead 工具读取持久化的文件路径——这是**“按需恢复而非强制截断”**的设计思路。第一层MicroCompact工具结果持久化处理的是刚产生的大结果MicroCompact 处理的是已经在上下文里的旧结果。最常见的情况是某个工具结果很大比如读取了一个几千行的文件但模型已经处理完了不再需要它的原始内容。这时候最理想的操作是把这条工具结果缩小但不触动消息历史的其他部分也不破坏 Prompt Cache。MicroCompact 只针对特定工具的结果做清理这些工具的输出都是一次性消费型的const COMPACTABLE_TOOLS new Setstring([ FILE_READ_TOOL_NAME, // 文件读取 ...SHELL_TOOL_NAMES, // Shell 命令Bash 等 GREP_TOOL_NAME, // 文件搜索 GLOB_TOOL_NAME, // 路径匹配 WEB_SEARCH_TOOL_NAME, // 网页搜索 WEB_FETCH_TOOL_NAME, // 网页抓取 FILE_EDIT_TOOL_NAME, // 文件编辑 FILE_WRITE_TOOL_NAME, // 文件写入])MicroCompact 的核心工具是cache_editsAPI——Anthropic 提供的一个特殊接口允许在不改变消息历史语义的情况下用缓存版本替换消息内容。模型看到的是摘要或占位符但 Prompt Cache 中保留了原始内容缓存不会失效。这个接口直接解决了压缩不能破坏缓存的难点。但cache_edits有一个前提缓存必须还是热的。如果距离上次请求已经超过 5 分钟Prompt Cache 的 TTL 到期缓存已经失效再用cache_edits维护缓存就是无用功。这时 MicroCompact 切换到另一条路径直接把旧工具结果的内容清空替换为占位符[Old tool result content cleared]不再尝试维护缓存。// 时间触发路径缓存已冷直接清空内容return { ...block, content: TIME_BASED_MC_CLEARED_MESSAGE }// cache_edits 路径缓存仍热通过 API 层替换pendingCacheEdits cacheEdits两条路径的选择逻辑很清晰缓存热的时候保留缓存价值缓存冷的时候不做无用功。MicroCompact 在每次发送请求前自动运行不需要额外的 API 调用几乎没有额外代价。第二层Session Memory Compact当消息历史整体接近上限时MicroCompact 就无能为力了。这时系统会先尝试 Session Memory Compact再考虑代价更高的 AutoCompact。Session Memory Compact 的核心思路是Claude Code 在会话过程中会持续提取结构化的 Session Memory10 段记忆这份记忆文件本身就是对会话内容的高质量摘要。当需要压缩时如果记忆文件已经有内容就直接用它作为压缩摘要完全跳过 AI 摘要 API 调用。// autoCompact.ts — Session Memory Compact 排在 AutoCompact 之前被尝试const sessionMemoryResult await trySessionMemoryCompaction( messages, toolUseContext.agentId, recompactionInfo.autoCompactThreshold,)if (sessionMemoryResult) { // 成功直接返回不再调用 compactConversation return { wasCompacted: true, compactionResult: sessionMemoryResult }}// 失败或不适用回退到 AutoCompactconst compactionResult await compactConversation(...)压缩后保留哪些消息由配置决定export const DEFAULT_SM_COMPACT_CONFIG { minTokens: 10_000, // 压缩后至少保留 10K tokens 的近期消息 minTextBlockMessages: 5, // 至少保留 5 条有文本内容的消息 maxTokens: 40_000, // 保留消息的硬上限}从上次记忆提取的位置之后开始向前扩展直到满足最小 token 和最小消息数要求但不超过 40K token 上限。这保证了压缩后的上下文既有完整的记忆摘要又有足够的近期对话细节。Session Memory Compact 还有一个安全检查压缩后估算的 token 数如果仍然超过 AutoCompact 阈值就放弃这条路径回退到 AutoCompact。这防止了压缩后立即再次触发压缩的循环。这一层的设计巧妙之处在于它把**“持续提取记忆这个已有的功能复用为压缩时的摘要来源”**实现了零额外 API 成本的高质量压缩。Session Memory 写入的 10 段结构化记忆也会在下次会话开始时通过相关性检索注入到新会话的 Attachments 中实现跨会话的知识传递。存储路径使用 git-root 作为 key~/.claude/projects/git-root/memory/同一项目的多次会话共享同一份记忆不同项目相互隔离。三层存量清理代价递进第三层AutoCompact当 Session Memory Compact 不适用记忆文件为空或不存在时AutoCompact 发起一次独立的 API 调用把整个对话历史压缩成结构化摘要然后用摘要替换原来的消息历史重置到干净的起点。触发阈值AutoCompact 的触发阈值不是固定百分比而是动态计算的export const AUTOCOMPACT_BUFFER_TOKENS 13_000export function getAutoCompactThreshold(model: string): number { const effectiveContextWindow getEffectiveContextWindowSize(model) // 阈值 有效上下文窗口 - 13,000 tokens 缓冲 return effectiveContextWindow - AUTOCOMPACT_BUFFER_TOKENS}effectiveContextWindow等于模型上下文窗口减去为摘要输出预留的 token最多 20,000还可以通过CLAUDE_CODE_AUTO_COMPACT_WINDOW环境变量进一步限制。对于 200K 上下文的模型实际触发阈值大约在 167K tokens 左右但这个数字会随模型版本和配置变化。结构化摘要摘要不是让模型自由发挥而是严格按照九个章节生成——主要请求和意图、关键技术概念、涉及的文件和代码、错误和修复、问题解决过程、所有用户消息、待完成任务、当前工作、可选的下一步。其中所有用户消息这一节会逐条列出用户的每一条消息。这直接回应了用户意图不能丢失的约束——即使整个对话历史被压缩用户说过的每一句话都会被保留下来。摘要生成还有一个两阶段过程模型先在analysis标签内做草稿分析确保覆盖所有要点然后再生成最终的summary。草稿分析在摘要完成后被丢弃不进入上下文但它提高了摘要的覆盖质量。Hook 干预机制AutoCompact 在执行前后各有一个 Hook 扩展点允许外部脚本干预压缩过程PreCompact Hook 在生成摘要之前执行。Hook 脚本的标准输出会被作为自定义摘要指令与用户指定的customInstructions合并用户指令在前Hook 指令追加在后。这意味着你可以通过 Hook 脚本动态注入压缩时重点保留 XXX 信息的指令而不需要每次手动指定。// compact.tsconst hookResult await executePreCompactHooks({ trigger: isAutoCompact ? auto : manual, custom_instructions: customInstructions ?? null,})// Hook 输出追加到用户指令之后customInstructions mergeHookInstructions(customInstructions, hookResult.newCustomInstructions)PostCompact Hook 在摘要生成完成后执行接收完整的压缩摘要文本compact_summary。可以用来记录压缩事件、同步摘要到外部系统或者触发其他自动化流程。两个 Hook 点的职责是不对称的PreCompact 是干预影响摘要内容PostCompact 是观测读取摘要结果。Hook 的配置格式在settings.json中{ hooks: { PreCompact: [{ hooks: [{ type: command, command: python3 /path/to/pre_compact.py }] }], PostCompact: [{ hooks: [{ type: command, command: python3 /path/to/post_compact.py }] }] }}压缩后的上下文重建摘要只能保留做了什么无法保留文件现在是什么状态。AutoCompact 完成后会自动恢复最多 5 个最近修改的文件预算上限是 50,000 tokensexport const POST_COMPACT_MAX_FILES_TO_RESTORE 5export const POST_COMPACT_TOKEN_BUDGET 50_000export const POST_COMPACT_MAX_TOKENS_PER_FILE 5_000此外还会重新注入本次会话使用过的 Skills每个最多 5,000 tokens总预算 25,000 tokens、重新执行 SessionStart Hook 加载 CLAUDE.md、重新注入工具和 MCP 指令。这个重建过程保证了压缩后的 Claude 能立即进入有效工作状态。即使摘要和状态恢复都无法覆盖某个细节还有最后一道保障完整的会话转录文件。压缩后的摘要消息里包含一行提示If you need specific details from before compaction (like exact code snippets, error messages, or content you generated), read the full transcript at: /path/to/transcript如果模型在后续推理中发现自己需要某个压缩前的具体细节它可以主动读取转录文件找回原始信息。这是**“按需恢复而非全量重载”**——不会在压缩时就把所有历史都重新加载进来但也不会让信息永久丢失。AutoCompact 工程保障体系熔断器AutoCompact 依赖 Claude API 生成摘要但 API 调用失败的原因可能正是**“上下文太长导致 413 错误”——这是一个逻辑死锁**。熔断器通过计数打破这个循环const MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES 3// 连续失败 3 次后本次会话不再尝试 AutoCompactif (tracking?.consecutiveFailures MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES) { return { wasCompacted: false }}3 次的阈值是经验性参数1 次失败可能是暂时性网络错误值得重试3 次连续失败说明问题可能是结构性的。熔断后用户仍然可以手动执行/compact手动路径有独立的PTLPrompt Too Long重试逻辑会逐步截断最旧的消息组直到压缩请求能够成功const MAX_PTL_RETRIES 3for (;;) { summaryResponse await streamCompactSummary({ messages: messagesToSummarize, ... }) if (!summary?.startsWith(PROMPT_TOO_LONG_ERROR_MESSAGE)) break messagesToSummarize truncateHeadForPTLRetry(messagesToSummarize, summaryResponse)}总结设计亮点Claude Code 的上下文管理有几个值得记住的设计决策。入口管控 三层存量清理。工具结果持久化在内容入库前就拦截超限数据是代价最低的防线仅磁盘写入。存量清理部分代价递进MicroCompact零额外 API 调用清理历史工具结果Session Memory Compact零额外 API 调用复用已有记忆文件压缩整个会话AutoCompact 需要一次额外调用在前两者都不适用时兜底。每一层都在解决上一层解决不了的问题同时接受上一层不愿意承担的代价。缓存感知的压缩操作。MicroCompact 的两条路径cache_editsvs 时间触发清空体现了一个重要的工程意识压缩操作本身不能破坏 Prompt Cache否则省下的上下文空间会被增加的 token 处理成本抵消。这种压缩操作必须对缓存友好的约束在很多系统中是被忽略的。记忆提取的双重复用。Session Memory 既是跨会话知识传递的载体下次会话通过相关性检索注入又是当前会话压缩时的摘要来源Session Memory Compact。同一份数据服务两个目的是副产品转化为主产品的工程复用。结构化摘要 三道质量保障。AutoCompact 不依赖模型自由发挥而是用九章节结构强制覆盖关键信息再用状态恢复最近 5 个文件和完整转录兜底。摘要保留做了什么状态恢复保留现在是什么状态完整转录保留原始细节按需可查。三者分工明确互不重叠。Hook 机制是对不确定性的制度化应对。Anthropic 无法预知所有用户的压缩需求PreCompact Hook 把摘要指令这个变量暴露给用户让用户自己决定压缩时重点保留什么。这是**提供机制而非策略的设计哲学**——系统提供干预点用户填充领域知识。静态/动态边界的精确切分。SYSTEM_PROMPT_DYNAMIC_BOUNDARY和 userContext 的设计把会变化的内容和不会变化的内容精确分开最大化 Prompt Cache 命中率。这不是一个显眼的设计但它影响着每一次请求的成本。普通用户需要关注什么CLAUDE.md 要保持简洁。它通过 userContext 注入到消息历史开头不参与系统提示的缓存每次请求都会消耗 token。只放真正需要每次都提醒模型的内容不要把它当成知识库来用。AutoCompact 触发后早期对话的细节会变成摘要。摘要会保留所有用户消息但中间的工具调用细节会被压缩。对于长任务在关键节点明确告诉模型记住这个约束或者把重要约束写进 CLAUDE.md比依赖模型的记忆更可靠。压缩后模型会自动恢复最近 5 个文件。如果任务涉及很多文件压缩后模型可能无法立即看到所有文件的当前状态。在压缩后的第一轮可以明确告诉模型需要重新读取哪些文件。可以用 PreCompact Hook 定制摘要重点。如果你的项目有特定的信息需要在压缩时重点保留比如某个架构约束、某个正在进行的重构方向可以写一个 PreCompact Hook 脚本在每次压缩时自动注入这些指令而不需要每次手动指定。频繁切换 MCP 服务器会增加成本。连接和断开 MCP 服务器会改变工具定义导致 Prompt Cache 失效。如果不需要某个 MCP 服务器在会话开始前就断开而不是在会话中途操作。学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%免费】