
干Agent项目一年多我最大的一个感受是很多团队嘴上说的是优化成本手上做的却是跟Prompt字数较劲。今天这篇内容我想把这个账摊开算清楚——为什么让Agent少踩坑比压缩Prompt更省钱。起因是我带过一个内部工单分类Agent上线跑了两周费用报告出来了数字相当难看。当时我第一反应也是去压缩Prompt案例从五条减到两条工具说明从几十行缩成一句话。账面上确实好看了一点但分类错误率反而从8%飙到21%每天人工返修的工时多了两个多小时。后来跟项目组复盘了一个下午才发现一个很扎心的事实Agent真正的成本黑洞从来不是Prompt太长而是它反复试错、来回绕路、最后还得人来兜底。这篇内容适合这几类人看正在跑Agent项目的开发者为Token费用发愁的负责人还有那些已经觉得Prompt压缩边际收益越来越小的人。我会从踩坑模式、底层设计、一个完整改造案例、排查技巧和成本算法几个角度把整套思路拆开讲。1. 先说省钱这件事到底省在哪1.1 Agent账单上的三大开销正常来讲Agent每处理一个任务钱都花在三个地方。第一有效推理token。这是模型真正理解问题、想清楚怎么做、输出结果的花费属于该花的钱。第二试错token。这一步就耐人寻味了Agent调用工具失败、返回格式不对、绕进死胡同、自己跟自己反复解释每一次失败都在烧token而且往往比正常推理烧得还猛。第三多余上下文token。把历史记录、知识库全文、上一轮的失败原因一股脑塞进来模型看的时候要按输入token全量计费。很多人压缩Prompt压缩的主要是第一类里的字面长度和第三类的一部分但对第二类也就是试错token几乎没有约束力。我见过不少项目Prompt已经压得特别短了账单却没怎么降就是因为Agent的失败轮次一点没少甚至因为Prompt太短导致它更迷茫失败率反而升了。我统计过几个项目试错和纠错相关的token一般能占到总消耗的40%到60%。这个数字很说明问题你每付1块钱给Agent里面有差不多一半是在为错误买单。1.2 压缩Prompt的边际陷阱必须说清楚我不是让大家别压缩Prompt。Prompt精简本身是对的问题在于很多人把它当成了唯一的省钱杠杆。压缩Prompt有一个明显的边际递减规律刚开始从五千字压到三千字效果立竿见影Token成本肉眼可见地降再往下压就开始伤筋动骨了。我自己踩过的几个典型坑是这样的删掉示例后模型的输出格式开始飘。少了一条错误输入示例它就对边界情况没有概念偶尔会给你传一个明显不合理的参数。把CoT步骤从十步精简成三步复杂任务开始跳步推理过程不完整结果质量明显下降。为了省字数把一些约束条件写得过于省略模型理解不到位甚至会自行发挥出一些业务上绝对不能允许的行为。压缩Prompt在本质上是在删信息而Agent的稳定性高度依赖信息完整性。当信息删过头的时候表面上每个token单价低了执行次数却变多了总账反而更难看。这就引出一个关键概念Agent成本不只是Prompt长度的线性函数它是轮次×每轮token的乘积。当你把失败轮次从8次降到2次即使每轮贵一点总成本也在降。2. Agent踩的坑都有哪些特征2.1 典型的五个踩坑模式要让Agent少踩坑先得知道坑长什么样。我把平时见过最多的失败模式整理成了一张表踩坑模式典型表现费钱方式指令漂移跑着跑着开始自行加戏偏离原始目标多做无用轮次容易把后续逻辑带偏工具参数错误日期格式传错、把字符串传成数字、漏必填参数一次失败这次调用的token全白花了上下文污染历史失败记录、无关对话都留在上下文里模型被带偏在一个错误方向上反复努力死循环同一个失败方案换个姿势再来一次直到预算烧穿最烧钱的一种模式过早放弃遇到小挫折就整个任务中断前面步骤全部白做用户还得重新发起指令漂移是很多复杂任务里最隐蔽的问题。Agent一开始还沿着你的目标走跑到第三轮开始自己给自己加戏做一些跟原目标不太相关的事。比如让它整理数据它中途开始给数据做可视化让它做分类它顺手生成了一段报告。这些扩展动作表面上看起来很能干但实际上消耗了额外的轮次而且很容易让任务的最终输出偏离预期。工具参数错误是调用类Agent最常见的问题工具越复杂、参数越多这种错误越频繁。上下文污染的麻烦在于它不会直接报错只会默默影响判断——模型读到一堆垃圾信息很容易被带偏在错误方向上反复努力。死循环和过早放弃则是两个极端前者是太执着后者是太脆弱都让成本失控。2.2 失败是有连锁成本的一个Agent任务失败不是只浪费当次那几轮token。它的连锁成本是这样滚起来的第一次失败触发了自我修正修正又错了继续浪费最终失败然后把这一堆错误历史全塞给下一个任务下一个任务也被污染。每一层都在放大消耗。这也是为什么减少失败率对成本的影响远远超过减少单次token。我做过的项目里一个普通任务如果成功平均两三轮就能结束如果失败平均会跑到八九轮甚至更多。也就是说一次失败的成本大约是成功任务的三到四倍。如果把失败率从20%降到5%省下来的不是15%的成本而是接近一半的无效消耗。这个杠杆效应是没有任何Prompt压缩手段能替代的。2.3 为什么撞运气式调参解决不了问题有些团队的做法是在Agent出错之后改Prompt、调温度参数、换模型但下次遇到类似问题还是错。原因是这些做法没有触及真正的问题结构。举一个真实的例子。Agent把日期格式传错你怎么改Prompt都很难让它每次都记住要传YYYY-MM-DD因为这是模型在生成输出时天然的弱点。但如果你把工具接口改成直接接收已格式化的日期对象或者让它在调用工具之前先经过一道规则校验问题就从根本上消失了。所以让Agent少踩坑不能只靠在字面上劝它别犯错而是要在架构上让错误发生的机会变少。这也是我今天要强调的重点。3. 让Agent少踩坑的五个底层设计3.1 工具设计接口短而准错误消息要说人话先讲工具设计因为这是Agent落地里影响最大、却最容易被忽视的一层。Agent会调用你暴露给它的每一个工具但模型对工具的理解完全来自你的工具描述。描述写得不清楚它一定踩坑描述写得太长它聚焦不了工具参数太多它总会在某个参数上出错。我的设计原则是三条。第一参数越少越好。不要给工具塞五个甚至八个参数能用默认值、能自动获取的就不要让模型猜。参数少了出错面自然就小了。第二错误消息要结构化并且包含下一步建议。很多工具在失败时只给一个Error 500或者调用失败模型看到这种信息根本不知道怎么处理只能瞎试。第三在工具描述里把常见误用写进去。工具描述本身就是一个免费的Prompt它不会增加多少token但能显著降低出错的概率。我贴一个小例子这是一个查询相似工单工具的简化版描述工具find_similar_tickets(query: str, limit: int 3) 说明根据关键词查找历史相似工单用于辅助判断分类。 注意 - query只传核心关键词例如退款失败不要传完整工单内容。 - limit最大为10传大了会被拒绝。 - 找不到结果时返回空列表不代表失败不要重复尝试。这段描述一共不到一百个字但把三个最容易踩的坑都提前堵住了。我在几个项目里都试过工具层描述稍微加几条注意参数错误率能明显降一截而且这部分几乎不消耗token。3.2 上下文管理不该喂的信息就别喂上下文窗口很大不代表可以无脑塞。你喂给模型的一切它都会读、会联想、会被影响。上下文里如果充满了历史失败记录、无关的领域知识、上一轮用户随口说的一句话这些信息都会干扰Agent对当前任务的判断。更关键的是上下文的长度直接决定每次调用的费用。所以上下文管理是少踩坑和省钱的交汇点。我的做法是三条。第一滚动窗口加摘要。最近的几轮对话保留原始信息更早的内容压缩成一个摘要需要时再展开。这样Agent既不会丢失关键背景也不会被远古的噪音带偏。第二按阶段加载上下文。规划阶段只给它规划需要的信息执行阶段再加载具体的数据细节不要一个任务从头到尾都背着一整本手册。第三工作记忆和长期记忆分开。工作记忆放当前任务相关的内容任务结束就清空长期记忆放用户偏好、企业规则、知识库条目按需检索。两类记忆混在一起是上下文污染的高发原因。举一个生活化的类比你让一个新人处理工单你不会把公司十年内的所有聊天记录都丢给他而是告诉他你先看这个工单本身遇到不会的再查知识库。Agent也是同样的道理给它看什么比它有多聪明更重要。3.3 任务拆解改造成Plan-Execute-Check循环很多Agent项目出问题是因为让一个Agent从头到尾负责完整任务中间没有阶段做完就是做完错了就整个重来。更稳的思路是把任务拆成三个环节循环起来先规划再执行最后校验。具体是这样的规划Agent先输出一个简短的步骤列表比如先查工单内容然后判断分类最后给出结论。执行每一步只做一件事只调用一个工具不要并行、不要跳步。校验拿到每一步的结果后比对预期。如果结果异常立刻停下来修正而不是硬着头皮继续下一步。这个循环看起来多了一步校验多花了一点token但换来的稳定性非常可观。错误可以在小范围内被立即拦截而不是等到最后一起爆发。我在一个报表生成Agent上试过这个改造。原来Agent是一条龙式从头跑到尾偶尔出错就要全部重来平均每个任务要跑四到五轮改成Plan-Execute-Check之后绝大多数任务稳定在两轮以内完成token总量反而降了。3.4 路由前置小模型做判断大模型做苦力如果你觉得所有任务都必须用最强的模型才靠谱那你的Agent成本一定会失控。真实场景里很多任务根本不需要大模型——比如判断工单属于网络类还是账户类比如判断一句话是查询还是投诉这类简单意图识别一个便宜的小模型就能做好。我常用的方案是加一层路由前置用户请求先进一个轻量模型它只做一件事——把请求分派给对应的专业Agent或者直接走模板化流程。只有那些确实需要复杂推理的请求才进入大模型Agent的环节。这个方案的好处是显而易见的。大模型的调用次数大幅减少账单直接降一截每个子Agent只处理自己擅长的那类请求指令更聚焦上下文更干净踩坑更少。而且小模型判断意图的准确率其实不低按我的经验大部分场景能到95%以上。这里要提醒一个常见误区有些人想省钱就直接把贵模型整体换成便宜模型。如果任务本身复杂度高换了之后质量掉下来用户就会开始返工、投诉隐性成本反而上来。折中的方案就是路由便宜模型负责选路贵模型负责干活。谁擅长什么就让谁做什么。3.5 失败降级给Agent装一个熔断器没有完美的Agent它一定会犯错。区别在于犯错之后它知道该怎么收拾。我建议给Agent定义一套清晰的降级规则别让它自由发挥。第一重试次数上限。一般同一类失败最多重试两次超过就停止。有些问题重试一万次也不会成功让它重试就是在烧钱。第二降级阶梯。重试失败之后按照预设的路径走先尝试简化版本的任务处理比如只输出部分结果还不行就要求用户确认或者补充信息最后一步转人工处理。第三把放弃也当成一种正常输出。Agent应该能诚实地输出这个问题超出我的能力我已经完成的部分是……而不是假装成功然后输出一个错误结果。在代码层面可以给Agent的执行循环包一层观察者逻辑记录尝试次数超过阈值就自动降级。这个熔断器不复杂十几行代码就能实现但它能把死循环和过早放弃两个极端都控制住。4. 实操记录一个工单分类Agent的省钱改造前面讲了一堆设计原则这里分享一个我在实际工作中做过的完整改造案例。为了叙述方便我把背景稍微简化一些但成本数字和改造思路都是可以直接复用的。4.1 改造前的痛点某公司内部有一个工单分类Agent职责是根据用户提交的工单内容自动判断工单属于哪个类目并分派给对应的处理小组。比如我付了款但没收到订阅应该分给支付组Wi-Fi经常掉线应该分给网络组。改造前这个Agent的架构是这样的一个大模型接收全部工单内容系统Prompt里塞了一份该业务全部的分类规则、客服手册和几个示例上下文里还加载着这个用户近期的所有历史工单。一单下来经常要烧三万多个token分类错误率在20%上下浮动错误工单需要人工重新分派整个流程效率很低。复盘这个项目时我发现问题不是大模型不够聪明而是架构把事情复杂化了所有工单都进同一个大模型模型的上下文里混着各种类型的知识它在判断网络问题时会受到支付问题规则的干扰上下文里塞满了用户历史工单大部分跟当前工单无关纯属噪音工具里的知识库查询参数特别宽泛模型经常查回一堆不相干的内容。4.2 改造方案与落地步骤我把它改成了四层结构。第一步加路由层。入口先过一个轻量模型根据工单标题和内容做一个粗分类网络、账户、支付、其他四类。这一步用小模型单次成本极低响应也快。第二步拆子Agent。每一类工单对应一个专项Agent每个专项Agent的系统Prompt只包含本类别的规则和典型场景。比如支付Agent不需要知道Wi-Fi怎么修网络Agent也不需要理解退款流程。上下文一下子就干净了。第三步工具瘦身。把查历史相似工单工具的query参数改为只传核心关键词并且加上了上面那种注意提示把查用户信息工具改成直接接收用户ID而不是让模型自己去解析。第四步校验层。分类结果在返回给用户之前过一道规则校验。比如支付类工单必须带有订单号网络类工单必须有关键设备词。不满足校验就要求Agent重新处理最多重试两次两次还不对就转人工。整个改造的代码工作量其实不大主要是把原来的单一大模型调用改成了路由加多个轻量Agent再加了一小段校验逻辑。4.3 改造效果与账本改造之后我跑了三周的数据来做对比单次处理token从平均三万左右降到了不到一万分类错误率从20%左右降到了4%到5%每千张工单的token总成本下降了一大截人工返工量减少了大部分这部分省下的工时比token费用还值钱。特别要说的是token成本下降的原因不是Prompt变短了而是每单跑的轮次变少了。很多工单在路由层就直接被分派了根本轮不到大模型出场需要大模型处理的工单上下文也干净了Agent不再反复试错。这个案例让我彻底相信了一件事架构上的少犯错优化效果远远超过文字层面的压字数。5. Agent出问题时按这四层来排查设计方案是一回事线上出问题还是不可避免。关键是怎么快速定位。我自己用的是一个四层归因法每次Agent表现不对都会按这个顺序检查。5.1 四层归因法第一层指令层。先看Agent收到的原始指令是什么是否存在歧义、缺少背景、例子没有覆盖到。很多时候问题根本不是模型不行而是你给它的指令本身就带着坑。第二层工具层。检查工具调用记录看模型是不是传了错误的参数、调用了错误的工具还是工具本身返回了模糊的报错。这一层的特征是有明确的技术错误日志好定位。第三层上下文层。看上下文里有没有被无关信息污染有没有该有的信息但没加载进来。上下文问题很隐蔽因为它不会直接报错只会默默影响决策。第四层策略层。看Agent是不是没有正确的重试策略遇到失败就死循环或者一失败就放弃。策略层的问题通常表现为轮次数异常token消耗曲线突然拔高。几乎所有的Agent异常都能归到这四层里。定位到层之后改动方式就清晰了指令层就改Prompt工具层就改工具设计和校验上下文层就改加载逻辑策略层就加重试和降级机制。5.2 用结构化日志做事故回放排查的前提是得有日志可以看。我见过很多Agent项目上线后连基本调用记录都没有出了问题只能靠猜。这是绝对不可取的。我在项目里习惯给每次Agent执行记录一份结构化日志字段包括步骤号、当前动作、调用的工具、工具输入、工具输出、token数、是否成功。就这一个简单做法排查效率直接上一个台阶。大致结构是这样的{ step: 3, action: call_tool, tool: find_similar_tickets, input: {query: 退款失败}, output: {matched: 2}, token_count: 812, success: true }出问题时拿着这份日志回到现场就能准确看到每一步发生了什么是哪一层的错误花了多少token。没有这份日志优化就永远是盲人摸象。5.3 常见问题速查表我把日常运维中遇到的几个高频问题整理成一张速查表现象优先排查位置常见处理Prompt已经压得很短费用还是没降策略层/工具层看看是不是有死循环或高频重试Agent偶尔输出格式不规范指令层补一条边界示例或者加校验换了便宜模型后质量下降明显指令层/上下文层不要整体换改成路由方案上下文不大但总是判断失准上下文层检查是否加载了不相关的历史内容Agent老是重复调用同一个工具策略层加最大重试次数和降级阶梯工具调用时报参数错误工具层精简参数补充常见误用提示这张表是我日常排查的起点大多数问题照着这个顺序走一遍很快能找到根因。6. 这笔账怎么算才能说服自己和老板如果你正在推动Agent架构改造领导首先会问一句这么做能省多少钱我建议建立一套简单的成本对比模型不要用感觉省了很多这种回答。6.1 一个可复用的成本对比公式先定义几个基础变量T平均每轮调用的token数R成功成功任务的平均轮数R失败失败任务的平均轮数通常远高于成功任务F任务失败率。每100次任务的总token消耗可以近似算成成功任务的消耗是(1-F)×100×T×R成功失败任务的消耗是F×100×T×R失败总成本等于两者相加。这个公式的价值在于它把两类钱拆开了一类是正常干活的钱另一类是为失败付的钱。你会发现优化失败率F和失败轮数R失败比优化单轮token数T敏感得多。原因很简单R失败往往是R成功的三到四倍失败率哪怕只是降几个百分点总成本的降幅都会被放大。6.2 三套方案的同口径对比下面用这个公式模拟一下三种方案。假设某个Agent任务每次调用平均token是1万成功任务平均2轮失败任务平均8轮。方案A基线失败率20%。100次任务的总token是(1-0.2)×100×1万×2 0.2×100×1万×8算下来160万加160万总共320万。方案B压缩Prompt单轮token降30%但失败率升到30%。总token是0.7×100×0.7万×2加0.3×100×0.7万×8也就是98万加168万总共266万。方案C架构优化单轮token略涨20%因为多了路由和校验开销但失败率降到5%。总token是1.2×100×1.2万×2加0.05×100×1.2万×8也就是228万加48万总共276万。方案单轮token失败率每100次任务总tokenA 基线1万20%320万B 压缩Prompt0.7万30%266万C 架构优化1.2万5%276万有意思的地方来了光看总token方案C和方案B差不多甚至C还略高一点。但方案C的真实优势体现在隐性成本上。6.3 隐性成本往往才是大头Agent失败的隐性成本包括但不限于人工返工的时间、用户体验下降造成的用户流失、错误结果上线后的修复费用、以及团队反复排查问题消耗的精力。这些隐性成本有一个特点不出现在账单里但实实在在地影响收益。方案B虽然token表面省了一点但失败率更高了意味着每天都有相当数量的工单需要人工返工按时薪一折算立刻超过省下来的token钱。方案C失败率低人工介入少体验稳定这部分省下来的钱远超账面差异。所以每次别人问我到底怎么给Agent省钱我都会说一句话先别盯着Prompt那几行字先把失败率打下来。让Agent少踩坑省下来的不是某一个token而是一整条错误链上的所有浪费。写到这里我再回头想那个工单分类Agent的事。当初为了省一点点token去压缩Prompt反而让失败率飞涨、人工救火忙成一片的做法其实是个典型的捡了芝麻丢西瓜。我现在做Agent项目会先花大量精力在工具设计、上下文管理、路由策略这些让人不犯错的细节上最后才考虑Prompt要不要缩。这并不花太多钱却能把Agent的成功率稳住。如果你也正在为Agent的成本发愁我建议你先去查一下你的失败率和重试次数答案可能一眼就出来了。