# OpenRouter 推出 Prompt Caching + Sticky Routing，降低多轮 Agent 调用成本

- 来源：OpenRouter：Announcements（RSS）
- 作者：OpenRouter
- 发布时间：2026-07-21 08:00
- AIHOT 分数：69
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmruybn7500lbbinvrohd9rio
- 原文链接：https://openrouter.ai/blog/tutorials/prompt-caching-sticky-routing

## 精选理由

Prompt caching 不是新概念，但 OpenRouter 把成本算得明明白白，sticky routing 配合 session_id 解决了缓存漂移的痛点，做 agent 的人该抄作业。

## AI 摘要

OpenRouter 通过 Prompt Caching 与 Sticky Routing 降低多轮 Agent 的 token 成本。缓存读取价格仅为正常输入的 0.1x-0.5x，其中 Claude Sonnet 4.6 缓存读取为 $0.30/M（正常 $3.00/M）。

## 正文

你的智能体在每一轮都会发送相同的系统提示词、工具定义、数据结构和策略指令。在一个 6 轮的会话中，即使唯一变化的只是用户的最新消息或智能体的最新工具结果，你也会为同一段开头内容被计费 6 次。

提示词缓存解决了这个问题。服务提供方会从缓存中读取你提示词中重复的部分，而不是每次都按全价向你收费。粘性路由则通过将会话送回持有热缓存的同一服务提供方，让这种机制在跨轮次中持续生效。

这篇文章讲的是钱的问题：缓存 token 的成本是多少，为什么缓存读取和写入的定价不同，session_id 如何从第一轮开始就让智能体的会话保持热状态，以及如何检查缓存是否真的在起作用。

太长不看版

缓存读取的成本是全新输入 token 的 0.1 倍到 0.5 倍，具体取决于服务提供方。在 Claude Sonnet 4.6 上，缓存读取的价格是 $0.30/M，而输入价格是 $3.00/M，正好是 0.1 倍。

第一个请求需要支付缓存写入费用。Anthropic 的写入成本是输入的 1.25 倍（5 分钟 TTL）或 2.0 倍（1 小时 TTL），所以一次未被复用的写入比完全不缓存还要贵。

热缓存只有在你的下一个请求落到同一个服务提供方端点时才有用。在 70 多个服务提供方之间，第二轮可能会命中冷端点，这时你就要付全价。

我们的粘性路由会把后续请求固定到持有热缓存的服务提供方上，而 session_id 则从第一个成功请求开始就强制这一点，哪怕此时还没有发生过任何缓存命中。

缓存未命中有 4 个原因：提示词太短、缓存过期、开头内容不断变化，或者请求被转移到了不同的服务提供方。请检查 usage 响应中的 cached_tokens 字段来确认是否命中。

提示词缓存能帮你省下多少 token 成本？

缓存读取的成本是正常输入定价的 0.1 倍到 0.5 倍，具体取决于服务提供方。正是这个区间，让缓存能够大幅降低智能体循环的成本。

重复的部分通常就是最昂贵的部分：一段很长的系统提示词、工具定义、JSON 模式、护栏、检索到的文档，或者让模型保持一致的示例。如果没有缓存，每一轮都要为所有这些内容再次支付全价。有了缓存，第一个请求会将其写入缓存，后续请求则以更低的费率读取。

以下是服务商层面的情况：

服务商缓存读取缓存写入启用方式

Anthropic Claude（5 分钟 TTL）输入价格的 0.1 倍输入价格的 1.25 倍自动或显式

Anthropic Claude（1 小时 TTL）输入价格的 0.1 倍输入价格的 2.0 倍显式（ttl: "1h"）

OpenAI（GPT-5.6 之前）输入价格的 0.25 倍-0.50 倍免费自动

OpenAI（GPT-5.6 及之后）输入价格的 0.25 倍-0.50 倍输入价格的 1.25 倍自动或显式

Google Gemini（隐式）输入价格的 0.25 倍免费自动

Grok (xAI)输入价格的 0.25 倍免费自动

Moonshot AI输入价格的 0.25 倍免费自动

Groq输入价格的 0.5 倍免费自动（Kimi K2 模型）

