О том, как «zero data retention» (нулевое хранение данных), или ZDR, применяется к этой функции, см. API и хранение данных.
Кэширование подсказок значительно сокращает задержку и стоимость, но только когда начало вашей подсказки байт-в-байт идентично недавнему запросу. Переупорядоченный инструмент, временная метка, интерполированная в вашу системную подсказку, или правка более раннего сообщения могут незаметно сделать кэш недействительным. Без диагностики кэша единственным сигналом является падение usage.cache_read_input_tokens до нуля без какого-либо указания на то, что изменилось.
Диагностика кэша закрывает этот пробел. Передайте id вашего предыдущего ответа, и API сравнит два запроса и сообщит вам, где они разошлись (модель, системная подсказка, инструменты или история сообщений), чтобы вы могли устранить первопричину вместо того, чтобы гадать.
Диагностика кэша находится в бета-версии. Включите бета-заголовок cache-diagnosis-2026-04-07 в ваши запросы к API, чтобы использовать эту функцию.
Диагностика кэша в настоящее время доступна только в Claude API. Она не поддерживается в Amazon Bedrock или Google Cloud.
Когда бета-заголовок присутствует, API сохраняет лёгкий отпечаток (fingerprint) каждого запроса, индексированный по id ответа. В вашем следующем запросе включите этот id как diagnostics.previous_message_id. API заново строит отпечаток для нового запроса, сравнивает его с сохранённым и прикрепляет к ответу объект diagnostics, описывающий первую точку расхождения.
Сравнение касается структуры запроса, независимо от того, произошло ли фактическое попадание в кэш. См. Чтение диагностики вместе с usage о том, как сочетать результат diagnostics с usage.cache_read_input_tokens.
Отпечатки содержат только хэши и оценки количества токенов (никогда не сырое содержимое подсказки), хранятся ограниченное время, ограничены вашей организацией и рабочим пространством и не используются ни для каких других целей.
Отправляйте бета-заголовок на каждом ходе. На первом ходе передайте "previous_message_id": null, чтобы включить функцию без предыдущего сообщения для сравнения. На последующих ходах передавайте id из предыдущего ответа.
client = anthropic.Anthropic()
SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"
# Ход 1: включаем функцию с previous_message_id=None
r1 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[{"role": "user", "content": "Summarize section 1."}],
diagnostics={"previous_message_id": None},
betas=["cache-diagnosis-2026-04-07"],
)
# Ход 2: ссылаемся на идентификатор предыдущего ответа
r2 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
)
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")В ответах с потоковой передачей diagnostics появляется в событии message_start.
# Ход 2: потоковая передача со ссылкой на id предыдущего ответа
with client.beta.messages.stream(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
r2 = stream.get_final_message()
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")Событие message_start несёт полное поле diagnostics; см. Формат ответа для возможных значений.
В многоходовом разговоре передавайте последний id ответа вперёд как previous_message_id на каждом ходе. Первая итерация передаёт null для включения функции; каждая последующая итерация передаёт id из предыдущего ответа.
Этот рабочий процесс плохо переносится на одноразовую команду оболочки. См. вкладки SDK для шаблона цикла; HTTP-запрос для каждого хода идентичен Базовому использованию.
Поле diagnostics в ответе Message имеет четыре возможных состояния:
| Значение | Смысл |
|---|---|
| поле отсутствует | Запрос не включал diagnostics, или бета-заголовок отсутствовал. |
null | Либо previous_message_id был null (первый ход, нечего сравнивать), либо сравнение выполнено и расхождений не найдено. |
{"cache_miss_reason": null} | Сравнение всё ещё выполнялось, когда ответ был сериализован. Это может произойти, когда ответ начинается очень быстро. Считайте это неокончательным и проверьте следующий ход. |
{"cache_miss_reason": {...}} | Прикреплён cache_miss_reason. Для типов *_changed это определяет первую точку расхождения; previous_message_not_found и unavailable — это случаи, когда сравнение не было произведено. |
Когда cache_miss_reason не равен null, он выглядит так:
{
"id": "msg_01Xyz...",
"type": "message",
"role": "assistant",
"content": [{ "type": "text", "text": "..." }],
"usage": {
"input_tokens": 42,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 41850,
"output_tokens": 210
},
"diagnostics": {
"cache_miss_reason": {
"type": "system_changed",
"cache_missed_input_tokens": 41850
}
}
}cache_miss_reason — это дискриминированное объединение по type. Ответ сообщает только о самом раннем расхождении, поэтому сначала исправьте его; более поздние могут быть скрыты за ним.
| Тип | Что это означает | Что изменить |
|---|---|---|
model_changed | model отличается от предыдущего запроса (например, маршрутизатор, A/B-тест или резервный вариант выбрал другую модель). Кэш привязан к модели. | Держите модель постоянной в рамках кэшированного разговора. |
system_changed | Параметр system отличается. Обычно временная метка, идентификатор запроса или другое значение, зависящее от запроса, было интерполировано в системную подсказку. | Сделайте системную подсказку байтово-стабильной константой и переместите динамические данные в первое сообщение user после вашей точки останова кэша. |
tools_changed | Массив tools отличается: инструменты были добавлены, удалены или переупорядочены между ходами, или JSON input_schema инструмента был сериализован недетерминированно. | Отправляйте один и тот же список инструментов на каждом ходе в фиксированном порядке с детерминированно сериализованными схемами (например, сортируйте ключи). |
messages_changed | Модель, система и инструменты совпадают, но более ранняя запись в messages была изменена, переупорядочена или удалена, а не дополнена. Обычно история разговора была усечена или отредактирована, или ходы ассистента и блоки tool_result были повторно сериализованы иначе при повторной отправке. | Рассматривайте историю как только дополняемую (append-only); возвращайте content ассистента и результаты инструментов дословно. |
previous_message_not_found | Для предоставленного previous_message_id не существует сохранённого отпечатка. Это не свидетельство того, что ваш запрос изменился. Обычно предыдущий запрос не содержал бета-заголовок, он пришёл из другого рабочего пространства, или прошло слишком много времени с момента его отправки. | Отправляйте бета-заголовок на каждом ходе и держите последовательные ходы близко друг к другу по времени. |
unavailable | Диагностическая информация была недоступна для этого запроса. Это включает случай, когда model, system и tools совпадают, но другой параметр запроса, влияющий на подсказку (tool_choice, thinking, context_management, output_config, output_format или набор активных заголовков anthropic-beta), отличается, а также очень длинные разговоры, где расхождение находится за пределами горизонта сравнения. Ваш запрос был обработан нормально. | Держите параметры запроса, влияющие на подсказку, постоянными на протяжении всего времени жизни кэшированного разговора. Если проблема сохраняется, примените ручные проверки из раздела Устранение распространённых проблем на странице кэширования подсказок. |
Четыре типа *_changed также несут целое число cache_missed_input_tokens: оценку того, сколько входных токенов оказалось после точки расхождения, что даёт вам представление о том, сколько кэшируемого префикса было потеряно. Оно вычисляется из длин в байтах до токенизации, поэтому рассматривайте его как индикатор порядка величины, а не как число для выставления счетов. Оно может отличаться от usage.input_tokens (и иногда превышать его).
diagnostics отвечает на вопрос «изменился ли мой запрос?», в то время как usage.cache_read_input_tokens отвечает на вопрос «произошло ли попадание в кэш?». Их сочетание подсказывает, где искать.
Эта матрица применима к ходам, где вы передали реальный previous_message_id. На первом ходе (previous_message_id: null) diagnostics всегда равен null, а cache_read_input_tokens обычно равен нулю, потому что кэш записывается, а не читается; устранение неполадок не требуется. Матрица также не применяется, когда cache_miss_reason равен null (сравнение всё ещё выполняется; проверьте следующий ход) или когда его type — previous_message_not_found или unavailable (сравнение не было произведено).
| Результат диагностики | Токены чтения кэша | Интерпретация |
|---|---|---|
null | много | Работает как ожидается. Ваш префикс стабилен, и произошло попадание в кэш. |
null | мало или ноль | Ваши запросы совпадают, но запись в кэше больше не была доступна. Рассмотрите возможность сокращения промежутков между ходами или использования 1-часового TTL кэша. |
cache_miss_reason имеет тип *_changed | мало или ноль | Ваша ошибка. Запрос изменился; устраните причину, указанную в type. |
cache_miss_reason имеет тип *_changed | много | Редко. Изменение произошло поздно в подсказке, но более ранняя точка останова cache_control всё же сработала. Стоит исправить, но влияние невелико. |
previous_message_id истекают через короткий период. Выполняйте диагностические сравнения между близко расположенными по времени запросами.unavailable, а не точным местоположением.unavailable или cache_miss_reason: null, когда сравнение всё ещё выполнялось.Диагностика кэша соответствует требованиям ZDR (квалифицирована). Anthropic не хранит сырой текст ваших подсказок или выходных данных Claude для этой функции.
Отпечаток, сохраняемый для каждого запроса, состоит только из криптографических хэшей и оценок количества токенов, индексирован по id ответа и ограничен вашей организацией и рабочим пространством. Отпечатки истекают через короткий период и не используются ни для каких других целей.
О соответствии требованиям ZDR для всех функций см. API и хранение данных.
Was this page helpful?