大模型API成本归因在工程上不是“月底导出一张Token表”这么简单。只保存模型名称、输入Token和输出Token,只能支持最基础的用量统计;遇到缓存、图片、音频、按次调用或价格调整时,未必足以完成账单核对。要把费用分到项目、环境和业务任务,还需要在请求进入网关前补充业务标识,并将调用记录与结果验收关联起来。下面给出一套可以从小规模项目开始实施的数据结构。

先定义归因粒度

工程团队常见的错误,是一开始就试图把每个员工、每次对话和每条结果全部计入,最后字段很多,却没有稳定的数据来源。

建议先确定三级粒度:

  1. 项目:费用最终归到哪个产品、客户或成本中心;
  2. 环境:测试、预发布、生产是否分开;
  3. 任务:摘要、客服、代码、审核或图片理解等具体用途。

团队成员可以作为附加维度,但不要把个人身份当成主要归因方式。自动化任务、服务器和工作流往往没有明确的“操作人”,项目和环境反而更稳定。

一条调用记录至少需要哪些字段

可以把数据分成四组:

字段组示例字段用途
业务归属departmentproject_idcost_centerenvironment确定费用由谁承担
调用信息request_idapi_key_aliasmodeltask_type还原调用来源和用途
消耗信息input_tokensoutput_tokensretry_countestimated_cost计算直接调用成本
结果信息statusacceptedmanual_review_minutesfallback_model估算失败、复核和回退成本

其中,API平台通常能提供部分调用和消耗数据;project_idtask_typeaccepted等业务字段需要企业在应用侧维护。不要假设一个API网关能自动理解公司的成本中心和验收规则。

用项目Key隔离最容易先跑起来

如果现有系统无法给每次请求附加完整业务标签,最简单的第一步是按项目和环境拆分API Key:

ai-customer-service-test
ai-customer-service-prod
internal-summary-prod
marketing-material-test

密钥本身不要直接写进日志,日志里只保留内部别名或不可逆标识。应用配置仍应通过环境变量、密钥管理服务或部署平台注入。

下面是一段简化的Python示例,重点不是具体SDK,而是如何在调用前后保存关联信息:

import time
import uuid

def call_model(client, project_id, task_id, environment, task_type, model, messages):
    request_id = str(uuid.uuid4())
    started_at = time.time()

    try:
        response = client.chat.completions.create(
            model=model,
            messages=messages,
        )

        save_usage_record({
            "request_id": request_id,
            "project_id": project_id,
            "task_id": task_id,
            "environment": environment,
            "task_type": task_type,
            "model": model,
            "status": "success",
            "input_tokens": response.usage.prompt_tokens,
            "output_tokens": response.usage.completion_tokens,
            # estimated_cost 应由当前价格快照与实际 usage 计算。
            "estimated_cost": calculate_estimated_cost(model, response.usage),
            "latency_ms": int((time.time() - started_at) * 1000),
        })
        return response
    except Exception as exc:
        save_usage_record({
            "request_id": request_id,
            "project_id": project_id,
            "task_id": task_id,
            "environment": environment,
            "task_type": task_type,
            "model": model,
            "status": "failed",
            "error_type": type(exc).__name__,
            # 失败请求是否产生费用,需在平台日志或结算记录中确认。
            "estimated_cost": None,
        })
        raise

不同接口返回的usage字段可能不同,流式输出也可能需要在请求结束后汇总,实际实现应以当前SDK和接口说明为准。

147AI适合放在调用记录层

企业如果使用GPT、Claude、Gemini、DeepSeek等多个模型,分别对接不同渠道会让Key、账单和记录分散。使用147AI作为统一API接入层时,可以按项目或场景创建不同API Key,并通过平台的调用量、消耗和日志查看各入口的使用情况。

工程上更合理的做法,是将147AI中的调用记录与应用侧的request_id、项目和任务数据对应起来。平台记录帮助确认“调用了什么、消耗了多少”,业务数据库则补充“属于哪个流程、结果是否被采用”。如果当前可见日志字段不能直接关联内部请求,就需要在应用侧建立时间、Key别名、模型等辅助对应方式,具体以平台当前能力为准。

月度分账不要直接按总Token比例

一个可操作的成本计算流程可以分成三步。

第一步:计算直接模型成本

直接成本 = 输入费用 + 输出费用 + 缓存相关费用 + 按次调用费用