DeepSeek输入价格的 0.1 倍输入价格的 1.0 倍自动

阿里云 Qwen输入价格的 0.1 倍输入价格的 1.25 倍显式（cache_control）

Z.AI约输入价格的 0.2 倍免费自动

提示词缓存文档中有完整的详细说明。具体的美元金额仍取决于模型和服务商路由；这个倍数告诉你，对于该服务商而言，缓存输入与正常输入的价格对比情况。

对于智能体构建者来说，模式很简单：第一轮可能需要付费来建立缓存，但只要后续轮次复用相同的开头部分，之后的每一轮都会便宜得多。

成本花在哪里：缓存写入还是缓存读取？

提示词缓存有两种成本：写入和读取。

当服务商存储提示词中可复用的部分时，就会发生写入。当后续请求复用该存储内容时，就会发生读取。一旦相同内容被读取足够多次以覆盖写入成本，你就开始省钱了。

在某些服务商那里，写入成本高于正常输入。Anthropic 的缓存写入，默认 5 分钟 TTL 的成本是输入价格的 1.25 倍，1 小时 TTL 的成本是输入价格的 2.0 倍。如果一次 Anthropic 缓存写入从未被复用，其成本比不缓存直接发送相同提示词还要高。

对于一次性请求，缓存可能帮不上忙。但对于多轮智能体而言，重复才是常态：智能体在整个会话期间都携带相同的指令、工具、模式（schema）和策略上下文。因此，写入缓存的成本在几轮之后就能回本。

对于下一轮很快到来的短促请求，请使用 5 分钟缓存生命周期（TTL）。当会话可能暂停较久、导致默认缓存过期，但内容仍值得保留时，请使用 1 小时缓存生命周期。

为什么热缓存并不总能对下一个请求生效？

只有当下一个请求落在持有该缓存的提供商端点上时，热缓存才会生效。

当请求可以路由到多个提供商时，第一轮可能在某个提供商上写入缓存，而第二轮却落在另一个提供商上。第二个提供商没有可读取的热缓存。请求仍然能正常工作，但你需要支付全价，且 cached_tokens 会保持很低或为零。

这就是为什么我们将粘性路由与提示词缓存搭配使用。在缓存请求之后，当某个提供商的缓存读取价格低于常规输入价格时，我们会将同一模型的后续请求路由回该提供商的同一端点。如果该粘性提供商不可用，OpenRouter 会回退到下一个可用提供商，而不是让请求失败。

默认情况下，OpenRouter 通过对会话的第一条系统消息或开发者消息以及第一条非系统消息进行哈希来识别会话。当这些开头消息保持不变时，这种方式有效。

智能体常常会打破这一点。有些智能体会在总结状态时重写首条消息、重新排列工具上下文，或添加新的运行元数据。当开头消息发生变化时，哈希值也会改变，会话就可能落到不同的提供商上。解决办法是使用显式的 session_id。

使用 session_id 从第一轮起强制启用热缓存

对于智能体循环，请设置 session_id。当你传入该参数时，OpenRouter 会直接将其用作粘性路由键，而不是从开头消息推导出键值。

使用 `session_id` 时，粘性路由会在首次请求成功之后、任何缓存命中发生之前就生效。如果不使用它，粘性只能在检测到缓存命中后才开始。对于多轮智能体来说，这决定了缓存是从第一轮起就可靠，还是只能偶尔保持温热。

你可以将 `session_id` 作为请求体的顶层字段发送，也可以通过 `x-session-id` 请求头传递。请在整个对话或智能体运行期间保持其稳定，并将其长度控制在 256 个字符以内。

curl https://openrouter.ai/api/v1/chat/completions \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-4.6", "session_id": "my-agent-session-abc123", "messages": [{"role": "system", "content": "..."}] }'

from openrouter import OpenRouter

client = OpenRouter()

resp = client.chat.send( model="anthropic/claude-sonnet-4.6", session_id="my-agent-session-abc123", messages=[{"role": "system", "content": "..."}], )

import { OpenRouter } from '@openrouter/sdk';

const openRouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });

