Erarotraktado
Peto, kiu malsukcesas, redonas HTTP-statokodon kaj JSON-korpon kun speco de eraro kaj mesaĝo. Ĉi tiu paĝo listigas ĉiun staton, montras la erarkorpon de ĉiu API-formato kaj diras, kiujn erarojn indas resendi.
La SDK ĵetas erarobjekton, kiu portas la statokodon kaj la kampojn de la korpo. Ĉi tiu peto nomas modelon, kiu ne ekzistas:
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"}]
}' Ĝi redonas staton 400 kaj ĉi tiun korpon:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Erarkorpo
Estas du korpoj. /v1/messages respondas en la formato Anthropic; ĉiu alia endpoint respondas en la formato OpenAI. En ambaŭ la detaloj estas en error.type kaj error.message, do unu legilo servas ĉiujn endpoints.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Kampo | Tipo | Priskribo |
|---|---|---|
error.type | string | La speco de la eraro. Vidu Specoj de eraroj sube. |
error.message | string | Frazo por homo. La tekstoj en la tabeloj sube estas stabilaj ĝis siaj variaj partoj, montritaj kiel <id>, <n> aŭ …. |
error.code | string | null | Ĉeestas ĉe kelkaj eraroj de la formato OpenAI: invalid_api_key kun 401, request_too_large kun 413, context_length_exceeded kiam konversacio estas tro longa, alie null aŭ forestas. Decidu unue laŭ la stato kaj error.type, kaj traktu code kiel kroman informon. |
error.param | null | Ĉeestas ĉe la samaj eraroj kiel code. Ĉiam null. |
type | string | Nur en la formato Anthropic. Ĉiam error. |
Specoj de eraroj
| Tipo | Statoj | Priskribo |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | La peto mem estas malĝusta: kampo, la korpo, la model-id aŭ enigo, kiun la modelo ne akceptas. Ŝanĝu la peton antaŭ ol resendi ĝin. |
authentication_error | 401 | La API-ŝlosilo mankas, estas nekonata aŭ revokita. |
not_found_error | 404 | La vojo ne ekzistas. |
rate_limit_error | 429 | La saldo ne kovras la peton, flood protection haltigis ĝin, aŭ la modelo estas okupata. La mesaĝo diras kiu. |
api_error | 500, 502, 503, 504 | La peto estis bona kaj la malsukceso estas ĉe ni. Resendu ĝin. |
server_error | 500 | La peto estis bona kaj la malsukceso estas ĉe ni. Resendu ĝin. |
Statokodoj
| Stato | Tipo | Mesaĝo | Kiam |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | La korpo ne estas valida JSON. |
400 | invalid_request_error | unknown model: <id> | model ne estas publikigita id. Ĉe /v1/responses ankaŭ kiam model mankas. |
400 | invalid_request_error | No user message provided | Niveloj de Shannon: la peto enhavas neniun tekston de uzanto. |
400 | invalid_request_error | <id> does not accept image input | Bildo estis sendita al gastigita malfermpeza modelo sen bilda enigo. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Aŭdio- aŭ videoparto estis sendita al gastigita malfermpeza modelo. |
400 | invalid_request_error | <id> does not accept response_format | Strukturita eligo estis petita de gastigita malfermpeza modelo sen ĝi. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON-skemo estis sendita al gastigita malfermpeza modelo, kiu akceptas nur json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | La raciuma peno ne estas unu el la listigitaj valoroj. Gastigitaj malfermpezaj modeloj. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Kalkulado de tokenoj estis petita por modelo ekster la gastigitaj malfermpezaj modeloj. |
401 | authentication_error | Missing authentication | Neniu API-ŝlosilo estis sendita. |
401 | authentication_error | Invalid API key | La ŝlosilo estas nekonata, estis anstataŭigita per pli nova, aŭ estis revokita. |
404 | not_found_error | Not Found | La vojo ne ekzistas, ekzemple /v1/embeddings. |
405 | api_error | Method Not Allowed | La vojo ekzistas, sed ne kun ĉi tiu HTTP-metodo. |
413 | invalid_request_error | Failed to buffer the request body: … | La korpo de la peto estas pli granda ol 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | La kapo Content-Type mankas aŭ ne estas application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Deviga kampo mankas, ekzemple messages, aŭ kampo havas malĝustan JSON-tipon. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | La eliga limo de la peto estas pli granda ol tio, kio restas de via saldo. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: pli ol 120 petoj en unu minuto en via konto. <n> estas la nombro da sekundoj ĝis la fino de la minuto. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 ĉe /v1/chat/completions kaj /v1/messages: la vokoj de Shannon Coder de via plano por la nuna 4-hora fenestro estas uzitaj. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | La modelo estas okupata en ĉi tiu momento. |
500 | server_error | The model backend failed to answer. Please retry. | La modelo ne produktis respondon. |
500 | server_error | An internal error occurred. Please retry. | Interna malsukceso dum la peto estis preparata. |
502 | api_error | The model backend failed to answer. Please retry. | La modelo ne produktis respondon. Familio Shannon 3 kaj gastigitaj malfermpezaj modeloj. |
503 | api_error | Could not verify your quota right now. Please retry. | Via saldo ne povis esti legita en ĉi tiu momento. |
503 | api_error | token counting is temporarily unavailable for this model | Kalkulado de tokenoj ne disponeblas por ĉi tiu modelo en ĉi tiu momento. |
504 | api_error | upstream timed out | Gastigita malfermpeza modelo bezonis pli longe ol la tempolimo de peto, kiu ne estas fluata. |
La kontroloj okazas en ĉi tiu ordo: API-ŝlosilo, korpo de peto, model-id, flood protection, saldo. Peto kun malĝusta ŝlosilo kaj malĝusta korpo do redonas 401. Peto, kiu estas rifuzita per stato 4xx, ne estas kalkulata.
Saldo kaj flood protection
Ĉiu peto estas servata egale: ne ekzistas tarifaj niveloj de limoj nek aparta API-kvoto. Du aferoj tamen povas respondi 429, ambaŭ kun la tipo rate_limit_error. La mesaĝo distingas ilin.
Saldo
Via saldo estas la plana kvoto de hodiaŭ, kiu renoviĝas je 00:00 UTC, kaj post ĝi via aĉetita kreditaĵo. Babilo kaj la API prenas el la sama saldo.
Ĉiu peto unue rezervas sian eligan limon: max_tokens, aŭ max_output_tokens ĉe /v1/responses, 4,096 kiam vi sendas neniun. Kiam la respondo estas kompleta, la rezervita kvanto estas anstataŭata per tio, kion la peto uzis. Se la kvanto ne eniras en la restantan saldon, la peto redonas Quota exceeded antaŭ ol la modelo komencas.
Petoj, kiuj funkcias samtempe, rezervas ĉiu sian propran kvanton. Multaj paralelaj petoj kun alta max_tokens do povas momente elĉerpi la saldon, eĉ kiam ĉiu respondo estas mallonga. Pli malalta max_tokens rezervas malpli.
Flood protection
Flood protection permesas 120 petojn por minuto por konto. Ĝi kalkulas la konton, ne la ŝlosilon, kune ĉe /v1/chat/completions, /v1/responses kaj /v1/messages. La minuto komenciĝas per via unua peto.
La peto numero 121 en tiu minuto redonas Too many requests. Retry in <n>s. kaj kostas nenion. Rifuzitaj petoj ankaŭ estas kalkulataj, do kliento, kiu resendas sen atendi, restas rifuzata ĝis la fino de la minuto. Atendu la <n> sekundojn el la mesaĝo.
Paralele senditaj petoj ne estas rifuzataj pro tio, ke ili estas paralelaj. Ili atendas en vico kaj estas respondataj laŭvice.
GET /v1/models kaj la endpoints por kalkulado de tokenoj ne estas kalkulataj.
Pli pri limoj kaj saldo, kaj kie vidi vian propran saldon kaj uzadon: Limoj kaj saldo Ŝlosiloj kaj uzado
Kion reprovi
Resendu peton nur kiam la sama peto povas sukcesi. La SDK de OpenAI kaj de Anthropic jam mem reprovas respondojn 429 kaj 5xx dufoje; agordu max_retries (maxRetries en JavaScript) por ŝanĝi tion.
| Eraro | Ĉu resendi? | Kiel |
|---|---|---|
400, 404, 405, 413, 415, 422 | Ne. Korektu unue la peton. | La mesaĝo nomas la kampon, la modelon aŭ la enigon, kiu estas malĝusta. |
401 | Ne. Uzu validan ŝlosilon. | Kreu aŭ anstataŭigu la ŝlosilon en la paĝo Keys & usage. |
429 Too many requests | Jes, post la atendo. | Atendu la nombron da sekundoj en la mesaĝo, poste sendu la saman peton. |
429 Quota exceeded | Ne tiel, kiel ĝi estas. | Malaltigu max_tokens, atendu la ĉiutagan renovigon je 00:00 UTC, aŭ aldonu kreditaĵon. |
429 Shannon Coder call quota reached | Jes, en la sekva fenestro. | La fenestroj komenciĝas ĉiun 4 horojn ekde 00:00 UTC. Alia modelo respondas tuj. |
429 … temporarily busy | Jes. | Atendu kelkajn sekundojn, poste pli longe ĉe ĉiu plia provo. |
500, 502, 503 | Jes. | Atendu 1 sekundon, poste 2, 4 kaj 8. Haltu post kelkaj provoj kaj raportu la id de la peto. |
504 | Jes. | Sendu ĝin kun stream agordita al true: la tempolimo validas por respondoj, kiuj ne estas fluataj. |
Reprova ciklo, kiu sekvas ĉi tiun tabelon:
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); Eraroj en fluo
Fluo havas staton 200 ekde sia unua bajto. Malsukceso poste venas kiel evento en la fluo: peco kun membro error ĉe /v1/chat/completions, evento error ĉe /v1/messages, evento response.failed aŭ error ĉe /v1/responses. La finaj eventoj de la fluo tamen sekvas. Traktu tian respondon kiel malsukcesan kaj resendu la peton, kiel ĉe stato 5xx.
Konversacio pli longa ol la kunteksta fenestro de la modelo estas raportata tiel, kun la tipo invalid_request_error kaj la kodo context_length_exceeded. Mallongigu la konversacion antaŭ ol resendi.
La precizaj kadroj estas priskribitaj ĉe streaming. Fluigo
Id de petoj
Ĉiu respondo, eraroj inkluzive, havas kapon x-request-id. Ĝi estas la valoro, kiun vi sendis en via propra kapo x-request-id, aŭ 12 deksesumaj signoj, kiam vi sendis nenion. Registru ĝin kaj citu ĝin, kiam vi petas helpon pri peto.