Loading...
    • Руководство разработчика
    • Справочник API
    • MCP
    • Ресурсы
    • Примечания к выпуску
    Search...
    ⌘K
    Первые шаги
    Введение в ClaudeБыстрый старт
    Модели и цены
    Обзор моделейВыбор моделиЧто нового в Claude 4.5Миграция на Claude 4.5Устаревшие моделиЦены
    Разработка с Claude
    Обзор функцийИспользование Messages APIКонтекстные окнаЛучшие практики промптирования
    Возможности
    Кэширование промптовРедактирование контекстаРасширенное мышлениеУсилиеПотоковая передача сообщенийПакетная обработкаЦитированияМногоязычная поддержкаПодсчет токеновEmbeddingsЗрениеПоддержка PDFFiles APIРезультаты поискаСтруктурированные выходные данные
    Инструменты
    ОбзорКак реализовать использование инструментовПотоковая передача инструментов с детализациейИнструмент BashИнструмент выполнения кодаПрограммное вызывание инструментовИнструмент управления компьютеромИнструмент текстового редактораИнструмент веб-выборкиИнструмент веб-поискаИнструмент памятиИнструмент поиска инструментов
    Agent Skills
    ОбзорБыстрый стартЛучшие практикиИспользование Skills с API
    Agent SDK
    ОбзорБыстрый стартTypeScript SDKTypeScript V2 (preview)Python SDKРуководство по миграции
    MCP в API
    MCP коннекторУдаленные MCP серверы
    Claude на сторонних платформах
    Amazon BedrockMicrosoft FoundryVertex AI
    Инженерия промптов
    ОбзорГенератор промптовИспользование шаблонов промптовУлучшитель промптовБудьте ясны и прямолинейныИспользуйте примеры (многошаговое промптирование)Дайте Claude подумать (CoT)Используйте XML-тегиДайте Claude роль (системные промпты)Предзаполните ответ ClaudeЦепочка сложных промптовСоветы по длинному контекстуСоветы по расширенному мышлению
    Тестирование и оценка
    Определение критериев успехаРазработка тестовых случаевИспользование инструмента оценкиСнижение задержки
    Усиление защиты
    Снижение галлюцинацийПовышение согласованности выходных данныхСмягчение взломовПотоковые отказыСнижение утечки промптовДержите Claude в образе
    Администрирование и мониторинг
    Обзор Admin APIAPI использования и затратClaude Code Analytics API
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Documentation

    Обработка причин остановки

    Узнайте, как обрабатывать различные значения stop_reason в ответах Messages API для создания надежных приложений.

    Когда вы делаете запрос к Messages API, ответ Claude включает поле stop_reason, которое указывает, почему модель остановила генерацию своего ответа. Понимание этих значений имеет решающее значение для создания надежных приложений, которые надлежащим образом обрабатывают различные типы ответов.

    Для получения подробной информации о stop_reason в ответе API см. справочник Messages API.

    Что такое stop_reason?

    Поле stop_reason является частью каждого успешного ответа Messages API. В отличие от ошибок, которые указывают на сбои при обработке вашего запроса, stop_reason говорит вам, почему Claude успешно завершил генерацию своего ответа.

    Example response
    {
      "id": "msg_01234",
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "Here's the answer to your question..."
        }
      ],
      "stop_reason": "end_turn",
      "stop_sequence": null,
      "usage": {
        "input_tokens": 100,
        "output_tokens": 50
      }
    }

    Значения stop_reason

    end_turn

    Наиболее распространенная причина остановки. Указывает, что Claude естественным образом завершил свой ответ.

    if response.stop_reason == "end_turn":
        # Process the complete response
        print(response.content[0].text)

    Пустые ответы с end_turn

    Иногда Claude возвращает пустой ответ (ровно 2-3 токена без содержимого) с stop_reason: "end_turn". Это обычно происходит, когда Claude интерпретирует, что ход ассистента завершен, особенно после результатов инструмента.

    Распространенные причины:

    • Добавление текстовых блоков сразу после результатов инструмента (Claude учится ожидать, что пользователь всегда вставляет текст после результатов инструмента, поэтому он завершает свой ход, чтобы следовать этому шаблону)
    • Отправка завершенного ответа Claude обратно без добавления чего-либо (Claude уже решил, что он готов, поэтому он останется готовым)

    Как предотвратить пустые ответы:

    # INCORRECT: Adding text immediately after tool_result
    messages = [
        {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
        {"role": "assistant", "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678}
            }
        ]},
        {"role": "user", "content": [
            {
                "type": "tool_result",
                "tool_use_id": "toolu_123",
                "content": "6912"
            },
            {
                "type": "text",
                "text": "Here's the result"  # Don't add text after tool_result
            }
        ]}
    ]
    
    # CORRECT: Send tool results directly without additional text
    messages = [
        {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
        {"role": "assistant", "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678}
            }
        ]},
        {"role": "user", "content": [
            {
                "type": "tool_result",
                "tool_use_id": "toolu_123",
                "content": "6912"
            }
        ]}  # Just the tool_result, no additional text
    ]
    
    # If you still get empty responses after fixing the above:
    def handle_empty_response(client, messages):
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            messages=messages
        )
    
        # Check if response is empty
        if (response.stop_reason == "end_turn" and
            not response.content):
    
            # INCORRECT: Don't just retry with the empty response
            # This won't work because Claude already decided it's done
    
            # CORRECT: Add a continuation prompt in a NEW user message
            messages.append({"role": "user", "content": "Please continue"})
    
            response = client.messages.create(
                model="claude-sonnet-4-20250514",
                max_tokens=1024,
                messages=messages
            )
    
        return response

    Лучшие практики:

    1. Никогда не добавляйте текстовые блоки сразу после результатов инструмента - Это учит Claude ожидать ввод пользователя после каждого использования инструмента
    2. Не повторяйте попытки пустых ответов без изменений - Просто отправка пустого ответа обратно не поможет
    3. Используйте подсказки продолжения в качестве последнего средства - Только если приведенные выше исправления не решают проблему

    max_tokens

    Claude остановился, потому что достиг лимита max_tokens, указанного в вашем запросе.

    # Request with limited tokens
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=10,
        messages=[{"role": "user", "content": "Explain quantum physics"}]
    )
    
    if response.stop_reason == "max_tokens":
        # Response was truncated
        print("Response was cut off at token limit")
        # Consider making another request to continue

    stop_sequence

    Claude встретил одну из ваших пользовательских последовательностей остановки.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        stop_sequences=["END", "STOP"],
        messages=[{"role": "user", "content": "Generate text until you say END"}]
    )
    
    if response.stop_reason == "stop_sequence":
        print(f"Stopped at sequence: {response.stop_sequence}")

    tool_use

    Claude вызывает инструмент и ожидает, что вы его выполните.

    Для большинства реализаций использования инструментов мы рекомендуем использовать tool runner, который автоматически обрабатывает выполнение инструмента, форматирование результатов и управление разговором.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        tools=[weather_tool],
        messages=[{"role": "user", "content": "What's the weather?"}]
    )
    
    if response.stop_reason == "tool_use":
        # Extract and execute the tool
        for content in response.content:
            if content.type == "tool_use":
                result = execute_tool(content.name, content.input)
                # Return result to Claude for final response

    pause_turn

    Используется с серверными инструментами, такими как веб-поиск, когда Claude нужно приостановить длительную операцию.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
        messages=[{"role": "user", "content": "Search for latest AI news"}]
    )
    
    if response.stop_reason == "pause_turn":
        # Continue the conversation
        messages = [
            {"role": "user", "content": original_query},
            {"role": "assistant", "content": response.content}
        ]
        continuation = client.messages.create(
            model="claude-sonnet-4-5",
            messages=messages,
            tools=[{"type": "web_search_20250305", "name": "web_search"}]
        )

    refusal

    Claude отказался генерировать ответ по соображениям безопасности.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": "[Unsafe request]"}]
    )
    
    if response.stop_reason == "refusal":
        # Claude declined to respond
        print("Claude was unable to process this request")
        # Consider rephrasing or modifying the request

    Если вы часто встречаете причины остановки refusal при использовании Claude Sonnet 4.5 или Opus 4.1, вы можете попробовать обновить свои вызовы API для использования Sonnet 4 (claude-sonnet-4-20250514), который имеет другие ограничения использования. Узнайте больше о понимании фильтров безопасности API Sonnet 4.5.

    Чтобы узнать больше об отказах, вызванных фильтрами безопасности API для Claude Sonnet 4.5, см. Understanding Sonnet 4.5's API Safety Filters.

    model_context_window_exceeded

    Claude остановился, потому что достиг лимита контекстного окна модели. Это позволяет вам запросить максимально возможное количество токенов без знания точного размера входа.

    # Request with maximum tokens to get as much as possible
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=64000,  # Model's maximum output tokens
        messages=[{"role": "user", "content": "Large input that uses most of context window..."}]
    )
    
    if response.stop_reason == "model_context_window_exceeded":
        # Response hit context window limit before max_tokens
        print("Response reached model's context window limit")
        # The response is still valid but was limited by context window

    Эта причина остановки доступна по умолчанию в Sonnet 4.5 и более новых моделях. Для более ранних моделей используйте заголовок бета-версии model-context-window-exceeded-2025-08-26 для включения этого поведения.

    Лучшие практики обработки причин остановки

    1. Всегда проверяйте stop_reason

    Сделайте привычкой проверять stop_reason в логике обработки ответов:

    def handle_response(response):
        if response.stop_reason == "tool_use":
            return handle_tool_use(response)
        elif response.stop_reason == "max_tokens":
            return handle_truncation(response)
        elif response.stop_reason == "model_context_window_exceeded":
            return handle_context_limit(response)
        elif response.stop_reason == "pause_turn":
            return handle_pause(response)
        elif response.stop_reason == "refusal":
            return handle_refusal(response)
        else:
            # Handle end_turn and other cases
            return response.content[0].text

    2. Обрабатывайте усеченные ответы корректно

    Когда ответ усечен из-за лимитов токенов или контекстного окна:

    def handle_truncated_response(response):
        if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
            # Option 1: Warn the user about the specific limit
            if response.stop_reason == "max_tokens":
                message = "[Response truncated due to max_tokens limit]"
            else:
                message = "[Response truncated due to context window limit]"
            return f"{response.content[0].text}\n\n{message}"
    
            # Option 2: Continue generation
            messages = [
                {"role": "user", "content": original_prompt},
                {"role": "assistant", "content": response.content[0].text}
            ]
            continuation = client.messages.create(
                model="claude-sonnet-4-5",
                max_tokens=1024,
                messages=messages + [{"role": "user", "content": "Please continue"}]
            )
            return response.content[0].text + continuation.content[0].text

    3. Реализуйте логику повторных попыток для pause_turn

    Для серверных инструментов, которые могут приостановиться:

    def handle_paused_conversation(initial_response, max_retries=3):
        response = initial_response
        messages = [{"role": "user", "content": original_query}]
        
        for attempt in range(max_retries):
            if response.stop_reason != "pause_turn":
                break
                
            messages.append({"role": "assistant", "content": response.content})
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                tools=original_tools
            )
        
        return response

    Причины остановки в сравнении с ошибками

    Важно различать значения stop_reason и фактические ошибки:

    Причины остановки (успешные ответы)

    • Часть тела ответа
    • Указывают, почему генерация остановилась нормально
    • Ответ содержит действительное содержимое

    Ошибки (неудачные запросы)

    • Коды состояния HTTP 4xx или 5xx
    • Указывают на сбои при обработке запроса
    • Ответ содержит детали ошибки
    try:
        response = client.messages.create(...)
        
        # Handle successful response with stop_reason
        if response.stop_reason == "max_tokens":
            print("Response was truncated")
        
    except anthropic.APIError as e:
        # Handle actual errors
        if e.status_code == 429:
            print("Rate limit exceeded")
        elif e.status_code == 500:
            print("Server error")

    Рассмотрения потоковой передачи

    При использовании потоковой передачи stop_reason:

    • null в начальном событии message_start
    • Предоставляется в событии message_delta
    • Не предоставляется ни в каких других событиях
    with client.messages.stream(...) as stream:
        for event in stream:
            if event.type == "message_delta":
                stop_reason = event.delta.stop_reason
                if stop_reason:
                    print(f"Stream ended with: {stop_reason}")

    Распространенные шаблоны

    Обработка рабочих процессов использования инструментов

    Проще с tool runner: Пример ниже показывает ручную обработку инструментов. Для большинства случаев использования tool runner автоматически обрабатывает выполнение инструмента с гораздо меньшим количеством кода.

    def complete_tool_workflow(client, user_query, tools):
        messages = [{"role": "user", "content": user_query}]
    
        while True:
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                tools=tools
            )
    
            if response.stop_reason == "tool_use":
                # Execute tools and continue
                tool_results = execute_tools(response.content)
                messages.append({"role": "assistant", "content": response.content})
                messages.append({"role": "user", "content": tool_results})
            else:
                # Final response
                return response

    Обеспечение полных ответов

    def get_complete_response(client, prompt, max_attempts=3):
        messages = [{"role": "user", "content": prompt}]
        full_response = ""
    
        for _ in range(max_attempts):
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                max_tokens=4096
            )
    
            full_response += response.content[0].text
    
            if response.stop_reason != "max_tokens":
                break
    
            # Continue from where it left off
            messages = [
                {"role": "user", "content": prompt},
                {"role": "assistant", "content": full_response},
                {"role": "user", "content": "Please continue from where you left off."}
            ]
    
        return full_response

    Получение максимального количества токенов без знания размера входа

    С причиной остановки model_context_window_exceeded вы можете запросить максимально возможное количество токенов без расчета количества входных токенов:

    def get_max_possible_tokens(client, prompt):
        """
        Get as many tokens as possible within the model's context window
        without needing to calculate input token count
        """
        response = client.messages.create(
            model="claude-sonnet-4-5",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=64000  # Set to model's maximum output tokens
        )
    
        if response.stop_reason == "model_context_window_exceeded":
            # Got the maximum possible tokens given input size
            print(f"Generated {response.usage.output_tokens} tokens (context limit reached)")
        elif response.stop_reason == "max_tokens":
            # Got exactly the requested tokens
            print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
        else:
            # Natural completion
            print(f"Generated {response.usage.output_tokens} tokens (natural completion)")
    
        return response.content[0].text

    Правильно обрабатывая значения stop_reason, вы можете создавать более надежные приложения, которые корректно обрабатывают различные сценарии ответов и обеспечивают лучший пользовательский опыт.

    • Что такое stop_reason?
    • Значения stop_reason
    • end_turn
    • max_tokens
    • stop_sequence
    • tool_use
    • pause_turn
    • refusal
    • model_context_window_exceeded
    • Лучшие практики обработки причин остановки
    • 1. Всегда проверяйте stop_reason
    • 2. Обрабатывайте усеченные ответы корректно
    • 3. Реализуйте логику повторных попыток для pause_turn
    • Причины остановки в сравнении с ошибками
    • Причины остановки (успешные ответы)
    • Ошибки (неудачные запросы)
    • Рассмотрения потоковой передачи
    • Распространенные шаблоны
    • Обработка рабочих процессов использования инструментов
    • Обеспечение полных ответов
    • Получение максимального количества токенов без знания размера входа