const response = await openRouter.chat.send({ model: 'anthropic/claude-sonnet-4.6', session_id: 'my-agent-session-abc123', messages: [{ role: 'system', content: '...' }], });

请使用与工作单元相匹配的值：例如一个聊天线程、工单、工作流运行或智能体任务。不要为每一轮都创建新的 `session_id`，否则请求将无法继续落在持有缓存的供应商上。

如果你使用 Auto Router 或 Pareto Router 这类路由模型，会话粘性还会固定住路由器所选定的模型，而不仅仅是供应商。这可以防止对话在会话中途切换模型，从而保持行为一致性并让缓存保持温热。

我该如何确认提示词缓存是否真的在生效？

最快的检查方式是查看 usage 信息。

在响应中，`usage.prompt_tokens_details.cached_tokens` 会显示从缓存中读取了多少 token。如果该值大于零，说明请求命中了缓存。`cache_write_tokens` 则显示在一次缓存写入请求期间写入了多少 token。

{ "usage": { "prompt_tokens": 10339, "completion_tokens": 60, "total_tokens": 10399, "prompt_tokens_details": { "cached_tokens": 10318, "cache_write_tokens": 0 } } }

在这个示例中，大部分提示词 token 都来自缓存，而这一轮没有写入新的缓存条目。

你可以在三个地方检查缓存行为：Activity 页面的详情视图、`/api/v1/generation` API，以及 API 响应中返回的 `usage.prompt_tokens_details` 对象。

使用 `cache_discount` 来查看一次生成节省了多少成本。在按写入计费的供应商上，你可能会在写入轮次看到负折扣，因为缓存写入的成本高于普通输入。在后续的缓存读取轮次中，折扣应该会转为正值。

为什么你的缓存会未命中，又该如何避免？

当缓存看起来失效时，通常可以归结为以下 4 个原因之一：提示词太短、缓存已过期、开头内容发生变化，或者请求被转移到了不同的供应商。

提示词低于供应商的最低要求。

每个提供商都有最低提示词大小要求，低于该要求则不会缓存任何内容。在 Anthropic 上，Claude Opus 4.5 至 4.8 以及 Claude Haiku 4.5 需要 4,096 个 token；Claude Haiku 3.5 需要 2,048 个；Claude Sonnet 4、4.5 和 4.6（以及 Opus 4 / 4.1）需要 1,024 个。OpenAI 需要 1,024 个。Gemini 2.5 Pro 需要 4,096 个；Gemini 2.5 Flash 需要 1,024 个。

如果你的可复用内容低于该最低要求，缓存将不会启动。不要为了强行触发缓存而用填充文本给请求注水。请在你已经拥有大量可复用内容的地方使用缓存：工具、模式、检索到的文档、示例或策略文本。

缓存在两轮对话之间过期了

缓存的存活时间不长。Anthropic 的默认值是 5 分钟，并提供 1 小时选项用于更长的会话。Gemini 的隐式缓存大约持续 3-5 分钟，并且读取时不会重置计时。一旦缓存过期，下一个请求就必须写入新的缓存。

如果你的用户经常在轮次之间停顿，请在支持的情况下使用更长的 TTL，或者将智能体设计为在空闲期后接受新的缓存写入。

提示词的开头一直在变化

自动和隐式缓存在提示词开头保持不变时效果最佳。把稳定的内容放在前面：系统指令、工具、模式以及固定的参考资料。把变化的内容放在后面：用户问题、时间戳、临时状态、工具输出和短期元数据。

小细节在这里很重要。第一条系统消息中的时间戳会让提示词在每一轮看起来都是新的。如果时间戳不需要成为缓存内容的一部分，请将其移到后面的用户或工具消息中。

请求被路由到了不同的提供商

缓存放置在它被写入的地方。如果后续请求被路由到不同的提供商端点，该端点无法读取之前的缓存。

对于智能体工作流，请设置 `session_id`，并让粘性路由将会话保持在已预热（有缓存）的提供商上。有一点需要注意：如果你自己设置了 `provider.order`，你的顺序会优先于粘性路由。如果你需要特定的提供商顺序，请使用提供商路由控制。

将缓存和粘性路由结合用于智能体循环

