资讯动态

Agent 上下文管理详解:Prompt Caching、压缩与记忆

发布时间:2026/10/14 17:30:02 来源:尧图企业网站定制
前言Agent 基座系列第五篇。第一篇的循环里每一步都把完整历史重发一遍。跑十个八个工具调用没事但真实的 Agent 任务动辄几十上百步——上下文窗口会满账单会更惊人。本篇讲上下文管理的三板斧Prompt Caching 管省钱压缩Compaction管窗口记忆Memory管跨会话。三件事解决的是三个不同维度的问题组合起来才能跑长任务。一、问题上下文是怎么涨没的每一步都在追加循环的每一轮追加一条 assistant 消息和一条 tool_result。工具结果是绝对大头——一次数仓查询返回几千 token一次文件读取几百到几千 token。计费是平方级放大模型无状态第 N 步的请求要携带前 N-1 步的全部历史。30 步任务、每步新增 2K token第 30 步的请求输入就是 ~60K全程累加的输入 token 是 1K2K…60K ≈93 万 token。跑一个任务烧掉百万级输入 token就是这么来的。窗口是硬顶上下文窗口如 200K / 1M一旦占满请求直接报错任务死在半路。缓存救不了窗口——它只降价不减体积。二、第一板斧Prompt Caching省钱不省窗口原理前缀精确匹配服务端把请求前缀缓存下来下次请求如果从第一个字符起逐字节一致命中部分按原价 1/10 计费。任何一处变了一个字符从那之后的缓存全部作废。断点放置请求的渲染顺序是tools → system → messages稳定的部分必须排前面responseclient.messages.create(modelMODEL,max_tokens16000,toolsTOOLS,system[{type:text,text:SYSTEM_PROMPT,# 稳定内容放 systemcache_control:{type:ephemeral},# 在稳定前缀末尾打断点}],messagesmessages)# 对话尾巴自动增量缓存验证是否命中别猜看响应字段response.usage.cache_read_input_tokens 0才是真的命中了。上线后把这个字段打进日志每天看一眼。静默失效排查清单缓存失效不报错只有账单知道。四个常见凶手system prompt 里有datetime.now()、随机 id、请求序号——每次都变每次都 miss中途改了 tools 列表加一个工具 从头作废中途切了模型对话历史被原地编辑只有追加是安全的。Agent 场景下缓存命中后输入成本普遍降一半以上这板斧是必开的。三、第二板斧压缩救窗口触发时机监控usage.input_tokens超过阈值经验值窗口的 70%触发一次压缩。做法摘要替换原文把早期历史发给模型总结成一段结构化摘要用摘要替换原始消息任务在摘要之上继续defcompact(messages,client):summary_prompt把以上对话总结成接续任务所需的上下文必须保留 1. 用户的原始目标和所有硬性约束口径、格式、命名要求 2. 已完成的事项清单和关键结论含具体数字、文件路径 3. 当前进行到哪一步、下一步计划 4. 踩过的坑和明确不能再做的事 丢弃原始工具输出全文、中间探索过程、已否决的方案细节respclient.messages.create(modelMODEL,max_tokens4000,messages[*messages,{role:user,content:summary_prompt}])summarynext(b.textforbinresp.contentifb.typetext)return[{role:user,content:fsummary\n{summary}\n/summary\n\n请继续执行任务。}]保留什么、丢什么最重要的一段压缩的质量取决于摘要提示词。原则结论和约束全保过程和原文全丢。具体数字、文件路径、任务目标丢一条后面就全歪了而工具返回的原始文本90% 在后续步骤用不上。服务端压缩的坑Claude API 的服务端 compaction 会返回带加密信息的 compaction 块回传时必须原样保留丢掉或改写会导致后续请求被拒。自研压缩没有这个约束但要自己保证摘要质量。四、第三板斧记忆跨会话压缩解决不了跨会话压缩是会话内的手段。关掉终端明天再开一个新会话模型对昨天的一切一无所知——messages从空开始。设计给模型一个记忆目录把记忆做成文件目录 几个文件操作工具让模型自己决定什么值得存mcp.tool()defmemory_write(name:str,content:str)-str:把一条长期有效的信息写入记忆。只存用户偏好、项目关键决策、 环境配置。不存一次性任务细节、临时状态。pathMEMORY_DIR/f{name}.mdpath.write_text(content)returnf已写入{path}mcp.tool()defmemory_list()-str:列出已有的记忆条目。会话开始时调用恢复历史上下文。return\n.join(p.nameforpinMEMORY_DIR.glob(*.md))索引式结构防膨胀记忆文件本身也会变成上下文负担。生产验证有效的结构是目录 索引一个MEMORY.md索引文件每条记忆一行标题 一句话钩子每次会话自动加载正文按主题拆成独立.md文件模型按需读取不默认全量进上下文。这正是 Claude Code 的CLAUDE.md memory 目录的设计思路。写入纪律记忆不是越多越好。判断标准这条信息下次会话还会用吗用户偏好、项目决策、环境配置——存任务过程、中间状态——不存。有疑问时不存less is more。五、三板斧组合手段作用域解决什么代价Prompt Caching每次请求输入成本1/10 价几乎无压缩会话内窗口溢出丢过程细节记忆跨会话状态持久化索引要维护组合策略缓存常开 逼近上限触发压缩 会话收尾沉淀记忆。一个管理良好的长任务 Agent配合前几篇的循环和工具层跑到几百步不炸窗口、单任务成本可控是完全可以做到的。参考资料Prompt CachingClaude 官方文档Context Editing本系列第一篇《从零手写 Agent 基座》

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