Claude Fable 5 включает классификаторы безопасности, которые могут отклонить запрос. Когда это происходит, вы получаете обычный ответ, а не ошибку, со значением stop_reason: "refusal". Как правило, вы всё равно можете получить ответ, отправив тот же запрос другой модели Claude. На этой странице показано, как распознать отказ и как настроить такую повторную попытку.
Прочитайте эту страницу, если вы разрабатываете на базе Claude Fable 5 и хотите, чтобы отклонённые запросы автоматически передавались другой модели. Она также пригодится, если вы только что увидели "refusal" в ответе и хотите понять, что делать дальше.
Полный список значений stop_reason приведён на странице Причины остановки и резервная модель. Подробности о том, как тарифицируются отклонённые запросы и как избежать двойной оплаты за кэширование подсказок при повторной попытке, приведены на странице Кредит резервной модели. Вспомогательный компонент SDK, который оборачивает всё это, описан на странице Промежуточное ПО SDK. Полный сквозной пример см. в руководстве по резервной модели и тарификации.
Простейшая настройка: укажите резервную модель в запросе, и API выполнит повторную попытку.
await client.beta.messages.create({
model: "claude-fable-5",
max_tokens: 1024,
messages,
betas: ["server-side-fallback-2026-06-01"],
fallbacks: [{ model: "claude-opus-4-8" }]
});В разделах ниже рассматривается, что содержит ответ с отказом, когда использовать серверную или клиентскую резервную модель и как тарифицируется каждый вариант.
Отказ — это успешный ответ HTTP 200 со значением stop_reason: "refusal":
{
"id": "msg_01XFUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-fable-5",
"content": [],
"stop_reason": "refusal",
"stop_details": {
"type": "refusal",
"category": "cyber",
"explanation": "This request was declined because it could enable cyber harm."
},
"usage": {
"input_tokens": 412,
"output_tokens": 0
}
}Объект stop_details объясняет причину отклонения. Его поле category указывает область политики, которая активировала классификатор. Его поле explanation — это человекочитаемое описание; текст не является стабильным, поэтому отображайте его, а не анализируйте программно. Оба поля равны null, когда отказ не соответствует именованной категории, и null — это нормальное постоянное значение, а не заглушка. Сам объект stop_details равен null для всех причин остановки, кроме refusal.
category | Что это означает |
|---|---|
"cyber" | Запрос может способствовать киберугрозам, например разработке вредоносного ПО или эксплойтов. Безобидная работа в области кибербезопасности также может активировать эту категорию. |
"bio" | Запрос может способствовать биологическим угрозам, например опасным лабораторным методам. Полезная работа в области наук о жизни также может активировать эту категорию. |
"reasoning_extraction" | Запрос просит модель воспроизвести её внутренние рассуждения в тексте ответа. Чтобы получить рассуждения в структурированной форме, используйте адаптивное мышление. |
Отказ может поступить до какого-либо вывода или в середине потока после частичного вывода. В любом случае считайте любой частичный вывод незавершённым и отбрасывайте его.
Как тарифицируются отказы: при отказе до какого-либо вывода поле content остаётся пустым, и плата не взимается (количество токенов отображается в usage, но не тарифицируется, и запрос не учитывается в ограничениях скорости). При отказе в середине потока входные токены и уже переданный вывод тарифицируются по обычным ставкам.
Существует три способа повторить отклонённый запрос на другой модели. Правильный выбор зависит от того, где вы работаете и какой уровень контроля вам нужен.
| Ваша ситуация | Используйте | Почему |
|---|---|---|
| Claude API или Claude Platform на AWS, простейшая настройка | Серверная резервная модель | Один запрос, один ответ. API выполняет повторную попытку. |
| Любая платформа с SDK для TypeScript, Python, Go, Java или C# | Промежуточное ПО SDK | Настраивается один раз на клиенте. Повторные попытки происходят автоматически. |
| Ruby, PHP, прямой HTTP или собственная логика повторных попыток | Ручная повторная попытка с кредитом резервной модели | Полный контроль. Кредит резервной модели снижает стоимость. |
Серверная резервная модель и промежуточное ПО SDK применяют кредит резервной модели за вас, поэтому та страница нужна только при самостоятельной реализации повторной попытки.
Серверная резервная модель повторяет отклонённый запрос внутри одного вызова API. Вы указываете до трёх резервных моделей, и когда Claude Fable 5 отклоняет запрос, API запускает следующую модель в цепочке с тем же запросом. Вы получаете один ответ, в котором указана ответившая модель, так что ваш пользователь получает ответ за один цикл обмена.
Серверная резервная модель находится в бета-версии на Claude API и Claude Platform на AWS. Параметр fallbacks отклоняется в Message Batches API и недоступен на Amazon Bedrock, Vertex AI и Microsoft Foundry. На этих платформах используйте вместо этого промежуточное ПО SDK.
Укажите резервные модели в параметре fallbacks и отправьте бета-заголовок server-side-fallback-2026-06-01.
К списку fallbacks применяется несколько правил:
allowed_fallback_models в записи модели в Models API.model и может переопределить max_tokens и thinking только для этой попытки.Бета-заголовок должен содержать именно дату 2026-06-01. При любом другом значении server-side-fallback-* параметр fallbacks отклоняется с ошибкой 400. Если вы разрабатывали на основе более ранней предварительной версии этой функции, обновите бета-заголовок и форматы запроса и ответа одновременно до тех, что приведены на этой странице.
Ответ выглядит как любое другое сообщение, с двумя дополнениями:
model верхнего уровня указывает модель, которая создала возвращённое сообщение, будь то запрошенная модель или резервная.fallback отмечает каждую точку в content, где вывод одной модели сменяется выводом следующей: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}. from.model повторяет строку модели, которую вы отправили, когда отклоняющий шаг — это запрошенная модель. to.model — это всегда разрешённый идентификатор модели, которая продолжает работу.При отказе до какого-либо вывода блок fallback является первым блоком контента:
{
"id": "msg_01XFUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-opus-4-8",
"content": [
{
"type": "fallback",
"from": { "model": "claude-fable-5" },
"to": { "model": "claude-opus-4-8" }
},
{ "type": "text", "text": "Hi! How can I help you today?" }
],
"stop_reason": "end_turn",
"stop_details": null,
"usage": {
"input_tokens": 412,
"output_tokens": 264,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"iterations": [
{
"type": "message",
"model": "claude-fable-5",
"input_tokens": 535,
"output_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
},
{
"type": "fallback_message",
"model": "claude-opus-4-8",
"input_tokens": 412,
"output_tokens": 264,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
}
]
}
}Массив usage.iterations фиксирует каждую попытку. Модель, которая отклонила запрос, отображается как обычная запись message, а модель, обслужившая ход, — как запись fallback_message. Если каждая модель в цепочке отклоняет запрос, ответом является отказ последней модели с записью message для каждого предыдущего шага и записью fallback_message для последнего.
На следующем ходе отправьте контент ассистента обратно в том виде, в каком вы его получили. После переключения на резервную модель в середине вывода content может включать типы блоков, которые отклонившая модель создала до передачи; в таблице ниже указано, какие из них сохранить, а какие отбросить при повторении хода.
| Тип блока | На следующем ходе |
|---|---|
fallback | Сохраните его точно там, где он появился. API использует его позицию для валидации блоков мышления вокруг него, поэтому запрос, повторяющий блоки мышления с обеих сторон границы, отклоняется, если блок пропущен или перемещён. |
text | Сохраните. |
Любой блок после последнего блока fallback | Сохраните. |
thinking, redacted_thinking или connector_text до последнего блока fallback | Отбросьте. |
Клиентский tool_use до последнего блока fallback | Отбросьте. |
server_tool_use до последнего блока |
Блок connector_text содержит текст повествования, который некоторые ответы с использованием инструментов включают между вызовами инструментов.
При потоковом запросе повторная попытка происходит в том же потоке, и ничто из уже полученного вами не становится недействительным. Когда отклонение происходит до какого-либо вывода, message_start указывает резервную модель, а блок fallback является первым блоком контента; поскольку message_start ожидает начала попытки резервной модели, время до первого байта включает отклонённую попытку. Когда отклонение происходит в середине вывода, открытый блок контента закрывается, блок fallback (обычная пара content_block_start и content_block_stop без дельт) отмечает границу, и резервная модель продолжает с частичного вывода. Только блоки text частичного вывода передаются резервной модели в качестве контекста; другие типы блоков остаются в content. В случае отклонения в середине вывода message_start уже указал запрошенную модель, поэтому считывайте обслуживающую модель из поля to.model блока fallback и из записи fallback_message в usage.iterations финального message_delta.
При непотоковом запросе отклонение в середине вывода ведёт себя иначе: ответ не включает частичный вывод отклонившей модели, и резервная модель отвечает с нуля. Результат выглядит как отклонение до какого-либо вывода, с блоком fallback в начале. Отклонённая попытка и её выходные токены всё равно отображаются в usage.iterations.
Когда отклонение срабатывает после того, как серверные инструменты (например, веб-поиск или выполнение кода) уже выполнились в рамках запроса, API возвращает отказ вместо перехода к резервной модели. Если заголовок fallback-credit-2026-06-01 также установлен, этот отказ содержит токен кредита, который можно использовать, продолжив частичный ответ, так что выполненная работа инструментов не теряется. Это относится только к серверным инструментам, итерирующим в рамках одного запроса; разговоры, использующие клиентские инструменты, переключаются на резервную модель обычным образом.
SDK для TypeScript, Python, Go, Java и C# включают промежуточное ПО для переключения на резервную модель при отказе. Вы настраиваете его один раз на клиенте со своим списком резервных моделей. Вызовы через client.beta.messages затем автоматически повторяют отклонённые запросы на любой платформе. Промежуточное ПО также отправляет бета-заголовок fallback-credit-2026-06-01 с каждым обрабатываемым запросом, поэтому повторные попытки пересчитываются по цене без настройки для каждого запроса.
Вспомогательный компонент промежуточного ПО для переключения на резервную модель при отказе пока недоступен в SDK для Ruby и PHP. В этих SDK реализуйте шаблон «обнаружить и повторить» напрямую.
Передайте промежуточное ПО в конструктор клиента и используйте один экземпляр BetaFallbackState для всех запросов разговора.
fallback на каждой границе моделей, так же как и ответы серверной резервной модели. Промежуточное ПО управляет этими блоками за вас при последующих запросах.BetaFallbackState, поэтому последующие запросы, использующие это состояние, остаются закреплёнными за ней, а не повторно обращаются к модели, которая отказала.Промежуточное ПО и серверный параметр fallbacks выполняют одну и ту же работу. Настраивайте одно или другое, но никогда оба в одном запросе. Чтобы отправить запрос с серверным fallbacks из приложения, которое устанавливает промежуточное ПО, используйте отдельный экземпляр клиента без него.
Отклонённый запрос в Message Batch возвращается как result.type: "succeeded" со значением stop_reason: "refusal". Поле stop_details может быть null в результатах пакета, поэтому обнаруживайте отказы, проверяя stop_reason напрямую.
Серверная резервная модель недоступна для пакетов (пакетный запрос, включающий fallbacks, создаёт результат с ошибкой для каждого элемента). Чтобы повторить отклонённые элементы пакета:
fallbacks не распространяется на вызовы модели, выполняемые изнутри выполнения инструментов.fallback_message в отмечает последнее), затем настройте оповещение на разрыв между двумя счётчиками.Избегайте двойной оплаты стоимости кэша подсказок при самостоятельной реализации повторной попытки.
Все значения stop_reason и как их обрабатывать.
Was this page helpful?
client = Anthropic()
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
fallbacks=[{"model": "claude-opus-4-8"}],
betas=["server-side-fallback-2026-06-01"],
)
# Запись fallback_message в usage.iterations означает, что сработала резервная модель;
# сопоставьте её со stop_reason, чтобы убедиться, что ответ дала именно резервная модель.
fallback_ran = any(
iteration.type == "fallback_message"
for iteration in response.usage.iterations or []
)
served_by_fallback = fallback_ran and response.stop_reason != "refusal"
print(
json.dumps(
{
"stop_reason": response.stop_reason,
"model": response.model,
"served_by_fallback": served_by_fallback,
}
)
)fallback| Сохраните, если он сопряжён со своим результатом. Отбросьте, если у него нет соответствующего результата. |
# При отказе промежуточное ПО повторяет запрос на указанной резервной модели и
# автоматически отправляет бета-заголовок резервного кредита с каждым обрабатываемым запросом.
client = Anthropic(
middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)
state = BetaFallbackState() # pins follow-ups to the model that accepted
# Потоковая передача: при отказе промежуточное ПО повторяет запрос на резервной модели и
# вставляет её события в открытый поток.
with (
state,
client.beta.messages.stream(
max_tokens=1024,
model="claude-fable-5",
messages=[{"role": "user", "content": "Hello, Claude"}],
) as stream,
):
for event in stream:
if event.type == "text":
print(event.text, end="", flush=True)
final_message = stream.get_final_message()
print(f"\nserved by: {final_message.model}")
# Без потоковой передачи: повторное использование состояния сохраняет привязку разговора.
with state:
message = client.beta.messages.create(
max_tokens=1024,
model="claude-fable-5",
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(f"served by: {message.model}")usage.iterationsstop_reason, а не по stop_details или content. stop_details носит информационный характер и может быть null при отказе. Проверяйте, что stop_reason равен "refusal", напрямую.Как работает промежуточное ПО SDK, включая вспомогательный компонент для переключения на резервную модель при отказе.