Virheiden käsittely
Epäonnistuva pyyntö palauttaa HTTP-tilakoodin ja JSON-rungon, jossa on virhetyyppi ja viesti. Tällä sivulla listataan jokainen tila, näytetään kunkin API-muodon virherunko ja kerrotaan, mitkä virheet kannattaa lähettää uudelleen.
SDK:t nostavat virheobjektin, joka kuljettaa tilakoodin ja rungon kentät. Tämä pyyntö nimeää mallin, jota ei ole:
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"}]
}' Se palauttaa tilan 400 ja tämän rungon:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Virheen runko
Rungoilla on kaksi muotoa. /v1/messages vastaa Anthropic-muodossa; jokainen muu päätepiste vastaa OpenAI-muodossa. Molemmissa tiedot ovat kentissä error.type ja error.message, joten yksi lukija palvelee kaikkia päätepisteitä.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Kenttä | Tyyppi | Kuvaus |
|---|---|---|
error.type | string | Virheen laji. Katso alta Virhetyypit. |
error.message | string | Lause ihmiselle. Alla olevien taulukoiden tekstit ovat vakaita muuttuvia osiaan lukuun ottamatta, jotka näkyvät muodossa <id>, <n> tai …. |
error.code | string | null | Esiintyy joissakin OpenAI-muodon virheissä: invalid_api_key tilalla 401, request_too_large tilalla 413, context_length_exceeded, kun keskustelu on liian pitkä, muuten null tai puuttuu. Päätä ensin tilan ja error.type-kentän perusteella ja pidä code-kenttää lisätietona. |
error.param | null | Esiintyy samoissa virheissä kuin code. Aina null. |
type | string | Vain Anthropic-muoto. Aina error. |
Virhetyypit
| Tyyppi | Tilat | Kuvaus |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Pyyntö itsessään on väärä: kenttä, runko, mallin id tai syöte, jota malli ei ota. Muuta pyyntöä ennen kuin lähetät sen uudelleen. |
authentication_error | 401 | API-avain puuttuu, on tuntematon tai mitätöity. |
not_found_error | 404 | Polkua ei ole. |
rate_limit_error | 429 | Saldo ei riitä pyyntöön, tulvasuoja pysäytti sen tai malli on kiireinen. Viesti kertoo, mikä. |
api_error | 500, 502, 503, 504 | Pyyntö oli kunnossa ja vika on meidän puolellamme. Lähetä se uudelleen. |
server_error | 500 | Pyyntö oli kunnossa ja vika on meidän puolellamme. Lähetä se uudelleen. |
Tilakoodit
| Tila | Tyyppi | Viesti | Milloin |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Runko ei ole kelvollista JSONia. |
400 | invalid_request_error | unknown model: <id> | model ei ole julkaistu id. Päätepisteessä /v1/responses myös silloin, kun model puuttuu. |
400 | invalid_request_error | No user message provided | Shannon-tasot: pyynnössä ei ole käyttäjän tekstiä. |
400 | invalid_request_error | <id> does not accept image input | Kuva lähetettiin hostatulle avoimen painon mallille, joka ei tue kuvasyötettä. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Ääni- tai videoosa lähetettiin hostatulle avoimen painon mallille. |
400 | invalid_request_error | <id> does not accept response_format | Strukturoitua tulostetta pyydettiin hostatulta avoimen painon mallilta, jolla sitä ei ole. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON-skeema lähetettiin hostatulle avoimen painon mallille, joka ottaa vain json_object-tilan. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Päättelyn teho ei ole yksi listatuista arvoista. Hostatut avoimen painon mallit. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Tokenien laskentaa pyydettiin mallille, joka ei kuulu hostattuihin avoimen painon malleihin. |
401 | authentication_error | Missing authentication | API-avainta ei lähetetty. |
401 | authentication_error | Invalid API key | Avain on tuntematon, korvattu uudemmalla tai mitätöity. |
404 | not_found_error | Not Found | Polkua ei ole, esimerkiksi /v1/embeddings. |
405 | api_error | Method Not Allowed | Polku on olemassa, mutta ei tällä HTTP-metodilla. |
413 | invalid_request_error | Failed to buffer the request body: … | Pyynnön runko on suurempi kuin 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Content-Type-otsake puuttuu tai se ei ole application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Pakollinen kenttä puuttuu, kuten messages, tai kentän JSON-tyyppi on väärä. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Pyynnön tulosteen raja on suurempi kuin saldostasi jäljellä oleva määrä. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Tulvasuoja: tililtäsi tuli yli 120 pyyntöä minuutissa. <n> on sekuntien määrä minuutin loppuun. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 päätepisteissä /v1/chat/completions ja /v1/messages: tilauksesi Shannon Coder -kutsut nykyiseltä 4 tunnin jaksolta on käytetty. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Malli on tällä hetkellä kiireinen. |
500 | server_error | The model backend failed to answer. Please retry. | Malli ei tuottanut vastausta. |
500 | server_error | An internal error occurred. Please retry. | Sisäinen vika pyyntöä valmisteltaessa. |
502 | api_error | The model backend failed to answer. Please retry. | Malli ei tuottanut vastausta. Shannon 3 -perhe ja hostatut avoimen painon mallit. |
503 | api_error | Could not verify your quota right now. Please retry. | Saldoasi ei voitu tällä hetkellä lukea. |
503 | api_error | token counting is temporarily unavailable for this model | Tokenien laskenta ei ole tällä hetkellä käytettävissä tälle mallille. |
504 | api_error | upstream timed out | Hostattu avoimen painon malli kesti kauemmin kuin suoratoistamattoman pyynnön aikaraja. |
Tarkistukset tehdään tässä järjestyksessä: API-avain, pyynnön runko, mallin id, tulvasuoja, saldo. Pyyntö, jossa on väärä avain ja väärä runko, palauttaa siksi 401. 4xx-tilalla hylättyä pyyntöä ei veloiteta.
Saldo ja tulvasuoja
Jokaista pyyntöä palvellaan yhtäläisesti: nopeustasoja ja erillistä API-kiintiötä ei ole. Kaksi asiaa voi silti vastata 429, molemmat tyypillä rate_limit_error. Viestistä erottaa ne toisistaan.
Saldo
Saldosi on päivän tilauskiintiö, joka nollautuu kello 00:00 UTC, ja sen jälkeen ostettu saldo. Chat ja API käyttävät samaa saldoa.
Jokainen pyyntö varaa ensin tulosteen rajansa: max_tokens tai päätepisteessä /v1/responses max_output_tokens, 4,096 jos et lähetä kumpaakaan. Kun vastaus on valmis, varattu määrä korvataan pyynnön käyttämällä määrällä. Jos määrä ei mahdu jäljellä olevaan saldoon, pyyntö palauttaa Quota exceeded ennen kuin malli aloittaa.
Samaan aikaan ajettavat pyynnöt varaavat kukin oman määränsä. Monta rinnakkaista pyyntöä korkealla max_tokens-arvolla voi siksi hetkeksi kuluttaa saldon loppuun, vaikka jokainen vastaus olisi lyhyt. Pienempi max_tokens varaa vähemmän.
Tulvasuoja
Tulvasuoja sallii 120 pyyntöä minuutissa tiliä kohti. Se laskee tilin, ei avaimen, päätepisteiden /v1/chat/completions, /v1/responses ja /v1/messages yhteenlasketuista pyynnöistä. Minuutti alkaa ensimmäisestä pyynnöstäsi.
Pyyntö numero 121 saman minuutin sisällä palauttaa Too many requests. Retry in <n>s. eikä maksa mitään. Myös hylätyt pyynnöt lasketaan, joten asiakas, joka lähettää uudelleen odottamatta, pysyy hylättynä, kunnes minuutti on kulunut. Odota viestissä mainitut <n> sekuntia.
Rinnakkain lähetettyjä pyyntöjä ei hylätä rinnakkaisuuden vuoksi. Ne odottavat jonossa ja saavat vastauksen vuorollaan.
GET /v1/models ja tokenien laskennan päätepisteet eivät kuulu laskentaan.
Lisää rajoista ja saldosta sekä siitä, mistä näet oman saldosi ja käyttösi: Rajat ja saldo Avaimet ja käyttö
Mitä kannattaa yrittää uudelleen
Lähetä pyyntö uudelleen vain, kun sama pyyntö voi onnistua. OpenAI- ja Anthropic-SDK:t yrittävät 429- ja 5xx-vastauksia jo itse kahdesti uudelleen; muuta tätä asetuksella max_retries (maxRetries JavaScriptissä).
| Virhe | Lähetetäänkö uudelleen? | Miten |
|---|---|---|
400, 404, 405, 413, 415, 422 | Ei. Korjaa ensin pyyntö. | Viesti nimeää kentän, mallin tai syötteen, joka on väärin. |
401 | Ei. Käytä kelvollista avainta. | Luo tai vaihda avain sivulla Avaimet ja käyttö. |
429 Too many requests | Kyllä, odotuksen jälkeen. | Odota viestissä mainittu sekuntimäärä ja lähetä sama pyyntö. |
429 Quota exceeded | Ei sellaisenaan. | Pienennä max_tokens-arvoa, odota päivittäistä nollausta kello 00:00 UTC tai lisää saldoa. |
429 Shannon Coder call quota reached | Kyllä, seuraavassa jaksossa. | Jaksot alkavat 4 tunnin välein kello 00:00 UTC alkaen. Toinen malli vastaa heti. |
429 … temporarily busy | Kyllä. | Odota muutama sekunti, sitten pidempään jokaisella uudella yrityksellä. |
500, 502, 503 | Kyllä. | Odota 1 sekunti, sitten 2, 4 ja 8. Lopeta muutaman yrityksen jälkeen ja ilmoita pyynnön id. |
504 | Kyllä. | Lähetä se asetuksella stream arvoon true: aikaraja koskee suoratoistamattomia vastauksia. |
Uudelleenyrityssilmukka, joka noudattaa tätä taulukkoa:
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); Virheet virran sisällä
Virran tila on 200 ensimmäisestä tavusta alkaen. Sen jälkeinen virhe saapuu tapahtumana virran sisällä: pala, jossa on error-jäsen päätepisteessä /v1/chat/completions, error-tapahtuma päätepisteessä /v1/messages, response.failed- tai error-tapahtuma päätepisteessä /v1/responses. Virran päätöstapahtumat seuraavat silti. Käsittele tällainen vastaus epäonnistuneena ja lähetä pyyntö uudelleen kuten 5xx-tilan jälkeen.
Mallin kontekstikokoa pidempi keskustelu ilmoitetaan näin, tyypillä invalid_request_error ja koodilla context_length_exceeded. Lyhennä keskustelua ennen kuin lähetät sen uudelleen.
Tarkat kehykset on kuvattu suoratoiston yhteydessä. Suoratoisto
Pyyntöjen id:t
Jokaisessa vastauksessa, myös virheissä, on otsake x-request-id. Se on arvo, jonka lähetit omassa x-request-id-otsakkeessasi, tai 12 heksadesimaalimerkkiä, jos et lähettänyt mitään. Kirjaa se lokiin ja mainitse se, kun pyydät apua pyynnön kanssa.