Към съдържанието
Обработка на грешки

Обработка на грешки

Заявка, която пропадне, връща HTTP статус код и JSON тяло с тип на грешка и съобщение. Тази страница изброява всеки статус, показва тялото на грешката във всеки API формат и казва кои грешки си струва да се изпратят отново.

SDK вдигат обект на грешка, който носи статус кода и полетата на тялото. Тази заявка назовава модел, който не съществува:

import openai
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.shannon-ai.com/v1",
)

try:
    client.chat.completions.create(
        model="no-such-model",
        messages=[{"role": "user", "content": "Hello"}],
    )
except openai.APIStatusError as error:
    print(error.status_code)                           # 400
    print(error.type)                                  # invalid_request_error
    print(error.body["message"])                       # unknown model: no-such-model
    print(error.response.headers.get("x-request-id"))  # the id of this request

Тя връща статус 400 и това тяло:

400 JSON
{
  "error": {
    "type": "invalid_request_error",
    "message": "unknown model: no-such-model"
  }
}

Тяло на грешката

Има две тела. /v1/messages отговаря във формата на Anthropic; всеки друг ендпоинт отговаря във формата на OpenAI. И в двата подробностите са в error.type и error.message, така че един четец обслужва всички ендпоинти.

401 Формат OpenAI
{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key",
    "code": "invalid_api_key",
    "param": null
  }
}
401 Формат Anthropic
{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}
Поле Тип Описание
error.type string Видът на грешката. Вижте Типове грешки по-долу.
error.message string Изречение за човек. Текстовете в таблиците по-долу са стабилни с точност до променливите си части, показани като <id>, <n> или ….
error.code string | null Присъства при някои грешки във формата на OpenAI: invalid_api_key при 401, request_too_large при 413, context_length_exceeded, когато разговорът е твърде дълъг, иначе null или липсва. Решавайте първо по статуса и error.type, а code третирайте като допълнение.
error.param null Присъства при същите грешки като code. Винаги null.
type string Само във формата на Anthropic. Винаги error.

Типове грешки

Тип Статуси Описание
invalid_request_error 400, 413, 415, 422 Самата заявка е грешна: поле, тяло, id на модел или вход, който моделът не приема. Променете заявката, преди да я изпратите отново.
authentication_error 401 API ключът липсва, непознат е или е отменен.
not_found_error 404 Пътят не съществува.
rate_limit_error 429 Балансът не покрива заявката, защитата от наводняване я е спряла или моделът е зает. Съобщението казва кое от тях.
api_error 500, 502, 503, 504 Заявката е била наред, а неуспехът е от наша страна. Изпратете я отново.
server_error 500 Заявката е била наред, а неуспехът е от наша страна. Изпратете я отново.

Статус кодове

Статус Тип Съобщение Кога
400 invalid_request_error Failed to parse the request body as JSON: … Тялото не е валиден JSON.
400 invalid_request_error unknown model: <id> model не е публикуван id. На /v1/responses и когато model липсва.
400 invalid_request_error No user message provided Нива на Shannon: заявката не съдържа потребителски текст.
400 invalid_request_error <id> does not accept image input Изображение е изпратено към хостван open-weight модел без вход с изображения.
400 invalid_request_error audio and video input are not supported by any hosted model Аудио или видео част е изпратена към хостван open-weight модел.
400 invalid_request_error <id> does not accept response_format Структуриран изход е поискан от хостван open-weight модел, който го няма.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object JSON схема е изпратена към хостван open-weight модел, който приема само json_object.
400 invalid_request_error unknown reasoning effort '<value>'; expected off, low, medium or high Усилието за разсъждение не е една от изброените стойности. Хоствани open-weight модели.
400 invalid_request_error count_tokens is available for the hosted open models; unknown model: <id> Поискано е броене на токени за модел извън хостваните open-weight модели.
401 authentication_error Missing authentication Не е изпратен API ключ.
401 authentication_error Invalid API key Ключът е непознат, заменен е с по-нов или е отменен.
404 not_found_error Not Found Пътят не съществува, например /v1/embeddings.
405 api_error Method Not Allowed Пътят съществува, но не с този HTTP метод.
413 invalid_request_error Failed to buffer the request body: … Тялото на заявката е по-голямо от 32 MiB.
415 invalid_request_error Expected request with `Content-Type: application/json` Хедърът Content-Type липсва или не е application/json.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Липсва задължително поле, като messages, или поле има грешен JSON тип.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan Лимитът на изхода на заявката е по-голям от остатъка по баланса ви.
429 rate_limit_error Too many requests. Retry in <n>s. Защита от наводняване: повече от 120 заявки в минута за вашия акаунт. <n> е броят секунди до края на минутата.
429 rate_limit_error Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan shannon-coder-1 на /v1/chat/completions и /v1/messages: извикванията на Shannon Coder по вашия план за текущия 4-часов прозорец са изразходвани.
429 rate_limit_error Shannon routes are temporarily busy. Please retry. Моделът е зает в този момент.
500 server_error The model backend failed to answer. Please retry. Моделът не даде отговор.
500 server_error An internal error occurred. Please retry. Вътрешен неуспех, докато заявката се подготвяше.
502 api_error The model backend failed to answer. Please retry. Моделът не даде отговор. Семейство Shannon 3 и хоствани open-weight модели.
503 api_error Could not verify your quota right now. Please retry. Балансът ви не можа да бъде прочетен в този момент.
503 api_error token counting is temporarily unavailable for this model Броенето на токени не е налично за този модел в този момент.
504 api_error upstream timed out Хостван open-weight модел е отнел повече от времевия лимит на заявка без стрийминг.

