不核算成本的Agent,账单会教你做人

Agent应用的成本有三个特点:不可预测(取决于用户输入长度)、累加迅速(多轮对话+重试+工具调用来回翻倍)、难以归因(说不清钱花在哪个会话)。本文给出一个可落地的成本核算与预算熔断方案:按会话记账、按模型分级、超预算熔断。

一、成本模型:先算清每一笔账

每轮LLM调用的成本 = 输入tokens × 输入单价 + 输出tokens × 输出单价。关键是用返回的usage字段记账,而不是估算

class CostLedger:
    def __init__(self):
        self.entries = []

    def record(self, session_id, model, usage, unit_prices):
        input_cost = usage.prompt_tokens * unit_prices[model]["input"]
        output_cost = usage.completion_tokens * unit_prices[model]["output"]
        entry = {
            "session_id": session_id, "model": model,
            "input_tokens": usage.prompt_tokens,
            "output_tokens": usage.completion_tokens,
            "cost": round(input_cost + output_cost, 6),
        }
        self.entries.append(entry)
        return entry

# 示例单价(元/百万tokens,按实际渠道价替换)
PRICES = {
    "deepseek-chat":  {"input": 1.0,  "output": 2.0},
    "gpt-4o":         {"input": 17.5, "output": 70.0},
    "gpt-4o-mini":    {"input": 1.1,  "output": 4.4},
}

二、会话级预算:实时熔断

单次对话失控(比如Agent陷入循环重试)会烧掉整月预算。在记账的同时做实时熔断:

class BudgetGuard:
    def __init__(self, session_limit=2.0, daily_limit=50.0):
        self.session_limit = session_limit   # 单会话限额(元)
        self.daily_limit = daily_limit       # 全局日限额(元)
        self.session_costs = {}
        self.daily_cost = 0.0

    def check(self, session_id) -> bool:
        """返回False表示应熔断本次调用"""
        if self.daily_cost >= self.daily_limit:
            return False
        if self.session_costs.get(session_id, 0.0) >= self.session_limit:
            return False
        return True

    def charge(self, session_id, cost):
        self.session_costs[session_id] = self.session_costs.get(session_id, 0.0) + cost
        self.daily_cost += cost

熔断后的降级策略按优先级:缓存命中 → 换便宜模型 → 精简上下文 → 明确告知用户限额

三、降级路由:把非关键请求导向廉价模型

结合分级模型路由,成本能再降30%-50%:

def pick_model(task_type, budget_left):
    # 高价值任务用强模型,其余走便宜模型
    if task_type in ("code_review", "legal_advice") and budget_left > 5:
        return "gpt-4o"
    if task_type == "chat":
        return "gpt-4o-mini"
    return "deepseek-chat"

关键经验:把"分类、改写、摘要"这类中间步骤固定路由到廉价模型,只有最终面向用户的高价值输出才用强模型。

四、周报与告警:成本可视化

-- 按模型聚合的日成本报表(示例SQL)
SELECT model, SUM(input_tokens) AS in_tok,
       SUM(output_tokens) AS out_tok,
       ROUND(SUM(cost), 2) AS total_cost
FROM cost_ledger
WHERE date >= date('now', '-7 day')
GROUP BY model ORDER BY total_cost DESC;

建议配置三级告警:日成本达到限额的70%告警、90%限流、100%熔断;同时监控单会话成本P99,P99异常上涨往往意味着提示词或工具链路出了问题。

五、避坑要点

  • **重试也要记账**:自动重试的调用一样花钱,重试前先查预算
  • 2. 缓存是省钱第一手段:语义缓存命中一次省一次全量调用,优先于换模型

    3. 别忽略输出token:长输出任务(写代码、写文章)输出token占比常超60%,用max_tokens限制

    总结:成本管理不是事后看账单,而是事前定预算、事中做熔断、事后可归因。一套记账+熔断+降级的组合拳,能把API成本波动控制在预算线以内。