提示

返回博客列表

三个功能共用一个 key,账单分不清

月度对账的时候被问了一句:「AI 这一千多块,是哪个功能花的?」

我打开服务商后台,只有一张按 key 汇总的账单,一行总数、一行 token 明细,没有别的维度。而那把 key 底下接着三路调用:客服离线兜底、内部批量生成视频摘要、还有我自己跑回归集和各种临时验证。

前两路是常驻的,第三路看心情,有时候一天几百次。真要摊,摊不清。

先打点

最直接的补法是给每次调用打个来源,这个半天就做完了:

def generate_reply(user_content, history=None, source='chat'):
    ...
    usage = resp.usage
    AIAudit.objects.create(
        source=source,
        usage_prompt=usage.prompt_tokens,
        usage_completion=usage.completion_tokens,
        model=settings.AI_CHAT_MODEL,
        cache_hit='prompt_tokens_details' in (resp.usage or {}),
        ...
    )

三路各自传 source='chat' / 'summary' / 'eval'。加上这个之后,至少能回答"各路调用了多少次、各占多少 token"。

以前 77 篇里提过一句给入口加 source 字段,当时是随手写的,没真去用。这次才把它接进成本表。

误差来源 影响方向 能不能精确分摊
提示词缓存折扣 估算偏高 不能,服务商只按整把 key 给
失败重试漏记 估算偏低 能,补 attempt 字段后归到发起方
内部测试重复跑 全落在 eval 能归,但多少算必要说不清

有了打点,粗估公式就很简单:某路的成本 ≈ 该路 prompt token × 输入单价 + completion token × 输出单价,按天的汇率和单价算下来,跟账单总量对一下误差。

第一回跑出来差了 18%。

差在哪

查了两天,主要是两处,都挺有意思。

第一处是提示词缓存。客服那路的 SYSTEM_PROMPT 是固定的,前缀命中了服务商的缓存,实际单价打折。可我们的估算按全价算,自然偏高。麻烦的是缓存命中跟调用顺序有关:三路共用一个 key、前缀又各不相同,一路的请求插进来,另一路的缓存就可能失效。也就是说,分得越细,缓存越难命中,总账反而越贵。我们把 source 打点加上之后,一度想把三路拆成三个 key 方便对账,试算了一下缓存损失,比省下来的对账精力值钱多了,就没拆。

第二处是重试。81 篇那套结构化输出会重试,失败的那次也计费,但审计表只记了最终成功的那条。批量摘要那路重试最多,漏记的 token 全堆在它头上。补了个 attempt 字段、把失败调用也记进去,误差才降到 5% 上下。

剩下那 5% 我一直没查清,可能是跨时区结算的时间差,也可能是某次临时脚本忘了传 source,落到默认值 chat 上了。这个默认值现在看是个坏设计:漏传不报错,悄悄把账记到别人头上。

估算表长什么样

最后是一段很朴素的查询,按天按来源聚合:

SELECT date(created_at) AS d, source,
       sum(usage_prompt) AS pt, sum(usage_completion) AS ct,
       count(*) AS calls,
       sum(CASE WHEN attempt > 1 THEN 1 ELSE 0 END) AS retries
FROM downloader_aiaudit
WHERE created_at >= now() - interval '30 days'
GROUP BY 1, 2 ORDER BY 1, 2;

导进表格,乘单价,再拿账单总数校一次。这个数只能叫"估算",因为缓存折扣没法精确归到某一路——服务商只告诉你整把 key 省了多少,不告诉你哪次请求命中的。

我们试过按 source 的固定前缀比例去摊,越算越像在做会计分录,最后放弃了,表里就留一行"未分摊折扣"。

没解决的问题

重试那次算谁的,到现在没定论。同一笔业务请求因为模型返回格式不对重试了一次,钱是这业务花的,可失败原因是模型不稳定,算到功能头上有点冤。现在一律记给发起方,理由只是实现简单。

内部测试那路更尴尬。回归集是我手动跑的,有时候为了对比连跑三遍,三遍都算进 eval。财务问"测试为什么要花钱",我只能说这是必要成本,但多少算必要,说不出数。

还有个一直想做没做的:给每路设独立预算和告警。现在只有一个总的月度上限,真哪路写了个死循环,得等整把 key 都快烧完才发现。分 key 能解决,可又绕回缓存那笔账。

VidDown 技术博客,免费那部分功能的账也得有人算。

那张估算表我每个月手工跑一次,跑完发群里,从来没人回过。上个月我忘了发,也没人问。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部