账单从 300 涨到 3000:你的 Agent 在烧钱而不是干活
上个月一个朋友跑来找我,说他用 LangChain 写了个客服 Agent,每天处理大概 2000 条消息。月初看账单 300 多,月中开始飙升,月底一看快 3000 了。他第一反应是「模型涨价了」,查了价格表发现没涨。又怀疑是用户量涨了,后台数据一看,日活根本没动。
问题出在他写的 Agent 循环里:每次用户问一句,Agent 要把历史对话全部重新发给 GPT-4o,再加上工具返回的完整 JSON,一条消息平均消耗 8000 个 token。更离谱的是,他给每个工具调用都包了一层「反思」提示词,让模型自己评价自己的输出对不对。一个简单查询,模型要来回调用三次工具,每次调用都带上 2000 字的系统提示词。
这不是个例。我见过太多人把 API 花费失控归结为「模型太贵」,实际是代码写得浪费。token 是 Agent 的燃料,但绝大多数开发者对 token 的消耗完全没有概念。你写一行 messages.append() 很容易,但每次 append 进去的几千字,都是真金白银。
拿他那个客服 Agent 举例,最基础的优化是改消息历史策略。原代码把 20 轮对话全量塞给模型,改成只保留最近 5 轮,加上一个「用户意图摘要」字段。就这么一个小改动,token 消耗直接降了 60%。账单从 3000 回到 1200,效果还更好了,因为模型不再被 8000 字的历史干扰判断。
你手头如果也有 Agent 在跑,先别急着换便宜模型。打开你的日志,算一下平均每轮对话消耗多少 token,再对比一下你实际需要的上下文长度。多数时候,问题不在模型定价,在于你让模型看了太多不该看的东西。
模型选型:不是所有任务都配得上 GPT-4o
很多人写 Agent 的时候,全程用一个模型,从意图识别到工具调用到最终回复,全部走 GPT-4o。这就像开着一辆 6.0 排量的皮卡去便利店买瓶水——能到,但油钱够你买十瓶。
我现在的做法是三层模型策略。第一层,意图识别和简单分类,用 gpt-4o-mini 或者 claude-3-haiku,这类任务单次输入不超过 500 token,输出只要一个 JSON 标签,mini 模型完全够用,价格是 4o 的 1/30。第二层,工具调用的参数提取,用 gpt-4o-mini 配合强约束的 JSON Schema,准确率能做到 95% 以上。第三层,只有最终生成回复的时候才用 gpt-4o 或 claude-sonnet,因为这一步需要语言质量和逻辑连贯性。
以 Hermes Agent 为例,在 ~/.hermes/config.yaml 里可以这样配置模型路由:
models:
router: gpt-4o-mini # 意图识别,便宜
extractor: gpt-4o-mini # 参数提取,快
generator: gpt-4o # 最终回复,贵但值得
实际跑下来,一个典型的客服对话里,70% 的 token 消耗在 router 和 extractor 上,但成本只占 8%。真正花钱的是 generator,但你没法省,因为那才是用户感知到的质量。
另一个容易忽略的点是模型版本。Claude 3.5 Sonnet 在工具调用上比 GPT-4o 便宜 30% 且准确率更高,适合任务型 Agent。如果你的 Agent 主要做结构化数据操作(查数据库、调 API),Sonnet 是性价比之王。如果你的 Agent 偏创意写作或长文生成,GPT-4o 的连贯性更好,多花的钱值。
最后说一个反直觉的结论:不要为了省钱把生成模型换成 mini。用户能明显感知到回答质量的下降,然后你花更多时间调 prompt 去弥补,时间成本也是成本。省钱的正确姿势是让 mini 干杂活,让大模型只做它擅长的事。
上下文窗口:token 消耗的隐形黑洞
我见过最夸张的案例,有人给每个 Agent 都塞了 3000 字的系统提示词,包含公司介绍、产品手册、客服话术、禁忌词列表,甚至还有品牌色的 RGB 值。每次调用都把这 3000 字原封不动发出去,一天 5000 次调用,光系统提示词就烧掉 1500 万 token。
上下文窗口管理是成本控制的核心。你每发一个 token 给模型,不管它用不用,钱都照扣。所以原则很简单:只发模型完成任务所必需的信息。
Hermes Agent 的技能系统(~/.hermes/skills/)就是干这个的。你可以把不同任务需要的知识拆成独立技能文件,按需加载。比如一个技能文件 order_refund.yaml,只在用户问退款相关问题时才加载,平时不占上下文。
skills:
order_refund:
trigger: ["退款", "退货", "换货"]
context_file: ~/.hermes/skills/refund_policy.md # 只有触发时才加载
这样做的效果立竿见影:普通问题只需要 500 token 的上下文,退款问题才加载 2000 字的政策说明。平均上下文长度从 3500 token 降到 800 token,成本直接砍掉 75%。
另一个技巧是「对话压缩」。当对话超过 10 轮时,用 mini 模型把前面的内容总结成 200 字的摘要,替换掉原始历史。Hermes 的 memory 命令可以自动做这件事,配置里设置压缩阈值:
memory:
compression_threshold: 10 # 超过10轮开始压缩
summary_model: gpt-4o-mini # 用便宜模型做摘要
还要警惕一个陷阱:函数返回结果。你调一个天气 API,返回 50KB 的 JSON,里面可能只有 3 个字段有用。在把结果传给模型之前,先做一次结构化提取,只保留关键字段。Hermes 里可以用 response_filter 配置:
tools:
weather:
response_filter: ["temperature", "condition", "humidity"]
这 50KB 的 JSON 不会进模型,模型只看到 3 个字段。省下的 token 不是小数目——一个 50KB 的 JSON 大约等于 12,500 token,而过滤后的 3 个字段不到 20 token。差了 600 倍。
缓存与重试:别为重复计算付两次钱
很多 Agent 的调用模式里,同一段上下文被反复发送。比如每天早上 9 点的定时任务,系统提示词和用户需求基本不变,只有日期和数字在变。你每次都全量发送,模型每次都重新计算,费用照收。
OpenAI 在 2024 年 8 月推出了 Prompt Caching,同一个前缀超过 1024 token 的部分,缓存命中后价格打 50%。Anthropic 的缓存更便宜,Cache hit 的输入价格是 miss 的 1/10。用好了,成本直接砍半。
关键是要让请求的前缀稳定。你写代码的时候,把系统提示词放在 messages 数组的最前面,保持完全一致,不要在里面拼时间戳或随机数。用户消息放在后面,这样前面的大段提示词就能稳定命中缓存。
Hermes Agent 里可以这样配置缓存策略:
llm:
cache:
enabled: true
min_prefix_tokens: 1024 # 低于这个长度不启用缓存
cache_ttl: 300 # 缓存有效时间(秒)
再一个是重试机制。API 偶尔会超时或返回 429,很多人直接重新调用一次,相当于多付一次钱。正确做法是开启自动重试,但带指数退避。Hermes 内置了重试逻辑:
llm:
retry:
max_attempts: 3
backoff_base: 2.0 # 第一次失败等2秒,第二次4秒,第三次8秒
retry_on: [429, 500, 503]
重试时还有个省钱技巧:如果第一次调用因为超时失败,但请求已经到达服务器且开始计算了,你重试时会重复计费。所以超时时间别设太长,5 秒就够。超过 5 秒直接放弃重试,别等 30 秒超时,那 25 秒的 token 已经烧掉了。
还有一类重复计算来自「同一问题反复问」。用户问「你们营业时间是什么?」Agent 每次都要调模型生成答案。这种高频固定问题,直接做一层静态答案缓存——用 hermes cron create 定时把常见问题的答案预生成好,存到内存里,命中就直接返回,连 API 都不用调。
工具调用:每个多余的工具都在烧钱
你的 Agent 里注册了多少个工具?我见过有人给 Agent 挂了 30 多个工具,从查天气到订机票到算房贷。每次模型决定调用哪个工具,它都要把工具描述全部读一遍——30 个工具的描述加起来几千 token,模型每轮都要重新看一遍。
工具调用的 token 消耗常常被忽略。模型需要先「思考」用哪个工具,再把参数填好,这分两步走:第一步生成工具调用的 JSON,第二步你拿到结果后再发回给模型让它继续。每一步都是完整的 API 调用,每一步都按输入和输出 token 双向计费。
优化方向有两个。第一,精简工具数量。把 30 个工具合并成 5 个,比如「查询订单」「修改订单」「取消订单」三个工具合并成一个 order_operation,用 operation 参数区分。工具描述变短了,模型的选择准确率反而更高,因为干扰项少了。
第二,工具描述要写「触发条件」而不是「功能介绍」。Hermes 的工具配置里,description 字段直接决定模型会不会选它。你写「查询天气信息」不如写「当用户问到天气、温度、降雨、台风时使用」,后者让模型更精准地触发,避免误调。
tools:
weather_query:
description: "当用户提到天气、温度、降雨、风力、空气质量时,调用此工具获取实时气象数据"
parameters:
city: string
第三,用「并行工具调用」。OpenAI 和 Anthropic 都支持在一条消息里同时调用多个工具。如果你让 Agent 查「北京和上海明天哪个适合出游」,它需要同时查两个城市的天气。如果不支持并行,它得先查北京,拿到结果,再查上海,两次往返。支持并行的话,一条消息就搞定,省一半的往返 token。
Hermes Agent 在配置里开启并行:
tools:
parallel_calls: true
实测效果:并行开启后,多城市查询场景的 token 消耗降低约 45%,响应时间缩短 60%。
最后,给每个工具加一个 cost_hint 字段,标注调用这个工具的平均成本。Hermes 会把这个信息传给模型,让模型在低成本工具和高成本工具之间做取舍。比如查数据库只要 2 分钱,调第三方金融 API 要 5 毛钱,模型会倾向于先用数据库。
定时任务与批处理:把高频调用变成低价调用
你的 Agent 如果跑定时任务,比如每小时检查一次库存、每天生成一份报表,这些任务的特点是:输入输出结构固定,但频率高。每一次调用都是全价,积累下来是一笔不小的开销。
用 hermes cron create 创建定时任务时,注意几个省钱配置。第一,尽量把任务安排在模型价格低谷时段。OpenAI 的 batch API 有 50% 折扣,Anthropic 也有类似机制。Hermes 支持 batch 模式:
hermes cron create --name daily_report \
--schedule "0 2 * * *" \
--batch-mode true \
--model claude-sonnet
batch 模式的任务最长 24 小时内返回结果,但价格便宜一半。适合日报、周报、数据同步这类不要求实时性的任务。
第二,定时任务之间共享上下文。如果你有 5 个定时任务都用到同一个系统提示词,把它们合并成一个任务,内部循环处理 5 个业务。这样系统提示词只发一次,而不是 5 次。
第三,用「流式输出」处理长响应。如果你的 Agent 要生成 3000 字的报告,普通模式是一次性返回,按 3000 token 计费。流式模式下,模型边生成边返回,虽然总 token 数一样,但你可以在生成到 80% 时判断「质量不达标」,提前中断,省下最后 20% 的钱。Hermes 里设置 stream: true 即可。
还有一个容易忽略的点:定时任务的失败重试。默认设置下,任务失败会立即重试,如果 API 持续报错,你会连续扣费。建议设置最大重试次数为 2 次,且间隔至少 10 分钟。宁可让这次任务失败,等下一个周期再跑,也别在 5 分钟内重试 10 次。
最后,给定时任务加 cost_limit_per_run 字段,比如单次任务成本上限 1 元。Hermes 会在执行前预估成本,超过上限直接跳过。这能在 API 价格变动或 prompt 意外变长时保护你的钱包。
监控与告警:先知道钱花哪了,再谈省钱
不看账单的省钱都是耍流氓。你需要实时知道每个 Agent、每个技能、每个模型各花了多少钱。Hermes 内置了用量统计,每 10 分钟记录一次 token 消耗,按模型、技能、时间三个维度聚合。
查看当日消耗:
hermes cost report --today
输出示例:
模型 输入token 输出token 费用(元)
gpt-4o 1,234,567 234,567 187.32
gpt-4o-mini 890,123 67,890 12.45
claude-sonnet 456,789 89,012 56.78
合计 2,581,479 391,469 256.55
设置预算告警,超过阈值自动通知。配置文件 ~/.hermes/config.yaml:
cost_control:
monthly_budget: 1000
alert_threshold: 80% # 用掉800元时告警
alert_channel: webhook # 支持 webhook/email/飞书
webhook_url: "https://your-server.com/alert"
告警不是终点,关键是告警后你要能定位到问题。Hermes 的 hermes cost trace 命令可以追踪单次对话的完整 token 流向:
hermes cost trace --conversation-id abc123
你会看到每一步的消耗明细:系统提示词 2000 token、历史消息 4500 token、工具返回 12000 token、最终生成 800 token。一眼就能看出哪个环节在烧钱。
我用的一个实操技巧:每周一早上跑一次 hermes cost report --weekly,对比上周的数据。如果某类技能的成本环比涨了 30% 以上,基本可以断定是新增了某个工具调用或系统提示词被改长了。这时候用 hermes cost trace 查那个技能最近的对话,90% 的情况能找到问题。
监控的意义不是事后算账,而是让你形成「成本直觉」。当你写代码的时候,能预判到「这一步会多发 2000 token」,你的 Agent 成本自然就下来了。这种直觉来自对数据的持续观察,没有监控,你永远在盲飞。
💬 你用过哪些AI工具?
说到最后,想问问你手头现在用的是哪家的模型?GPT-4o、Claude 还是开源的 Llama?有没有遇到过账单失控的情况,又是怎么解决的?
我最近在研究 AI Agent 的成本优化时,发现一个叫 AI House 的排行榜(aibunkhouse.com/rankings/),上面有各种模型在真实任务上的性价比对比,不是官方宣传的那种跑分,而是用户实际体验后的反馈。你可以上去看看自己用的模型排第几,顺便给用得顺手的模型投一票。投票的人多了,排名会更接近真实情况,下次选模型的时候可以参考。
另外,你如果跑过 Agent 的定时任务,可以试试 Hermes 的 hermes cron create 配合 batch 模式,能省一半钱。有什么好用的省钱技巧,也欢迎交流。
常见问题 / FAQ
账单从 300 涨到 3000:你的 Agent 在烧钱而不是干活
上个月一个朋友跑来找我,说他用 LangChain 写了个客服 Agent,每天处理大概 2000 条消息。月初看账单 300 多,月中开始飙升,月底一看快 3000 了。他第一反应是「模型涨价了」,查了价格表发现没涨。又怀疑是用户量涨了,后台数据一看,日活根本没动。 问题出在他写的 Agent 循环里:每次用户问一句,Agent 要把历史对话全部重新发给 GPT-4o,再加上工具返回的完整 J...
模型选型:不是所有任务都配得上 GPT-4o
很多人写 Agent 的时候,全程用一个模型,从意图识别到工具调用到最终回复,全部走 GPT-4o。这就像开着一辆 6.0 排量的皮卡去便利店买瓶水——能到,但油钱够你买十瓶。 我现在的做法是三层模型策略。第一层,意图识别和简单分类,用 gpt-4o-mini 或者 claude-3-haiku,这类任务单次输入不超过 500 token,输出只要一个 JSON 标签,mini 模型完全够用,价...
上下文窗口:token 消耗的隐形黑洞
我见过最夸张的案例,有人给每个 Agent 都塞了 3000 字的系统提示词,包含公司介绍、产品手册、客服话术、禁忌词列表,甚至还有品牌色的 RGB 值。每次调用都把这 3000 字原封不动发出去,一天 5000 次调用,光系统提示词就烧掉 1500 万 token。 上下文窗口管理是成本控制的核心。你每发一个 token 给模型,不管它用不用,钱都照扣。所以原则很简单:只发模型完成任务所必需的...
缓存与重试:别为重复计算付两次钱
很多 Agent 的调用模式里,同一段上下文被反复发送。比如每天早上 9 点的定时任务,系统提示词和用户需求基本不变,只有日期和数字在变。你每次都全量发送,模型每次都重新计算,费用照收。 OpenAI 在 2024 年 8 月推出了 Prompt Caching,同一个前缀超过 1024 token 的部分,缓存命中后价格打 50%。Anthropic 的缓存更便宜,Cache hit 的输入价...
工具调用:每个多余的工具都在烧钱
你的 Agent 里注册了多少个工具?我见过有人给 Agent 挂了 30 多个工具,从查天气到订机票到算房贷。每次模型决定调用哪个工具,它都要把工具描述全部读一遍——30 个工具的描述加起来几千 token,模型每轮都要重新看一遍。 工具调用的 token 消耗常常被忽略。模型需要先「思考」用哪个工具,再把参数填好,这分两步走:第一步生成工具调用的 JSON,第二步你拿到结果后再发回给模型让它...