Agent 跑起来 API 费暴涨?工作流控成本 6 个技巧
普通聊天一次请求几十个 token,Agent 多轮对话 + 反复调工具,一个任务轻松吃掉几千 token。上线前不控成本,月底账单能吓一跳。下面 6 个技巧都是工程里踩过坑后总结的,按顺序用就能把费用压下来。
技巧一:限制最大轮数
Agent 最常见的烧钱原因是「停不下来」——模型一直调工具、一直追问。先用max_turns兜底:
MAX_TURNS=8# 超过就强制收尾turn=0whileturn<MAX_TURNS:resp=client.chat.completions.create(model="YOUR_MODEL",messages=messages,tools=tools)ifnotresp.choices[0].message.tool_calls:breakturn+=1技巧二:上下文只留必要的
每轮都把完整历史发给模型,token 随轮数线性增长。把早轮的工具结果裁剪掉:
deftrim_messages(messages,keep_last=6):"""只保留最近若干条,旧的工具结果摘要化"""returnmessages[-keep_last:]# 大结果先摘要再入上下文messages.append({"role":"tool","tool_call_id":cid,"content":result[:500],# 超长结果截断})技巧三:分类和路由用便宜模型
「这句话要不要调工具」「归到哪类任务」这类判断,不需要强模型。用 gpt-4o-mini 做路由,强模型只干重活:
router=OpenAI(api_key="YOUR_KEY",base_url="YOUR_BASE_URL")kind=router.chat.completions.create(model="gpt-4o-mini",messages=[{"role":"user","content":f"分类:{user_text}"}],)# 复杂才交给 YOUR_MODEL技巧四:开 Prompt Caching 命中共用前缀
Agent 的系统提示、工具 schema 每轮都重复发。把它们放前面并标cache_control,相同前缀命中缓存,输入费大幅降:
messages=[{"role":"system","content":SYSTEM_PROMPT,"cache_control":{"type":"ephemeral"}},# 缓存这段*dynamic_messages,]技巧五:工具返回先截断再回传
数据库查询、文件读取经常返回几千字,全塞进上下文最费钱。工具侧就做裁剪:
| 返回类型 | 处理 |
|---|---|
| 列表 | 只回前 N 条 + 总数 |
| 长文本 | 截断到 500 字 |
| JSON | 只回需要的字段 |
技巧六:设预算上限 + 实时监控
给单次任务设 token 硬上限,超了就中止并降级:
fromcollectionsimportCounter budget=20000# 单任务 token 上限used=Counter()defguard(model,messages):ifused[model]>budget:returnNone# 超预算,降级到缓存答案r=client.chat.completions.create(model=model,messages=messages)used[model]+=r.usage.total_tokensreturnr同时把每次调用的 token 记到日志,按任务维度汇总,哪类任务贵一目了然。
成本对照(示意)
| 做法 | 单任务 token | 相对 |
|---|---|---|
| 无控制 | ~8000 | 100% |
| 限轮数 + 截断 | ~3500 | 44% |
| 再开缓存 | ~1500 | 19% |
| 路由用便宜模型 | ~900 | 11% |
数字为示意,实际取决于任务长度与工具返回大小。
快速排错表
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 账单暴涨 | 无限轮数 | 加 max_turns |
| 上下文越来越长 | 全量历史 | 裁剪 + 摘要 |
| 强模型做小事 | 没路由 | 分类用便宜模型 |
| 输入费高 | 重复前缀 | 开 Prompt Caching |
| 返回撑爆 | 工具回传全量 | 工具侧截断 |
| 单任务失控 | 无预算 | 设 token 上限 |
| 贵的任务定位难 | 没日志 | 按任务记 token |
| 降级无效 | 没兜底 | 超预算返缓存答案 |
配置检查清单
| 检查项 | 怎么确认 |
|---|---|
| 最大轮数 | 代码有 max_turns |
| 上下文裁剪 | 旧结果已摘要 |
| 路由分层 | 简单判断用便宜模型 |
| 缓存开启 | 共用前缀标 cache_control |
| 工具截断 | 返回有长度上限 |
| 预算上限 | 单任务 token 封顶 |
| 计量日志 | 每次调用记 token |
| 降级路径 | 超预算有兜底回答 |
Agent 不是不能省钱,是把「轮数、上下文、模型档位、缓存、截断、预算」六件事在工程里钉死。每一项都是实打实的降幅,叠起来就能把费用压到原来的零头。