stop_reason: refusal
stop_reason: refusal в Claude Fable 5
Классификатор безопасности отклонил запрос. Это успешный HTTP 200 — поэтому большинство интеграций его не замечает.
Кратко за 30 секунд
Fable 5 использует классификаторы безопасности, которые могут отклонить запрос. Отклонение — HTTP 200 со stop_reason refusal, пустой content и объект stop_details с category. Исключение не возникает. После каждого вызова проверяйте stop_reason, читайте category и повторяйте на другой модели Claude. Категория reasoning_extraction часто застаёт команды врасплох: промпты с «покажи ход мыслей» её вызывают.
Пять категорий отказа
stop_details.category называет policy area, которая сработала. category и explanation могут быть null, когда отказ не попадает в именованную категорию — это постоянно, не placeholder.
bio
Запрос мог бы способствовать биологическому вреду — например, опасным лабораторным методам. Безвредная работа в life sciences тоже может сработать. В Claude Code bio-флаг на Fable 5 переводит сессию на Opus 5; у Opus 5 свои biology-классификаторы без дальнейшего fallback — последующие bio-flagged запросы там заканчиваются отказами.
cyber
Запрос мог бы способствовать кибервреду — malware или разработке эксплойтов. Безвредная работа по cybersecurity тоже попадает сюда. Pentest, CTF и репозитории security tooling часто с первого запроса — это ожидаемая маршрутизация, а не флаг на вашем аккаунте.
frontier_llm
Запрос мог бы помочь разработке конкурирующих AI-моделей — commercial terms Anthropic это ограничивают. Безвредная ML-работа тоже; evaluation harnesses и tooling сравнения моделей иногда неожиданно попадают сюда.
general_harms
Запрос затрагивает область, признанную вредной, и не попадает в более конкретную категорию. Безвредная работа иногда тоже; это категория, которую чаще всего решают переформулировкой или контекстом о намерении.
reasoning_extraction
Запрос просит модель воспроизвести внутреннее рассуждение в тексте ответа. Промпты, skills или harness с «покажи ход мыслей», «think step by step», «объясни рассуждение» попадают в эту категорию и дают повышенные fallbacks на Opus 4.8. Самый частый самонавязанный refusal на Fable 5.
Исправляйте в таком порядке
Сначала обнаружение, потом смягчение. Если вы не считаете отказы, не поймёте, работает ли fallback.
- 1
2. Проверьте промпты на язык reasoning-extraction
Ищите в system prompts, skills и harness всё, что просит эхо, транскрипцию или объяснение internal reasoning как response text, и удалите. Нужна видимость рассуждения — читайте structured thinking blocks из adaptive thinking.
- 2
1. Ветвление по stop_reason, не по content
Сразу после вызова проверяйте stop_reason equal refusal или stop_details.type. Не выводите отказ из пустого content и не разбирайте stop_details.explanation — текст нестабилен и предназначен для отображения, а не для логики.
- 3
3. Fallback на каждом request path
Server-side fallback: параметр fallbacks плюс beta header server-side-fallback-2026-07-01 (beta на Claude API). SDK middleware работает на любой платформе. Подключите в retry handlers и background workers; subagent calls — свой fallback, параметр не propagates в model calls внутри tool execution.
- 4
5. Отказы как отдельная метрика
Refusal — 200, поэтому monitoring на error rates или 5xx never sees it. Эмитируйте event per refusal и per fallback-served (fallback_message в usage.iterations); alert на gap между counts.
- 5
4. Резервной модели нужен запас rate limit
Если fallback model rate limited или overloaded, попытка fallback пропускается и возвращается исходный refusal. Заложите лимиты fallback под ожидаемый объём отказов — иначе fallback silently degrades to refusal при highest load.
Это не отказ?
Если ответ — настоящая HTTP-ошибка, а не 200, начните со status code. Обработка полностью другая.