Стриминг
stream-ро ба true гузоред ва ҷавоб ҳамчун server-sent events ҳангоми навишта шуданаш меояд: аввал reasoning, баъд ҷавоб, баъд чанки охирин бо сабаби анҷом ва usage. Онро ҳар вақт истифода баред, ки одам матнро интизор аст, ва барои ҷавобҳои дароз.
POST https://api.shannon-ai.com/v1/chat/completions
SDK-ҳои OpenAI чанкҳоро яке-яке ба шумо медиҳанд. Ҳар чанкро аз рӯи он чи дорад бихонед: порчаи reasoning, порчаи ҷавоб, даъвати абзор ё охири ҷавоб.
from openai import OpenAI, APIError
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
stream = client.chat.completions.create(
model="shannon-3",
messages=[{"role": "user", "content": "Explain server-sent events in three sentences."}],
stream=True,
)
answer, reasoning, tool_calls = [], [], []
finish_reason = usage = None
try:
for chunk in stream:
if chunk.usage:
usage = chunk.usage
if not chunk.choices:
continue
choice = chunk.choices[0]
delta = choice.delta
thought = getattr(delta, "reasoning_content", None)
if thought:
reasoning.append(thought)
if delta.content:
answer.append(delta.content)
print(delta.content, end="", flush=True)
for call in delta.tool_calls or []:
tool_calls.append((call.id, call.function.name, call.function.arguments))
if choice.finish_reason:
finish_reason = choice.finish_reason
except APIError as error:
# A failure after the stream started arrives as an error chunk.
print(f"\nstream failed: {error}")
print(f"\n{finish_reason} {usage}") import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const stream = await client.chat.completions.create({
model: "shannon-3",
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
stream: true,
});
let answer = "";
let reasoning = "";
const toolCalls = [];
let finishReason = null;
let usage = null;
try {
for await (const chunk of stream) {
if (chunk.usage) usage = chunk.usage;
const choice = chunk.choices?.[0];
if (!choice) continue;
const delta = choice.delta;
if (delta.reasoning_content) reasoning += delta.reasoning_content;
if (delta.content) {
answer += delta.content;
process.stdout.write(delta.content);
}
for (const call of delta.tool_calls ?? []) {
toolCalls.push({ id: call.id, name: call.function.name, arguments: call.function.arguments });
}
if (choice.finish_reason) finishReason = choice.finish_reason;
}
} catch (error) {
// A failure after the stream started arrives as an error chunk.
console.error("\nstream failed:", error.message);
}
console.log("\n", finishReason, usage); curl -N https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}],
"stream": true
}' Ҷараён чӣ гуна чаҳорчӯба мешавад
- Ҷавоб ҳолати
200ва сарлавҳаҳоиcontent-type: text/event-streamваcache-control: no-cacheдорад. - Ҳар рӯйдод як хат аст, ки бо
data:оғоз мешавад ва пас аз он хати холӣ меояд. Матни баъд азdata:як чанки JSON аст. Хатҳоиevent:ёid:нестанд. - Хате, ки бо дунуқта оғоз мешавад, масалан
: ping, эзоҳест, ки пайвастшавиро кушода нигоҳ медорад. Онро гузаронед. - Ҷараён бо
data: [DONE]ба охир мерасад. Ҷараёне, ки бе он қатъ мешавад, нопурра аст.
Чанкҳо бо тартиб
Ҳар чанк объекти chat.completion.chunk аст:
{
"id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "chat.completion.chunk",
"created": 1791625200,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {
"content": "Server-sent"
},
"finish_reason": null
}
]
} Ҳамаи чанкҳои як ҷараён id, created ва model-и якхела доранд. choices ҳамеша як сабт дорад. delta-и он чизи навро дорад ва finish_reason то чанки охирин null аст.
| Калид дар delta | Навъ | Тавсиф | Фиристанда |
|---|---|---|---|
role | string | Ҳамеша assistant. Он як бор, дар оғози ҷараён меояд. | Моделҳои open-weight-и хостшуда, shannon-2-lite, shannon-2-pro |
reasoning_content | string | Порчаи reasoning-и модел. Порчаҳоро бо тартиб якҷоя кунед. | Моделҳои open-weight-и хостшуда, оилаи Shannon 3, shannon-1.6-pro, shannon-coder-1 |
content | string | Порчаи ҷавоб. Порчаҳоро бо тартиб якҷоя кунед. | Ҳамаи моделҳо |
tool_calls | array | Як даъвати пурраи абзор. Delta-ҳои даъвати абзорро бинед. | Ҳамаи моделҳо |
Аввал reasoning меояд, баъд ҷавоб, баъд даъватҳои абзор. Чанкро аз рӯи калидҳои delta-и он бихонед, на аз рӯи ҷойгиршавии он дар ҷараён: delta метавонад role-ро якҷоя бо порчаи аввали матн дошта бошад ва охирини он холӣ аст.
Тамоми ҷараён ҳамон тавр, ки мегузарад. Барои кӯтоҳ нигоҳ доштани хатҳо, id, object, created ва model дар ин ҷо аз ҳар чанк хориҷ карда шудаанд.
data: {"choices":[{"index":0,"delta":{"reasoning_content":"Three sentences:"},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{"reasoning_content":" what it is, how it is framed, why it is used."},"finish_reason":null}]}
: ping
data: {"choices":[{"index":0,"delta":{"content":"Server-sent"},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{"content":" events let a server push text to a client over one HTTP reply."},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":1190,"completion_tokens":84,"total_tokens":1274}}
data: [DONE] Deltaҳои reasoning
Модели reasoning-кунанда reasoning-и худро пеш аз ҷавоб дар delta.reasoning_content мефиристад. Ду матнро ҷудо нигоҳ доред: reasoning-ро ҳамчун қисми алоҳидаи ҷамъшаванда нишон диҳед, ё онро партоед.
Моделҳои open-weight-и хостшуда вақте ки reasoning_effort off аст, reasoning намефиристанд ва низ вақте ки дархост response_format дорад.
shannon-2-lite ва shannon-2-pro низ пеш аз ҷавоб reasoning мекунанд. Дар ин endpoint онҳо ҳангоми ин кор хатҳои эзоҳии : thinking-ро мефиристанд ва баъд ҷавобро.
reasoning_content дар моделҳои таипшудаи SDK-ҳои OpenAI нест. Дар Python онро бо getattr(delta, "reasoning_content", None) бихонед; дар JavaScript delta.reasoning_content ҳамон тавр кор мекунад.
Deltaҳои даъвати абзор
Даъвати абзор пурра меояд: як чанк барои ҳар даъват, ки delta-и он даъватро бо сатри пурраи arguments дорад. index даъватҳои ҷавобро аз 0 рақам мегузорад. Рамзе, ки arguments-ро порча ба порча якҷоя мекунад, бетағйир кор мекунад, зеро як порчаро якҷоя мекунад.
{
"tool_calls": [
{
"index": 0,
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
} Пас аз даъватҳо, чанки охирин finish_reason-и tool_calls дорад.
Вақте ки дархост tools дорад, shannon-1.6-lite, shannon-1.6-pro ва shannon-coder-1 матни ҷавобро ҳамчун як delta дар охири ҷавоб мефиристанд.
Чанки охирин
Чанки охирин пеш аз data: [DONE] delta-и холӣ, finish_reason ва usage-и дархостро дорад, ҳама дар ҳамон як чанк. Ҳар ҷараён онро дорад; ба шумо stream_options лозим нест.
{
"id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "chat.completion.chunk",
"created": 1791625200,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 1190,
"completion_tokens": 84,
"total_tokens": 1274
}
} Дар моделҳои open-weight-и хостшуда usage ҳамчунин prompt_tokens_details.cached_tokens ва completion_tokens_details.reasoning_tokens дорад.
Пас аз дархости дорои web_search: true, ки ҷустуҷӯяш чизе ёфтааст, чанки охирин ҳамчунин sources-ро дорад, ва як чанк пеш аз он нишонаҳои иқтибосро ҳамчун delta.annotations дорад. Ҷустуҷӯи веб
| finish_reason | Тавсиф | Фиристанда |
|---|---|---|
stop | Модел ҷавобашро тамом кард ё сатри stop пайдо шуд. | Ҳамаи моделҳо |
tool_calls | Ҷавоб як ё якчанд даъвати абзор дорад. | Ҳамаи моделҳо |
length | Ҷавоб дар ҳади баромад бурида шуд. | Оилаи Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
Майдонҳои usage дар баробари endpoint тавсиф шудаанд. Chat Completions
Хатҳои keep-alive
То даме ки модел кор мекунад ва ҳанӯз чизе барои фиристодан надорад, ҷараён хатҳои эзоҳиро мегузаронад. Онҳо маълумот надоранд. Парсери SSE онҳоро худаш мегузаронад; рамзе, ки хатҳои хомро мехонад, бояд ҳар хатеро, ки бо дунуқта оғоз мешавад, гузаронад.
| Хат | Фиристанда | Кай |
|---|---|---|
: ping | Оилаи Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | Ҳар 15 сония. |
: keepalive | Моделҳои open-weight-и хостшуда | Ҳар 15 сония, то даме ки модел кор мекунад. |
: thinking | shannon-2-lite, shannon-2-pro | Ҳангоме ки модел reasoning мекунад. |
Хатогиҳо дар дохили ҷараён
Вақте ки ҷараён оғоз шуд, ҳолати он 200 аст, бинобар ин нокомӣ дар дохили ҷараён меояд: чанк бо узви error дар ҷойи choices.
data: {"error":{"message":"The model backend failed to answer. Please retry.","type":"api_error","code":null,"param":null}}
data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":1190,"completion_tokens":12,"total_tokens":1202}}
data: [DONE] Пас аз чанки хатогӣ чанки охирин бо finish_reason ва usage, ва data: [DONE] ҳамоно меоянд. Ҳар чанкро барои error санҷед. Бе ин санҷиш ҷавобе, ки дар миёна ноком шудааст, пурра менамояд.
| Навъ | Код | Паём | Кай |
|---|---|---|---|
api_error | The model backend failed to answer. Please retry. | Модел ноком шуд ё чизе нанавишт. Дархостро дубора фиристед. | |
rate_limit_error | Shannon routes are temporarily busy. Please retry. | Модел дар ин лаҳза банд аст. Якчанд сония интизор шавед ва дархостро дубора фиристед. | |
invalid_request_error | context_length_exceeded | Гуфтугӯ аз тирезаи контексти модел дарозтар аст. Пеш аз дубора фиристодан онро кӯтоҳ кунед. Матни паём фарқ мекунад. |
Моделҳои open-weight-и хостшуда узви error-ро танҳо бо type ва message мефиристанд.
SDK-ҳои Python ва JavaScript-и OpenAI чанки хатогиро ҳангоми такрори шумо ҳамчун хатогии API мепартоянд, бинобар ин ҳалқаро бо идораи хатогии маъмулии худ печонед.
Рамзҳои ҳолат, ҷисми хатогӣ ва он ки чиро бояд такрор кард, саҳифаи худашро доранд. Идораи хатогиҳо
Бастани пайвастшавӣ
Бастани пайвастшавӣ расонидани ҷавобро қатъ мекунад, на дархостро. Модел ҷавобро то охир менависад ва дархост ҳамон тавр ҳисоб карда мешавад, ки гӯё шумо онро пурра хондаед. Барои камтар пардохт кардан, камтар талаб кунед: дар модели татбиқкунандаи max_tokens қимати пасттарро гузоред.
Ҷараён метавонад дар роҳ ба сӯи шумо барвақт қатъ шавад, масалан ҳангоми канда шудани шабака ё навсозии сервер. Он гоҳ бе чанки охирин ва бе data: [DONE] қатъ мешавад. Чунин ҷавобро нопурра ҳисоб кунед ва дархостро дубора фиристед.
Хондани ҷараён бе SDK
Хонандаи дуруст панҷ корро мекунад: хатогиҳоеро, ки пеш аз ҷараён меоянд, ба идораи хатогии худ мефиристад, ҷисмро ба хатҳо ҷудо мекунад, хатҳои эзоҳиро мегузаронад, дар data: [DONE] меистад ва ҳар чанкро барои error месанҷад.
import json
import requests
response = requests.post(
"https://api.shannon-ai.com/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "shannon-3",
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}],
"stream": True,
},
stream=True,
)
# 1. Errors before the stream are plain JSON with their own status.
if response.status_code != 200:
raise RuntimeError(f"{response.status_code}: {response.text}")
answer, done = [], False
for raw in response.iter_lines(): # 2. one line at a time
line = raw.decode("utf-8")
if not line.startswith("data: "): # 3. empty lines and ": ping" comments
continue
data = line[len("data: "):]
if data == "[DONE]": # 4. the end of the stream
done = True
break
chunk = json.loads(data)
if "error" in chunk: # 5. a failure inside the stream
raise RuntimeError(chunk["error"]["message"])
delta = chunk["choices"][0]["delta"]
if delta.get("content"):
answer.append(delta["content"])
if chunk.get("usage"):
print(chunk["choices"][0]["finish_reason"], chunk["usage"])
if not done:
raise RuntimeError("the stream ended before [DONE]")
print("".join(answer)) const response = await fetch("https://api.shannon-ai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "shannon-3",
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
stream: true,
}),
});
// 1. Errors before the stream are plain JSON with their own status.
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const decoder = new TextDecoder();
let buffer = "";
let answer = "";
let done = false;
read: for await (const bytes of response.body) {
buffer += decoder.decode(bytes, { stream: true });
const lines = buffer.split("\n"); // 2. one line at a time
buffer = lines.pop(); // keep the unfinished line
for (const line of lines) {
if (!line.startsWith("data: ")) continue; // 3. empty lines and ": ping" comments
const data = line.slice(6);
if (data === "[DONE]") { // 4. the end of the stream
done = true;
break read;
}
const chunk = JSON.parse(data);
if (chunk.error) throw new Error(chunk.error.message); // 5. a failure inside the stream
const choice = chunk.choices[0];
if (choice.delta.content) answer += choice.delta.content;
if (chunk.usage) console.log(choice.finish_reason, chunk.usage);
}
}
if (!done) throw new Error("the stream ended before [DONE]");
console.log(answer); Намунаи Python бастаи requests-ро истифода мебарад. Намунаи JavaScript дар Node.js 18 ё нав кор мекунад.
Ҷараёнҳои форматҳои дигар
Endpointҳои Responses ва Messages низ streaming мекунанд. Фреймҳои онҳо хати event: бо номи рӯйдод ва хати data: бо JSON-и он доранд. Ҳар саҳифа рӯйдодҳои худро бо тартиб номбар мекунад.
| Дар ҷараён | Chat Completions | Responses | Messages |
|---|---|---|---|
| Фреймҳо | Хатҳои data: | Хатҳои event: ва data: | Хатҳои event: ва data: |
| Reasoning меояд дар | delta.reasoning_content | response.reasoning_summary_text.delta | thinking_delta |
| Матни ҷавоб меояд дар | delta.content | response.output_text.delta | text_delta |
| Usage меояд дар | Чанки охирин | response.completed | message_delta |
| Ҷараён ба охир мерасад бо | Чанки охирин, баъд data: [DONE] | response.completed | message_stop |