შეცდომების დამუშავება
მოთხოვნა, რომელიც წარუმატებლად სრულდება, აბრუნებს HTTP სტატუს-კოდს და JSON body-ს შეცდომის ტიპითა და შეტყობინებით. ეს გვერდი ჩამოთვლის ყველა სტატუსს, აჩვენებს თითოეული API ფორმატის შეცდომის body-ს და გეუბნებათ, რომელი შეცდომების გაგზავნაა ხელახლა ღირს.
SDK-ები გამოაქვთ შეცდომის ობიექტს, რომელიც სტატუს-კოდსა და body-ის ველებს ატარებს. ეს მოთხოვნა დასახელებს მოდელს, რომელიც არ არსებობს:
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"}]
}' ის აბრუნებს სტატუსს 400 და ამ body-ს:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} შეცდომის body
ორი body არსებობს. /v1/messages პასუხობს Anthropic ფორმატში; ყველა სხვა endpoint — OpenAI ფორმატში. ორივეში დეტალები error.type-სა და error.message-შია, ამიტომ ერთი წამკითხველი ყველა 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"
}
} | ველი | ტიპი | აღწერა |
|---|---|---|
error.type | string | შეცდომის სახეობა. იხილეთ ქვემოთ შეცდომის ტიპები. |
error.message | string | წინადადება ადამიანისთვის. ქვემოთ ცხრილებში ტექსტები სტაბილურია მათი ცვლადი ნაწილების გარდა, რომლებიც ნაჩვენებია როგორც <id>, <n> ან …. |
error.code | string | null | არის OpenAI ფორმატის ზოგიერთ შეცდომაზე: invalid_api_key 401-თან, request_too_large 413-თან, context_length_exceeded, როცა საუბარი ძალიან გრძელია, სხვა შემთხვევაში null ან არ არის. ჯერ სტატუსსა და error.type-ს დაეყრდენით, code კი დამატებად მიიჩნიეთ. |
error.param | null | არის იმავე შეცდომებზე, რაზეც code. ყოველთვის null. |
type | string | მხოლოდ Anthropic ფორმატში. ყოველთვის error. |
შეცდომის ტიპები
| ტიპი | სტატუსები | აღწერა |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | თავად მოთხოვნაა არასწორი: ველი, body, მოდელის id ან შეტანა, რომელსაც მოდელი არ იღებს. გაგზავნამდე მოთხოვნა შეცვალეთ. |
authentication_error | 401 | API გასაღები არ არის, უცნობია ან გაუქმებულია. |
not_found_error | 404 | გზა არ არსებობს. |
rate_limit_error | 429 | ბალანსი მოთხოვნას არ ფარავს, flood protection-მა შეაჩერა, ან მოდელი დაკავებულია. შეტყობინება ამბობს, რომელია. |
api_error | 500, 502, 503, 504 | მოთხოვნა სწორი იყო და წარუმატებლობა ჩვენს მხარეზეა. გააგზავნეთ ხელახლა. |
server_error | 500 | მოთხოვნა სწორი იყო და წარუმატებლობა ჩვენს მხარეზეა. გააგზავნეთ ხელახლა. |
სტატუს-კოდები
| სტატუსი | ტიპი | შეტყობინება | როდის |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | body არ არის ვალიდური JSON. |
400 | invalid_request_error | unknown model: <id> | model არ არის გამოქვეყნებული id. /v1/responses-ზე აგრეთვე მაშინ, როცა model არ არის მითითებული. |
400 | invalid_request_error | No user message provided | Shannon-ის დონეები: მოთხოვნა მომხმარებლის ტექსტს არ შეიცავს. |
400 | invalid_request_error | <id> does not accept image input | სურათი გაიგზავნა hosted open-weight მოდელზე, რომელსაც სურათის შეტანა არ აქვს. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | აუდიო ან ვიდეო ნაწილი გაიგზავნა hosted open-weight მოდელზე. |
400 | invalid_request_error | <id> does not accept response_format | სტრუქტურირებული შედეგი მოითხოვეს hosted open-weight მოდელისგან, რომელსაც ის არ აქვს. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON სქემა გაიგზავნა hosted open-weight მოდელზე, რომელიც მხოლოდ json_object-ს იღებს. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | მსჯელობის effort არ არის ჩამოთვლილი მნიშვნელობებიდან ერთ-ერთი. Hosted open-weight მოდელები. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | ტოკენების დათვლა მოითხოვეს მოდელისთვის, რომელიც hosted open-weight მოდელებს არ ეკუთვნის. |
401 | authentication_error | Missing authentication | API გასაღები არ გაიგზავნა. |
401 | authentication_error | Invalid API key | გასაღები უცნობია, უფრო ახალმა ჩაანაცვლა, ან გაუქმდა. |
404 | not_found_error | Not Found | გზა არ არსებობს, მაგალითად /v1/embeddings. |
405 | api_error | Method Not Allowed | გზა არსებობს, მაგრამ არა ამ HTTP მეთოდით. |
413 | invalid_request_error | Failed to buffer the request body: … | მოთხოვნის body 32 MiB-ზე დიდია. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Content-Type header არ არის ან არ არის application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | სავალდებულო ველი აკლია, მაგალითად messages, ან ველს JSON-ის არასწორი ტიპი აქვს. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | მოთხოვნის გამოტანის ლიმიტი მეტია, ვიდრე თქვენი ბალანსის ნაშთი. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: თქვენს ანგარიშზე ერთ წუთში 120-ზე მეტი მოთხოვნა. <n> არის წამების რაოდენობა წუთის დასრულებამდე. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 /v1/chat/completions-სა და /v1/messages-ზე: თქვენი გეგმის Shannon Coder-ის გამოძახებები მიმდინარე 4-საათიანი ფანჯრისთვის ამოიწურა. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | მოდელი ამ მომენტში დაკავებულია. |
500 | server_error | The model backend failed to answer. Please retry. | მოდელმა პასუხი ვერ შექმნა. |
500 | server_error | An internal error occurred. Please retry. | შიდა წარუმატებლობა მოთხოვნის მომზადებისას. |
502 | api_error | The model backend failed to answer. Please retry. | მოდელმა პასუხი ვერ შექმნა. Shannon 3 ოჯახი და hosted open-weight მოდელები. |
503 | api_error | Could not verify your quota right now. Please retry. | თქვენი ბალანსი ამ მომენტში ვერ წაიკითხა. |
503 | api_error | token counting is temporarily unavailable for this model | ტოკენების დათვლა ამ მოდელისთვის ამ მომენტში მიუწვდომელია. |
504 | api_error | upstream timed out | Hosted open-weight მოდელმა არასტრიმული მოთხოვნის დროის ლიმიტზე მეტი დრო დახარჯა. |
შემოწმებები ამ თანმიმდევრობით სრულდება: API გასაღები, მოთხოვნის body, მოდელის id, flood protection, ბალანსი. ამიტომ მოთხოვნა არასწორი გასაღებითა და არასწორი body-ით აბრუნებს 401-ს. მოთხოვნა, რომელიც 4xx სტატუსით უარყოფილია, არ ირიცხება.
ბალანსი და flood protection
ყოველი მოთხოვნა თანაბრად მუშავდება: არც rate-დონეებია და არც ცალკე API კვოტა. მაინც ორ რამეს შეუძლია 429-ით პასუხი, ორივე ტიპით rate_limit_error. მათ შეტყობინება არჩევს.
ბალანსი
თქვენი ბალანსი არის დღევანდელი გეგმის ლიმიტი, რომელიც 00:00 UTC-ზე ახლდება, და მის შემდეგ თქვენი შეძენილი კრედიტი. ჩატი და API ერთსა და იმავე ბალანსს იყენებენ.
ყოველი მოთხოვნა ჯერ თავის გამოტანის ლიმიტს ირეზერვებს: max_tokens, ან max_output_tokens /v1/responses-ზე, 4,096, თუ არცერთს არ გააგზავნით. როცა პასუხი სრულდება, დარეზერვებული რაოდენობა მოთხოვნის მიერ გამოყენებულით იცვლება. თუ რაოდენობა დარჩენილ ბალანსში არ ეტევა, მოთხოვნა აბრუნებს Quota exceeded-ს მოდელის დაწყებამდე.
მოთხოვნები, რომლებიც ერთდროულად სრულდება, თითოეული თავის რაოდენობას ირეზერვებს. ამიტომ ბევრმა პარალელურმა მოთხოვნამ მაღალი max_tokens-ით შეიძლება ბალანსი ერთი წამით ამოწუროს, თუნდაც თითოეული პასუხი მოკლე იყოს. ნაკლები max_tokens ნაკლებს ირეზერვებს.
Flood protection
Flood protection ანგარიშზე წუთში 120 მოთხოვნას უშვებს. ის ითვლის ანგარიშს და არა გასაღებს, /v1/chat/completions-ს, /v1/responses-სა და /v1/messages-ს ერთად. წუთი თქვენი პირველი მოთხოვნით იწყება.
ამ წუთში 121-ე მოთხოვნა აბრუნებს Too many requests. Retry in <n>s.-ს და არაფერი ღირს. უარყოფილი მოთხოვნებიც ითვლება, ამიტომ კლიენტი, რომელიც ლოდინის გარეშე ხელახლა აგზავნის, უარყოფილი რჩება წუთის დასრულებამდე. დაელოდეთ შეტყობინებაში მითითებულ <n> წამს.
პარალელურად გაგზავნილი მოთხოვნები პარალელურობის გამო არ უარყოფა. ისინი რიგში დგანან და რიგრიგობით პასუხდებიან.
GET /v1/models და ტოკენების დათვლის endpoint-ები არ ითვლება.
მეტი ლიმიტებისა და ბალანსის შესახებ და სად ნახოთ საკუთარი ბალანსი და გამოყენება: ლიმიტები და ბალანსი გასაღებები და გამოყენება
რა უნდა გაიგზავნოს ხელახლა
მოთხოვნა ხელახლა მხოლოდ მაშინ გააგზავნეთ, როცა იგივე მოთხოვნას შეუძლია წარმატება. OpenAI-სა და Anthropic-ის SDK-ები 429 და 5xx პასუხებს უკვე თავისით ორჯერ იმეორებენ; ამის შესაცვლელად დააყენეთ max_retries (JavaScript-ში maxRetries).
| შეცდომა | ხელახლა გაიგზავნოს? | როგორ |
|---|---|---|
400, 404, 405, 413, 415, 422 | არა. ჯერ მოთხოვნა გაასწორეთ. | შეტყობინება ასახელებს ველს, მოდელს ან შეტანას, რომელიც არასწორია. |
401 | არა. გამოიყენეთ მოქმედი გასაღები. | შექმენით ან ჩაანაცვლეთ გასაღები გვერდზე Keys & usage. |
429 Too many requests | დიახ, ლოდინის შემდეგ. | დაელოდეთ შეტყობინებაში მითითებულ წამებს, შემდეგ გააგზავნეთ იგივე მოთხოვნა. |
429 Quota exceeded | ისე, როგორც არის, არა. | შეამცირეთ max_tokens, დაელოდეთ დღიურ განახლებას 00:00 UTC-ზე ან შეავსეთ კრედიტი. |
429 Shannon Coder call quota reached | დიახ, შემდეგ ფანჯარაში. | ფანჯრები ყოველ 4 საათში იწყება 00:00 UTC-დან. სხვა მოდელი მაშინვე პასუხობს. |
429 … temporarily busy | დიახ. | დაელოდეთ რამდენიმე წამს, შემდეგ ყოველ მომდევნო მცდელობაზე უფრო დიდხანს. |
500, 502, 503 | დიახ. | დაელოდეთ 1 წამს, შემდეგ 2-ს, 4-სა და 8-ს. რამდენიმე მცდელობის შემდეგ შეწყვიტეთ და შეატყობინეთ მოთხოვნის id. |
504 | დიახ. | გააგზავნეთ stream-ით true: დროის ლიმიტი არასტრიმულ პასუხებზე მოქმედებს. |
განმეორების ციკლი, რომელიც ამ ცხრილს მიჰყვება:
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); შეცდომები სტრიმის შიგნით
სტრიმს პირველივე ბაიტიდან სტატუსი 200 აქვს. ამის შემდეგ წარუმატებლობა მოვლენის სახით მოდის სტრიმის შიგნით: chunk error წევრით /v1/chat/completions-ზე, error მოვლენა /v1/messages-ზე, response.failed ან error მოვლენა /v1/responses-ზე. სტრიმის დამხურავი მოვლენები მაინც მოჰყვება. ასეთი პასუხი წარუმატებლად ჩათვალეთ და მოთხოვნა ხელახლა გააგზავნეთ, ისევე როგორც 5xx სტატუსისას.
საუბარი, რომელიც მოდელის კონტექსტის ფანჯარაზე გრძელია, ამგვარად ცხადდება, ტიპით invalid_request_error და კოდით context_length_exceeded. ხელახლა გაგზავნამდე საუბარი შეამოკლეთ.
ზუსტი ფრეიმები სტრიმინგთან ერთად არის აღწერილი. სტრიმინგი
მოთხოვნის id-ები
ყოველ პასუხს, შეცდომებისას ჩათვლით, აქვს x-request-id header. ის არის მნიშვნელობა, რომელიც თქვენს საკუთარ x-request-id header-ში გაგზავნეთ, ან 12 თექვსმეტობითი სიმბოლო, თუ არაფერი გაგიგზავნიათ. ჩაიწერეთ ჟურნალში და მიუთითეთ, როცა მოთხოვნასთან დაკავშირებით დახმარებას ითხოვთ.