DikayaОткрыть чат

Почему AI API отказывается отвечать?

Если AI API отказывается отвечать, сначала разделите содержание ответа и технический исход запроса. Текстовый отказ может прийти с HTTP 200; пустой content иногда связан с лимитом длины или вызовом инструмента; 401, 402 и 429 требуют проверки ключа, средств и частоты. Ни один из этих признаков сам по себе не объясняет все причины. Разберём диагностику для разработчика на примере Chat Completions в Dikaya, без автоматической повторной генерации.

Коротко о главном

  • HTTP-успех не гарантирует полезный или завершённый текст.
  • Проверяйте finish_reason, message.refusal, tool_calls и наличие содержимого отдельно.
  • Таймаут и обрыв не доказывают, что обработка не состоялась; новый вызов может быть отдельно оплачен.

Как отличить отказ модели от ошибки API

У запроса есть несколько независимых уровней. Транспорт показывает, удалось ли получить HTTP-ответ. Статус говорит, принят ли запрос выбранным endpoint. Поля результата описывают завершение генерации, а текст сообщения — её содержание. Когда интерфейс сводит всё к надписи «AI отказался», разработчик теряет сведения, необходимые для правильного следующего действия.

При HTTP 200 модель может вернуть явное поле refusal или написать отказ обычным текстом. Наличие отдельного поля удобно для обработки, но его отсутствие не доказывает, что отказа нет. И наоборот, короткий ответ или отсутствие привычной фразы не означает цензуру: сперва изучите finish_reason и структуру сообщения. Для оценки смысла иногда требуется просмотр самого результата.

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

Что проверять при 400, 401, 402, 403 и 429

При 400 проверьте JSON, допустимый model и параметры: повтор того же неверного тела обычно не исправляет запрос. При 401 проверьте действующий ключ, способ авторизации и отсутствие случайных пробелов; недействительный или отозванный доступ не нужно лечить сменой текста вопроса. Для 403 посмотрите сообщение о разрешениях, например доступность модели для подключения.

В Dikaya 402 может означать нехватку свободных средств для предварительного резерва. Большой контекст или max_tokens способны потребовать резерв больше фактической цены короткого ответа. Посмотрите /v1/balance, уменьшите вход или осознанно выберите меньший выходной предел. Не называйте такую ситуацию отказом модели по теме запроса: до генерации дело могло не дойти.

При 429 выясните, где возник лимит: в частоте запросов, параллельной обработке демо или ответе внешней системы. Снизьте нагрузку и изучите сообщение. Перед повтором убедитесь, что предыдущая работа не находится в неизвестном состоянии. HTTP 5xx также не означает одинаковую причину во всех случаях: сохраняйте время, endpoint и статус, но не ключ и полное приватное содержимое в общедоступных логах.

  • 400 — тело, модель, параметры.
  • 401 — ключ и авторизация.
  • 402 — свободный баланс и размер резерва.
  • 403 — разрешения подключения.
  • 429 — частота, параллельность и сообщение ошибки.

Почему HTTP 200 может содержать пустой ответ

При finish_reason=length выходной бюджет мог закончиться до формирования обычного текста, в том числе на рассуждение. Поле content в таком случае может быть пустым. Не подставляйте выдуманный ответ вместо отсутствующего и не объявляйте каждый такой случай отказом по правилам модели. Покажите пользователю признак неполного завершения и сохраните уже полученную часть.

При tool_calls модель предлагает вызов клиентского инструмента, а не обязана одновременно выдавать обычный абзац. Дальнейшее действие выполняет ваше приложение с собственными проверками. Сам шлюз не превращает строку с именем функции в исполненную команду. Если инструменты не нужны, начните с простого текстового запроса без их описаний и отдельно проверьте выбранный сценарий.

Значение stop означает завершение, но не удостоверяет фактическую точность, полезность или отсутствие смыслового отказа. Возможен и пустой результат без достаточного объяснения в доступных полях. В таком случае честный статус «пустой ответ, причина не установлена» полезнее уверенной догадки. Различайте наблюдаемые признаки и выводы, для которых ещё нет данных.

Пример Python: классификация ответа без повторной отправки

Установите openai и задайте DIKAYA_API_KEY в окружении, затем сохраните пример как diagnose.py. Команда python diagnose.py отправляет один короткий запрос. Функция classify_message работает и с сохранённым Chat Completions JSON, поэтому её можно проверить локально, не вызывая модель снова. Встроенные повторы SDK отключены через max_retries=0.

Классификатор замечает явное refusal, инструменты, длину, отсутствие текста и неизвестный finish_reason. Он не пытается определять смысловой отказ по списку слов: такой список легко даёт ложные срабатывания на цитате или обычном объяснении. ConnectionError и Timeout выделены как неопределённый исход; приложение должно решить дальнейший шаг отдельно, а не скрыто повторить оплачиваемую работу.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://dikaya.cloud/v1",
    api_key=os.environ["DIKAYA_API_KEY"],
    max_retries=0,
    timeout=90.0,
)

import openai

def classify_message(data):
    choices = data.get("choices") or []
    if not choices:
        return "missing_choice"
    choice = choices[0]
    message = choice.get("message") or {}
    if message.get("refusal"):
        return "explicit_refusal"
    if message.get("tool_calls"):
        return "tool_call"
    if choice.get("finish_reason") == "length":
        return "truncated"
    if not (message.get("content") or "").strip():
        return "empty"
    if choice.get("finish_reason") != "stop":
        return "review_finish_reason"
    return "text_received"