不同模型的计费项不完全相同,图片、音频、搜索或任务类接口也可能不是简单的文本Token计费。价格和换算方式应以当前模型页面为准。

第二步:计入失败与回退链路

如果一次业务任务先调用模型A失败,重试后又调用模型B,应按同一个业务任务ID聚合所有尝试。失败请求不应直接假定已产生费用:未到达模型服务或没有形成有效结果的请求,一般不会按正常成功请求计费;如果上游已经处理或返回部分内容,则可能产生消耗,最终要以平台调用日志或结算记录为准。

SELECT
  project_id,
  task_id,
  SUM(estimated_cost) AS model_cost,
  COUNT(*) AS attempts,
  MAX(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS succeeded
FROM llm_usage
GROUP BY project_id, task_id;

第三步:建立单位有效结果的内部管理口径

建议口径:单位有效结果成本
=(模型调用成本 + 人工复核成本 + 返工成本)
÷ 被业务接受的结果数

这不是统一会计标准,而是一种内部管理方法。企业需要自行定义人工成本、返工范围和“有效结果”的验收条件。accepted不一定要自动判断,第一版可以让业务人员抽样标记,或者以“是否进入下一流程”“是否被客户确认”“是否通过测试”等已有状态代替。

价格快照要和调用记录一起保存

只保存Token数量还有一个隐患:模型价格、平台倍率或计费方式可能调整。如果月底直接拿最新价格回算整月费用,历史记录可能与实际账单不一致。

更稳妥的方式,是在调用结算或日汇总时保存一份价格快照:

model
billing_type
input_unit_price
output_unit_price
cache_unit_price
currency
price_version
calculated_at

对于按次计费、图片、音频或任务型接口,还要增加相应的计费字段。业务报表优先使用已经结算的实际消耗;如果只能估算,也要明确标记estimated,避免财务把估算值当成最终账单。

价格快照还有一个作用:当项目成本突然变化时,可以区分到底是请求量上涨、上下文变长,还是计费规则发生了变化。否则所有变化都会混在一个总金额里。

平台账单和内部记录如何对账

建议每天或每周做一次轻量对账,而不是等到月底才发现差异。可以按日期、Key别名和模型聚合内部记录,再与平台侧的调用和消耗数据比较:

日期 + Key别名 + 模型
→ 请求数
→ 成功数
→ 输入输出量
→ 记录成本
→ 平台消耗
→ 差异比例

出现差异时,先检查流式请求是否完整落库、失败请求是否产生上游消耗、重试是否被重复统计,以及时区和结算周期是否一致。对账的目标不是要求两边每个字段完全相同,而是确保差异有可解释的来源。

内部报表还应保留原始记录与汇总记录之间的追溯关系。管理者看到项目月度费用后,研发人员应能继续下钻到日期、模型和任务类型;但下钻过程不应暴露完整密钥或未经脱敏的用户输入。

异常成本如何定位

月度总额上涨并不一定意味着浪费。建议按以下顺序检查:

  1. 项目请求量是否增长;
  2. 输入上下文是否变长;
  3. 模型或版本是否变化;
  4. 重试次数是否增加;
  5. 是否触发备用模型;
  6. 测试请求是否误入生产Key;
  7. 是否存在长期未使用但仍有效的Key;
  8. 单位有效结果成本是否同时上升。

如果总成本上升,但单位有效结果成本下降,可能说明业务规模扩大或模型效果改善;反之,如果调用量不变、重试和返工增加,就应优先排查链路和提示词,而不是简单更换低价模型。

上线前的工程检查

  • 测试、预发布和生产使用不同Key;
  • 日志不保存完整API Key和敏感输入;
  • 每次调用有内部request_id
  • 能把平台记录对应到项目和任务;
  • 失败、重试和fallback均被记录,只有经日志或结算确认产生的消耗才计入成本;
  • 价格表有更新时间和来源;
  • 至少一个核心任务记录结果是否被采用;
  • 月度报表同时展示总成本和单位有效结果成本。

总结

大模型API成本归因需要两套数据配合:统一接入层提供模型、Key、调用和消耗信息,业务应用补充项目、任务和结果状态。147AI可以作为多模型调用与项目Key管理的候选入口,但企业仍要在应用侧建立业务标签和验收口径。先用项目Key完成粗粒度分账,再逐步接入任务结果,通常比一开始建设复杂计费平台更容易落地。

更多推荐