Проверките вървят в този ред: API ключ, тяло на заявката, id на модел, защита от наводняване, баланс. Заявка с грешен ключ и грешно тяло затова връща 401. Заявка, отказана със статус 4xx, не се таксува.

Баланс и защита от наводняване

Всяка заявка се обслужва равнопоставено: няма нива на скоростта и няма отделна квота за API. Две неща все пак могат да отговорят с 429, и двете с тип rate_limit_error. Съобщението ги различава.

Баланс

Вашият баланс е днешният лимит на плана, който се нулира в 00:00 UTC, а след него закупеният кредит. Чатът и API теглят от един и същ баланс.

Всяка заявка първо заделя лимита на своя изход: max_tokens или max_output_tokens на /v1/responses, 4,096, когато не изпратите нито едното. Когато отговорът е готов, заделената сума се заменя с онова, което заявката е използвала. Ако сумата не се побира в оставащия баланс, заявката връща Quota exceeded, преди моделът да стартира.

Заявките, които се изпълняват едновременно, заделят всяка своя сума. Много паралелни заявки с високо max_tokens могат затова да изчерпят баланса за момент, дори всеки отговор да е къс. По-ниско max_tokens заделя по-малко.

Защита от наводняване

Защитата от наводняване позволява 120 заявки в минута на акаунт. Брои акаунта, а не ключа, общо за /v1/chat/completions, /v1/responses и /v1/messages. Минутата започва с първата ви заявка.

Заявка номер 121 в рамките на тази минута връща Too many requests. Retry in <n>s. и не струва нищо. Отказаните заявки също се броят, така че клиент, който изпраща отново, без да чака, остава отказван до края на минутата. Изчакайте <n> секунди от съобщението.

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

GET /v1/models и ендпоинтите за броене на токени не се броят.

Повече за лимитите и баланса и къде да видите собствения си баланс и използване: Ограничения и баланс Keys & usage

Какво да се опита отново

Изпращайте заявка отново само когато същата заявка може да успее. SDK на OpenAI и Anthropic вече сами повтарят отговорите 429 и 5xx по два пъти; задайте max_retries (maxRetries в JavaScript), за да промените това.

Грешка Да се изпрати ли отново? Как
400, 404, 405, 413, 415, 422 Не. Първо поправете заявката. Съобщението назовава полето, модела или входа, които са грешни.
401 Не. Използвайте валиден ключ. Създайте или сменете ключа на страницата Keys & usage.
429 Too many requests Да, след изчакването. Изчакайте броя секунди от съобщението, после изпратете същата заявка.
429 Quota exceeded Не така, както е. Намалете max_tokens, изчакайте дневното нулиране в 00:00 UTC или добавете кредит.
429 Shannon Coder call quota reached Да, в следващия прозорец. Прозорците започват на всеки 4 часа от 00:00 UTC. Друг модел отговаря веднага.
429 … temporarily busy Да. Изчакайте няколко секунди, после по-дълго при всеки следващ опит.
500, 502, 503 Да. Изчакайте 1 секунда, после 2, 4 и 8. Спрете след няколко опита и съобщете id на заявката.
504 Да. Изпратете я със stream, зададен на true: времевият лимит важи за отговори без стрийминг.

Цикъл за повторни опити, който следва тази таблица:

import re
import time

import openai
from openai import OpenAI

# max_retries=0: this loop does the retrying, the SDK does not add its own.
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1", max_retries=0)


def create_with_retry(attempts=5, **request):
    for attempt in range(attempts):
        try:
            return client.chat.completions.create(**request)
        except openai.RateLimitError as error:
            text = str(error)
            flood = re.search(r"Retry in (\d+)s", text)
            if flood:
                time.sleep(int(flood.group(1)))   # flood protection: wait out the minute
            elif "temporarily busy" in text:
                time.sleep(2 ** attempt)
            else:
                raise                             # balance: a wait of seconds does not help
        except (openai.InternalServerError, openai.APIConnectionError):
            time.sleep(2 ** attempt)              # 1, 2, 4, 8 seconds
    raise RuntimeError("the request failed after all attempts")


response = create_with_retry(
    model="shannon-3",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)

Грешки вътре в стрийм

Стриймът има статус 200 от първия си байт. Неуспех след това пристига като събитие вътре в стрийма: chunk с член error на /v1/chat/completions, събитие error на /v1/messages, събитие response.failed или error на /v1/responses. Заключителните събития на стрийма пак следват. Считайте такъв отговор за неуспешен и изпратете заявката отново, както при статус 5xx.

Разговор, по-дълъг от контекстния прозорец на модела, се съобщава по този начин, с тип invalid_request_error и код context_length_exceeded. Съкратете разговора, преди да го изпратите отново.

Точните кадри са описани при стрийминга. Стрийминг

Id-та на заявки

Всеки отговор, включително грешките, има хедър x-request-id. Това е стойността, която сте изпратили в собствения си хедър x-request-id, или 12 шестнадесетични знака, ако не сте изпратили. Записвайте го в логове и го цитирайте, когато искате помощ за заявка.