AI API 账单对账自动化
内部监控显示一天消耗了多少 token,不代表财务最终会看到相同金额。供应商可能按不同账期汇总、延迟补录用量、区分缓存或批处理计费;应用侧又可能遗漏超时后的实际消耗,或把一次业务请求中的多次重试合并。对账自动化的目标不是强求两边每分钟完全相等,而是持续回答:差额有多大、来自哪里、何时可以关账,以及应如何留下可审计的修正。
一、先定义三套数字的职责
对账系统通常同时面对三种数字。第一是应用调用事实,记录请求、模型、token 和状态;第二是内部成本账本,按当时价格快照生成估算与调整分录;第三是供应商结算数据,代表外部计费口径。三者用途不同,不能用后到的数据覆盖前面的事实。
| 数据层 | 主要用途 | 典型主键 | 是否允许改写 |
|---|---|---|---|
| 调用事件 | 工程追踪、业务归因 | request_id | 原则上不可变 |
| 内部账本 | 预算、毛利、成本分摊 | entry_id | 追加调整分录 |
| 外部账单 | 付款与结算依据 | 账单行或导入批次 | 保留原始版本 |
如果尚未建立前两层,应先按 LLM Token 成本账本设计 保存原始事件和价格版本。对账任务不应临时从应用日志猜成本,否则日志保留期、采样和字段变化都会让历史结果无法重跑。
二、导入层必须保留原始快照
供应商数据可能来自账单 API、控制台导出文件或定期汇总。无论入口是什么,都先把原始响应按 provider + account + period + fetched_at 保存为不可变快照,再解析成标准行。快照应记录内容哈希、导入时间、时区、币种和解析器版本,便于将来解释“同一账期为何两次导入结果不同”。
标准行不要只留总金额,尽量保留供应商提供的维度:时间桶、项目或账号、模型标识、计费单位、输入与输出用量、缓存用量、折扣、税费和贷项。解析器把缺失值标为 unknown,不要擅自填零;未知与确实为零在对账中含义不同。
导入任务必须幂等。可用原始快照哈希或供应商行 ID 建唯一约束,同一文件重复上传只返回已有批次。供应商对历史数据补录时,新快照创建新版本,由对账任务重算受影响窗口,而不是修改旧导入记录。
三、先统一账期、币种和计费维度
大量“差异”只是口径没对齐。内部可能按 UTC 日切,供应商按账号时区或结算月切分;内部事件用模型别名,账单使用具体模型标识;内部金额可能未含税,信用卡扣款则包含税费和汇率影响。比较前要建立显式转换层。
建议生成统一键:
recon_key = account + billing_day_utc + normalized_model + charge_type
charge_type = input | output | cache | batch | tool | credit | tax
模型别名映射要带生效时间,不能用今天的映射回写过去。币种转换也要保存汇率来源与日期;若目标只是核对供应商用量,优先比较原币和计费单位,把税费、汇率、信用卡手续费留到付款对账层处理。这样能区分“API 用量不一致”和“最终支付金额不一致”两类问题。
四、采用由粗到细的分层匹配
并非所有供应商账单都提供请求级 ID,因此对账应分层,而不是假设可以逐请求 join。
- 账期总额:确认导入完整,发现整批缺失或币种错误。
- 日 × 账号:定位时区、延迟入账和账号归属问题。
- 日 × 模型 × 计费类型:定位模型映射、缓存或价格口径差异。
- 请求级:只有双方都有稳定 ID 时才做精确匹配。
每层都同时计算绝对差额与相对差额。小流量模型的相对差可能很大但金额很小;主力模型即使只偏离少量比例,也可能具有实质影响。阈值应使用自家账单规模回放确定,并支持按账号或计费类型配置,不能把一个固定百分比套在所有维度上。
五、差异分类比“是否相等”更重要
自动任务发现差异后,应尝试给出原因码,而不是只报警。常见分类如下:
| 原因码 | 识别线索 | 处理方式 |
|---|---|---|
LATE_ARRIVAL | 最近账期差异随重跑收敛 | 延迟关账 |
TIMEZONE_SHIFT | 相邻日期差额方向相反、合计接近 | 修正日切映射 |
MODEL_MAPPING | 未识别模型或别名切换日突增 | 更新版本化映射 |
METERING_GAP | 外部有用量、内部无对应事件 | 检查落库与超时链路 |
PRICE_VERSION | 用量接近但金额持续偏离 | 核对生效价格 |
CREDIT_OR_TAX | 只出现在金额、不出现在 token | 转付款层处理 |
“无法解释”也应是正式状态 UNEXPLAINED,带负责人、证据和复核期限。不要为了让报表变绿而把差额塞进“其他”;长期无法解释的差异往往暴露了埋点丢失、账号共享或计价模型不完整。
六、用调整分录修正,不覆盖历史估算
假设内部日账估算为 100 个计价单位,稳定后的外部账单是 98。正确处理不是把原分录更新为 98,而是写一条 reconciliation_adjustment = -2,关联外部账单批次、差异原因和批准记录。净额变成 98,同时保留当初为何估成 100。
调整要有确定性唯一键,例如 recon_run_id + recon_key + reason_code。任务重跑时先计算期望调整,再与已存在分录比较,只追加差额或生成冲销,避免每次运行都重复记账。对租户成本归因的影响也要明确:平台计量误差通常进入平台调整,不应盲目摊回客户;归因口径可参考 AI Agent 多租户成本归因。
七、把日结设计成可重跑状态机
每天先对昨天及前几天的滑动窗口重跑,因为近期账单最容易迟到。一个账期可依次处于 OPEN、PROVISIONAL、RECONCILED 和 CLOSED:刚结束时允许变化;差异低于阈值后进入暂结;超过供应商补录窗口且复核通过后才关账。已关账窗口若收到新数据,应创建重开记录和审计事件。
任务每次输出机器可读报告:内部金额、外部金额、差额、最大贡献维度、原因码、证据链接、解析器版本和数据水位。告警只推送新出现、扩大或超期的差异,已经确认的迟到数据不必每次重复通知。成本突增本身应交给 LLM 成本异常检测;对账关注的是两套记录是否一致,不要混成一个值班规则。
八、上线前的最小验收集
准备一组固定 fixture,覆盖时区跨日、模型改名、缓存计费、贷项、重复导入、历史补录、请求缺失和同一任务重跑。每个 fixture 都要断言标准行、匹配键、原因码、调整分录与最终状态。再选一个已人工核对过的历史账期回放,确认自动结果能解释人工结论。
生产中监控导入延迟、未识别模型数、未解释差额、调整金额占比、账期关闭耗时和重开次数。若解析器更新,先影子运行新旧版本并比较结果,再切换正式版本。对账系统的可信度来自可重复证据,而不是某次跑出的总额刚好相等。
九、相关阅读
如果你需要先统一多模型调用入口,再沉淀用量事件并建设自己的对账流程,YoTradeApi 可减少不同协议带来的接入差异,方便你在应用侧统一核算口径。