如果你的智能体在每一轮都发送相同的内容，请遵循以下检查清单：

将稳定内容放在前面：系统提示词、工具定义、模式、策略和长期上下文。

将变化的内容放在后面：用户消息、工具结果、时间戳以及每次运行特有的状态。

为需要显式 `cache_control` 的提供商启用提示词缓存。

为对话或工作流运行设置稳定的 `session_id`。

检查 `cached_tokens` 和 `cache_discount`，确认缓存读取确实在发生。

粗略来说，可以想象一个智能体在 6 轮对话中重复使用相同的 10,000 个 token。

场景第 1 轮第 2-6 轮总成本（对比 1 轮无缓存）

无缓存完整输入每轮完整输入6.0 倍

Anthropic 5 分钟缓存 + 粘性路由1.25 倍写入0.1 倍读取1.75 倍

免费写入提供商 + 0.25 倍读取1.0 倍输入/写入0.25 倍读取2.25 倍

免费写入提供商 + 0.5 倍读取1.0 倍输入/写入0.5 倍读取3.5 倍

此示例仅涵盖重复内容，忽略了较小的变化消息和模型的输出 token。节省的成本会随着轮数增加而增长。

何时使用哪种方式：

对于多轮对话，当复用内容随对话增长时，使用自动缓存。

当你确切知道哪些大块内容应被缓存时，使用显式缓存断点：检索到的文档、长参考文件、角色卡、CSV 数据或策略文本。

对于智能体会话、支持工单、聊天线程、工作流运行，以及任何开场消息可能在轮次之间变化的对话，使用 `session_id`。

对于更长的 Anthropic 会话，当默认的 5 分钟缓存可能在轮次之间过期时，使用 1 小时缓存。对于简短、密集的来回对话，使用默认设置。

当你的智能体反复发送相同的昂贵内容时，缓存读取和粘性路由可防止它成为循环中最昂贵的部分。

常见问题

OpenRouter 支持提示词缓存吗？

支持。OpenRouter 在支持的提供商和模型上支持提示词缓存。大多数提供商会自动启用，而 Anthropic 和阿里巴巴通义千问（Qwen）使用 `cache_control` 进行显式缓存。缓存读取的成本为正常输入定价的 0.1 倍到 0.5 倍，具体取决于提供商，因此在首次请求后，复用的前缀会便宜得多。

在 OpenRouter 上，缓存 token 的费用是多少？

缓存读取的价格为正常输入定价的 0.1 倍至 0.5 倍，具体取决于提供商。Anthropic、DeepSeek 和阿里云通义千问的读取价格为 0.1 倍。OpenAI 的读取价格为 0.25 倍至 0.50 倍。Gemini、Grok 和月之暗面的读取价格为 0.25 倍。Groq 的读取价格为 0.5 倍。

为什么通过 OpenRouter 使用提示词缓存不生效？

常见原因包括：提示词低于提供商的 token 最低要求、缓存已过期、提示词前缀不稳定，或各轮对话之间提供商发生漂移。对于智能体工作流，首先设置一个稳定的 session_id，然后检查 usage 响应中的 cached_tokens，只要该值大于零，即可确认缓存命中。

如何在智能体的多轮对话中保持缓存热度？

为对话、工单或工作流运行传入一个稳定的 session_id。OpenRouter 会将其用作粘性路由键，因此后续请求会路由回持有热缓存的同一提供商端点。设置 session_id 后，粘性会在首次成功请求后激活，此时尚未观察到任何缓存命中。

如何检查缓存是否节省了费用？

检查 usage.prompt_tokens_details.cached_tokens 以查看缓存读取情况，检查 cache_write_tokens 以查看缓存写入情况；cached_tokens 值大于零即确认命中。您还可以查看响应中的 cache_discount，以了解每次生成的成本影响，或者打开 Activity 页面或 /api/v1/generation API 中的详情视图。

缓存功能在 Auto Router 下是否可用？

可用。设置 session_id 后，Auto Router 和 Pareto Router 等路由模型会将解析后的模型和提供商固定到该对话，因此后续轮次会持续命中同一个热缓存。
