跳到正文
Prompt 缓存

Prompt 缓存

自动

托管的开源权重模型会自动缓存重复的 prompt 前缀。当一次请求的系统 prompt、工具和早期消息与同一模型的近期请求相同时,该共享前缀将从缓存中读取,并按模型输入价格的 25% 计费。无需手动启用,且写入缓存免费。

工作原理

  • 前缀顺序 — Prompt 按顺序读取:系统 prompt $\to$ 工具定义 $\to$ 消息。缓存从该序列的起始端匹配,直到出现第一个不同的 token 为止。
  • 命中定义 — 如果一次请求的 prompt 开头与近期请求的内容相同(通常是同一对话的上一轮,并附加了新消息),则匹配的前缀部分为缓存输入;其后的所有内容为常规输入。
  • 粒度 — 缓存以 1,568 tokens 为一块保存 prompt,因此短于约 1,500 tokens 的 prompt 不会被缓存。回复中的缓存计数是你的输入计数乘以 prompt 中被缓存的比例,向下取整。它不一定是块大小的整数倍。
  • 未命中时 — 开头不在缓存中的请求按常规输入单价计费。缓存的 prompt 没有公布保留时长,也不保证命中:请查看 usage 了解请求从缓存中取了多少。
  • 没有开关 — 请求无需主动启用,也没有任何字段可以关闭缓存。
  • 适用模型 — 所有托管的开源权重 ID。GET /v1/models 会报告其 capabilities.prompt_caching: true 以及 pricing.cached_input_per_million_usd。Shannon 模型则按统一费率计费。

在回复中查看缓存命中

发送两个以相同长系统提示词开头的请求,并打印各自的用量。第一个数字是请求的输入,第二个数字是其中从缓存读取的部分。

from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")

handbook = open("handbook.txt").read()  # a long text that stays the same


def ask(question):
    response = client.chat.completions.create(
        model="Kimi-K3-3BIT-REAP",
        messages=[
            {"role": "system", "content": handbook},
            {"role": "user", "content": question},
        ],
    )
    usage = response.usage
    print(usage.prompt_tokens, usage.prompt_tokens_details.cached_tokens)


ask("What is the refund policy?")
ask("Who approves travel?")  # same start: read the second number

定价

缓存输入 token 按模型输入费率的 25% 计费,四舍五入至每 1M $0.001。写入缓存无需额外付费,输出按常规计费。每个 ID 的缓存费率见“模型与定价”表。 模型与定价

一次调用的输入按 (输入 − 缓存) × 输入单价 + 缓存 × 缓存单价 计费。缓存计数永远不会大于输入计数。

模型 输入 / 1M 缓存输入 / 1M
DeepSeek-V4-Pro-0813-3BIT-REAP $1.95 $0.488
GLM-5.2-3BIT-REAP $0.73 $0.183
Kimi-K3-3BIT-REAP $3.83 $0.958
Nemotron3Ultra-3BIT-REAP $0.75 $0.188
MiniMax-M3-3BIT-REAP $0.50 $0.125
DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP $0.50 $0.125
Kimi-K2.6-W4A16-AUTOROUND-REAP $0.78 $0.195
Laguna-S-2.1-W4A16-AUTOROUND-REAP $0.50 $0.125
inkling-W4A16-AUTOROUND-REAP $1.42 $0.355
MiMo-V2.5-Pro-W8A16 $0.50 $0.125
MiMo-V2.5-W8A16 $0.50 $0.125
Hy3-W8A16 $0.50 $0.125

用量日志列出每次调用的缓存输入。其计费 tokens 和费用已经包含缓存单价。 密钥与用量

使用字段

端点 缓存输入 推理
/v1/chat/completions usage.prompt_tokens_details.cached_tokens — prompt_tokens 的一部分 usage.completion_tokens_details.reasoning_tokens — completion_tokens 的一部分
/v1/responses usage.input_tokens_details.cached_tokens — input_tokens 的一部分 usage.output_tokens_details.reasoning_tokens — output_tokens 的一部分
/v1/messages usage.cache_read_input_tokens — 独立报告:input_tokens 为非缓存部分;cache_creation_input_tokens 始终为 0 思考过程计入 output_tokens
{
  "usage": {
    "prompt_tokens": 20000,
    "completion_tokens": 812,
    "total_tokens": 20812,
    "prompt_tokens_details": {
      "cached_tokens": 18000
    },
    "completion_tokens_details": {
      "reasoning_tokens": 604
    }
  }
}

流式回复在最终用量中带有相同的字段。你无需特意请求:

端点 用量的返回位置
/v1/chat/completions data: [DONE] 之前最后一个数据块上的 usage。每个流都会发送。
/v1/responses response.completed 事件的 response.usage。
/v1/messages message_delta 事件的 usage。message_start 的 usage 全为零。

提高缓存命中率

  • 确保多次调用之间的系统 prompt 和工具定义在字节级保持一致。将时间戳或请求 ID 等单次调用值放在最新消息的末尾,而不是系统 prompt 中。
  • 仅在历史记录后追加内容。编辑、修剪或总结早期的对话轮次会改变前缀,导致第一个更改点之后的所有内容都被计为常规输入。
  • 在调用之间不要重新排列工具、消息或内容块,并确保每次以相同方式序列化 JSON(工具 Schema、工具参数和结果)。
  • 一个对话中请始终使用同一个模型 id,并在上一次调用之后尽快发送后续调用。

在以下情况下,API 会保持对话开头稳定:

  • 在对话后面发送的 system 或 developer 消息保持在原位。它不会改变 prompt 的开头,因此它之前的轮次仍保持缓存。
  • 之前 assistant 轮次中工具调用的参数按值比较。该 JSON 的键顺序和空白无关紧要。
  • 三个端点以相同方式读取对话。在另一个端点上继续的对话,只要内容相同,就保留共享的前缀。

请求字段

支持 prompt_cache_key(聊天补全与响应)以及 Messages 内容块中的 cache_control,因此现有客户端代码无需更改即可运行。两者都不是必须的:缓存是自动的,即使没有它们也能正常工作。

字段 发送到 含义
prompt_cache_key /v1/chat/completions, /v1/responses OpenAI API 的缓存路由键。
cache_control /v1/messages Anthropic API 中内容块、system 块或消息上的缓存断点。
stream_options /v1/chat/completions include_usage 用于在 OpenAI API 上请求流的用量。在这里,每个流都以用量结尾。

计算 tokens

两个免费端点 POST /v1/tokenize 和 POST /v1/messages/count_tokens 可在发送之前,为托管开源权重模型统计一段文本或整个请求的 tokens。 它们有专门的页面: Token 计数