Pengendalian Ralat
Permintaan yang gagal memulangkan kod status HTTP dan badan JSON dengan jenis ralat dan mesej. Halaman ini menyenaraikan setiap status, menunjukkan badan ralat bagi setiap format API dan menyatakan ralat mana yang wajar dihantar semula.
SDK menimbulkan objek ralat yang membawa kod status dan medan badan. Permintaan ini menamakan model yang tidak wujud:
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"}]
}' Ia memulangkan status 400 dan badan ini:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Badan ralat
Terdapat dua badan. /v1/messages menjawab dalam format Anthropic; setiap endpoint lain menjawab dalam format OpenAI. Dalam kedua-duanya, butirannya ada dalam error.type dan error.message, jadi satu pembaca melayani semua endpoint.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Medan | Jenis | Penerangan |
|---|---|---|
error.type | string | Jenis ralat. Lihat Jenis ralat di bawah. |
error.message | string | Ayat untuk manusia. Teks dalam jadual di bawah stabil kecuali bahagian pemboleh ubahnya, yang ditunjukkan sebagai <id>, <n> atau …. |
error.code | string | null | Hadir pada sesetengah ralat format OpenAI: invalid_api_key dengan 401, request_too_large dengan 413, context_length_exceeded apabila perbualan terlalu panjang, selain itu null atau tiada. Putuskan berdasarkan status dan error.type dahulu dan anggap code sebagai tambahan. |
error.param | null | Hadir pada ralat yang sama seperti code. Sentiasa null. |
type | string | Format Anthropic sahaja. Sentiasa error. |
Jenis ralat
| Jenis | Status | Penerangan |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Permintaan itu sendiri salah: medan, badan, id model atau input yang tidak diterima oleh model. Ubah permintaan sebelum anda menghantarnya semula. |
authentication_error | 401 | Kunci API tiada, tidak dikenali atau telah dibatalkan. |
not_found_error | 404 | Laluan tidak wujud. |
rate_limit_error | 429 | Baki tidak menampung permintaan, perlindungan lonjakan menghentikannya, atau model sedang sibuk. Mesej menyatakan yang mana satu. |
api_error | 500, 502, 503, 504 | Permintaan baik dan kegagalan berada di pihak kami. Hantar semula. |
server_error | 500 | Permintaan baik dan kegagalan berada di pihak kami. Hantar semula. |
Kod status
| Status | Jenis | Mesej | Bila |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Badan bukan JSON yang sah. |
400 | invalid_request_error | unknown model: <id> | model bukan id yang diterbitkan. Pada /v1/responses juga apabila model tiada. |
400 | invalid_request_error | No user message provided | Peringkat Shannon: permintaan tidak mengandungi teks pengguna. |
400 | invalid_request_error | <id> does not accept image input | Imej dihantar kepada model open-weight yang dihoskan tanpa input imej. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Bahagian audio atau video dihantar kepada model open-weight yang dihoskan. |
400 | invalid_request_error | <id> does not accept response_format | Output berstruktur diminta daripada model open-weight yang dihoskan yang tidak mempunyainya. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | Skema JSON dihantar kepada model open-weight yang dihoskan yang hanya menerima json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Tahap usaha penaakulan bukan salah satu nilai yang disenaraikan. Model open-weight yang dihoskan. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Pengiraan token diminta untuk model di luar model open-weight yang dihoskan. |
401 | authentication_error | Missing authentication | Tiada kunci API dihantar. |
401 | authentication_error | Invalid API key | Kunci tidak dikenali, telah diganti dengan yang lebih baharu, atau telah dibatalkan. |
404 | not_found_error | Not Found | Laluan tidak wujud, contohnya /v1/embeddings. |
405 | api_error | Method Not Allowed | Laluan wujud tetapi tidak dengan kaedah HTTP ini. |
413 | invalid_request_error | Failed to buffer the request body: … | Badan permintaan lebih besar daripada 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Header Content-Type tiada atau bukan application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Medan yang diperlukan tiada, seperti messages, atau sesuatu medan mempunyai jenis JSON yang salah. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Had output permintaan lebih besar daripada baki anda yang tinggal. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Perlindungan lonjakan: lebih daripada 120 permintaan dalam satu minit pada akaun anda. <n> ialah bilangan saat sehingga minit berakhir. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 pada /v1/chat/completions dan /v1/messages: panggilan Shannon Coder pelan anda untuk tetingkap 4 jam semasa telah digunakan. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Model sedang sibuk pada masa ini. |
500 | server_error | The model backend failed to answer. Please retry. | Model tidak menghasilkan balasan. |
500 | server_error | An internal error occurred. Please retry. | Kegagalan dalaman semasa permintaan disediakan. |
502 | api_error | The model backend failed to answer. Please retry. | Model tidak menghasilkan balasan. Keluarga Shannon 3 dan model open-weight yang dihoskan. |
503 | api_error | Could not verify your quota right now. Please retry. | Baki anda tidak dapat dibaca pada masa ini. |
503 | api_error | token counting is temporarily unavailable for this model | Pengiraan token tidak tersedia untuk model ini pada masa ini. |
504 | api_error | upstream timed out | Model open-weight yang dihoskan mengambil masa lebih lama daripada had masa permintaan yang bukan stream. |
Semakan berjalan mengikut urutan ini: kunci API, badan permintaan, id model, perlindungan lonjakan, baki. Permintaan dengan kunci yang salah dan badan yang salah oleh itu memulangkan 401. Permintaan yang ditolak dengan status 4xx tidak dicaj.
Baki dan perlindungan lonjakan
Setiap permintaan dilayani sama rata: tiada peringkat kadar dan tiada kuota API yang berasingan. Dua perkara masih boleh menjawab 429, kedua-duanya dengan jenis rate_limit_error. Mesej membezakannya.
Baki
Baki anda ialah kuota pelan hari ini, yang ditetapkan semula pada 00:00 UTC, dan selepasnya kredit yang anda beli. Sembang dan API mengambil daripada baki yang sama.
Setiap permintaan mula-mula mengetepikan had outputnya: max_tokens, atau max_output_tokens pada /v1/responses, 4,096 apabila anda tidak menghantar kedua-duanya. Apabila balasan selesai, jumlah yang diketepikan digantikan dengan apa yang digunakan oleh permintaan. Jika jumlah itu tidak muat dalam baki yang tinggal, permintaan memulangkan Quota exceeded sebelum model bermula.
Permintaan yang berjalan serentak masing-masing mengetepikan jumlahnya sendiri. Banyak permintaan selari dengan max_tokens yang tinggi boleh menghabiskan baki seketika, walaupun setiap balasan pendek. max_tokens yang lebih rendah mengetepikan lebih sedikit.
Perlindungan lonjakan
Perlindungan lonjakan membenarkan 120 permintaan seminit bagi setiap akaun. Ia mengira akaun, bukan kunci, merentas /v1/chat/completions, /v1/responses dan /v1/messages bersama-sama. Minit bermula dengan permintaan pertama anda.
Permintaan nombor 121 dalam minit itu memulangkan Too many requests. Retry in <n>s. dan tidak berkos apa-apa. Permintaan yang ditolak turut dikira, jadi klien yang menghantar semula tanpa menunggu kekal ditolak sehingga minit berakhir. Tunggu <n> saat daripada mesej itu.
Permintaan yang dihantar secara selari tidak ditolak kerana selari. Ia menunggu dalam giliran dan dijawab satu demi satu.
GET /v1/models dan endpoint pengiraan token tidak dikira.
Lebih lanjut tentang had dan baki, serta tempat melihat baki dan penggunaan anda sendiri: Had dan baki Kunci & penggunaan
Apa yang perlu dicuba semula
Hantar permintaan semula hanya apabila permintaan yang sama boleh berjaya. SDK OpenAI dan Anthropic sudah mencuba semula balasan 429 dan 5xx sebanyak dua kali dengan sendirinya; tetapkan max_retries (maxRetries dalam JavaScript) untuk mengubahnya.
| Ralat | Hantar semula? | Bagaimana |
|---|---|---|
400, 404, 405, 413, 415, 422 | Tidak. Betulkan permintaan dahulu. | Mesej menamakan medan, model atau input yang salah. |
401 | Tidak. Gunakan kunci yang sah. | Cipta atau gantikan kunci pada halaman Kunci & penggunaan. |
429 Too many requests | Ya, selepas menunggu. | Tunggu bilangan saat dalam mesej, kemudian hantar permintaan yang sama. |
429 Quota exceeded | Tidak seperti sedia ada. | Rendahkan max_tokens, tunggu penetapan semula harian pada 00:00 UTC, atau tambah kredit. |
429 Shannon Coder call quota reached | Ya, pada tetingkap seterusnya. | Tetingkap bermula setiap 4 jam dari 00:00 UTC. Model lain menjawab serta-merta. |
429 … temporarily busy | Ya. | Tunggu beberapa saat, kemudian lebih lama pada setiap percubaan seterusnya. |
500, 502, 503 | Ya. | Tunggu 1 saat, kemudian 2, 4 dan 8. Berhenti selepas beberapa percubaan dan laporkan id permintaan. |
504 | Ya. | Hantar dengan stream ditetapkan kepada true: had masa terpakai pada balasan yang bukan stream. |
Gelung cuba semula yang mengikut jadual ini:
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); Ralat di dalam stream
Stream mempunyai status 200 sejak bait pertamanya. Kegagalan selepas itu tiba sebagai peristiwa di dalam stream: ketulan dengan ahli error pada /v1/chat/completions, peristiwa error pada /v1/messages, peristiwa response.failed atau error pada /v1/responses. Peristiwa penutup stream masih mengikuti. Anggap balasan sedemikian gagal dan hantar permintaan sekali lagi, seperti bagi status 5xx.
Perbualan yang lebih panjang daripada tetingkap konteks model dilaporkan dengan cara ini, dengan jenis invalid_request_error dan kod context_length_exceeded. Pendekkan perbualan sebelum anda menghantarnya semula.
Bingkai yang tepat diterangkan bersama streaming. Penstriman
Id permintaan
Setiap balasan, termasuk ralat, mempunyai header x-request-id. Ia ialah nilai yang anda hantar dalam header x-request-id anda sendiri, atau 12 aksara heksadesimal apabila anda tidak menghantar apa-apa. Catatkannya dalam log, dan nyatakannya apabila anda meminta bantuan tentang sesuatu permintaan.