我让 Agent 批处理 5000 条数据发现上下文压缩根本行不通做了上下文压缩、摘要、滑动窗口——全试了Agent 反而越来越笨。最后发现不是压缩算法的问题是 Agent 的执行模式和压缩天然互斥。起因想做一个能自己读 Excel 的智能 Agent项目需求很简单门店有几千行不规范的商品数据需要用 AI 匹配到总部标准库或者标准化后输出。最初的想法很直觉——给 Agent 装几个工具让它自己搞定工具 - read_excel(path) → 读文件 - search_products(query) → 搜索总部商品 - web_search(query) → 联网搜商品信息 - write_excel(data, path) → 输出结果 Agent 拿到任务把这个 Excel 里的所有商品标准化第一步就爆炸了。Excel 有几千行Agent 一次性读完上下文直接撑爆。于是改成让 Agent 分批读取文件再到后来发现分批之后会膨胀用压缩来处理。压缩上线后Agent 的行为变得诡异引入中间件压缩之后Agent 的行为开始变得无法理解明明搜到了正确结果最终输出却是空的某些行的商品名写到一半就开始编最诡异的是处理到第 300 行左右Agent 突然重新搜索第 17 行的商品——那条数据一个多小时前就处理过了Agent 在失忆而且它自己知道自己在失忆于是陷入了一个死循环上下文膨胀 → 压缩 → 信息丢失 → 发现不对 → 重新搜索 → 更膨胀 → 再压缩 → 更多丢失...翻日志找到了根因仔细看了几轮完整执行的日志后发现了一个和预期完全不同的执行模式。我想象中 Agent 应该这样做逐行完成行 1: 搜索 → 处理 → 输出 ✓ 行 2: 搜索 → 处理 → 输出 ✓ 行 3: 搜索 → 处理 → 输出 ✓Agent 实际上是这样做的按工具并发read_batch(第 1 批, 50行) → search_products(行1) search_products(行2) ... search_products(行50) 50 个向量搜索同时发出 → search_by_barcode(行1) search_by_barcode(行2) ... search_by_barcode(行50) 50 个条码搜索同时发出 → web_search(行1) web_search(行2) ... web_search(行50) 50 个联网搜索同时发出 → LLM 尝试在一条消息里生成 50 行的结果...Agent 的并发工具调用机制倾向于把一批数据里所有行的同一个工具一次调完。这个执行模式对压缩是致命的压缩算法只能判断一条消息在对话里的位置是否靠前无法判断它是否已经被充分使用过。当中间件按时间顺序压缩旧消息时行 1 的搜索结果被压缩时行 1 还没有完成。它只做完了搜索还没轮到综合和生成。压缩之后行 1 丢失了具体搜索内容。剩下的摘要可能是行 1 搜索完成有 3 个候选——但具体是哪 3 个、每个的规格是什么全丢了。Agent 无法继续处理行 1。信息不全它要么跳过这一行要么重新搜索。但此时上下文早已面目全非。经过多次压缩后Agent 已经不记得它原本要处理的是这 50 行商品数据上下文被稀释成了零散的语义片段。深层矛盾在这里上下文压缩的隐含假设是早期消息对当前决策不再关键——这在对话里成立10 轮前的你好不重要。但批处理场景里每行数据的中间结果对产出最终输出都至关重要——压缩等于把没完工的东西的施工图纸扔了。解决方案不压缩直接消灭上下文既然压缩怎么调都失败换个思路——不让上下文积累for 每一行 in Excel: agent 新建 Agent(thread_idfitem-{i}) # 全新上下文 result agent.invoke(处理这一个商品: {row}) save(result) # agent 销毁 → 上下文消失 → 零累积用ThreadPoolExecutor并发跑四个这样的单行 Agent。核心洞察不是在 Agent 内部管理上下文让它不膨胀而是从外部杜绝上下文的积累。每行的 Agent 只见过一件商品开始时空的结束时销毁。不需要压缩因为根本没有需要压缩的东西。那对话 Agent 的上下文压缩能用吗当然能用。对话 Agent 的上下文管理有成熟的套路方案做法适用场景滑动窗口只保留最近 N 轮旧消息直接丢弃闲聊、简单问答LLM 摘要对旧消息做总结把摘要拼到新消息前面需要长程记忆的对话结构化记忆维护事实列表用户偏好、关键决定等每次只更新列表有明确用户画像需求的场景混合方案摘要 窗口旧消息摘要最近几轮完整保留最常用这些方案之所以能工作是因为对话里每轮的产出是自包含的完整回答——压缩掉第 10 轮的对话不会让第 11 轮的对话变成半成品。总结数据批处理 Agent 的上下文问题解决办法不是更好的压缩而是隔离。Agent 的并发工具调用虽然是性能红利但也让它天然不适合逐行完成的批处理模式。如果你需要保证每行完全处理后才能开始下一行把这个保证放在 Agent 外面——用外部循环调度一个个只有单行上下文的小 Agent。系列文章第一篇Agent 批处理中上下文压缩为何失败本文第二篇给 Agent 的工具加了默认参数它反而更笨了第三篇从 LLM-only 到 Agent一个商超项目的架构选型完整项目代码GitHub