缓存价降 60% 后,发送全量 schema(带缓存)vs 仅检索相关 schema 的成本比从 2.1x 缩至 1.2x,决策点从成本转向准确率。
TL;DR: Claude Opus 5.5 昨天发布,cache reads 价格降到每百万 token $0.20,比 Opus 5 便宜了 60%。我重新算了一遍 text-to-SQL CRM 助手的成本账。对于一种设计方案,"只取相关 schema"和"每次发送完整 schema 并缓存"之间的成本差距从 2.1 倍缩小到了 1.2 倍。到了这个节点,选择就不再是成本问题,而是准确率问题。迁移指南里还有两个 breaking changes 会直接影响 text-to-SQL 架构。
几个月前我写过 Aria,它是一个 AI 助手,让 CRM 代理可以用自然语言提问并从实时 SQL 中获取答案。
核心技巧是对 schema 做 RAG,而不是对数据做 RAG。一个 Python pipeline 会把 CRM 里每个表、每个列、每个枚举值写成一段纯英文描述(约 90 个文档)。当代理提问时,我会把问题向量化,在这些文档上跑一遍 pgvector 搜索,然后把最相关的 5 个文档连同问题一起发给模型。
我这样设计的理由是:
成本。我不想每次请求都为整个语义层付费。
专注。我认为模型看到 5 张相关表比看到全部 15 张表写出的 SQL 更好。
Opus 5.5 的定价基本上把理由 #1 去掉了。剩下的理由 #2,我从未真正测量过。
大多数报道关注的是输入和输出降价 20%。但对于 schema 密集型工作负载来说,cache reads 才是关键。以前 cache reads 价格是输入价的 0.1 倍,现在降到了 0.05 倍。
以下是我的假设,你可以代入自己的数字:
我只计算 prompt 中 schema 部分,因为那是两种设计方案唯一有差异的部分。
方案 A:检索 top-5,不缓存(检索出的文档每个问题都不同,所以没有稳定的可缓存前缀)
方案 B:每次请求发送完整语义层作为缓存前缀
在 Opus 5.5 上,每个问题的成本是 $0.0044 vs $0.0053。按每月 22 个工作日算,约是 $77 vs $92。
在 Opus 5 上,"直接把全部给模型"要贵一倍,这让 pgvector 步骤很容易被证明合理。在 Opus 5.5 上,整个团队每月多花约 $15。
到了这个价格,成本就不再决定选择。准确率才是。
每个问题前不再需要 embedding 调用或向量搜索。少了一次网络跳转,也少了一个可能出错的环节。
不会有检索漏召回。用检索时,如果问题说"stale leads"而 embedding 没有拉出解释 last_activity_at 的那个文档,SQL 在模型开始工作前就已经错了。用完整语义层,模型始终能看到每张表。
一个静态的 prompt 前缀,这对下一节很重要。
它不能替代的是:intent examples,那些从点赞反馈中提炼出来的问题→SQL 对。它们会随时间积累,所以仍然需要放在检索步骤里。最终形态很可能是混合的:静态缓存的 schema 加上检索出来的 examples。
我带着 Aria 的视角读了 Opus 5.5 迁移指南。有两个变化比较突出。
tool_choice 类型为 tool 或 any 的请求会被拒绝。很多 text-to-SQL 架构会强制模型调用 run_sql 工具,防止它凭记忆回答。在 Opus 5.5 下,修复方法是 tool_choice: auto,把工具标记为 strict,并在 prompt 里明确说明何时必须使用该工具。
我的 SQL 校验器不需要改。那个步骤从来不信任模型:只做 SELECT 检查、从 JWT 注入 agent ID、只读 Postgres 角色。迁移到更好的模型不应该移动你的信任边界。
Opus 5.5 中 thinking 始终开启(用 effort 控制,而不是关闭)。指南要求保持对话 append-only,不要在对话中途编辑 system、tools 或更早的消息。对于较新的账户,在这种编辑之后重放 thinking 块默认会返回 400。
如果我把当前设计不做修改直接迁移到 Opus 5.5,这就有问题了。我会在每一轮重新构建 system prompt,加入新的一组检索出的 schema 文档。这等于是在对话中途编辑了 system。
所以合规有两个方向:
把检索出的文档从 system 移出来,放到每个新的 user turn 里,或者
让 system 保持静态——也就是方案 B。
定价和 API 现在都指向同一个方向:把大量、很少变化的内容放在静态前缀里,缓存它,只通过追加来添加新内容。
请求体大致长这样:
{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"output_config": { "effort": "low" },
"system": [
{ "type": "text", "text": "You write read-only PostgreSQL for a student-housing CRM. Always answer by calling query_crm_database." },
{ "type": "text", "text": "<full semantic layer: every table, column, enum>",
"cache_control": { "type": "ephemeral" } }
],
"tools": [{ "name": "query_crm_database", "strict": true, "...": "..." }],
"tool_choice": { "type": "auto" },
"messages": [
{ "role": "user", "content": "<retrieved intent examples>\n\nWhich of my leads haven't been contacted in 3 days?" }
]
}
(我会在格式化 pass 用 effort: low,在 SQL 生成时试一下 medium——新的默认值。)
我还没切换到 Opus 5.5。这只是纸上算账和文档精读,不是基准测试。计划如下:
用 schema pipeline 已经生成的 30 个问题→SQL examples 作为评估集。
跑两种方案:top-5 检索 vs 完整缓存层。
比较生成的 SQL 和参考 SQL 返回的行数是否一致,以及延迟和实际成本(从 usage 字段里看,cache_read_input_tokens 能告诉你缓存是否真的生效了)。
如果完整上下文版本准确率至少相当,我就从问题路径上去掉 pgvector 步骤。有结果了会发出来。
如果你在做 text-to-SQL,你是每个问题检索 schema 还是全量发送?更便宜的缓存有没有让你重新思考 RAG 周围的那些环节?欢迎在评论区留言。