if __name__ == "__main__":
    try:
        response = client.chat.completions.create(
            model="seller-pro-2", max_tokens=512,
            messages=[{"role": "user", "content": "Объясни разницу между фактом и мнением."}],
        )
        print(classify_message(response.model_dump()))
    except (openai.APITimeoutError, openai.APIConnectionError):
        print("outcome_unknown: не повторять автоматически")
    except openai.APIStatusError as error:
        print("HTTP", error.status_code, "— проверьте статус и сообщение в закрытом журнале")

Какой вопрос помогает проверить отказ и фактический ответ

Для проверки спорной темы задайте конкретный аналитический вопрос с понятной формой ответа. Например, попросите сравнить аргументы сторон, отделить факты от оценок и отметить неопределённость. Это даёт критерии качества, а не ставит диагноз модели по одной эмоциональной фразе. В тестовом наборе сохраняйте точную постановку и дату, чтобы не сравнивать разные условия.

Следующий образец — иллюстрация результата, не запись фактической генерации. Получите собственный ответ через кнопку, а затем оцените смысл отдельно от HTTP-статуса и finish_reason. Если модель действительно отказала обычным текстом, сохраните это наблюдение без выдуманного поля refusal. Так приложение не перепутает протокольную проверку с анализом содержания.

Что делать при таймауте и обрыве потока

Локальное время ожидания относится к вашему клиенту. Если оно закончилось, сервер мог уже принять запрос и продолжить обработку. Аналогично, закрытие вкладки не является доказательством отсутствия токенов и расхода. Сохраните идентификатор собственной задачи, время отправки, полученные фрагменты и статус. Не показывайте нулевую стоимость только потому, что итоговый JSON не дошёл.

В Dikaya платная обработка начинается с резерва. При известном usage происходит расчёт и возврат неиспользованной части, а при неизвестном исходе резерв может удерживаться до сверки. Если до этого был выполнен этап описания изображения, его расход также не исчезает из-за ошибки основной модели. Для спорного запроса обращайтесь через кабинет с временем и описанием без секрета.

Поток нужно читать до нормального завершения, учитывая ошибки и частичные события. Уже показанный текст не следует стирать при потере соединения. Предложите явное решение: сохранить часть, проверить состояние или создать новый запрос с пониманием дополнительного расхода. Внешние SDK описывают собственные повторы; это не обещание идемпотентности генерации в Dikaya.

Короткий порядок проверки AI API

Начните с HTTP-статуса и сообщения, затем проверьте наличие choices, finish_reason и поля сообщения. Отдельно оцените содержание: там может быть смысловой отказ без отдельного признака. После этого посмотрите usage и доступный баланс. Только сочетание этих сведений позволяет выбрать следующий шаг: исправить подключение, уменьшить запрос, обработать инструмент или отправить новую задачу вручную.

Для сравнения используйте одинаковые условия: публичный model, текст без инструментов и явный небольшой выходной предел. У новых подходящих аккаунтов демо $0.5 / до 25 запросов, 512 токенов выхода и 6000 байт контекста; у платного режима иные пределы. Не выдавайте различие режимов за изменение цензуры. Диагностика AI API начинается с наблюдаемых данных, а не с предположения о единственной причине.

Вопросы и ответы

Всегда ли отказ AI API приходит как HTTP-ошибка?

Нет. Модель может вернуть отказ обычным текстом или отдельным полем refusal внутри успешного HTTP-ответа. Транспортный статус и смысл сообщения проверяются отдельно. В обратную сторону это тоже работает: 401, 402 или 429 могут относиться к ключу, резерву средств или нагрузке, а не к теме вопроса.

Означает ли пустой content, что модель цензурирует запрос?

Не обязательно. Проверьте finish_reason, tool_calls, поле refusal и наличие других частей сообщения. Возможны выходной лимит, вызов инструмента, ошибка чтения или недостаток данных о причине. Не определяйте цензуру по пустой строке: сохраняйте доступные признаки и честно помечайте неопределённые случаи, особенно если часть ответа уже пришла потоком.

Можно ли автоматически повторить запрос после таймаута?

Такой повтор способен создать отдельную обработку и дополнительный расход. Таймаут клиента не доказывает, что сервер не выполнил работу. В примере повторы SDK отключены; приложение сохраняет задачу и показывает неопределённый исход. При спорном списании уточняйте обстоятельства через поддержку аккаунта, не обещая автоматический возврат или бесплатную повторную генерацию.

Источники и условия

Материал подготовлен с помощью AI. Факты о Dikaya сверены с каталогом, документацией и правилами сервиса; примеры запросов не являются записью реального ответа или сравнительным тестом моделей. Внешние источники поясняют исходные технологии и не заменяют условия Dikaya. Публикует Dikaya — сервис, о котором идёт речь в руководстве.

Продолжить по теме

Проверьте на своей задаче

Возьмите один пример, подставьте свои вводные и оцените результат. Для короткой проверки подойдёт доступное вашему аккаунту демо; для длинных запросов ознакомьтесь с условиями пополнения.

Открыть чат Dikaya Перейти к документации