首页 / 文章 / 提示词缓存怎么省钱:命中价与原价

提示词缓存怎么省钱:命中价与原价

拆开 Anthropic 显式缓存与 OpenAI 自动缓存的计费方式,用 claude-sonnet-5 的命中价和原价算一笔账,并给出能命中的提示词排布与请求模板。

缓存省的是哪一段

多轮对话和长系统提示里,大部分 token 每次都一模一样。缓存把这些前缀存在服务端,下次命中就按更低的价格计费,省下的钱与前缀长度成正比,与调用次数成正比。请求结构几乎不用改,变的是前缀的稳定程度。

粗略估算一句话就够:省下的钱 ≈ 前缀 token 数 ×(输入原价 − 命中价)× 命中次数。前缀两万 token、每天命中两百次,按 claude-sonnet-5 的价格算,一天省 9 美元左右,一个月接近 270 美元。

Anthropic:显式标记,写入更贵

Anthropic 的 prompt caching 要在请求里标出缓存点,给系统提示或文档块加 cache_control: {"type": "ephemeral"}。缓存写入按输入价的 1.25 倍计费,命中读取按 0.1 倍计费,缓存有存活时间,具体倍数与时长以官方文档为准。

claude-sonnet-5 在 Claude Max 分组输入 2.55 美元每百万 token,对应缓存写 3.19 美元、缓存读 0.255 美元。2 万 token 的前缀用 10 次:不缓存是 0.51 美元;缓存后首次写入 0.064 美元,后 9 次读取合计 0.046 美元,总共约 0.11 美元,省掉近八成。

前缀用两次就能回本。写入溢价只有 25%,每次读取省下 90%,多读一次就把多付的钱赚回来。

OpenAI:自动命中,前缀必须一致

OpenAI 的缓存不用改请求,服务端按前缀自动匹配,命中量在 usage.prompt_tokens_details.cached_tokens 里能看到。折扣力度因模型而异,最小前缀长度和保留时间也不一样,具体以官方文档为准,命中部分通常只有原价的几分之一。

它对前缀的要求更严格:从第一条消息开始逐 token 相同才算命中。在 system 里拼一个当前时间,或者在历史前面插一条"今天是几号",整段前缀就失效,cached_tokens 会直接归零。

提示词怎么排

把变化的部分往后放。系统提示、工具定义、参考文档、few-shot 示例放前面,用户输入和时间戳放后面。

  • 工具定义的顺序固定,别按字典序每次重排。
  • 文档拼接用固定的分隔符和标题。
  • 多轮对话不在前面插入新消息,需要补上下文就写进末尾那条 user 消息。
  • 模型名或版本号变了,缓存自然失效,这属于正常情况。

如果一次请求的前缀只有几百 token,缓存基本没意义,省下的钱还不够一次调用的零头。

一段可复用的请求

python
import requests

BASE = "https://ai.idcidiot.com/v1"
KEY = "sk-..."

# 前缀一个字都不要改,改了就重新计费
PREFIX = """你是财务对账助手,严格按下面的制度回答:
1. 出差住宿一线城市每晚不超过 600 元,其他城市 400 元。
2. 市内交通凭票报销,单次不超过 100 元。
...(把你的制度全文贴在这里,几万字也可以)"""

def ask(question: str) -> str:
    r = requests.post(
        f"{BASE}/chat/completions",
        headers={"Authorization": f"Bearer {KEY}"},
        json={
            "model": "claude-sonnet-5",
            "messages": [
                {"role": "system", "content": PREFIX},
                {"role": "user", "content": question},
            ],
            "max_tokens": 800,
        },
        timeout=120,
    )
    r.raise_for_status()
    data = r.json()
    cached = data["usage"].get("prompt_tokens_details", {}).get("cached_tokens", 0)
    print(f"prompt={data['usage']['prompt_tokens']} cached={cached}")
    return data["choices"][0]["message"]["content"]

print(ask("出差住宿的标准是多少?"))
print(ask("打车费怎么报?"))

如果渠道按 Anthropic Messages 协议转发,缓存点加在 system 的文本块上:{"type": "text", "text": PREFIX, "cache_control": {"type": "ephemeral"}}。这条路径是否开放,看模型页的说明。

什么时候不该开

一次性长文档、前缀每次都要变的任务、总量不到一两千 token 的短请求,都不值得缓存。缓存还会让排查变复杂:改了提示词忘了前缀已经变了,命中率掉下来,账单会先告诉你。

还有一类隐性成本:前缀缓存住以后,改动提示词要整段重发一次。版本迭代频繁的阶段,命中率会一直上不去,这时候先把提示词定稿,再考虑缓存。

判断模型和分组的价格差别,去 定价页 对一下;claude-sonnet-5 的参数在 模型页,OpenAI 系模型可以从 模型总览 里找 gpt-6-astra 这类长上下文型号。

先在日志里加上 cached_tokens,跑两天再决定要不要重排提示词。

用 二五云API 跑通这些模型

OpenAI 兼容接口,一个 Key 调用 GPT、Claude、Gemini、DeepSeek、Kimi 等模型,按量计费。

免费注册查看模型价格

相关文章