SpringAI Token 成本治理:用量统计、语义缓存与 CLS 监控告警
SpringAI Token 成本治理:用量统计、语义缓存与 CLS 监控告警
基于 SpringBoot 3.3.x 与 SpringAI 1.0.x,用 AOP 切面把混元的 promptTokens/completionTokens 结构化推送到腾讯云 CLS,并按 user/session/model 维度统计。语义缓存用 VectorStore 做相似度匹配,命中率 38%,日均 Token 消耗从 40.8 万降到 25.3 万,月成本从 ¥2448 降至 ¥1518,综合降幅 79%。CLS 另配日预算、单用户异常、5 分钟突增三条告警规则,经企业微信 Webhook 通知。
正文
摘要: AI 应用的最大变动成本是 Token 消耗,但传统 APM 不懂 Token。本文实现 Token 用量统计(CLS 结构化推送)、语义缓存(相似问题命中缓存不调混元)、成本告警(日预算超限通知)。语义缓存命中率 38%,日均 Token 消耗再降 38%,月节省 ¥930。
适用版本: SpringBoot 3.3.x / SpringAI 1.0.x / 腾讯云 CLS / 混元 / JDK 17+ 一、背景:Token 账单的三个盲盒
第 8 篇用多模型路由降了 66% 成本,但 Token 账单仍有三个盲盒:
盲盒一:不知道钱花在哪。 月账单 ¥2448,但不知道哪个会话、哪个用户、哪类问题消耗最多。CLS 收集了日志但没有 Token 维度的统计。
盲盒二:重复问题重复付费。 100 个用户问"退货政策是什么",混元被调 100 次,每次消耗 200 Token。但答案完全一样,白白付了 99 次钱。
盲盒三:异常消耗无告警。 某用户写了个循环脚本刷接口,一晚上消耗 50 万 Token(¥100),第二天看账单才发现。
二、Token 用量统计:CLS 结构化推送 2.1 Token 统计切面
【为什么需要这段代码】 SpringAI 的 ChatResponse 包含 Usage 对象,记录了 promptTokens(输入)和 completionTokens(输出)。用 AOP 切面自动提取,推送到 CLS,按 user/session/model 维度统计。相比传统日志,CLS 支持按 Token 字段聚合查询。
2.2 CLS 查询:Token 消耗分析
推送到 CLS 后,可以用 CLS 查询语句分析 Token 消耗:
【为什么需要这段查询】 CLS 支持类 SQL 查询,按维度聚合统计 Token 消耗。这些查询在 CLS 控制台直接跑,或配成定时报表。model 字段区分不同档位的消耗。
三、语义缓存:相似问题不重复调混元 3.1 语义缓存原理
传统缓存按 key 精确匹配,但用户问"退货政策"和"怎么退货"是同一个问题,key 不同。语义缓存:把问题 Embedding 向量化,在缓存中找相似度 > 阈值的历史问题,命中则直接返回缓存的回复,不调混元。
3.2 语义缓存实现
【为什么需要这段代码】 用 SpringAI 的 VectorStore 做语义缓存:问题向量化后存 ES,下次先在 ES 里相似度检索。SIMILARITYTHRESHOLD = 0.95 很高,确保命中的问题语义几乎相同。缓存表单独建索引,和知识库索引分开。
3.3 带缓存的对话 Service
【为什么需要这段代码】 缓存逻辑:先查缓存,命中直接返回(0 Token);未命中调混元,结果写入缓存。cacheHit 标记用于统计命中率。
四、Token 成本告警 4.1 CLS 告警规则
【为什么需要这段配置】 在 CLS 控制台配置告警规则,当 Token 消耗超阈值时触发企业微信通知。三条规则:日预算超限、单用户异常、5 分钟突增。CLS 告警无需写代码,在控制台配置即可。
4.2 企业微信通知
【为什么需要这段代码】 CLS 告警触发后调企业微信 Webhook,推送告警详情。markdown 格式在企微群里渲染成卡片,包含告警名称、当前值、阈值、CLS 查询链接。
五、效果对比 语义缓存效果
| 指标 | 无缓存 | 有语义缓存 | 提升 | |------|--------|-----------|------| | 日均混元调用次数 | 12000 | 7440 | ↓38% | | 缓存命中率 | — | 38% | — | | 日均 Token 消耗 | 40.8 万 | 25.3 万 | ↓38% | | 日均成本 | ¥81.6 | ¥50.6 | ↓38% | | 平均响应时间 | 350ms | 210ms(命中时 5ms) | ↓40% | 综合成本治理效果
| 阶段 | 月成本 | 优化措施 | |------|--------|---------| | 全量 pro | ¥7200 | 基线 | | 多模型路由 | ¥2448 | ↓66% | | +语义缓存 | ¥1518 | ↓79% | | +Token 告警 | ¥1518 | 成本不变,异常可控 |
六、踩坑实录 坑 1:语义缓存命中但回复不匹配
现象: 用户问"怎么退货",命中了缓存中"退货政策是什么"的回复,但回复内容是"退货政策是7天无理由...",用户其实想问退货流程步骤。
定位: 相似度 0.95 太低,"怎么退货"和"退货政策"语义相近但意图不同。
解决: 提高阈值到 0.97,或加意图分类校验——缓存命中后用 lite 模型快速判断两个问题是否真的等价。 坑 2:缓存膨胀占用 ES 存储
现象: 运行一个月后缓存索引 50 万条,ES 磁盘占用 20GB。
定位: 每个未命中的问题都写缓存,大量长尾问题只问一次也存了。
解决: 只缓存高频问题——用 CDB 统计问题频率,只缓存出现 ≥ 3 次的问题。或设缓存容量上限,LRU 淘汰。 坑 3:CLS 告警频繁误报
现象: "5 分钟突增"告警频繁触发,但实际是正常高峰流量。
定位: 5 分钟窗口太短,高峰期正常流量就超 10 万 Token。
解决: 改为 15 分钟窗口 + 连续 2 次超限才告警(避免单次波动)。CLS 告警支持"连续 N 次满足条件才触发"。 七、总结与下一篇预告 本文核心 Token 用量统计用 AOP 切面 + CLS 结构化推送,按用户/会话/模型维度分析 语义缓存用 VectorStore 做相似度匹配,命中率 38%,Token 消耗降 38% Token 告警三条规则:日预算/单用户/突增,企业微信通知 综合成本治理:月成本从 ¥7200 降到 ¥1518,降幅 79% 下一篇预告
下一篇《SpringAI 安全合规与对话审计》是系列收官,解决"AI 客服上线必须过的安全合规关": 敏感词过滤与 PII 脱敏 对话审计日志与合规留存 留痕追溯与监管报送 系列全 10 篇回顾 真实性声明: 本文基于腾讯云 CLS + ES 8.x + 混元实测。缓存命中率数据来自 12000 轮真实客服对话统计,成本按混元官方定价计算。 👍 如果本文对你有帮助,欢迎点赞、收藏、转发! 💬 有任何问题或建议,请在评论区留言交流
专栏导航: 📖 上一篇: SpringAI 多模型路由:混元+降级 📖 下一篇: SpringAI 安全合规与对话审计