Klaidų tvarkymas
Nepavykusi užklausa grąžina HTTP būsenos kodą ir JSON turinį su klaidos tipu ir pranešimu. Šiame puslapyje išvardyta kiekviena būsena, parodytas kiekvieno API formato klaidos turinys ir nurodyta, kurias klaidas verta siųsti iš naujo.
SDK sukelia klaidos objektą, kuriame yra būsenos kodas ir turinio laukai. Ši užklausa nurodo modelį, kurio nėra:
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"}]
}' Ji grąžina būseną 400 ir šį turinį:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Klaidos turinys
Yra du turinio variantai. /v1/messages atsako Anthropic formatu; visi kiti galiniai taškai atsako OpenAI formatu. Abiem atvejais detalės yra error.type ir error.message, todėl vienas skaitytuvas tinka visiems galiniams taškams.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Laukas | Tipas | Aprašymas |
|---|---|---|
error.type | string | Klaidos rūšis. Žr. žemiau Klaidų tipai. |
error.message | string | Sakinys žmogui. Tekstai toliau pateiktose lentelėse stabilūs, išskyrus kintamąsias dalis, pažymėtas kaip <id>, <n> ar …. |
error.code | string | null | Yra kai kuriose OpenAI formato klaidose: invalid_api_key su 401, request_too_large su 413, context_length_exceeded, kai pokalbis per ilgas, kitais atvejais null arba nėra. Pirmiausia vadovaukitės būsena ir error.type, o code laikykite papildomu. |
error.param | null | Yra tose pačiose klaidose kaip code. Visada null. |
type | string | Tik Anthropic formatas. Visada error. |
Klaidų tipai
| Tipas | Būsenos | Aprašymas |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Pati užklausa neteisinga: laukas, turinys, modelio id ar įvestis, kurios modelis nepriima. Prieš siųsdami iš naujo, pakeiskite užklausą. |
authentication_error | 401 | API rakto nėra, jis nežinomas arba atšauktas. |
not_found_error | 404 | Tokio kelio nėra. |
rate_limit_error | 429 | Balansas nepadengia užklausos, ją sustabdė apsauga nuo užplūdimo arba modelis užimtas. Pranešime nurodyta, kuris atvejis. |
api_error | 500, 502, 503, 504 | Užklausa buvo tvarkinga, o triktis mūsų pusėje. Siųskite ją dar kartą. |
server_error | 500 | Užklausa buvo tvarkinga, o triktis mūsų pusėje. Siųskite ją dar kartą. |
Būsenos kodai
| Būsena | Tipas | Pranešimas | Kada |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Turinys nėra galiojantis JSON. |
400 | invalid_request_error | unknown model: <id> | model nėra paskelbtas id. Kelyje /v1/responses taip pat tada, kai model nenurodytas. |
400 | invalid_request_error | No user message provided | Shannon lygiai: užklausoje nėra vartotojo teksto. |
400 | invalid_request_error | <id> does not accept image input | Vaizdas išsiųstas talpinamam atvirų svorių modeliui, kuris nepriima vaizdo įvesties. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Garso ar vaizdo įrašo dalis išsiųsta talpinamam atvirų svorių modeliui. |
400 | invalid_request_error | <id> does not accept response_format | Struktūruotos išvesties paprašyta iš talpinamo atvirų svorių modelio, kuris jos neturi. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON schema išsiųsta talpinamam atvirų svorių modeliui, kuris priima tik json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Mąstymo pastangos nėra viena iš išvardytų reikšmių. Talpinami atvirų svorių modeliai. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Tokenų skaičiavimo paprašyta modeliui, kuris nėra talpinamas atvirų svorių modelis. |
401 | authentication_error | Missing authentication | API raktas neišsiųstas. |
401 | authentication_error | Invalid API key | Raktas nežinomas, pakeistas naujesniu arba atšauktas. |
404 | not_found_error | Not Found | Tokio kelio nėra, pavyzdžiui, /v1/embeddings. |
405 | api_error | Method Not Allowed | Kelias egzistuoja, bet ne su šiuo HTTP metodu. |
413 | invalid_request_error | Failed to buffer the request body: … | Užklausos turinys didesnis nei 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Antraštės Content-Type nėra arba ji nėra application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Trūksta privalomo lauko, pavyzdžiui, messages, arba laukas turi netinkamą JSON tipą. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Užklausos išvesties riba didesnė nei jūsų balanso likutis. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Apsauga nuo užplūdimo: per vieną minutę jūsų paskyroje gauta daugiau nei 120 užklausų. <n> yra sekundžių iki minutės pabaigos skaičius. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 galiniuose taškuose /v1/chat/completions ir /v1/messages: išnaudoti jūsų plano Shannon Coder kreipiniai dabartiniam 4 valandų langui. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Modelis šiuo metu užimtas. |
500 | server_error | The model backend failed to answer. Please retry. | Modelis neparengė atsakymo. |
500 | server_error | An internal error occurred. Please retry. | Vidinė triktis rengiant užklausą. |
502 | api_error | The model backend failed to answer. Please retry. | Modelis neparengė atsakymo. Shannon 3 šeima ir talpinami atvirų svorių modeliai. |
503 | api_error | Could not verify your quota right now. Please retry. | Šiuo metu nepavyko nuskaityti jūsų balanso. |
503 | api_error | token counting is temporarily unavailable for this model | Tokenų skaičiavimas šiam modeliui šiuo metu nepasiekiamas. |
504 | api_error | upstream timed out | Talpinamas atvirų svorių modelis užtruko ilgiau nei leidžia nesrautinės užklausos laiko riba. |
Patikros vykdomos šia tvarka: API raktas, užklausos turinys, modelio id, apsauga nuo užplūdimo, balansas. Todėl užklausa su neteisingu raktu ir neteisingu turiniu grąžina 401. Užklausa, atmesta 4xx būsena, neapmokestinama.
Balansas ir apsauga nuo užplūdimo
Kiekviena užklausa aptarnaujama vienodai: nėra spartos lygių ir atskiros API kvotos. Vis dėlto du dalykai gali atsakyti 429, abu su tipu rate_limit_error. Juos atskiria pranešimas.
Balansas
Jūsų balansas yra šios dienos plano kvota, kuri atsistato 00:00 UTC, o po jos nusipirkti kreditai. Pokalbiai ir API naudoja tą patį balansą.
Kiekviena užklausa pirmiausia rezervuoja savo išvesties ribą: max_tokens arba max_output_tokens galiniame taške /v1/responses, 4,096, kai nesiunčiate nė vieno. Kai atsakymas baigtas, rezervuota suma pakeičiama užklausos sunaudota suma. Jei suma netelpa į likusį balansą, užklausa grąžina Quota exceeded modeliui dar nepradėjus.
Vienu metu vykdomos užklausos kiekviena rezervuoja savo sumą. Todėl daug lygiagrečių užklausų su dideliu max_tokens trumpam gali išnaudoti balansą, net jei kiekvienas atsakymas trumpas. Mažesnis max_tokens rezervuoja mažiau.
Apsauga nuo užplūdimo
Apsauga nuo užplūdimo leidžia 120 užklausų per minutę vienai paskyrai. Ji skaičiuoja paskyrą, o ne raktą, kartu per /v1/chat/completions, /v1/responses ir /v1/messages. Minutė prasideda nuo jūsų pirmos užklausos.
121-oji užklausa tą minutę grąžina Too many requests. Retry in <n>s. ir nieko nekainuoja. Atmestos užklausos taip pat skaičiuojamos, todėl klientas, siunčiantis iš naujo nelaukdamas, lieka atmetamas, kol praeis minutė. Palaukite <n> sekundžių iš pranešimo.
Lygiagrečiai siunčiamos užklausos nėra atmetamos dėl lygiagretumo. Jos laukia eilėje ir atsakomos paeiliui.
GET /v1/models ir tokenų skaičiavimo galiniai taškai neįskaičiuojami.
Daugiau apie ribas ir balansą bei kur pamatyti savo balansą ir naudojimą: Ribos ir balansas Raktai ir naudojimas
Ką kartoti
Užklausą siųskite iš naujo tik tada, kai ta pati užklausa gali pavykti. OpenAI ir Anthropic SDK jau patys du kartus kartoja 429 ir 5xx atsakymus; tai pakeisite nustatę max_retries (maxRetries JavaScript).
| Klaida | Siųsti dar kartą? | Kaip |
|---|---|---|
400, 404, 405, 413, 415, 422 | Ne. Pirmiausia ištaisykite užklausą. | Pranešime nurodytas laukas, modelis ar įvestis, kuri neteisinga. |
401 | Ne. Naudokite galiojantį raktą. | Sukurkite arba pakeiskite raktą puslapyje Raktai ir naudojimas. |
429 Too many requests | Taip, po laukimo. | Palaukite pranešime nurodytą sekundžių skaičių, tada siųskite tą pačią užklausą. |
429 Quota exceeded | Ne tokią, kokia yra. | Sumažinkite max_tokens, palaukite dienos atsistatymo 00:00 UTC arba papildykite kreditus. |
429 Shannon Coder call quota reached | Taip, kitame lange. | Langai prasideda kas 4 valandas nuo 00:00 UTC. Kitas modelis atsako iškart. |
429 … temporarily busy | Taip. | Palaukite kelias sekundes, o kiekvieną kitą kartą ilgiau. |
500, 502, 503 | Taip. | Palaukite 1 sekundę, tada 2, 4 ir 8. Po kelių bandymų sustokite ir nurodykite užklausos id. |
504 | Taip. | Siųskite su stream, nustatytu į true: laiko riba taikoma ne srautu siunčiamiems atsakymams. |
Pakartojimo ciklas pagal šią lentelę:
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); Klaidos sraute
Srautas turi būseną 200 nuo pirmo baito. Vėliau įvykusi triktis ateina kaip įvykis srauto viduje: gabalas su nariu error galiniame taške /v1/chat/completions, error įvykis galiniame taške /v1/messages, response.failed ar error įvykis galiniame taške /v1/responses. Baigiamieji srauto įvykiai vis tiek seka. Tokį atsakymą laikykite nepavykusiu ir siųskite užklausą iš naujo, kaip esant 5xx būsenai.
Pokalbis, ilgesnis už modelio konteksto langą, pranešamas šitaip, su tipu invalid_request_error ir kodu context_length_exceeded. Prieš siųsdami iš naujo, sutrumpinkite pokalbį.
Tikslūs kadrai aprašyti prie srautinio perdavimo. Srautinė transliacija
Užklausų id
Kiekvienas atsakymas, įskaitant klaidas, turi antraštę x-request-id. Tai reikšmė, kurią išsiuntėte savo x-request-id antraštėje, arba 12 šešioliktainių simbolių, jei nieko nesiuntėte. Užsirašykite ją ir nurodykite prašydami pagalbos dėl užklausos.