第 27 轮崩了:AI Agent 长对话降本 70% 的 7 大上下文工程技术
客户在线等着,Agent 报了 prompt_too_long,会话中断。
这不是极端场景。一个中等复杂度的客服 Agent,加上工具调用、RAG 召回、用户上传的截图 OCR,跑 25 轮上下文就能从 8K token 涨到 118K——再多两轮,直接撞墙。
这不是模型的问题,也不是上下文窗口不够大的问题。是你送进去的 token 里,有太多是废的。
Anthropic 在 2025 年 9 月专门发了一篇工程文章定义这件事——Context Engineering(上下文工程)。不是怎么写 prompt,而是每一轮 LLM 调用时,进入上下文的每个 token 是否都值得它的成本。
这是 Prompt Engineering 解决不了的问题。它发生在更底层,影响也更大。
一个真实的生产事故
先把问题的规模感建立起来。
这是一个电商客服 Agent 的单次会话 token 增长曲线:
| 轮次 | 累积 Token | 主要构成 |
|---|---|---|
| 1 | 8K | system prompt + 用户首问 + 工具列表 |
| 5 | 18K | + 5 次工具调用结果(订单详情、物流轨迹) |
| 10 | 35K | + RAG 召回的退款政策(每轮都在召回) |
| 15 | 62K | + 用户上传 3 张订单截图的 OCR 结果 |
| 20 | 95K | + 工具调用累积、Memory 召回累积 |
| 25 | 118K | ⚠️ 接近 Claude 128K 上限 |
| 27 | ❌ | prompt_too_long,会话中断,客户在线等着 |
这是生产事故,不是演示 Bug。
然后工程师开始修:
| 修法 | 结果 |
|---|---|
| 加滑动窗口(只保留最近 10 轮) | 答非所问——用户在第 1 轮说的订单号,第 15 轮被丢了 |
| 改全量摘要压缩 | 成本翻了 4 倍——KV Cache 命中率从 92% 骤降到 3% |
| 工具返回 200KB 数据直接塞进上下文 | 单条工具结果直接撑爆 |
| 摘要 prompt 写得太简单 | LLM 失忆——把用户名记错了 |
每一个"修法"都制造了新的问题。
这 4 个坑,是绝大多数做过长对话 Agent 的开发者都踩过的。本文接下来讲的,是把这 4 个坑填上之后的完整方案。
为什么上下文越长越贵、越长越蠢
Token 对 Agent 有两种成本,大多数人只在意了第一种。
财务成本是显性的——按百万输入 Token 计费,多步 Agent 循环里快速累积。30 轮对话下来,单次调用的 token 量是第 1 轮的十几倍。
认知成本是隐性的,也更危险。Transformer 的注意力机制要计算 n² 对的关系,n 是 token 数量。上下文越长,每个 token 分到的"注意力配额"越少。你塞进去的信息越多,模型对每一条的记忆越差。
Anthropic 把这个现象命名为 Context Rot(上下文腐化):随着 token 数增长,模型准确召回上下文信息的能力持续下降。不是到上限才突然崩,而是从第一轮就开始的缓慢劣化曲线。
所以把上下文窗口从 128K 扩到 200K,解决不了根本问题——只是把撞墙推后几轮,Context Rot 照样在发生。
Anthropic Applied AI 团队给出的核心结论:
“Find the smallest possible set of high-signal tokens that maximize the likelihood of the desired outcome.”
不是让模型看更多,而是让模型少看、看对的。
上下文不是一段 Prompt,是 6 个组件的工程视图
把上下文理解成"一段越来越长的 prompt"——这个认知直接决定你会优化错方向。
上下文是每次 LLM 调用时即时组装的工程视图,由 6 个来源、生命周期完全不同的组件构成:
本次 LLM 请求的 Context├── System Prompt(系统指令 + 工具列表)← 静态,KV Cache 友好├── Memory 召回(历史记忆检索结果) ← 动态,每轮可能不同├── RAG 召回(知识库检索结果) ← 动态,每轮不同├── 历史消息(对话记录序列) ← 累积增长,主要压力来源├── 工具返回值(本轮工具调用结果) ← 体积不可预测,可能很大└── 当前用户输入(本轮) ← 最新,绝对不能压缩
6 个组件,各有各的生命周期,各有各的压缩策略。把它们当成一整段文本统一处理——这是大多数 Agent "莫名变贵、莫名变蠢"的根源。
| 维度 | 把上下文当 prompt | 把上下文当工程视图 |
|---|---|---|
| 优化对象 | 整段文本一刀切 | 每个组件独立优化 |
| 压缩策略 | 统一处理 | 各组件不同策略 |
| KV Cache | 不在意 | 静态前缀必须保住 |
| 故障隔离 | 出错时整锅倒 | 每个组件独立可调试 |
| 成本归因 | 只知道总 token | 知道每个组件占多少 |
更关键的一点:四类失败(召回不准、上下文膨胀、摘要丢信息、缓存失效)在外部表现完全一样——LLM 回答变差了。混在一个黑盒里,你永远找不到根因。分层,才能分层调试。
技术一:Token 预算四象限
控制成本的第一步,是主动分配预算,而不是被动等着溢出。
以 Claude 128K 为例,留出 28K 安全余量,工作预算是 100K:
高静态性 低静态性 ┌──────────────────┬─────────────────────────┐ 高优先级 │ System Prompt │ 当前用户输入 + 工具返回 │ │ 约 10K │ 约 25K │ │ 工具列表 + 角色设定 │ 本轮新增内容,不可压缩 │ ├──────────────────┼─────────────────────────┤ 低优先级 │ 历史消息 │ RAG / Memory 召回 │ │ 约 40K │ 约 25K │ │ 累积最快,压缩收益最大 │ 控制 top_k,限制单条长度 │ └──────────────────┴─────────────────────────┘
四个象限对应四种处理策略:
- • 高静态 + 高优先级(System Prompt):绝对不压缩,保住 KV Cache 命中基石
- • 低静态 + 高优先级(当前输入 + 工具返回):不压缩,用预算硬保
- • 高静态 + 低优先级(历史消息):累积最快,压缩收益最大,走压缩管线
- • 低静态 + 低优先级(RAG/Memory 召回):从源头控制,限制检索 top_k 和单条长度
超预算时的让步顺序(写进代码,不是约定):
历史消息 → RAG 召回 → System Prompt → 永不压缩当前用户输入和工具返回值
每次组装上下文时,输出一份预算报告——出问题时一眼看出哪个象限失控了:
{ "session_id": "sess_001", "turn": 27, "budget_total": 100_000, "budget_used": 87_500, "breakdown": { "system": 9_800, "history": 38_200, "rag": 18_500, "current_input": 350, "tool_results": 20_650, }, "compactions_applied": ["snip", "microcompact"], "cache_anchor_intact": True,}
💡 这部分建议收藏——预算四象限是上下文管理的思维框架,比任何单项技术都重要。
技术二:七步压缩管线
这是整篇文章的核心。
绝大多数开发者在上下文超预算时,会选两种方案之一:滑动窗口(丢信息)或全量摘要(成本爆炸)。这两种都是极端。真实工程需要的是从轻到重的代价梯度。
核心原则:能截断就不摘要,能轻量压缩就不全量摘要。
AgentLoop 调用 LLM 之前 ↓步骤 1:工具结果预算检查 单条工具返回值超阈值(如 8K token) → 替换为 Reference ID + 本地摘要(不调 LLM,成本 0) ↓(还超预算?)步骤 2:Snip(截断,成本 0) 历史消息中过长的工具返回值就地截断 保留头尾,中间用 [... truncated ...] 替代 ↓(还超预算?)步骤 3:Microcompact(缓存友好压缩) 只压缩缓存锚点之外的部分,锚点之前一字不动 → KV Cache 命中率保持不变,这是关键 ↓(还超预算?)步骤 4:Context Collapse(折叠) 把"用户问→助手调工具→工具返回→助手答"4条消息折叠为1条 ↓(还超预算?)步骤 5:System Prompt 重组 ↓(还超预算?)步骤 6:Autocompact(全量摘要,最后手段)⚠️ 把 N 轮历史摘要成一段文字 → KV Cache 全废,成本倒灌 ↓(仍超预算?)步骤 7:ContextOverflow 阻断 抛异常,交给业务层处理
七步代价对比:
| 步骤 | 信息损失 | 额外 LLM 成本 | 缓存破坏 | 延迟 |
|---|---|---|---|---|
| 1 工具结果预算 | 低 | 0 | 否 | <10ms |
| 2 Snip | 中(截断中间) | 0 | 否 | <10ms |
| 3 Microcompact | 中 | 1 次小调用 | 否(关键) | ~500ms |
| 4 Context Collapse | 中高 | 1 次中调用 | 部分 | ~1s |
| 6 Autocompact | 高 | 1 次大调用 | 是(核心代价) | ~3s |
七步管线的全部价值,就是尽可能不走到第 6 步。 Autocompact 一旦触发,KV Cache 全废,下一轮 API 调用费用直接倒灌。很多开发者不明白为什么"摘要完成本反而涨了"——原因就在这里。
Context Collapse(步骤 4)的折叠效果大概是这样:
折叠前(约 780 token): user: 帮我查订单 2026052001 assistant: [调用 query_order 工具] tool: {status: "运输中", logistics: "顺丰", eta: "今晚20:00", ...} assistant: 您的订单正在运输中,预计今晚 20:00 到达折叠后(约 80 token): [已处理交互] 用户查询订单 2026052001;结论:运输中,顺丰,今晚20:00到
单次折叠节省约 90% 的 token,且信息完整保留。
技术三:Reference ID 模式
工具返回值是上下文膨胀速度最快、最容易被忽视的来源。
一次数据库查询可能返回 500 条记录,一个文件读取可能返回 200KB 文本,一个搜索工具可能带内容地返回 20 条结果。这些数据全塞进上下文,3 轮就能把 100K 的预算打满——而且其中 95% 的内容,在那一轮之后再也不会被用到。
做法:超过阈值的工具返回值,不进上下文,改存 Redis,只留一个 Reference ID 和本地摘要。
# 工具返回值处理逻辑(伪代码)TOOL_RESULT_THRESHOLD = 8_000# token 数阈值defhandle_tool_result(result, session_id): if estimate_tokens(result) > TOOL_RESULT_THRESHOLD: # 超过阈值:存外部,上下文里只放摘要 + 引用 ID ref_id = store_to_redis(result, session_id, ttl=1800) return { "content": ( f"[大结果已外挂. ref_id={ref_id}]\n" f"摘要: {local_summary(result)}\n" f"如需完整内容: fetch_full_result(ref_id='{ref_id}')" ) } else: # 未超阈值:正常注入 return {"content": result}
配套需要给 Agent 一个 fetch_full_result 工具,让它在需要完整数据时自行拉取。但工具描述里要显式劝退:
【使用场景】摘要信息不足以回答用户问题时使用。【不适用】摘要已经够用时请勿调用,避免浪费 token。
这个"劝退"不是摆设——大部分情况下,摘要已经包含了模型做决策所需的信息,全量数据是不必要的。显式劝退能有效减少模型的"习惯性"全量拉取。
技术四:KV Cache 边界维护(最容易被忽视的成本杠杆)
这一节是本文含金量最高的部分,但也是大多数 Agent 工程教程完全不讲的内容。
KV Cache 是什么: OpenAI、Anthropic、DeepSeek 都有 Prompt Cache 机制——前缀字节级完全一致的请求,KV 计算结果会被缓存,后续请求直接复用,不重新计算。
各家 cache 命中的折扣:
| 模型 | 未命中 | 命中 |
|---|---|---|
| Claude | 1.0× | 0.1×(省 90%) |
| GPT-4o | 1.0× | 0.5×(省 50%) |
| DeepSeek | 1.0× | 0.25×(省 75%) |
对于一个 system prompt 有 1 万 token 的 Agent,KV Cache 命中与否,意味着这 1 万 token 的成本差了 10 倍。
什么动作会破坏 KV Cache:
- • system prompt 改了任何一个字
- • 工具列表顺序变了(一定要排序稳定)
- • 历史消息中间插入或修改了内容
- • 用摘要替换了历史消息——这是 Autocompact(第 6 步)的主要代价
最后这条就是为什么"全量摘要把成本砍了"这个说法是错的——摘要确实缩短了上下文,但它同时破坏了 KV Cache,下一轮的 system prompt 要重新全量计算,实际成本反而可能翻倍。
Microcompact 的设计精妙之处:
Microcompact(七步管线第 3 步)的核心思想,就是保住缓存边界:
缓存状态(前缀完全一致,可命中 KV Cache):[system][m1][m2][m3][m4] | [m5][m6][m7][m8][m9][m10] ↑ ↑ ↑已缓存的前缀 缓存锚点 当前末尾Microcompact 只压缩:[m5][m6][m7][m8][m9][m10] 保持:[system][m1][m2][m3][m4] 一字不动→ 下次请求:[system][m1][m2][m3][m4] 前缀完全一致 → 继续命中 KV Cache
实测效果:从粗暴全量摘要(Autocompact)切换到 Microcompact 后,KV Cache 命中率从 3% 拉回 89%,单次 token 成本降到原来的 1/3。
RAG 注入的一个常见错误:
很多开发者会把 RAG 召回的文档拼进 system prompt——理由是"系统知识,应该放系统里"。这是错的。
每轮 RAG 召回的内容不同,只要 system prompt 发生变化,整个缓存前缀就失效了,后面无论历史消息多长都无法命中缓存。
正确做法:system prompt 保持完全稳定,RAG 召回结果作为每轮独立的附加消息注入。
技术五:不要用简单 Prompt 做摘要
当不得不走到 Autocompact(全量摘要)时,摘要的质量决定了 Agent 会不会"失忆"。
最常见的反例 prompt:
请将以下对话历史摘要为 200 字以内的总结。{history}
这个 prompt 的输出大概是:
用户咨询了订单问题,客服提供了帮助,处理了退款申请。
——关键订单号、金额、用户名、reference_id 全部丢失。第 30 轮,Agent 开始用错误的名字称呼用户。
生产级摘要 prompt 需要做三件事:
1. 显式白名单(必须保留的实体):
必须保留的实体,原文照抄:- 所有订单号(纯数字格式)- 所有金额(含币种)- 所有时间日期- 用户提到的姓名、地址、电话- 所有 reference_id(toolres_ 开头)
2. 显式黑名单(允许省略的内容):
可以省略:- 客套话、寒暄- 重复出现的相同信息- 已被后续操作覆盖的旧状态(如旧地址被新地址覆盖)
3. 强制结构化输出:
输出格式(必须严格遵守):[关键事实]:逐条列出所有必须保留的实体[处理过程]:用户做了什么、助手做了什么(顺序叙述)[当前状态]:还在等什么、下一步是什么
加入这三条约束后,"失忆型幻觉"率从 12% 降到 1.5%。
技术六:检索是预算决策,不是自动管道
大多数 RAG 实现是这样的:用户输入 → 触发检索 → 召回 top-10 → 注入上下文。这里有两个隐性浪费,加在一起往往占了 RAG 成本的一半以上。
浪费一:每轮都检索,不管有没有必要。 用户追问"刚才那个订单号多少来着",上下文里明明有答案,RAG 还是跑了一趟,召回 10 条文档,全部注入——这一轮的检索 token 完全是净浪费。
浪费二:召回 top-10,真正有用的只有 1-2 条。 那 8 条不相关的文档在上下文里占着位置,既烧 token,又稀释了注意力权重,让模型对真正有用的那两条更不专注。
我自己在一个知识问答 Agent 上测过:把 RAG 从 top-10 改成"召回后评分过滤、只保留相似度 > 0.7 的块",平均每轮注入从 4,200 token 降到 680 token,回答准确率反而提高了——因为去掉了那些相关度不高但会干扰模型的块。
两个具体改进:
Post-retrieval Filtering(召回后过滤):注入上下文之前对每个召回块打相关性分,设一个阈值,低于阈值的直接丢弃。是成本优化里单位实施成本最低、收益最大的操作之一。
Agent-Controlled Retrieval(按需检索):不要每轮自动触发检索,改成让 Agent 自己决定什么时候需要查知识库。只有推理链真正遇到知识空白时才触发,召回精准度大幅提升,无效注入基本消失。代价是要求模型的 tool-use 能力足够稳定,不会忘记在应该检索的时候检索。
技术七:把预算意识注入 Agent 自身
前六个技术都是外部工程控制。最后一个,是让 Agent 自己有预算意识。
Anthropic 在官方工程文章中专门提到了一个被大量忽视的技术:在 Agent 的上下文里告诉它自己还剩多少预算。
# 在每轮组装上下文时,把预算状态告诉 Agentbudget_message = { "role": "system", "content": f"[当前会话状态] 已用 {used_tokens:,} / {budget_total:,} token," f"剩余 {remaining:,} token。" f"{'请开始精简回答,优先完成关键步骤。' if remaining < 20_000 else ''}"}
当 Agent 知道自己的预算状态时,它会自然地开始更精简地使用工具、更早做出决策、在快耗尽时主动报告进度而不是继续探索。这个技术几乎不增加任何工程成本,但能让 Agent 的行为更像一个有成本意识的工程师。
综合效果:月度账单能降多少
把 7 个技术叠加,成本能降到什么量级?
以下是一个参考 ROI 计算(月处理量 100 万 tokens,Claude Sonnet 定价,数据来源:生产案例综合统计,实际结果因业务场景差异较大):
| 优化项 | 月度节省 | 说明 |
|---|---|---|
| 优化前基准 | $9,000/月 | 50万输入 + 50万输出,无任何优化 |
| 语义缓存(70% 命中率) | −$4,530 | 相似请求复用,是单项最大贡献 |
| Prefix Caching(80% 重复率) | −$1,800 | system prompt 前缀命中 KV Cache |
| 上下文压缩(七步管线,50% 压缩率) | −$1,350 | 历史消息 + 工具结果压缩 |
| 优化后 | ≈$1,320/月 | 节省约 85% |
这些数字来自真实部署中多个 Agent 的叠加效果,但不是保证值。不同业务的 token 分布差异很大——对话密集型 Agent(客服、导购)的优化空间通常比任务执行型(代码生成、数据分析)更大。
两件事是确定的:长对话支持能力从 25 轮 → 200+ 轮;KV Cache 命中率从 3% 到 89%,成本差距是实打实的 3 倍。
Anthropic 对长任务的三个建议
最后补充 Anthropic 工程团队在官方文章里,专门针对长任务(跑几十分钟甚至几小时的任务)给出的三个策略,和七步管线互补:
Compaction(滚动压缩):接近上下文上限时,把历史摘要后开一个新的干净窗口继续跑。适合需要大量来回对话的任务。这就是七步管线里 Autocompact 的宏观版本。
Structured Note-Taking(结构化笔记):让 Agent 主动把关键信息写入外部文件(比如 NOTES.md),按需调回。好处是持久化成本极低,召回灵活。Anthropic 用这个技术让 Claude 在 Claude Plays Pokémon 里跨越数千步和多次上下文重置,自主追踪地图和战略状态。
Sub-Agent 分工:专业子 Agent 处理专注任务,完成后只返回 1,000-2,000 token 的摘要给主 Agent。子 Agent 可能消耗数万 token 做深度工作,但主 Agent 始终保持干净的上下文。Anthropic 自家的多 Agent 研究系统用的就是这个方案,在复杂研究任务上"远优于单 Agent 系统"。
三种技术适用不同场景,选型参考:
| 场景 | 推荐策略 |
|---|---|
| 需要大量来回对话的任务 | Compaction(滚动压缩) |
| 有明确阶段里程碑的开发任务 | Structured Note-Taking |
| 需要并行探索的复杂研究/分析 | Sub-Agent 分工 |
| 以上都有 | 组合使用 |
行动清单
如果你的 Agent 现在还没做上下文工程,按优先级来:
第一周(立竿见影):
- • 给 system prompt 加 Prefix Cache 标记(Claude:
cache_control,OpenAI: 自动) - • 把 RAG 召回从 system prompt 里移出来,改为每轮独立消息
- • 给工具列表排序固定化,避免顺序变化破坏缓存
第二周(核心防护):
- • 实现工具返回值阈值检测,超过 8K token 走 Reference ID 模式
- • 实现 Token 预算监控报告,每轮打印各组件占比
- • 实现 Snip(步骤 2)——最小成本,第一道防线
第三周(工程级):
- • 实现 Microcompact(步骤 3)——保住 KV Cache 命中率的关键
- • 写生产级 Autocompact Prompt(白名单 + 黑名单 + 结构化输出)
- • 给 Agent 注入预算状态消息
把这三周做完,你的 Agent 大概率不会再在第 27 轮崩掉了。
写在最后:名字之前,问题就在
Context Engineering 这个词,Anthropic 在 2025 年 9 月才给它命名。但这个问题本身,从第一个人做 Agent 就存在了——只是之前叫"上下文管理"或"token 优化",没有一套系统的框架。
有了名字和框架的价值不在于概念本身,而在于它让你能把分散的技术手段归拢到同一个问题维度下讨论。知道"这是 KV Cache 边界问题"和"这是压缩管线没有做分层",才能对症下药,而不是在无数可能的原因里瞎猜。
我的判断是:2026 年做生产级 Agent 的工程师,Context Engineering 会是像数据库索引一样的基础能力——不是加分项,而是不做就一定出问题。
学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%免费】

更多推荐


所有评论(0)