「从零到 AI 应用工程师」专栏 · 第 17 篇
RAG 比纯聊天多了检索,但大头费用往往仍在大模型 token 。
演示时同一句问十遍、前端重试、热门故障码被反复点------不缓存就重复付费。
今天两件事:把每次花销记下来 ,以及 FAQ 级缓存。
一、先看见钱:token 用量进日志与响应
每次 LLM 调用后记录:
| 字段 | 含义 |
|---|---|
prompt_tokens |
输入(含参考片段!) |
completion_tokens |
输出 |
total_tokens |
合计 |
cost_cny |
按单价估算(可标 estimated) |
响应里带上 token_usage,日志里带 request_id,你才能回答:
- 哪类问题最贵?(往往是参考片段太长)
- 缓存命中后是否降为 0 模型调用?
- 调小
MAX_RAG_CONTEXT_CHARS有没有省钱?
单价放配置,不写死在代码;换模型只改价表。
二、FAQ 缓存放哪一层
和 chat-api 的 Redis 缓存同构,但 Key 要包含「会影响答案的因素」:
text
rag:faq:{hash(规范化问题 + filter_category + 关键开关)}
流程:
text
POST /rag/query
→ 查 Redis
├─ 命中:直接返回,from_cache=true,跳过检索/Rerank/LLM
└─ 未命中:走全链路 → 写入缓存(TTL)
建议:
| 情况 | TTL / 策略 |
|---|---|
| 正常有依据回答 | 较长 TTL |
| 拒答 | 短 TTL(避免错误拒答缓存太久) |
llm_error |
不缓存 |
知识库更新(新文档入库)后:按前缀批量失效,或接受 TTL 内短暂旧答案。
三、省钱的其它杠杆(缓存之外)
- 上下文截断:参考片段总长设上限;
- Rerank 后少喂:Top5→Top3,少 token;
- 热门问题缓存:比反复跑全链路便宜;
- 检索调试走
/retrieve:别每次调试都打付费生成。
四、验收
- 一次问答响应含
token_usage或日志可查 - 同一问题连打两次,第二次
from_cache=true(若已启用) - 错误 Token/失败结果不会脏缓存
五、带走这三条
- 先计量,再优化------看不见 token 就谈不上省钱。
- FAQ 缓存 Key 要包含过滤条件与规范化问句。
- 拒答短 TTL、错误不缓存;入库后要能失效。
下一篇(阶段 2 收官):pytest 三条底线------入库、检索、引用,防止重构改崩。
这是专栏第 17 篇。两到三天一更,测试见。