Compaction:让Agent长时间跑下去的上下文压缩术 Agent 能不能长时间跑下去最终都会撞上同一个问题上下文窗口是有限的。一次任务刚开始时模型能看到完整的 System Prompt、用户需求、工具结果和中间推理。跑久之后对话历史越来越长工具输出越来越多再大的 context window 也会被填满。这时候就需要 Compaction把旧上下文压缩成更短、更结构化、仍然足够有用的摘要让 Agent 继续往下跑。Compaction 不是一个简单的“把历史变短”功能。它牵涉到压缩策略、触发时机、Token 预算、Prompt Cache、种子文件重新注入以及 Agent loop 本身怎么设计。先搞清楚一个问题压缩不是记忆很多人把Compaction和Memory混在一起说。它们是两件完全不同的事。Compaction解决的是单session内的上下文溢出。你跟Agent聊了50轮对话历史越来越长200K的context窗口快装不下了。Compaction就是把这个对话历史压缩一下让它能继续跑下去。Memory解决的是跨session的信息共享。你今天用Agent改了一个API的接口规范明天开新session的时候你不希望它又从零开始。Memory就是把这些偏好、决策、踩过的坑持久化下来下次启动时加载。一个是同一次对话里的生存问题一个是多次对话间的延续问题。类比一下Compaction像你收拾行李——箱子快塞不下了你得把旧衣服压缩成真空袋腾出空间放新东西。Memory像你搬了新家之后把老家带过来的东西分类放进不同的柜子——下次找的时候不用回老家翻。两者的技术手段也完全不同维度CompactionMemory目的维持单session内上下文不溢出跨session的信息共享和积累触发时机Context使用率到阈值时自动触发新session启动时加载存储方式通常在当前会话链路内生效MD文件/SQLite/向量数据库信息流向对话历史 → 摘要历史 → 提炼 → 持久化用户感知Agent输出质量可能突然波动新session记得之前的偏好搞清楚这个区别之后我们聚焦Compaction。压缩策略保留关键原文压缩中间过程不同 Agent 框架的压缩策略不一样但有一个共性思路——不是一刀切地删掉前面的对话而是有选择地保留关键信息。一种常见的策略是这样的头部关键上下文保留原样——这部分通常是 System Prompt、最初任务目标、项目背景、用户偏好。它们决定 Agent 到底在做什么尾部最近上下文保留原样——这是最近的对话、工具调用结果、待办事项和当前卡点。它们决定 Agent 下一步怎么做中间过程压缩为摘要——这部分是过去做了但已经不那么重要的执行轨迹。可以交给一个 LLM 调用把长对话压缩成结构化摘要这个策略的直觉很简单。你回忆一下自己处理一个长任务的过程——你不需要记住每一分钟的细节但你一定记得最开始的目标和现在做到哪了。中间的过程你只需要一个结构化摘要就够了。这里的头部/尾部/中间不是固定比例。20%60%20% 只是一个容易理解的示意。真实系统会根据模型上下文窗口、当前任务长度、工具输出大小和摘要质量动态调整。压缩时机优先不打断 Agent loop一个关键设计问题是到底什么时候压缩如果每次调用 LLM 之前都无脑压缩会导致上下文割裂感。你想象一下——Agent 正在执行一个复杂任务中间调了好几个工具正要推理下一步突然 context 被压缩了。它之前仔细分析的中间结果全变成了摘要信息密度骤降。这时候 Agent 的输出质量可能会突然变差因为它丢失了关键细节。用户看到的现象就是Agent前面一直很聪明突然变傻了然后又慢慢恢复。体验很差。所以一个稳妥原则是能在 Agent loop 一轮结束后压缩就尽量在轮后压缩。Agent loop是什么简单说就是Agent接收用户请求→规划→调工具→观察结果→继续推理→最终回复这个完整周期。一轮结束后触发压缩通常更合理原因有三个多数任务的一轮 loop 能在当前 context 内跑完——尤其是没有读取超大文件、长日志、批量网页内容的时候信息是完整的——轮结束时任务已经完成了一个完整阶段。这时候压缩不会打断思路不会有割裂感——用户收到的是完整的回复压缩发生在后台用户无感知但这不是绝对规则。如果下一次 LLM 调用已经必然超过上下文窗口系统就必须在调用前压缩哪怕这发生在一个大任务中间。更准确的说法是压缩时机要在不中断推理和不超过上下文窗口之间做权衡。Token预算后验 usage 很有用但不能替代前置预算知道了什么时候压缩还差一个前置问题——怎么知道该压缩了你总得知道当前 context 用了多少 token才能判断是否到了阈值比如 80% 或 95%。这个问题看起来简单其实是个挺有意思的工程问题。方法一字符数÷4这是最快的估算方法。原理是在英文语境下大约4个字符≈1个token。统计当前messages的字符总数除以4再除以模型的context window大小比如200K就知道使用率了。优点极快零开销。缺点不准。不同语言、代码、JSON、Markdown、工具输出的 token/字符比例差别很大。如果你只依赖这个方法到了该压缩的时候可能没压缩context 直接爆了。方法二Tokenizer用模型对应的tokenizer比如tiktoken对整个messages做精确分词计数。优点准确。缺点有成本。现在的 Agent 一轮对话可能涉及几十个文件、几十次工具调用messages 非常长。每次调 LLM 之前都跑一遍完整 tokenizer会带来额外开销。不过在真正接近上下文上限时这个成本通常是值得的。方法三API返回的 usage这是很重要的后验信号。每次调用LLM API返回结果里都会带一个usage字段。以Anthropic为例usage: { input_tokens: 152348, output_tokens: 2048, cache_creation_input_tokens: 120000, cache_read_input_tokens: 32348 }OpenAI的类似usage: { prompt_tokens: 152348, completion_tokens: 2048, total_tokens: 154396 }Agent loop 结束后最后一次 LLM 调用返回的usage.input_tokens、prompt_tokens或类似字段能告诉你刚刚这次请求服务端实际看到了多少输入 token。这比字符数估算可靠得多也适合作为压缩阈值判断的输入。但它不是当前 session 总消耗 token 数也不应该用total_tokens来判断下一轮输入是否会超窗因为total_tokens还包含输出 token。真正要控制的是下一次请求将发送给模型的输入上下文长度。方法速度准确度适用场景字符数÷4极快不准误差累积首轮粗估Tokenizer慢准确不适合频繁调用API usage直接可用对刚刚那次请求准确Agent loop结束后的后验判断比较稳的做法是混合使用平时用字符数或增量计数做快速粗估接近阈值时用 tokenizer 或模型服务返回的 usage 校正一轮 loop 结束后用最后一次 usage 判断是否需要后台 compaction下一次调用前仍然检查即将发送的 messages 是否可能超过模型窗口所以这里不能把某一种计数方法当成放之四海皆准的答案。正确的是把 token 预算放到 Agent loop 的生命周期里看调用前防止超窗调用后校正实际用量轮结束时决定是否压缩。为什么这些东西是一体的Prompt Cache聊到这儿你可能会觉得Compaction是个独立的问题。其实不是——它跟Prompt Cache和上下文组织方式关系很密。Prompt Cache 是 LLM 提供商Anthropic、OpenAI、Google 等做的一个优化如果多次请求的 prompt 前缀相同可以复用之前计算的结果降低延迟和成本。这类缓存通常和前缀匹配有关。简单说越稳定、越靠前的 prompt 部分越适合被缓存越动态、越靠后的部分即使变化也只影响后面的缓存命中。这跟Compaction有什么关系关系大了。当你设计一个Agent系统的时候Skill元信息放在哪直接影响缓存效率放在System Prompt放在User MessageSystem ReminderSkill增减→System Prompt变化→缓存全废System Prompt不变→缓存持续有效每次都要重新处理整个System Prompt只有动态部分需要重新处理所以设计 Agent 上下文时一个常见原则是稳定内容尽量放在前面动态内容尽量放在后面。这样 System Prompt、长期规则、项目说明这些稳定部分更容易命中缓存Tools、Skills、检索结果、当前任务上下文这些动态内容变化时对缓存的破坏范围更小。这套设计形成了一个完整的闭环System Prompt保持稳定→ Prompt Cache持续命中动态部分Tools/Skills放在后面→ 即使失效token开销小Agent loop结束后优先触发Compaction→ 用 API usage 校正实际输入规模压缩后重新注入种子文件→ 恢复项目规则、用户偏好、长期记忆等关键上下文每一个设计选择都不是孤立的它们互相支撑。实际系统里怎么落地不同 Agent 框架的 compaction 细节差异很大。有些是公开文档能确认的有些只能从源码或运行行为推断不能混在一起当成确定事实。以 Claude Code 为例官方文档能确认的是• 支持/compact手动压缩当前对话• 支持 auto-compact在上下文接近上限时自动压缩• 官方成本文档提到 auto-compact 通常在 context 超过约 95% 时触发• hooks 里有PreCompact事件可以区分 manual 和 auto compaction这些信息能证明 Claude Code 有自动压缩机制也能证明它的触发阈值很靠后。但它具体怎么选择原始消息、摘要、种子文件重注入比例公开文档没有把所有内部细节讲完。写文章时最好把“公开可确认”和“源码/经验推断”分开。对任何 Agent 系统来说落地时都可以按这几项检查维度需要回答的问题触发阈值到多少 context 使用率开始压缩是否区分软阈值和硬阈值触发时机优先轮后压缩还是调用前压缩超窗时怎么兜底压缩策略保留哪些原文哪些变摘要工具输出怎么处理恢复机制压缩后是否重新加载项目规则、用户偏好、长期记忆、任务计划Token 预算调用前怎么估算调用后怎么用 usage 校正用户感知压缩是否会导致 Agent 突然忘记当前任务是否需要提示用户这个表比硬背某个框架的实现更有用。因为不同模型、不同 API、不同工具调用模式下最优压缩策略会变。写在最后Compaction不是功能是约束的产物拆完这些我有一个很深的感受。Compaction不是因为我们需要一个压缩功能而设计的。它是因为大模型有两个硬约束——context窗口有限、API调用无状态——所以你不得不压缩。所有围绕Compaction的设计选择——保留策略、触发时机、Token估算、缓存联动——全都是在这些约束下做权衡。• 头部关键上下文常常需要保留是因为 System Prompt 和任务目标丢了Agent 就不认识自己了• 优先 Agent loop 结束后触发是因为这样更不容易打断推理用户感知也更平滑• API usage 很重要是因为它能校正实际输入规模但调用前仍然需要预算• 动态内容尽量放后面是因为前缀稳定性直接影响 Prompt Cache 的命中范围每一个选择都不是最佳实践而是在特定约束下的最优解。下次再设计 Compaction别急着说前20%后20%保留。先想清楚三个问题什么时候压缩→ 优先 Agent loop 结束后即将超窗时必须调用前压缩怎么判断该压缩了→ 调用前预算 调用后 usage 校正压缩后怎么恢复→ 重新注入项目规则、长期记忆、任务计划和最近状态这三个答案背后是context有限、API无状态、缓存按prefix匹配这三个硬约束。理解了约束答案就自然出来了。学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%免费】