Appearance
成本治理与预算告警:给老板一个能看懂的数字
1. 本节产出
一套平台级成本治理:成本模型表(可给老板看)、按租户/团队的成本归因与内部结算、预算预测与告警、以及五个可量化的降本手段及预期收益。
2. 前置依赖
3. 为什么成本治理是「能不能持续」的关键
一个真实的对话场景:
老板:「AI 这块一个月花多少?」 你:「大概……几万?具体要看各团队。」 老板:「花在哪?值不值?下个月会不会更多?」 你:「……我查一下。」
这三个问题答不上来,第二年的预算就没了。
| 老板真正想知道的 | 你需要能提供的 |
|---|---|
| 花多少 | 总成本 + 按团队/场景拆分 |
| 花在哪 | Top10 成本来源 |
| 值不值 | 成本 vs 业务收益(人力节省/收入) |
| 会不会更多 | 趋势预测与预算告警 |
4. 核心原理
4.1 成本模型表(给老板看的那张表)
| 场景 | 月调用量 | 单次成本 | 月成本 | 替代方案成本 | 净收益 |
|---------|---------|---------|--------|------------|-------|
| 客服问答 | 50,000 | 0.008 | 400 | 人力 8,000 | +7,600|
| 文档检索 | 20,000 | 0.006 | 120 | 人力 3,000 | +2,880|
| 工单处理 | 5,000 | 0.045 | 225 | 人力 6,000 | +5,775|
| 代码审查 | 800 | 0.032 | 26 | 人力 4,000 | +3,974|
| 合计 | — | — | 771 | 21,000 | +20,229|「替代方案成本」这一列是说服力的关键。孤立地看「771 元」没感觉,对比「原本要 2.1 万人力」立刻有价值感。
注意:净收益要用保守口径。人力节省通常按「节省的时间 × 工时成本」估算,且要打个折扣(节省的时间不一定完全转化为产出)。
4.2 成本归因的三个维度
必须能按以下维度出报表(缺一个都答不上老板的问题):
├─ 按租户/团队(内部分摊)
├─ 按场景/应用(哪个功能费钱)
├─ 按模型/厂商(议价与选型依据)
└─ 按时间(趋势与预测)归因数据来源是网关的用量记录(04-02)。这就是为什么统计必须在网关做。
4.3 预算预测
简单预测:
日均成本 × 30 = 月预测
考虑增长:近 7 天斜率外推
告警阈值:
实际 > 预测 × 1.2 → 提醒
实际 > 预算 × 0.8 → 告警
实际 > 预算 × 0.95 → 自动降级
单日 > 日均 × 3 → 异常告警(可能是死循环或滥用)「单日 > 日均 3 倍」这个异常检测很重要:它能抓住死循环、脚本刷接口这类突发问题,而月度预算告警发现时已经晚了。
4.4 五个降本手段及预期收益
| # | 手段 | 预期降本 | 代价 |
|---|---|---|---|
| 1 | 缓存(精确+语义) | 30~40% | 需要失效机制 |
| 2 | 模型分级路由 | 20~35% | 需要任务分类 |
| 3 | 上下文压缩 | 15~25% | 需要摘要逻辑 |
| 4 | 减少不必要调用(去重、合并) | 10~20% | 需要流程梳理 |
| 5 | Prompt 精简 | 5~10% | 需要验证效果不降 |
按性价比排序:1 > 2 > 3 > 4 > 5。
注意:降本要以评测集守护质量。每个降本动作跑一次评测(02-17 / 03-18),确认召回率或完成率没有明显下降。省了钱但效果崩了,是最坏的结果。
5. 代码走查
5.1 成本汇总
java
// src/main/java/com/example/platform/cost/CostReportService.java
@Service
public class CostReportService {
/** 按租户 × 场景的成本报表 */
public List<CostRow> byTenantAndCase(YearMonth month) {
return jdbc.query("""
SELECT tenant_id,
COALESCE(case_name, 'unknown') AS case_name,
SUM(prompt_tokens) AS pt,
SUM(completion_tokens) AS ct,
SUM(cost_yuan) AS cost
FROM ai_usage
WHERE at >= ? AND at < ?
GROUP BY tenant_id, case_name
ORDER BY cost DESC
""", mapper, month.atDay(1), month.plusMonths(1).atDay(1));
}
/** 预测:近 7 天日均外推 */
public Forecast forecast() {
double avg7 = jdbc.queryForObject("""
SELECT COALESCE(SUM(cost_yuan),0)/7
FROM ai_usage WHERE at > now() - INTERVAL '7 days'
""", Double.class);
return new Forecast(avg7 * 30, avg7, budgetMonthly());
}
}5.2 预算告警
java
// src/main/java/com/example/platform/cost/BudgetAlertJob.java
@Component
public class BudgetAlertJob {
@Scheduled(cron = "0 0 9 * * *") // 每天 9 点
public void check() {
double monthToDate = costRepo.monthToDate();
double budget = props.monthlyBudget();
double ratio = monthToDate / budget;
// 1. 进度告警
if (ratio > 0.8) {
alert.send("AI 成本告警",
"本月已用 %.0f%%(%.0f / %.0f 元)".formatted(ratio*100, monthToDate, budget));
}
// 2. 异常检测:单日超日均 3 倍(可能是死循环或滥用)
double today = costRepo.today();
double dailyAvg = monthToDate / DayOfMonth();
if (today > dailyAvg * 3 && today > props.minAbsoluteThreshold()) {
alert.send("AI 成本异常",
"今日 %.0f 元,是日均的 %.1f 倍,请检查是否有异常任务".formatted(today, today/dailyAvg));
}
// 3. 进度与日期不匹配(月中就用了 90%)
int dayOfMonth = LocalDate.now().getDayOfMonth();
double expectedRatio = dayOfMonth / 30.0;
if (ratio > expectedRatio * 1.5) {
alert.send("AI 成本进度偏快",
"第 %d 天已用 %.0f%%,超出正常进度".formatted(dayOfMonth, ratio*100));
}
}
}第三条「进度与日期不匹配」很实用:它能在月中就发现问题,而不是等到月底。
5.3 内部结算(chargeback)
java
/** 按租户生成月度账单,供内部结算 */
public Invoice invoice(String tenantId, YearMonth month) {
List<CostRow> rows = byTenant(tenantId, month);
double total = rows.stream().mapToDouble(CostRow::cost).sum();
return new Invoice(tenantId, month, rows, total,
pricingPlan.of(tenantId)); // 可能有套餐价
}5.4 成本模型表导出
java
/** 导出为 xlsx,供汇报使用 */
public void exportModel(Path out) {
// 列:场景 / 月调用量 / 单次成本 / 月成本 / 替代成本 / 净收益
}6. 跑起来
bash
git checkout ch04-07-cost
docker compose up -d
mvn spring-boot:runbash
# 1. 成本报表
curl "http://localhost:8080/api/cost/report?month=2026-10"
# 期望:按租户 × 场景的明细
# 2. Top10
curl "http://localhost:8080/api/cost/top?limit=10"
# 3. 预测
curl "http://localhost:8080/api/cost/forecast"
# 期望:{"dailyAvg":26.4,"monthlyForecast":792,"budget":2000,"ratio":0.396}
# 4. 告警验证(注入一笔大额用量)
curl -X POST http://localhost:8080/admin/cost/inject -d '{"yuan":500}'
# 期望:触发「成本异常」告警
# 5. 导出成本模型表
curl "http://localhost:8080/api/cost/export" -o cost-model.xlsx| 检查项 | 通过标准 |
|---|---|
| 三维归因 | 租户/场景/模型都能出报表 |
| 预测可用 | 给出月预测与预算占比 |
| 三类告警 | 进度/异常/进度偏快都能触发 |
| 模型表 | 含「替代方案成本」列 |
| 结算 | 能按租户出账单 |
7. 生产避坑
- 成本模型表必须有「替代方案成本」列。孤立的成本数字没有说服力,对比人力成本才能体现价值。这一列是预算审批能不能过的关键。
- 必须做单日异常检测,不能只看月度预算。月度预算告警发现问题时钱已经花完了。单日突增(3 倍日均)往往意味着死循环或滥用,早发现能省下大钱。
- 每一次降本都要用评测集验证质量。缓存、模型降级、上下文压缩都会影响效果。做法是:每次降本动作跑一次评测,召回率/完成率下降超过阈值就回滚。省了钱但效果崩了,比不省钱更糟。
8. 延伸与锚点
- 思考题:技术、成本、合规都讲完了,最后一件事——怎么证明团队用 AI 真的提效了?(04 篇最后一节)
- 代码锚点:
git checkout ch04-07-cost - 下一课时:04-08 团队与效能度量
- 对应课件:L04-07 成本治理