Кредит при резервном переключении
Избегайте двойной оплаты стоимости кэша подсказок при повторной отправке отклонённого запроса на другую модель.
Кэши подсказок привязаны к конкретной модели. Когда модель отклоняет запрос и вы повторяете его на другой модели, префикс разговора, уже закэшированный для первой модели, должен быть записан в кэш новой модели с нуля. Запись в кэш стоит дороже, чем чтение из кэша. «Fallback credit» (кредит при резервном переключении) устраняет эту дополнительную стоимость. Отказ содержит токен кредита, вы передаёте этот токен обратно при повторной попытке, и повторная попытка тарифицируется так, как если бы разговор с самого начала вёлся на новой модели.
Эта страница нужна вам только в том случае, если вы реализуете повторную попытку самостоятельно: через «сырой» HTTP или с собственной логикой повторов. Резервное переключение на стороне сервера и промежуточное ПО SDK применяют кредит при резервном переключении автоматически. Если вы используете любой из этих вариантов, пропустите эту страницу.
Страница Отказы и резервное переключение описывает обнаружение отказов и выбор подхода к резервному переключению. Страница Кэширование подсказок объясняет, что такое «cache reads» (чтение из кэша) и «cache writes» (запись в кэш), если эти термины вам незнакомы.
Базовый процесс
Подключитесь с помощью бета-заголовка
Отправьте запрос, который может быть отклонён, с заголовком
anthropic-beta: fallback-credit-2026-07-01. Заголовокserver-side-fallback-2026-07-01также предоставляет те же поля, а более ранний заголовокfallback-credit-2026-06-01по-прежнему принимается и предоставляет те же поля.Прочитайте два поля из отказа
При отказе
stop_detailsвключает два поля:fallback_credit_token: непрозрачная строка, представляющая кредит.fallback_has_prefill_claim: логическое значение, указывающее, какую форму тела повторного запроса использовать.
Оба поля равны
null, когда для данного отказа кредит недоступен.Сформируйте повторный запрос
Начните с тела отклонённого запроса. Установите
modelв резервную модель и добавьте токен как параметр верхнего уровняfallback_credit_token. Выберите форму тела из следующей таблицы.Отправьте повторный запрос с тем же заголовком
Отправьте повторный запрос с тем же бета-заголовком
fallback-credit-2026-07-01. Заголовок необходим повторному запросу для погашения токена.
Поле fallback_has_prefill_claim сообщает, может ли повторный запрос продолжить частичный вывод отказавшей модели вместо того, чтобы начинать заново:
fallback_has_prefill_claim | Тело повторного запроса |
|---|---|
true | Тело отклонённого запроса без изменений плюс одно добавленное в конец сообщение ассистента, чьё поле content повторяет content отклонённого ответа. Резервная модель продолжает ответ с того места, где остановилась отказавшая модель, а завершённые вызовы серверных инструментов не выполняются повторно. |
false | Тело отклонённого запроса без изменений. |
Пример
В следующем примере выполняется запрос, который может быть отклонён, и токен кредита погашается при повторной попытке на Claude Opus 4.8. Когда повторная попытка отклоняется, пример последовательно спускается по «лестнице отклонений»: последовательности всё более простых форм повторного запроса, описанной в разделе Когда повторный запрос отклонён.
client = Anthropic()
request = {
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}],
}
def send(model: str, body: dict[str, object]) -> BetaMessage:
return client.beta.messages.create(
model=model, betas=["fallback-credit-2026-07-01"], **body
)
response = send("claude-fable-5", request)
if (
response.stop_reason == "refusal"
and (details := response.stop_details)
and (token := details.fallback_credit_token)
):
exact_body = request | {"fallback_credit_token": token}
# Предпочитать форму продолжения, если claim не равен False
if details.fallback_has_prefill_claim is not False:
echoed = [block.model_dump() for block in response.content]
match echoed:
case [*_, {"type": "text"} as final_block]:
final_block["text"] = final_block["text"].rstrip()
attempt = exact_body | {
"messages": [
*request["messages"],
{"role": "assistant", "content": echoed},
]
}
else:
attempt = exact_body
try:
response = send("claude-opus-4-8", attempt)
except BadRequestError as error:
if "redemption temporarily unavailable" in error.message:
raise # Transient: retry with the token within its five-minute window
try:
# Откат к неизменённому телу, по-прежнему с токеном
response = send("claude-opus-4-8", exact_body)
except BadRequestError as retry_error:
if "redemption temporarily unavailable" in retry_error.message:
raise # Transient: retry with the token within its five-minute window
# Сам токен был отклонён: отказаться от него и повторить без него.
response = send("claude-opus-4-8", request)
print(json.dumps({"stop_reason": response.stop_reason, "model": response.model}))Где это работает
Кредит при резервном переключении находится в бета-версии на Claude API, Amazon Bedrock, Claude Platform на AWS, Google Cloud и Microsoft Foundry. Отказы в Message Batches не выпускают токены кредита, а погашение применяется только к прямым запросам Messages API: токен, переданный в пакетном запросе, принимается, но игнорируется.
Резервная модель должна быть одной из разрешённых целей резервного переключения для отказавшей модели. Для Claude Fable 5.1 и Claude Fable 5 это Claude Opus 4.8 (claude-opus-4-8) и Claude Opus 5 (claude-opus-5).
На Claude API и Claude Platform на AWS список целей публикуется как allowed_fallback_models в записи каждой модели в Models API, когда установлен бета-заголовок server-side-fallback-2026-07-01. Список пока не виден при использовании только заголовка fallback-credit-*. Он не предоставляется на Amazon Bedrock, Google Cloud и Microsoft Foundry.
Проверка применения кредита
Возврат виден в поле usage повторного запроса. По сравнению с тем, что тот же запрос показал бы без токена, значение cache_creation_input_tokens ниже, а cache_read_input_tokens выше на ту же величину. Нулевой сдвиг означает, что токен был принят, но переоценивать было нечего, например потому, что кэш резервной модели уже был «прогрет».
Когда повторный запрос отклонён
Большинство повторных запросов погашают токен с первой попытки. Если этого не происходит, API возвращает ошибку 400, которая подсказывает, что попробовать дальше.
Продолжение отклонено: отправьте тело без изменений
Если повторный запрос с добавленным сообщением ассистента отклонён с ошибкой 400, отправьте тело отклонённого запроса без изменений, по-прежнему с токеном.
Токен отклонён: уберите токен
Если тело без изменений также отклонено с ошибкой 400, в сообщении которой упоминается
fallback_credit_token, повторите запрос без токена. Кредит теряется, но сам повторный запрос проходит.
Это отклонение временное, а не вердикт о форме вашего повторного запроса. Повторите тот же запрос с тем же токеном в пределах пятиминутного окна действия токена. Не переходите к следующей ступени лестницы.
Справочник
Следующие разделы описывают пограничные случаи и полные правила погашения. Большинству интеграций они не нужны.
При погашении повторный запрос сравнивается с отклонённым. Каждое поле, формирующее подсказку, должно совпадать в точности. Поля, не формирующие подсказку, могут изменяться в повторном запросе.
| Правило | Поля |
|---|---|
| Должны совпадать в точности | system, messages, tools, tool_choice, thinking и cache_control, а также output_config, mcp_servers, context_management и container, если вы их используете |
| Могут изменяться в повторном запросе | model, max_tokens, stop_sequences, temperature, top_p, top_k, stream, metadata и service_tier |
Форма продолжения (fallback_has_prefill_claim: true) — единственное исключение из правила совпадения messages: она добавляет ровно одно сообщение ассистента в конец messages.
Не удаляйте блоки thinking или redacted_thinking из предыдущих ходов в повторном запросе, даже несмотря на то, что обычный повторный запрос без токена, как правило, их удаляет. Тело должно совпадать с отклонённым запросом, а сервер обрабатывает эти блоки самостоятельно.
Отправляйте в повторном запросе те же заголовки anthropic-beta, что и в отклонённом. Бета-заголовок, присутствующий в одном из двух запросов, но отсутствующий в другом, может привести к несовпадению, даже если тела идентичны. Результирующая ошибка 400 содержит то же сообщение request body ... does not match, что и при различии тел, поэтому различие в заголовках легко ошибочно принять за проблему с телом. В частности, не добавляйте и не убирайте бета-заголовки в зависимости от того, на какую модель направлен запрос.
Два семейства заголовков освобождены от проверки совпадения ради повторного запроса:
server-side-fallback-*: повторный запрос должен убрать параметрfallbacks, и удаление этого заголовка вместе с ним не вызывает несовпадения.fallback-credit-*: сохраняйте этот заголовок в обоих запросах. Он необходим повторному запросу для погашения токена.
Поле равно null только тогда, когда токен тоже равен null, поэтому значение, которое вы наблюдаете при наличии токена, никогда не бывает null. Тем не менее оно может отсутствовать (None в типизированных SDK) на Amazon Bedrock, Google Cloud и Microsoft Foundry, пока поддержка этого поля там внедряется. В этом случае считайте форму повторного запроса неизвестной, а не равной false. Сначала попробуйте форму с добавленным сообщением ассистента и полагайтесь на обработку отклонений из раздела Когда повторный запрос отклонён, которая откатывается к телу без изменений.
Когда токен отказа поддерживает форму продолжения, поле content ответа содержит только собственный вывод модели, а объяснение отказа передаётся в stop_details.explanation. Поэтому вы можете повторить content в добавленном сообщении ассистента как есть.
Перед отправкой всё же могут потребоваться две корректировки:
- Если последний отправляемый вами блок — это блок
text, удалите его завершающие пробельные символы. - Опустите любой клиентский блок
tool_use, у которого нет соответствующегоtool_result.
Если повторяемое содержимое включает блок fallback от более раннего резервного переключения на стороне сервера, сохраните блок точно на том месте, где он находился. Он принимается в любом запросе без бета-заголовка. API использует его позицию для проверки блоков мышления вокруг него, поэтому запрос, повторяющий блоки мышления с обеих сторон этой границы, отклоняется, если блок опущен или перемещён.
Токен погашается только из той организации и рабочего пространства, которые получили отказ, в том числе на Microsoft Foundry. На Amazon Bedrock и Google Cloud, где нет рабочих пространств, токен вместо этого привязан к идентификатору вызывающей стороны на платформе.
Срок действия токена истекает через пять минут после отказа. После этого отправляйте повторный запрос без него. Токен также не имеет состояния: сервер ничего о нём не хранит, и не существует конечной точки для его проверки или отзыва.
Если отказ поступил после того, как серверные инструменты уже были выполнены в рамках запроса, токен погашается только путём продолжения частичного ответа. Именно это ограничение предотвращает повторный запуск и повторную тарификацию завершённых вызовов инструментов.
Поэтому одна комбинация может сделать токен непогашаемым ни одной из форм, когда верны оба следующих условия:
- Запрос использовал
output_config.formatилиtool_choice, принудительно требующий использования инструментов. Любое из них исключает форму с добавленным сообщением ассистента. - Отказ поступил после выполнения серверных инструментов. Это исключает тело без изменений.
Если повторный запрос с телом без изменений отклонён с ошибкой 400, сообщающей, что токен должен быть погашен путём продолжения частичного ответа, отбросьте токен. Повторный запрос без него проходит, но заново запускает и заново тарифицирует завершённые серверные инструменты. Сообщите о стоимости или об ошибке вызывающей стороне, а не повторяйте запрос молча.
Следующие шаги
Обнаруживайте отказы и выбирайте между резервным переключением на стороне сервера, промежуточным ПО SDK и ручной повторной попыткой.
Как тарифицируются чтение из кэша и запись в кэш.
Все значения stop_reason и способы их обработки.
Вспомогательный инструмент SDK, который применяет кредит при резервном переключении автоматически.
Was this page helpful?