Zpracování chyb
Požadavek, který selže, vrátí stavový kód HTTP a tělo JSON s typem chyby a zprávou. Tato stránka uvádí každý stav, ukazuje tělo chyby pro každý formát API a říká, které chyby stojí za opakování.
SDK vyvolají objekt chyby, který nese stavový kód a pole těla. Tento požadavek uvádí model, který neexistuje:
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 import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
try {
await client.chat.completions.create({
model: "no-such-model",
messages: [{ role: "user", content: "Hello" }],
});
} catch (error) {
if (!(error instanceof OpenAI.APIError)) throw error;
console.log(error.status); // 400
console.log(error.type); // invalid_request_error
console.log(error.error.message); // unknown model: no-such-model
} curl -i https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "no-such-model",
"messages": [{"role": "user", "content": "Hello"}]
}' Vrátí stav 400 a toto tělo:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Tělo chyby
Existují dvě těla. /v1/messages odpovídá ve formátu Anthropic; každý jiný endpoint odpovídá ve formátu OpenAI. V obou jsou podrobnosti v error.type a error.message, takže jeden čtecí kód obslouží všechny endpointy.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Pole | Typ | Popis |
|---|---|---|
error.type | string | Druh chyby. Viz Typy chyb níže. |
error.message | string | Věta pro člověka. Texty v tabulkách níže jsou stabilní až na své proměnné části, uvedené jako <id>, <n> nebo …. |
error.code | string | null | Přítomno u některých chyb ve formátu OpenAI: invalid_api_key s 401, request_too_large s 413, context_length_exceeded, když je konverzace příliš dlouhá, jinak null nebo chybí. Rozhodujte nejprve podle stavu a error.type a code berte jako doplněk. |
error.param | null | Přítomno u stejných chyb jako code. Vždy null. |
type | string | Pouze formát Anthropic. Vždy error. |
Typy chyb
| Typ | Stavy | Popis |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Samotný požadavek je špatně: pole, tělo, id modelu nebo vstup, který model nepřijímá. Požadavek před novým odesláním změňte. |
authentication_error | 401 | API klíč chybí, je neznámý nebo zrušený. |
not_found_error | 404 | Cesta neexistuje. |
rate_limit_error | 429 | Zůstatek požadavek nepokrývá, zastavila jej ochrana proti zahlcení, nebo je model vytížen. Zpráva říká, který případ nastal. |
api_error | 500, 502, 503, 504 | Požadavek byl v pořádku a chyba je na naší straně. Pošlete jej znovu. |
server_error | 500 | Požadavek byl v pořádku a chyba je na naší straně. Pošlete jej znovu. |
Stavové kódy
| Stav | Typ | Zpráva | Kdy |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Tělo není platný JSON. |
400 | invalid_request_error | unknown model: <id> | model není zveřejněné id. Na /v1/responses také tehdy, když model chybí. |
400 | invalid_request_error | No user message provided | Úrovně Shannon: požadavek neobsahuje žádný uživatelský text. |
400 | invalid_request_error | <id> does not accept image input | Obrázek byl odeslán hostovanému modelu s otevřenými váhami bez obrázkového vstupu. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Část s audiem nebo videem byla odeslána hostovanému modelu s otevřenými váhami. |
400 | invalid_request_error | <id> does not accept response_format | Strukturovaný výstup byl vyžádán od hostovaného modelu s otevřenými váhami, který jej nemá. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | Schéma JSON bylo odesláno hostovanému modelu s otevřenými váhami, který přijímá pouze json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Úsilí uvažování není jednou z uvedených hodnot. Hostované modely s otevřenými váhami. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Počítání tokenů bylo vyžádáno pro model mimo hostované modely s otevřenými váhami. |
401 | authentication_error | Missing authentication | Nebyl odeslán žádný API klíč. |
401 | authentication_error | Invalid API key | Klíč je neznámý, byl nahrazen novějším, nebo byla zrušena jeho platnost. |
404 | not_found_error | Not Found | Cesta neexistuje, například /v1/embeddings. |
405 | api_error | Method Not Allowed | Cesta existuje, ale ne s touto metodou HTTP. |
413 | invalid_request_error | Failed to buffer the request body: … | Tělo požadavku je větší než 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Hlavička Content-Type chybí nebo není application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Chybí povinné pole, například messages, nebo má některé pole špatný typ JSON. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Výstupní limit požadavku je větší, než kolik zbývá z vašeho zůstatku. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Ochrana proti zahlcení: více než 120 požadavků za jednu minutu na vašem účtu. <n> je počet sekund do konce minuty. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 na /v1/chat/completions a /v1/messages: volání Shannon Coder vašeho plánu pro aktuální 4hodinové okno jsou vyčerpána. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Model je v tuto chvíli vytížen. |
500 | server_error | The model backend failed to answer. Please retry. | Model nevytvořil odpověď. |
500 | server_error | An internal error occurred. Please retry. | Vnitřní selhání při přípravě požadavku. |
502 | api_error | The model backend failed to answer. Please retry. | Model nevytvořil odpověď. Rodina Shannon 3 a hostované modely s otevřenými váhami. |
503 | api_error | Could not verify your quota right now. Please retry. | Váš zůstatek se v tuto chvíli nepodařilo přečíst. |
503 | api_error | token counting is temporarily unavailable for this model | Počítání tokenů není pro tento model v tuto chvíli dostupné. |
504 | api_error | upstream timed out | Hostovanému modelu s otevřenými váhami trvalo déle, než je časový limit požadavku, který není streamovaný. |
Kontroly probíhají v tomto pořadí: API klíč, tělo požadavku, id modelu, ochrana proti zahlcení, zůstatek. Požadavek se špatným klíčem a špatným tělem proto vrátí 401. Požadavek odmítnutý se stavem 4xx se neúčtuje.
Zůstatek a ochrana proti zahlcení
Každý požadavek se obsluhuje stejně: neexistují žádné úrovně rychlosti ani samostatná kvóta API. Na 429 přesto mohou odpovědět dvě věci, obě s typem rate_limit_error. Odliší je zpráva.
Zůstatek
Váš zůstatek je dnešní limit plánu, který se obnovuje v 00:00 UTC, a po něm váš zakoupený kredit. Chat a API čerpají ze stejného zůstatku.
Každý požadavek nejprve vyhradí svůj výstupní limit: max_tokens, nebo max_output_tokens na /v1/responses, 4,096, když neposlíte ani jedno. Po dokončení odpovědi se vyhrazená částka nahradí tím, co požadavek spotřeboval. Pokud se částka nevejde do zbývajícího zůstatku, požadavek vrátí Quota exceeded, ještě než model začne.
Požadavky běžící současně vyhrazují každý svou vlastní částku. Mnoho paralelních požadavků s vysokým max_tokens proto může na chvíli vyčerpat zůstatek, i když je každá odpověď krátká. Nižší max_tokens vyhradí méně.
Ochrana proti zahlcení
Ochrana proti zahlcení povoluje 120 požadavků za minutu na účet. Počítá účet, ne klíč, přes /v1/chat/completions, /v1/responses a /v1/messages dohromady. Minuta začíná vaším prvním požadavkem.
Požadavek číslo 121 v rámci té minuty vrátí Too many requests. Retry in <n>s. a nic nestojí. Odmítnuté požadavky se počítají také, takže klient, který posílá znovu bez čekání, zůstává odmítán, dokud minuta neskončí. Počkejte <n> sekund ze zprávy.
Požadavky odeslané paralelně se neodmítají kvůli tomu, že jsou paralelní. Čekají ve frontě a odpovídá se jim postupně.
GET /v1/models a endpointy pro počítání tokenů se nepočítají.
Více o limitech a zůstatku a kde vidět vlastní zůstatek a využití: Limity a zůstatek Klíče a využití
Co opakovat
Požadavek posílejte znovu, jen když může stejný požadavek uspět. SDK OpenAI a Anthropic už odpovědi 429 a 5xx samy opakují dvakrát; změníte to nastavením max_retries (maxRetries v JavaScriptu).
| Chyba | Poslat znovu? | Jak |
|---|---|---|
400, 404, 405, 413, 415, 422 | Ne. Nejprve požadavek opravte. | Zpráva jmenuje pole, model nebo vstup, který je špatně. |
401 | Ne. Použijte platný klíč. | Vytvořte nebo vyměňte klíč na stránce Klíče a využití. |
429 Too many requests | Ano, po čekání. | Počkejte počet sekund uvedený ve zprávě a pak pošlete stejný požadavek. |
429 Quota exceeded | Ne tak, jak je. | Snižte max_tokens, počkejte na denní obnovení v 00:00 UTC, nebo dobijte kredit. |
429 Shannon Coder call quota reached | Ano, v dalším okně. | Okna začínají každé 4 hodiny od 00:00 UTC. Jiný model odpoví hned. |
429 … temporarily busy | Ano. | Počkejte několik sekund, při každém dalším pokusu déle. |
500, 502, 503 | Ano. | Počkejte 1 sekundu, pak 2, 4 a 8. Po několika pokusech přestaňte a nahlaste id požadavku. |
504 | Ano. | Pošlete jej s stream nastaveným na true: časový limit platí pro odpovědi, které nejsou streamované. |
Smyčka opakování podle této tabulky:
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) import OpenAI from "openai";
// maxRetries: 0 — this loop does the retrying, the SDK does not add its own.
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1", maxRetries: 0 });
const sleep = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));
async function createWithRetry(request, attempts = 5) {
for (let attempt = 0; attempt < attempts; attempt++) {
try {
return await client.chat.completions.create(request);
} catch (error) {
const text = String(error.message);
const flood = text.match(/Retry in (\d+)s/);
if (error.status === 429 && flood) {
await sleep(Number(flood[1])); // flood protection: wait out the minute
} else if (error.status === 429 && text.includes("temporarily busy")) {
await sleep(2 ** attempt);
} else if (error.status >= 500 || error instanceof OpenAI.APIConnectionError) {
await sleep(2 ** attempt); // 1, 2, 4, 8 seconds
} else {
throw error; // wrong request, wrong key or balance
}
}
}
throw new Error("the request failed after all attempts");
}
const response = await createWithRetry({
model: "shannon-3",
messages: [{ role: "user", content: "Hello" }],
});
console.log(response.choices[0].message.content); Chyby uvnitř streamu
Stream má stav 200 od prvního bajtu. Selhání po něm přichází jako událost uvnitř streamu: chunk s členem error na /v1/chat/completions, událost error na /v1/messages, událost response.failed nebo error na /v1/responses. Závěrečné události streamu přesto následují. Takovou odpověď považujte za neúspěšnou a pošlete požadavek znovu, jako u stavu 5xx.
Konverzace delší než kontextové okno modelu se hlásí tímto způsobem, s typem invalid_request_error a kódem context_length_exceeded. Konverzaci před novým odesláním zkraťte.
Přesné rámce jsou popsány u streamování. Streamování
Id požadavků
Každá odpověď, včetně chyb, má hlavičku x-request-id. Je to hodnota, kterou jste poslali ve své vlastní hlavičce x-request-id, nebo 12 hexadecimálních znaků, pokud jste neposlali žádnou. Zaznamenejte si ji a uveďte ji, když žádáte o pomoc s požadavkem.