Эта функция соответствует требованиям Zero Data Retention (ZDR) с ограниченным техническим хранением. Подробности о том, что сохраняется и почему, см. в разделе Хранение данных.
Кэширование подсказок значительно снижает задержку и стоимость, но только если начало вашей подсказки побайтово идентично недавнему запросу. Переупорядоченный инструмент, временная метка, подставленная в вашу системную подсказку, или правка в более раннем сообщении могут незаметно инвалидировать кэш. Без диагностики кэша единственным сигналом является падение usage.cache_read_input_tokens до нуля — без какого-либо указания на то, что изменилось.
Диагностика кэша закрывает этот пробел. Передайте id вашего предыдущего ответа, и API сравнит два запроса и сообщит вам, где они разошлись (модель, системная подсказка, инструменты или история сообщений), чтобы вы могли устранить первопричину, а не гадать.
Диагностика кэша находится в бета-версии. Включите бета-заголовок cache-diagnosis-2026-04-07 в ваши запросы к API, чтобы использовать эту функцию.
Диагностика кэша в настоящее время доступна только в Claude API. Она не поддерживается в Amazon Bedrock или Vertex AI.
Когда бета-заголовок присутствует, 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-4-8",
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-4-8",
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: потоковая передача со ссылкой на идентификатор предыдущего ответа
with client.beta.messages.stream(
model="claude-opus-4-8",
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 из предыдущего ответа.
Поле 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 — это размеченное объединение (discriminated union) по полю type. В ответе сообщается только о самом раннем расхождении, поэтому сначала исправьте его; более поздние могут быть скрыты за ним.
| Тип | Что это означает | Что изменить |
|---|---|---|
model_changed | Параметр model отличается от предыдущего запроса (например, маршрутизатор, A/B-тест или резервный вариант выбрал другую модель). Кэш привязан к конкретной модели. | Сохраняйте модель неизменной в рамках кэшируемого разговора. |
system_changed | Параметр system отличается. Обычно в системную подсказку была подставлена временная метка, идентификатор запроса или другое значение, уникальное для каждого запроса. | Сделайте системную подсказку побайтово стабильной константой и переместите динамические данные в первое сообщение user после вашей точки разрыва кэша. |
tools_changed | Массив tools отличается: инструменты были добавлены, удалены или переупорядочены между ходами, либо JSON input_schema инструмента был сериализован недетерминированно. | Отправляйте один и тот же список инструментов на каждом ходе в фиксированном порядке с детерминированно сериализованными схемами (например, сортируйте ключи). |
messages_changed | Модель, system и tools совпадают, но более ранняя запись в messages была изменена, переупорядочена или удалена вместо того, чтобы к ней было добавлено новое. Обычно история разговора была усечена или отредактирована, либо ходы ассистента и блоки tool_result были повторно сериализованы иначе при повторной отправке. | Рассматривайте историю как доступную только для добавления; возвращайте 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?