计算机访问系统

Agent成本优化:降低API支出的实用指南


Agent成本优化:降低API支出的实用指南

你的Agent运行良好,每天处理200个请求,用户反馈也很满意。然后你查看API账单:本月$3,400。深入分析数据后,你发现Agent平均每个请求发起12次API调用,每次调用包含4,000个token的系统提示词。仅系统提示词每天就消耗960万个输入token。按每百万token $3计算,仅重复内容每月就要花费$864

成本是生产环境Agent部署被缩减或彻底终止的首要原因。优化并非过早之举——而是生存之道。好消息是:大多数Agent部署通过一些直接的改动就能降低50–80%的成本,无需重新设计整个系统。

本指南将介绍七种按投资回报率(ROI)排序的降本策略。从第一条开始,逐步推进,直到达到预算目标。每个部分都包含具体数字,让你在编写一行代码之前就能估算出节省的费用。


1. Token计费分析:了解资金流向

无法衡量的东西无从优化。在做任何改动之前,先全面梳理Agent工作流中每一分钱的去向。

输入Token构成

每次调用Claude的API,输入端都包含以下几类token:

  • 系统提示词 — 指令、角色设定、约束条件。通常为1,000–5,000个token,且每次调用都会重复发送。
  • 工具定义 — Agent可调用的每个工具的JSON schema。10个工具轻松消耗2,000–3,000个token。
  • 对话历史 — 会话中的所有历史消息,随每个步骤不断增长。
  • 工具调用结果 — 上一次工具调用的输出,重新注入上下文中。可能非常庞大(完整网页、数据库查询结果等)。

输出Token构成

输出token的费用是输入token的3–5倍,是关键的优化目标:

  • Agent推理过程 — 内部思维链(尤其是启用扩展思考时)。
  • 工具调用生成 — 工具调用的JSON内容。
  • 最终响应 — 面向用户的答案。

单任务成本计算

单个Agent任务的总成本计算公式:

总成本 = Σ (input_tokens × input_price + output_tokens × output_price)
(对任务中每次API调用求和)

成本构成示例

以下是使用Claude Sonnet(输入$3/百万token,输出$15/百万token)执行一个10步研究型Agent任务的实际成本分解:

步骤组件输入Token输出Token输入成本输出成本合计
1初始规划4,200800$0.0126$0.0120$0.025
2网络搜索调用4,800200$0.0144$0.0030$0.017
3处理搜索结果8,500600$0.0255$0.0090$0.035
4深度阅读(页面1)12,000500$0.0360$0.0075$0.044
5深度阅读(页面2)15,200500$0.0456$0.0075$0.053
6追加搜索16,800200$0.0504$0.0030$0.053
7处理结果20,100600$0.0603$0.0090$0.069
8综合分析22,5001,200$0.0675$0.0180$0.086
9核实验证24,000400$0.0720$0.0060$0.078
10最终响应25,5001,500$0.0765$0.0225$0.099
合计153,6006,500$0.461$0.098$0.558

注意输入成本占主导地位,且随着对话历史的积累,每个步骤的成本都在增长。第8–10步仅占总步骤数的30%,却贡献了47%的总成本。

成本追踪代码

从第一天起就实现一个追踪封装器:

import anthropic
import time
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class CostRecord:
step: int
model: str
input_tokens: int
output_tokens: int
cache_read_tokens: int = 0
cache_creation_tokens: int = 0
input_cost: float = 0.0
output_cost: float = 0.0
total_cost: float = 0.0
duration_ms: float = 0.0
# Pricing per million tokens (as of early 2026)
MODEL_PRICING = {
"claude-haiku": {"input": 0.25, "output": 1.25, "cache_read": 0.025, "cache_write": 0.30},
"claude-sonnet": {"input": 3.00, "output": 15.00, "cache_read": 0.30, "cache_write": 3.75},
"claude-opus": {"input": 15.00, "output": 75.00, "cache_read": 1.50, "cache_write": 18.75},
}
@dataclass
class TaskCostTracker:
task_id: str
budget_limit: Optional[float] = None
records: list = field(default_factory=list)
total_cost: float = 0.0
def record_call(self, step: int, model: str, usage) -> CostRecord:
pricing = MODEL_PRICING.get(model, MODEL_PRICING["claude-sonnet"])
input_cost = (usage.input_tokens / 1_000_000) * pricing["input"]
output_cost = (usage.output_tokens / 1_000_000) * pricing["output"]
cache_read_cost = (getattr(usage, 'cache_read_input_tokens', 0) / 1_000_000) * pricing["cache_read"]
cache_write_cost = (getattr(usage, 'cache_creation_input_tokens', 0) / 1_000_000) * pricing["cache_write"]
total = input_cost + output_cost + cache_read_cost + cache_write_cost
record = CostRecord(
step=step,
model=model,
input_tokens=usage.input_tokens,
output_tokens=usage.output_tokens,
cache_read_tokens=getattr(usage, 'cache_read_input_tokens', 0),
cache_creation_tokens=getattr(usage, 'cache_creation_input_tokens', 0),
input_cost=input_cost + cache_read_cost + cache_write_cost,
output_cost=output_cost,
total_cost=total,
)
self.records.append(record)
self.total_cost += total
print(f" Step {step} [{model}]: {usage.input_tokens} in / {usage.output_tokens} out = ${total:.4f} (cumulative: ${self.total_cost:.4f})")
if self.budget_limit and self.total_cost > self.budget_limit:
raise BudgetExceededError(
f"Task {self.task_id} exceeded budget: ${self.total_cost:.4f} > ${self.budget_limit:.4f}"
)
return record
def summary(self) -> dict:
return {
"task_id": self.task_id,
"total_steps": len(self.records),
"total_input_tokens": sum(r.input_tokens for r in self.records),
"total_output_tokens": sum(r.output_tokens for r in self.records),
"total_cost": self.total_cost,
"cost_by_model": self._cost_by_model(),
}
def _cost_by_model(self) -> dict:
by_model = {}
for r in self.records:
if r.model not in by_model:
by_model[r.model] = {"calls": 0, "cost": 0.0}
by_model[r.model]["calls"] += 1
by_model[r.model]["cost"] += r.total_cost
return by_model
class BudgetExceededError(Exception):
pass

即使还没开始优化,也要从今天起就记录数据。你需要基准数字来衡量改进效果。


2. 按任务选择模型

这是你手中最大的成本调节杠杆。并非每个Agent步骤都需要最强大的模型。

模型层级与定价

以Claude系列为参考:

模型输入(每百万token)输出(每百万token)适用场景
Haiku$0.25$1.25分类、路由、提取、简单格式化
Sonnet$3.00$15.00复杂工具调用、研究、综合分析、通用场景
Opus$15.00$75.00复杂规划、细致推理、高风险决策

Haiku的输入和输出成本均比Sonnet便宜12倍,Sonnet全面比Opus便宜5倍

各角色模型推荐

将每个Agent角色匹配到满足质量要求的最低成本模型:

  • 路由/分类AgentHaiku。“这是计费问题还是技术问题?“不需要Sonnet。对于定义明确的类别,Haiku的分类准确率超过95%。
  • 数据提取AgentHaiku。从文本中提取结构化字段、解析日期、识别实体——Haiku在这方面表现出色。
  • 工作Agent(工具调用)Sonnet。复杂的多步骤工具编排、研究综合和细致的响应生成都能受益于Sonnet的能力。
  • **编排/规划Agent

相关文章