系列《AI 应用生产化手册》第 14 篇(共 30 篇)|配套开源项目:github.com/ChenYingbo/... 从本篇进入模块四:成本工程与 AI 网关------成本算得清,才谈得上优化(C02/C03)和采购治理(C04/C05)
一、先看问题:三个答不上来的问题
AI 应用上线后,老板/财务问的第一批问题,往往一个都答不上来:
- "这个月花了多少钱?"------只能翻云账单猜,猜完了也不知道花在哪个功能上。
- "每个请求平均多少钱?"------不知道就没法定价、没法判断某个功能"值不值得上"。
- "成本突然涨了,涨在哪?"------没有按模型/功能拆解,只能等月底对账,涨完才发现。
解法:成本模型------按模型价格表,从日志里的 token 用量算出每次请求、每个模型的成本,并对预算做告警。
核心认知:成本不是"月底账单",是"实时可观测的指标"。只有拿到「每请求成本」,你才能做三件事:定价(值不值)、优化(C02/C03 省在哪)、控制(预算告警在哪断)。
二、原理
2.1 钱花在哪:四个计费项
| 计费项 | 说明 | 省钱的切入点 |
|---|---|---|
| 输入 token | prompt + 上下文 | 提示词精简、缓存(C02) |
| 输出 token | 模型生成的答案 | 控制 max_tokens、约束输出长度 |
| 缓存 | 命中缓存价格更低(部分供应商) | 精确/语义缓存(C02) |
| 推理模型溢价 | o1/R1 类按推理 token 额外计费 | 只在真需要推理时用 |
单次调用成本公式:
scss
成本 = (输入 tokens × 输入单价 + 输出 tokens × 输出单价) / 1_000_000
2.2 一次问答 ≠ 一次调用(Agent 的成本大头)
css
1 次用户问答
├── 1 次检索(Embedding 调用,小头)
├── 2-3 次 LLM 调用(生成 + 反思/重试,大头)
│ 每次调用的 input 都含上下文(系统提示词 + 检索结果)
└── 总计:可能 = 3 × 单次调用成本
关键认知:Agent 应用的成本 ≠ 单次问答 × 单价------是「调用次数 × 每次的上下文长度」。 所以成本工程的重心不是"换个便宜模型",而是"少调用 + 短上下文"------这也是 C 系列后面几篇的主线。
2.3 价格是变量,不是常量
| 现实 | 应对 |
|---|---|
| 模型价格经常变(而且是降价居多) | 价格表独立维护、可配置(--prices-file) |
| 不同供应商计价方式不同 | 价格表按模型标识配,不按品牌 |
| 新模型上线忘记配价格 | 未计价模型按 0 计,但报告里明确列出来(绝不静默) |
还有个容易被忽略的坑:日志里记的是逻辑名(chat-strong/chat-cheap),价格表配的是供应商名(deepseek/deepseek-chat)。两者没对齐,成本就全按 0 计------报告看起来"免费",实际钱照烧。
2.4 预算三层防线
css
① 单请求预算:超限拒绝/降级(和 R04 降级链联动)
② 周期预算:日/月超限告警(cost_model.py --budget)
③ 趋势告警:环比突增(接 O03 的成本指标)
告警设计原则和 E04/O03 一致:阈值 = 基线 + 容差,且告警要能行动------超预算不告诉你"是哪个模型、哪类请求在烧钱",等于没告警。
三、动手:三条命令把成本算出来(免 Key 可跑)
bash
git clone https://github.com/ChenYingbo/ai-prod-demo.git && cd ai-prod-demo
source .venv/bin/activate
# 1. 从结构化日志算成本拆解
python scripts/cost_model.py --log tests/fixtures/sample_structured.log
真实输出(10 次调用的合成样例日志):
yaml
===== Token 成本报告 =====
调用次数: 10 | 总 token 入/出: 1360 / 236
总成本: 0.004608 元 | 平均每请求: 0.000461 元
按模型拆解:
deepseek/deepseek-chat: 10 次 | in 1360 / out 236 | 成本 0.004608 元
注意这里最有用的不是总成本,是最后一个数:平均每请求 0.000461 元------有了它,才谈得上定价和优化。
bash
# 2. 预算告警:超限时退出码 1(可直接接 CI / 定时任务)
python scripts/cost_model.py --log tests/fixtures/sample_structured.log --budget 0.001
echo "exit=$?"
真实结果:
ini
总成本: 0.004608 元 | 平均每请求: 0.000461 元
[BUDGET-ALERT] 总成本 0.004608 元超过预算 0.001 元
exit=1
预算放到 1.0 元,退出码就是 0------告警是"退出码 + stderr",不靠人盯屏,这样它才能进 CI。
未计价模型:成本黑洞预警(必看)
新加一个模型但忘了配价格,会发生什么?造两行日志实测:
bash
# 造两行日志:chat-strong 已配价,gpt-5-mini 没配价
cat > /tmp/unpriced.log <<'LOG'
2026-11-11T10:00:00Z event=llm_call request_id=r1 model=chat-strong in_tokens=820 out_tokens=140 latency_ms=1200
2026-11-11T10:00:05Z event=llm_call request_id=r2 model=gpt-5-mini in_tokens=900 out_tokens=180 latency_ms=1500
LOG
python scripts/cost_model.py --log /tmp/unpriced.log
真实输出:
objectivec
===== Token 成本报告 =====
调用次数: 2 | 总 token 入/出: 1720 / 320
总成本: 0.00276 元 | 平均每请求: 0.00138 元
按模型拆解:
chat-strong: 1 次 | in 820 / out 140 | 成本 0.00276 元
gpt-5-mini: 1 次 | in 900 / out 180 | 成本 0.0 元
⚠️ 未计价模型(成本按 0 计,需补价格表): gpt-5-mini
gpt-5-mini 那次调用成本记成 0,报告"看起来"只花了 0.00276 元------实际成本被低估。工具至少把未计价模型列出来,人不至于完全瞎。
真实数据:50 次调用,0.001 元/请求
有 Key 之后,跑真实链路:10 个评测问题各问 5 遍 → 50 次调用,用真实价格表算 → ≈ 0.001 元/请求 (deepseek 档模型,配 R04 的降级链兜底)。这个数就是后面所有成本优化(C02 缓存、C03 路由)的对照基线:没有基线,"省了 40%" 只是感觉。
四、真实踩坑
- 价格表不维护:默认价格写着"参考日期",上线不更新 = 报告全错------价格是变量,得有人负责维护
- 逻辑名 vs 供应商名没对齐 :日志记
chat-strong、价格表配deepseek/deepseek-chat,成本全按 0 计(本工具已按逻辑名配价兜住,但自研很容易漏) - 未计价模型静默按 0:至少要把未计价模型列出来,否则成本报告是"看起来很美"
- 只算总成本不算每请求 :没法定价、没法优化------
avg_cost_per_request才是决策指标 - 只盯调用次数不看上下文长度:Agent 的成本大头往往是"每次 input 有多大"
- 预算告警不带定位入口:超限了只会"哦",不知道砍哪里------告警必须能追到按模型/按功能的拆解
- 忘了特殊计价:缓存命中价、推理 token 溢价都和普通 input/output 不同,价格表要按真实计费结构配
五、小结
- 一个公式 :
成本 = (in × 单价 + out × 单价) / 1M - 一个指标 :
avg_cost_per_request------定价、优化、告警全靠它 - 一条纪律:价格表是资产,不是常量;未计价模型必须显式暴露
- 三层预算:单请求 / 周期 / 趋势,告警用退出码进 CI,不靠人盯
下一篇(C02):《缓存策略》------让"同样的钱只花一遍":精确缓存 + TTL + 命中统计,实测"同一批问题跑第二遍,成本 ≈ 0(全命中)"。 收藏 + 关注,30 篇连载,把 AI 应用从 POC 送到生产。