成本分析
在成本分析中,你可以按环境、团队、成员、调用方 API Key、模型、目标模型、日期和成本归属标签查看组织的用量和支出。先筛选用量,再按要比较的维度分组。
你还可以展开任意分组或合计,查看影响费用的计价条件及计费项。如果组织需要按部门、子公司、项目或成本中心等自定义维度分析,可以配置成本归属标签。
前提条件
开始前,请确认以下条件。
- 你有读取组织用量的权限。
- 至少有一个环境已记录网关用量。
- 如果要按当前标签分组或筛选,组织需已声明该标签键,并且已记录的用量中含有该键。只要某个时间范围内的用量仍含有已 删除的标签键,该范围内就仍可使用该键。参见成本归属标签。
使用 Admin API 示例前,请设置控制面 URL 和有读取权限的 Admin Token。
# AISIX_CP 包含 /api,末尾没有斜杠。
# AISIX Enterprise 本地快速入门使用 http://localhost:8080/api。
export AISIX_CP="YOUR_AISIX_CONTROL_PLANE_API_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
准备完成后,先缩小要分析的用量范围。
筛选和分组查看用量
组织级的 成本分析 页面一次按一个维度对组织内所有环境的用量分组。在 筛选 中选定要分析的用量,在 统计 中查看分组结果。例如,先筛选 business_group=cloud,再按 department 标签分组,即可查看该业务组的支出如何分布在各部门。
在 筛选 中设置分析范围。
- 在 时间范围 中选择最近 24 小时、7 天、30 天或自定义范围。页面按整小时读取,开始时间向下取整,结束时间向上取整。
- 在 筛选条件 中选择环境、团队、成员、模型,或添加任意多个
key=value标签条件。不同标签键的条件必须同时满足,同一键的多个值满足其一即可。从 API Key 行下钻时,页面会将该 Key 加为筛选条件。生效的条件显示在控件下方,可用 清除筛选 一次移除。
在 统计 中查看筛选结果。
- 在 分组方式 中选择标签键、团队、成员、API Key、模型、环境、日期或目标模型。参见对比模型的目标模型。按日期分组时显示按天的柱状图,其他分组显示横向条形图。
- 在 排序依据 中选择成本、总 Token、输入 Token、输出 Token、请求数或成功请求数。分组按所选指标降序排列。
- 使用 刷新 重新加载数据、标签键以及团队、成员和环境的名称。
选择一行即可下钻。页面会将该分组加 为筛选条件,并选用尚未被条件限定的下一个分组维度。通过面包屑可以返回先前的步骤。
按团队或标签键分组时,预算(本期) 列显示相应团队预算或标签预算的本期支出和额度。按 API Key 分组时,选择 Key 所在的行可以打开其所属环境的请求日志,页面已按该 Key 筛选。
控制面升级后,此页会显示与用量视图相同的回填提示。数据在回填完成前可能不完整。成本以组织币种显示。
要了解某行费用如何计算,请展开其计费明细。
解读特殊分组和标签
即使资源或标签的当前信息发生变化,成本分析仍保留历史用量。可按下表解读显示结果。
| 标签或行 | 含义 | 可以执行的操作 |
|---|---|---|
| 未设置 | 用量在所选分组维度上没有值。 | 查看该行的整体用量。此行不支持下钻。 |
| 日期行 | 某个 UTC 日期内的用量。 | 更改时间范围或分组方式。日期行不支持下钻。 |
| 其他 N 个分组 | 排在前 50 名之后的分组合计。列出的分组与此行相加等于总计。 | 缩小筛选范围,让需要查看的分组进入前 50 名。 |
| 已删除 | 标签键或资源已不存在,但所选用量仍引用它。资源显示其 ID 的 前 8 个字符。 | 选择徽标查看并复制完整资源 ID。已删除的标签键没有取值建议,可以手动输入值或从分组行下钻。 |
| 已移出 | 成员已不属于该组织。 | 选择徽标查看并复制成员 ID。 |
| 名称不可用 | 控制台未能加载足够的信息来确认资源的当前状态。 | 重新加载此视图。出现该标签时,资源可能仍然存在。 |
标签控件会列出所有已声明的标签键,以及所选用量中仍存在的已删除标签键。取值建议来自当前调用方 API Key、团队、成员和最近的用量。如果组织尚未声明任何标签键,控件会提供标签键设置的入口。声明标签键后,才可以按标签筛选。
对比模型的目标模型
模型行按调用方指定的模型名称分组。要查看模型组的流量在各目标模型之间的分布,请在模型行选择 查看目标模型,或在 分组方式 中选择 目标模型。
每个目标模型的行显示其 Provider Key、计费金额 和 平台成本。平台成本按目标模型自身的价格计算,不含模型组价格和低峰折扣。金额旁会显示没有目标模型价格的尝试次数。
请求计数按各目标模型上的尝试次数计算,包 含失败的尝试和回退。因此,各目标模型的计数相加可能超过该模型的请求数。
直接调用某个模型的用量记在该模型自己的行,包括由网关缓存返回的响应。调用模型组时,如果请求没有到达任何目标模型,其用量归入 未设置。例如,响应直接从缓存返回,或请求在选择目标模型前失败。
目标模型行和平台成本只覆盖引入该功能的控制面版本之后记录的用量,因此较早的时间范围内,目标模型的汇总值可能低于模型行。按团队、成员、API Key 或标签筛选时,查看目标模型 和目标模型分组均不可用。
例如,假设 chat 模型组会将请求分发给多个目标。以下查询可以比较每个目标处理的用量、计费金额和按其自身价格计算的成本。
GET /usage_analysis?group_by=target_model&model=chat
此端点所需的权限与其他用量读取操作相同。对比目标模型时,如果同时按团队、成员、调用方 API Key 或标签筛选,端点会返回 400。每个分组包含以下字段。
| 字段 | 含义 |
|---|---|
key | 目标模型 ID。调用模型组时,如果没有到达任何目标模型,例如命中缓存,则为 null。 |
name | 目标模型的当前名称。模型已不存在时为 null。 |
environment_id | 目标 模型所属的环境。模型已不存在时不返回此字段。 |
provider、provider_key_name | 目标模型的服务提供方密钥所对应的厂商 ID 和显示名称。模型或密钥已不存在时为 null。 |
cost | 以组织币种表示的计费金额。响应也以已弃用的字段名 cost_usd 返回同一数值。 |
prompt_tokens、completion_tokens、total_tokens | 这些尝试的 Token 数量。 |
request_count | 在该目标模型上的尝试次数,包含每次失败的尝试和回退。 |
success_count | 在该目标模型上成功的尝试次数。 |
upstream_cost | 平台成本合计。所有尝试均未定价时为 null。 |
unpriced_request_count | 在该目标模型上 upstream_cost 为 null 的尝试次数。未到达任何目标模型的尝试不计入。 |
remainder 和 total 也包含 upstream_cost 和 unpriced_request_count。
读取计费明细
成本分析里的一笔费用,不一定是 Token 数量乘以价目上的某一个单价。输入 Token 分档会让长请求按另一档单价计费,服务档位价格可以替换基础单价,模型组的低峰折扣还会减掉一部分费用。计费明细展示一行费用是怎么算出来的:适用了哪些计价条件、每种条件下各计费项计了多少、平均单价是多少。
展开明细
成本分析结果表的每一行(包括 未设置 和 合计)在名称前都有一个展开按钮。选择 展开计费明细,该行下方会显示这一行用量的计费明细,时间范围和筛选条件与页面一致;选择 收起计费明细 即可收起。其他 N 个分组 行没有计费明细;要查看其中某个分组的明细,请收窄筛选条件,直到该分组单独列出。重新加载数据会收起所有已展开的明细。
明细按计价条件分块列出,费用高的在前。一种计价条件是下面几列取值的一个组合:
| 列 | 含义 |
|---|---|
| 模型 | 调用方指定的模型名称。对于模型组,这里是模型组本身,而不是实际处理请求的模型。 |
| 实际调用模型 | 该次尝试实际分派到的模型:直接调用某个模型时就是该模型,调用模型组时是组内的某个目标模型。没有分派到任何模型时显示 —,例如调用模型组的请求直接从网关响应缓存取得了响应。直接调用某个模型时的缓存命中仍显示该模型。 |
| 价格阶梯 | 实际为该请求某个计费项定价的输入 Token 分档,例如 第 2 档(无上限)。没有任何计费项用到分档单价时(例如统一定价)显示 —。决策端点上的请求和按音频时长计费的请求,只要有计费项按分档单价计费,也会列在该档下,尽管它们在请求日志中的 价格阶梯 为空。 |
| 服务档位 | 上游上报的实际处理档位;上游没有上报时显示 默认。 |
| 时段 | 请求在其模型组低峰折扣的时间内完成时为 低峰,否则为 正常。 |
| 价格 | 按模型组价格计费时为 模型组价格。按实际调用模型自己的价格计费时为 实际调用模型的价格:直接调用的模型、没有设置组价的模型组,以及组价不覆盖的请求,即决策端点上的请求和实际调用模型按音频时长计费的请求。 |
| 用量来源 | 用量由上游上报时为 上游上报。上游缺失请求的至少一项 Token 计数或将其报为零、由网关估算时为 网关估算。同一种计价条件两种用量都有时,会按来源分别列出两次。 |
在每种计价条件下,每个 计费项 各占一行,列出 用量、平均单价 和 金额。适用了低峰折扣的条件最后有一行 低峰折扣,显示折扣减掉的金额。没有产生费用的条件(例如缓存命中,或调用了没有价格的模型)只显示一行 不计费。
| 计费项 | Admin API 中的 component | 用量 | 单价 |
|---|---|---|---|
| 输入 | prompt | 未从缓存读取的输入 Token | 提示词 |
| 缓存读取 | cache_read | 从提示词缓存读取的输入 Token | 缓存读取(已缓存输入),留空时用 提示词 |
| 缓存写入(5 分钟) | cache_write | 有效期 5 分钟的提示词缓存写入,以及上游未按有效期拆分的写入 | 缓存写入(Anthropic 缓存创建),留空时用 提示词 |
| 缓存写入(1 小时) | cache_write_1h | 有效期 1 小时的提示词缓存写入 | 1 小时缓存写入的费率 |
| 输出 | completion | 推理以外的输出 Token | 补全 |
| 推理 | reasoning | 推理 Token | 推理,留空时用 补全 |
| 决策接口输入 | decisions_prompt | 决策端点上未从缓存读取的输入 Token | 决策接口定价 中的 提示词 |
| 决策接口缓存读取 | decisions_cache_read | 决策端点上从提示词缓存读取的输入 Token | 决策接口定价 中的 缓存读取(已缓存输入) |
| 决策接口缓存写入 | decisions_cache_write | 决策端点上的提示词缓存写入 | 决策接口定价 中的 缓存写入(Anthropic 缓存创建) |
| 决策接口输出 | decisions_completion | 决策端点上推理以外的输出 Token | 决策接口定价 中的 补全 |
| 决策接口推理 | decisions_reasoning | 决策端点上的推理 Token | 决策接口定价 中的 推理 |
| 音频时长 | duration | 音频秒数 | 音频每分钟 |
费率来自为请求计费的价目,已应用输入 Token 分档和服务档位价格。某项单价留空并使用回退费率时,原计费项名称保持不变。例如,按 提示词 单价计费的缓存读取仍记为 缓存读取。
决策端点上的请求,凡是按价格中的决策端点单价计费的部分,都记在对应的 决策接口 计费项下:
- 某部分设置了决策端点单价时,记在该单价的计费项下。
- 某部分的决策端点单价留空时,按单价的回退规则取价,并记在实际用到的那个单价的计费项下。例如只设置了决策端点的 提示词 单价、基础的 缓存读取 单价也留空时,缓存读取按决策端点的 提示词 单价计费,记在 决策接口缓存读取 下;如果设置了基础的 缓存读取 单价,则按它计费,记在 缓存读取 下。
- 1 小时缓存写入没有自己的决策端点单价。设置了决策端点缓存写入单价时记在 决策接口缓存写入 下;否则价格设置了 1 小时缓存写入单价时记在 缓存写入(1 小时) 下;再否则与该请求的其他缓存写入记在同一个计费项下。
- 价格没有设置任何决策端点单价时,决策端点上的请求与普通请求一样记在基础计费项下。
明细上方的摘要给出各计费项占金额的比例,例如 输入 62.5% · 输出 37.5%,有低峰折扣时再显示低峰折扣共节省了多少。导出 CSV 会下载这份明细:每种计价条件的每个计费项一行,包含平均单价;之后是低峰折扣(金额为负数)、无明细的用量和合计各一行。用量来源对应 usage_estimated 列,网关估算的用量为 true。
明细中有网关估算的用量时,合计 一行会以组织币种注明这部分费用。例如,美元组织可能显示 含网关估算用量 $1.20(3 次请求)。请求数为零时不显示请求数,例如只有重试或故障转移尝试使用了估算用量时。
数字之间的关系
先计算每种计价条件的费用。例如,应用 11.4 的低峰折扣前,输入费用为 18、输出费用为 4.8,这种计价条件的费用为 18 + 4.8 - 11.4 = 11.4。各计价条件的费用与 无明细 金额相加,等于该行的 合计。
下表说明了费用和平均单价在不同情况下的计算方式。
| 情形 | 明细中的计算方式 |
|---|---|
| 所选时间范围内价格发生变化 | 平均单价 是金额除以用量,即按用量加权的新旧费率平均值。价格未变化时,平均单价等于配置的费率。Token 价格按每百万 Token 显示,音频时长价格按每分钟显示。 |
| 请求跨过输入 Token 阈值 | AISIX 按请求的输入 Token 数量选择一个档位,计入缓存读取和缓存写入。该请求的所有计费 项都使用这个档位,一个请求不会拆到多个档位计费。 |
| 上游上报服务档位 | 匹配的服务档位价格替换基础费率和输入 Token 分档。没有匹配项时使用基础费率,服务档位 仍显示上游上报的档位。 |
| 网关填补缺失的 Token 计数 | 整个请求标为 网关估算,填补的计数使用常规费率。估算只改变用量来源,价格保持不变。 |
| 请求重试或发生故障转移 | 请求数计入第一次尝试的用量来源。后续尝试的用量和费用计入各自的计价条件,请求数保持不变。因此,发生故障转移且用量为估算值的尝试可能产生估算费用,但没有对应的请求数。 |
| 模型组请求在低峰时段完成 | 模型组的折扣系数乘以请求的整笔费用。低峰折扣 等于各计费项金额之和乘以(1 − 折扣系数)。 |
没有明细的用量
控制面在为请求计费时记录计费明细,不会重新计算以前的用量。新增计费明细的控制面版本之前记录的用量没有明细;滚动升级期间,由仍在旧版本上的控制面实例记录的用量也没有明细。
所选时间范围内有这类用量时,明细上方会提示从什么时间开始提供明细、有多少金额没有明细,表中还有一行 无明细,金额就是这部分,因此明细的 合计 仍与成本分析结果表中该分组的金额一致。
单次请求的计费明细
在请求日志中展开一行,计费明细 会逐行列出每个计费项。控制台使用组织币种的符号。例如,美元组织可能显示 输入:1,320 Token × $0.15 / 百万 Token = $0.000198。适用了低峰折扣时还有一行 低峰折扣。计费明细上线前记录的行,以及没有可计费内容的行(例如缓存命中,或调用了没有价格的模型),不显示这一项。
用量事件中对应的字段是 cost_components(由 component、quantity、amount 组成的列表)和 off_peak_discount,各金额之和减去 off_peak_discount 就是 cost。计费明细上线前记录的事件中这两个字段为 null,导出文件也带这两个字段。
通过 Admin API 分析成本
Admin API 提供与控制台相同的用量分组和计费明细。你可以导出所有分组、在其他系统中对账,或按业务维度比较计价条件。
GET /usage_analysis 返回控制台中的数据,GET /usage_analysis/tag_keys 返回指定时间范围内用量携带的标签键,包括已删除的键。参见 AISIX Enterprise / Cloud Admin API 参考。如需读取控制台未列出的分组,参见通过 Admin API 读取全部分组。
通过 Admin API 读取明细
GET /usage_analysis/breakdown 返回成本分析中显示的计费明细。它使用与 GET /usage_analysis 相同的 from、to 和筛选参数,所需权限也与其他用量读取操作相同。另有两个参数可将结果限制为某个维度下的一个分组。
target_model_id只保留分派到指定模型的用量。与group_by=target_model一样,target_model_id和unset=target_model都不能与team_id、member_id、api_key_id或tag同用,否则返回400。unset只保留在指定维度上没有值的用量。维度名称与group_by相同,可用tag:<key>、team、member、api_key、model或target_model。要指定多个维度,可以重复传入此参数。
如需按成员、标签或其他支持的维度比较明细,请传入 group_by。参见按成员、标签和其他维度比较费用。
按日期分组时,将对应 UTC 日期的起止时间作为 from 和 to。以下请求查看 chat 模型组一周的费用明细。
curl -sS --get "${AISIX_CP}/usage_analysis/breakdown" \
--data-urlencode "from=2026-11-01T00:00:00Z" \
--data-urlencode "to=2026-11-08T00:00:00Z" \
--data-urlencode "model=chat" \
-H "Authorization: Bearer ${AISIX_TOKEN}"
响应结构如下。
{
"group_by": null,
"currency": "USD",
"groups": [
{
"model": "chat",
"target_model": "31f302a2-d055-4f9f-a662-1dc4b84de9f7",
"target_model_name": "gpt-4o",
"price_tier": {
"index": 2,
"max_input_tokens": null
},
"service_tier": "priority",
"off_peak": true,
"group_price": true,
"usage_estimated": false,
"request_count": 120,
"components": [
{ "component": "prompt", "quantity": 3600000, "amount": 18 },
{ "component": "completion", "quantity": 240000, "amount": 4.8 }
],
"off_peak_discount": 11.4,
"cost": 11.4
}
],
"remainder": {
"group_count": 0,
"request_count": 0,
"components": [],
"off_peak_discount": 0,
"cost": 0
},
"total": {
"request_count": 120,
"components": [
{ "component": "prompt", "quantity": 3600000, "amount": 18 },
{ "component": "completion", "quantity": 240000, "amount": 4.8 }
],
"off_peak_discount": 11.4,
"cost": 11.4,
"group_count": 1,
"estimated_request_count": 0,
"estimated_cost": 0
},
"covered_from": "2026-11-01T08:00:00Z",
"uncovered_cost": 3.2
}
❶ group_price 对应控制台的 价格 列。true 表示按模型组价格计费,false 表示按目标模型自身价格计费。
❷ usage_estimated 对应 用量来源。true 表示至少一个 Token 计数由网关估算,false 表示用量由上游上报。
❸ remainder 汇总当前页未列出的所有计价条件。当前页分组与该值相加等于总计。
❹ total 涵盖所有分页结果。其中的估算请求数和估算费用只统计用量为估算值的计价条件。每个请求仅按第一次尝试计一次,计费项和费用涵盖所有尝试。
❺ covered_from 表示开始有明细数据的第一个小时。将 uncovered_cost 加到 total.cost 上,结果应等于 GET /usage_analysis 在相同时间范围和筛选条件下返回的总费用。
响应中的 groups 按费用降序排列。从 offset 开始,最多返回 limit 个分组。参见通过 Admin API 读取全部分组。currency 表示组织币种。
完整响应结构参见 AISIX Enterprise / Cloud Admin API 参考。
按成员、标签和其他维度比较费用
使用 group_by 可以按业务维度比较计价条件。以下请求按成员比较一周的费用。
curl -sS --get "${AISIX_CP}/usage_analysis/breakdown" \
--data-urlencode "from=2026-11-01T00:00:00Z" \
--data-urlencode "to=2026-11-08T00:00:00Z" \
--data-urlencode "group_by=member" \
-H "Authorization: Bearer ${AISIX_TOKEN}"
每个返回的分组仍对应一种计价条件,并标识产生这笔用量的成员。以下示例省略了与本例无关的响应字段和计价条件字段。
{
"group_by": "member",
"groups": [
{
"key": "e754c9ea-83c5-49e3-9e38-5d4fc782bd0e",
"name": "Alice",
"model": "chat",
"target_model_name": "gpt-4o",
"price_tier": {
"index": 2,
"max_input_tokens": null
},
"request_count": 18,
"components": [
{ "component": "prompt", "quantity": 420000, "amount": 2.1 },
{ "component": "completion", "quantity": 30000, "amount": 0.6 }
],
"cost": 2.7
}
]
}
❶ 响应会返回选用的分组维度。未传入 group_by 时,此字段为 null。
❷ key 是成员 ID,name 是成员当前的显示名称。没有成员的用量,其 key 为 null。成员已不存在时,name 为 null。
其余字段表示计价条件及其费用。同一成员的请求如果使用了不同模型、目标模型、价格阶梯或其他计价条件,该成员就会出现在多个分组中。
此请求也可以按以下维度比较。
| 比较维度 | group_by 值 | 分组标识 |
|---|---|---|
| 单个标签键 | tag:<key> | 标签值 |
| 团队 | team | 团队 ID 和当前名称 |
| 调用方 API Key | api_key | Key 的 ID 和当前名称。Key 仍存在时,还会返回其 environment_id。 |
| 环境 | environment | 环境 ID 和当前名称 |
| UTC 日期 | day | 日期 |
任何分组维度都可能返回 null 键,表示用量在该维度上没有值。按团队、成员、调用方 API Key 或环境分组时,会返回资源当前的显示名称。资源已不存在时,名称为 null。按标签或日期分组时不返回名称。
每种计价条件已包含模型和目标模型,所以 group_by=model 或 group_by=target_model 会返回 400。
完整响应结构参见 AISIX Enterprise / Cloud Admin API 参考。
通过 Admin API 读取全部分组
控制台不分页。主表展示排名前 50 的分组,其余分组合计在 其他 N 个分组 一行。展开的计费明细最多显示 500 种计价条件,其余合计在 其他条件 一行。
如需分析或导出全部分组,请依次分页调用 GET /usage_analysis 或 GET /usage_analysis/breakdown。
offset=0
while :; do
page=$(curl -sS --get "${AISIX_CP}/usage_analysis/breakdown" \
--data-urlencode "from=2026-11-01T00:00:00Z" \
--data-urlencode "to=2026-11-08T00:00:00Z" \
--data-urlencode "group_by=member" \
--data-urlencode "limit=500" \
--data-urlencode "offset=${offset}" \
-H "Authorization: Bearer ${AISIX_TOKEN}")
echo "${page}" | jq -c '.groups[] | {member: .key, name, model, target_model_name, price_tier, usage_estimated, request_count, components, cost}'
offset=$((offset + 500))
[ "${offset}" -lt "$(echo "${page}" | jq '.total.group_count')" ] || break
done
此示例每次读取 500 个成员分组,每个分组输出一行。分页字段的行为如下。
limit设置每页列出的分组数,默认 50,最大 500。offset表示在排序结果中跳过多少个分组,默认为0。total.group_count是所有分页结果的分组总数。remainder汇总当前页之前和之后所有未列出的分组。在每一页,已列出的分组与remainder相加都等于total。- 排序值相同的分组按
key排列。计费明细的条件再按其余列排列,最后比较用量来源,上游上报排在网关估算之前。只要请求之间的用量没有变化,连续读取各页就不会重复或跳过分组。
翻页前请选择已经结束的时间范围。当小时的用量可能在翻页过程中改变排序,使分组移到其他页。
请逐页读取。每一页都会对整个时间范围重新聚合,并发查询会成倍增加数据库内存用量。控制面不限制并发聚合查询的数量。
每次聚合查询的时限为 30 秒。查询超时返回 503 和错误码 QUERY_TIMEOUT,没有分组结果。请缩小时间范围或收紧筛选条件后再试。
下一步
如果组织需要自定义成本分摊维度,请配置成本归属标签。如果成本缺失或与服务提供方的计费依据不符,请查看模型定价。要了解组织总用量和上报行为,请参阅用量上报