Agent token消耗为何是对话的100倍?拆解成本黑洞与优化实践
发布时间:2026/10/20 6:47:23 锦皓数字建站

1. 一个反直觉的账单为什么你的Agent像个无底洞第一次认真核算Agent的token消耗时我盯着后台数据看了很久一度怀疑是统计口径出了问题。一个看起来只是帮我把这份会议纪要整理成待办清单的任务单次调用居然烧掉了将近四万token。而我手动把同样的内容丢给对话窗口撑死也就两千token出头。差了将近二十倍。这不是个例。后来我陆续复盘了十几个不同类型的Agent项目从简单的文档处理到多轮工具调用的自动化流程结论高度一致Agent的token消耗普遍是同等任务下人肉对话的5到100倍极端情况下甚至更高。标题里说的狠100倍不是夸张修辞而是很多多步Agent在真实负载下的常态。问题在于大多数人根本没意识到这件事。因为Agent跑起来的时候你看到的是它聪明地完成了任务中间那些反复的思考、工具调用、结果回填、自我纠错全都被封装在了一次成功的背后。账单是月底才来的而那时候你已经把这件事忘干净了。这篇内容我想干一件事把Agent烧token这件事彻底拆开讲清楚钱到底花在哪了、哪些环节是隐形的吞金兽、以及怎么在不牺牲效果的前提下把消耗压下来。不管你是刚上手Agent的新手还是已经跑了一段时间但没细算过账的开发者应该都能从中找到几个能立刻用上的点。先说结论省得你往下翻Agent的token消耗大头从来不是你写的那段提示词而是每一轮循环里被反复重发的上下文。理解这一点后面所有的优化才有方向。2. 拆开一次Agent调用token到底流向了哪里2.1 一次简单任务的完整token流水我们拿一个最典型的场景来算账用户让Agent读取一份本地文档总结要点然后根据要点生成三条待办事项。如果这是人肉操作流程很简单打开文档、读一遍、脑子里总结、写出待办。对应到对话模型大概就是一次输入加一次输出。但Agent不是这么干的。它的真实流程通常是这样的系统提示词注入包括角色设定、能力说明、输出格式要求、可用工具列表。这部分每次调用都要带上动辄一两千token。用户请求原始任务描述几百token。第一轮模型思考模型判断我需要先读取文档输出一个工具调用请求。工具执行结果回填文档内容被读进来作为新的消息追加到上下文里。如果文档有五千字这里就是七八千token。第二轮模型思考模型基于文档内容生成总结。第三轮模型思考模型基于总结生成待办。可能的格式修正如果输出不符合要求还要再来一轮。关键在于每一轮调用前面所有的消息都会被重新发送一遍。也就是说到第三轮的时候系统提示词、用户请求、文档全文、第一轮总结全都在上下文里一起被送进模型。这就是为什么单次任务的token消耗会指数级膨胀。2.2 上下文重发最容易被忽视的成本黑洞我用一个具体的数字来说明这个问题。假设系统提示词1500 token用户请求300 token文档内容6000 token每轮模型输出平均500 token如果任务需要4轮模型调用读文档、总结、生成待办、格式校验那么总消耗大致是轮次输入token输出token累计输入第1轮18002001800第2轮2000600080008009800第3轮8800800960060019400第4轮102006001080040030200总计输入约30200 token输出约2000 token。而如果人肉一次性完成输入也就7800 token左右。差了将近4倍而这还是一个相对克制的四轮任务。如果Agent需要调用五六个工具、经历多轮纠错差距轻松拉到十倍以上。这里有个反直觉的点输出token通常比输入token贵好几倍但Agent场景下输入token才是真正的成本主力因为它被反复重发。很多人优化Agent时盯着怎么让模型少说废话方向就偏了。2.3 为什么工具调用是token放大器工具调用本身不直接消耗token但它会强制增加轮次而每一轮都会重发全部上下文。这是它成为放大器的根本原因。一个需要调用三个工具的Agent任务至少需要第1轮模型决定调用工具A第2轮工具A结果回填模型决定调用工具B第3轮工具B结果回填模型决定调用工具C第4轮工具C结果回填模型生成最终答案四轮起步。如果工具返回的结果很长比如网页抓取、数据库查询每一轮都在往上下文里塞新内容后面的轮次输入token会滚雪球一样涨。我见过最夸张的一个案例是一个做竞品分析的Agent它会依次抓取十几个网页、逐个总结、最后汇总。单次任务跑了将近三十轮token消耗直接冲到六位数。用户看到的是一个漂亮的报告账单看到的是一个让人心跳加速的数字。3. 那些让token悄悄翻倍的隐形设计3.1 系统提示词里的安全感陷阱很多Agent的系统提示词写得极其详尽角色设定、语气要求、输出格式、边界条件、示例、反例、注意事项……洋洋洒洒两三千字。写的时候觉得这样模型才听话但没意识到这段文字每一轮都要重发。我做过一个对比测试。同一个任务一份系统提示词1800 token另一份精简到400 token效果差异其实很小——前提是任务本身不复杂。但在一个需要8轮调用的Agent里这1400 token的差距会被放大8倍变成11200 token的额外消耗。精简系统提示词的原则很简单只保留模型无法从上下文推断的信息。语气、格式这些很多时候在用户请求里带一句就够了没必要写进每轮都重发的系统提示。3.2 历史消息全量携带的默认行为大多数Agent框架的默认行为是把完整对话历史全部带上。这在短对话里没问题但在长任务里就是灾难。一个跑了二十轮的任务到最后一轮时前面十九轮的所有内容——包括每一次工具调用的原始返回——全都在上下文里。而这些内容里绝大部分对当前决策已经没有价值了。这里的关键认知是模型不需要看到全部历史它只需要看到与当前决策相关的部分。但默认配置不会帮你做这个筛选你得自己动手。3.3 工具返回结果的原样回填工具调用返回的结果很多框架是原样塞进上下文的。比如你调用一个搜索工具返回了十条结果每条都带标题、摘要、链接、时间戳可能还有一堆元数据。这些内容全部进入上下文然后被后续每一轮重发。但模型真正需要的可能只是其中三条结果的摘要。剩下的七条、以及所有的元数据都是纯浪费。我见过一个Agent调用数据库查询工具返回了完整的JSON包含几十个字段而模型实际只用了其中两个字段做判断。这个JSON在后续五轮里被重发了五次。4. 把token消耗压下来的实操手段4.1 上下文裁剪只留有用的最直接有效的手段就是在每一轮调用前对上下文做裁剪。核心思路是保留系统提示、保留最近N轮对话、保留与当前任务直接相关的工具结果其余全部丢弃或摘要化。具体怎么做取决于你用的框架。但通用的策略有这么几种滑动窗口只保留最近K轮的消息更早的丢弃。简单粗暴适合任务步骤之间相对独立的场景。摘要压缩把较早的对话内容用模型压缩成一段简短摘要替换掉原始消息。适合需要保留长期记忆的场景。工具结果截断工具返回的内容如果超过阈值先做一次摘要或字段筛选再放进上下文。按需检索不把所有历史都带上而是把历史存起来需要时再检索相关片段。我个人的经验是滑动窗口加工具结果截断这两招组合起来能砍掉大部分Agent一半以上的token消耗而且对效果的影响通常很小。4.2 工具结果的预处理别把原始数据直接喂给模型这一条值得单独拎出来讲因为它的收益极高但做的人不多。工具返回的结果在进入上下文之前应该先经过一层处理。处理的目标是只保留模型做决策所必需的信息。举个例子你调用一个天气API返回了完整的JSON包含温度、湿度、风速、气压、紫外线指数、日出日落时间等二十个字段。但你的Agent只需要知道今天会不会下雨。那么预处理就应该只提取降水相关的字段其余全部丢掉。再比如你调用一个文档检索工具返回了十个片段。预处理可以先用一个轻量模型或规则筛出最相关的三个片段再放进上下文。这层预处理本身也要消耗token但它是一次性的而它节省的是后续每一轮的重发成本。在长任务里这笔账非常划算。4.3 减少不必要的轮次让模型一次想清楚Agent轮次多很多时候是因为设计上让模型走一步看一步。但其实有些步骤是可以合并的。比如与其让模型先输出我要调用工具A等结果回来再输出我要调用工具B不如在提示词里引导它一次性规划出需要调用的多个工具然后并行执行结果一起回填。这样能把两轮甚至三轮压缩成一轮。另一个思路是在工具层面做聚合。如果Agent经常需要连续调用某几个工具可以封装成一个组合工具一次调用返回所有需要的结果。模型看到的还是一个工具调用但实际完成了多步操作。注意合并轮次会牺牲一部分灵活性。如果任务本身分支很多、需要根据中间结果动态调整强行合并反而会让模型做出错误决策。这个取舍要根据具体场景判断。4.4 缓存让重复的部分只算一次如果你的Agent有大量重复的前缀比如固定的系统提示词、固定的工具定义可以利用模型服务商提供的提示词缓存功能。缓存命中的部分计费通常只有正常价格的一小部分。这个手段的适用条件是前缀足够长、且在多轮之间保持稳定。系统提示词和工具定义通常满足这个条件所以把它们放在上下文的最前面、并且不要频繁改动就能吃到缓存的红利。我实测下来一个系统提示词加工具定义合计3000 token的Agent开启缓存后这部分成本能降到原来的十分之一左右。在长任务里这个节省非常可观。5. 监控与归因不知道钱花在哪就没法优化5.1 必须记录的几个关键指标优化token消耗的前提是能看清楚消耗。我建议至少记录这几个指标指标说明用途单次任务总输入token整个任务所有轮次的输入之和衡量整体成本单次任务总输出token所有轮次的输出之和衡量模型话量轮次数模型被调用的次数定位轮次膨胀问题单轮最大输入token峰值输入发现上下文膨胀工具调用次数每个工具被调用的次数定位工具滥用缓存命中率缓存命中的token占比评估缓存效果这些指标不需要多复杂的系统在Agent的执行循环里打点记录就行。关键是要按任务维度聚合而不是只看总量。总量只能告诉你花了很多按任务聚合才能告诉你哪个任务花得多、为什么。5.2 用token预算倒逼设计优化我给自己的Agent项目定过一个规矩每个任务类型设定一个token预算上限超了就报警。这个做法一开始很痛苦因为很多任务一上来就超标。但正是这种压力逼着我去做上下文裁剪、工具结果预处理、轮次合并。几轮迭代下来大部分任务的消耗能降到原来的三分之一到一半而效果基本没变。预算怎么定我的经验是先跑一批真实任务统计出token消耗的中位数和P90然后把预算定在P90附近。这样既能覆盖大部分正常任务又能及时抓住异常膨胀的情况。5.3 定位异常消耗的排查路径当你发现某个任务token消耗异常时排查顺序建议是看轮次数是不是轮次特别多如果是问题在任务设计或工具调用逻辑。看单轮输入峰值是不是某一轮输入突然暴涨如果是通常是某个工具返回了超大结果。看工具调用分布是不是某个工具被反复调用如果是可能是提示词没引导好或者工具设计有问题。看缓存命中率是不是缓存没生效如果是检查前缀是否稳定、缓存配置是否正确。这个顺序是从粗到细的能帮你快速缩小问题范围。我踩过的坑是一上来就盯着提示词改改了半天发现真正的问题是某个工具返回了整页HTML。6. 几个真实场景的优化前后对比6.1 文档处理Agent从四万到八千前面提到的那个会议纪要Agent最初的实现是读取完整文档、全文放进上下文、让模型总结、再生成待办。单次消耗约四万token。优化动作有三个文档读取后先做分段只把与待办相关的段落放进上下文其余丢弃。系统提示词从1800 token精简到500 token。总结和待办生成合并成一次调用。优化后单次消耗降到约八千token效果基本一致。关键收益来自文档分段筛选这一项就砍掉了大半。6.2 多工具调研Agent从六位数到五位数那个抓取十几个网页的竞品分析Agent最初单次消耗六位数token。优化动作每个网页抓取后立即摘要只保留摘要进上下文原始HTML丢弃。摘要结果做去重和相关性筛选不相关的直接不进上下文。最终汇总时只带筛选后的摘要不带任何原始内容。优化后降到五位数而且因为上下文更干净最终报告的质量反而更稳定了。6.3 一个反例过度优化导致效果崩坏也不是所有优化都成功。我试过一个极端方案把上下文裁剪得非常激进只保留最近两轮。结果在一个需要跨多步引用早期信息的任务上模型频繁失忆反复重新调用已经调用过的工具token消耗不降反升。这个教训是裁剪策略必须匹配任务的信息依赖结构。如果任务步骤之间强依赖就不能简单丢弃历史得用摘要或检索的方式保留关键信息。7. 关于Agent成本我踩过之后才明白的几件事第一件别用对话思维去估算Agent成本。对话是一问一答Agent是循环加状态。两者的成本模型完全不同用对话的直觉去估Agent一定会低估。第二件优化token消耗和优化效果很多时候方向是一致的。上下文越干净、越聚焦模型的表现往往越好。那些为了保险起见全带上的做法既费钱又容易让模型分心。第三件监控要趁早。我最早做Agent的时候没做token监控等到发现账单异常时已经跑了大半个月根本不知道问题出在哪个环节。后来补上监控才发现最大的浪费来自一个我完全没注意到的工具返回。第四件预算是设计工具不是限制工具。给Agent设token预算本质上是在逼自己想清楚这个任务真正需要什么信息。想清楚这件事消耗自然就下来了。最后分享一个我一直在用的小习惯每上线一个新Agent先拿十个真实任务跑一遍把token消耗和轮次数据拉出来看一眼。如果某个任务的消耗明显偏离预期先别急着上线花半小时排查一下。这半小时往往能省下后面几个月的冤枉钱。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。