Yawo
Ku saita stream zuwa true kuma amsar tana zuwa a matsayin server-sent events yayin da model ke rubuta ta: reasoning da farko, sannan amsar, sannan chunk na ƙarshe mai dalilin ƙarewa da usage. Ku yi amfani da shi duk lokacin da mutum yake jiran rubutun, da kuma don amsoshi masu tsawo.
POST https://api.shannon-ai.com/v1/chat/completions
OpenAI SDKs suna ba ku chunks ɗaya bayan ɗaya. Ku karanta kowane chunk ta abin da yake ɗauka: guntun reasoning, guntun amsa, kiran tool, ko ƙarshen amsar.
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
}' Yadda aka tsara stream
- Amsar tana da status
200da headerscontent-type: text/event-streamdacache-control: no-cache. - Kowane event layi ɗaya ne da ya fara da
data:kuma layi mara komai yana biye da shi. Rubutun da ke bayandata:chunk ɗaya ne na JSON. Babu layukanevent:koid:. - Layin da ya fara da colon, kamar
: ping, sharhi ne da ke riƙe haɗin a buɗe. Ku tsallake shi. - Stream yana ƙarewa da
data: [DONE]. Stream da ya tsaya ba tare da shi ba bai cika ba.
Chunks bisa tsari
Kowane chunk object ne na 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
}
]
} Dukkan chunks na stream ɗaya suna ɗauke da id, created da model iri ɗaya. choices koyaushe yana ɗauke da shigarwa ɗaya. delta ɗinsa yana ɗauke da abin da ke sabo, kuma finish_reason shi ne null har zuwa chunk na ƙarshe.
| Key a cikin delta | Nau'i | Bayani | Wanda ya aika |
|---|---|---|---|
role | string | Koyaushe assistant. Yana zuwa sau ɗaya, a farkon stream. | Hosted open-weight models, shannon-2-lite, shannon-2-pro |
reasoning_content | string | Guntun reasoning na model. Ku haɗa gunduwoyin bisa tsari. | Hosted open-weight models, iyalin Shannon 3, shannon-1.6-pro, shannon-coder-1 |
content | string | Guntun amsar. Ku haɗa gunduwoyin bisa tsari. | Dukkan models |
tool_calls | array | Cikakken kiran tool ɗaya. Duba Tool call deltas. | Dukkan models |
Reasoning yana zuwa da farko, sannan amsar, sannan duk wani kiran tool. Ku karanta chunk ta keys da ke cikin delta ɗinsa, ba ta wurinsa a cikin stream ba: delta na iya ɗaukar role tare da guntun rubutu na farko, kuma na ƙarshe babu komai a cikinsa.
Cikakken stream yadda yake tafiya. Don layukan su gajarta, an bar id, object, created da model daga kowane chunk a nan.
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] Deltas na reasoning
Model da ke yin reasoning yana aika reasoning ɗinsa a cikin delta.reasoning_content kafin amsar. Ku raba rubutun biyu: ku nuna reasoning a matsayin ɓangare na daban mai ruɓewa, ko ku bar shi.
Hosted open-weight models ba sa aika reasoning idan reasoning_effort shi ne off, kuma ba sa aikawa idan request yana da response_format.
shannon-2-lite da shannon-2-pro ma suna yin reasoning kafin su amsa. A wannan endpoint suna aika layukan sharhi na : thinking yayin da suke yi, sannan amsar.
reasoning_content ba ya cikin typed models na OpenAI SDKs. A Python ku karanta shi da getattr(delta, "reasoning_content", None); a JavaScript delta.reasoning_content yana aiki yadda yake.
Deltas na kiran tool
Kiran tool yana zuwa cikakke: chunk ɗaya a kowane kira, wanda delta ɗinsa yana ɗauke da kiran tare da cikakken string na arguments. index yana ƙirga kiran amsar daga 0. Code da ke haɗa arguments guntu-guntu yana aiki ba tare da canji ba, domin yana haɗa guntu ɗaya.
{
"tool_calls": [
{
"index": 0,
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
} Bayan kiran, chunk na ƙarshe yana da finish_reason tool_calls.
Idan request yana da tools, shannon-1.6-lite, shannon-1.6-pro da shannon-coder-1 suna aika rubutun amsa a matsayin delta ɗaya a ƙarshen amsar.
Chunk na ƙarshe
Chunk na ƙarshe kafin data: [DONE] yana da delta mara komai, finish_reason da usage na request ɗin, duka a chunk ɗaya. Kowane stream yana da shi; ba kwa buƙatar 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
}
} A hosted open-weight models usage yana kuma da prompt_tokens_details.cached_tokens da completion_tokens_details.reasoning_tokens.
Bayan request mai web_search: true wanda binciken sa ya sami wani abu, chunk na ƙarshe yana ɗauke da sources ma, kuma chunk ɗaya kafin shi yana ɗauke da alamomin ambato a matsayin delta.annotations. Binciken Yanar Gizon da aka Gina
| finish_reason | Bayani | Wanda ya aika |
|---|---|---|
stop | Model ya kammala amsarsa, ko kuma string na stop ya bayyana. | Dukkan models |
tool_calls | Amsar tana ɗauke da kiran tool ɗaya ko fiye. | Dukkan models |
length | An yanke amsar a iyakar output. | Iyalin Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
An bayyana fields na usage tare da endpoint. Chat Completions
Layukan keep-alive
Yayin da model ke aiki kuma bai da abin aikawa tukuna, stream yana ɗauke da layukan sharhi. Ba su da data. SSE parser yana tsallake su da kansa; code da ke karanta layuka na asali dole ne ya tsallake kowane layi da ya fara da colon.
| Layi | Wanda ya aika | Yaushe |
|---|---|---|
: ping | Iyalin Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | Kowane daƙiƙa 15. |
: keepalive | Hosted open-weight models | Kowane daƙiƙa 15 yayin da model ke aiki. |
: thinking | shannon-2-lite, shannon-2-pro | Yayin da model ke yin reasoning. |
Kurakurai a cikin stream
Da zarar stream ya fara, status ɗinsa shi ne 200, don haka gazawa tana zuwa a cikin stream: chunk mai member na error a inda choices zai kasance.
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] Bayan chunk na kuskure, chunk na ƙarshe, mai finish_reason da usage, da data: [DONE] har yanzu suna biyowa. Ku duba kowane chunk don error. Idan ba a yi wannan dubawa ba, amsar da ta gaza a tsakiya tana kama da cikakkiya.
| Nau'i | Code | Saƙo | Yaushe |
|---|---|---|---|
api_error | The model backend failed to answer. Please retry. | Model ya gaza, ko bai rubuta komai ba. Ku sake aika request ɗin. | |
rate_limit_error | Shannon routes are temporarily busy. Please retry. | Model yana da aiki a wannan lokaci. Ku jira daƙiƙa kaɗan sannan ku sake aika request ɗin. | |
invalid_request_error | context_length_exceeded | Tattaunawar ta fi context window na model tsawo. Ku rage ta kafin ku sake aikawa. Rubutun saƙon yana bambanta. |
Hosted open-weight models suna aika member na error da type da message kawai.
OpenAI Python da JavaScript SDKs suna jefa chunk na kuskure a matsayin kuskuren API yayin da kuke iterating, don haka ku saka loop ɗin a cikin gudanar da kurakurai na yau da kullun.
Status codes, body na kuskure da abin da za a sake gwadawa suna da shafinsu na kansu. Kuskuren Gudanarwa
Rufe haɗin
Rufe haɗin yana dakatar da isarwa, ba request ɗin ba. Model yana rubuta amsar har ƙarshe kuma ana cajin request kamar kun karanta ta duka. Don biyan ƙasa, ku nemi ƙasa: ku saita max_tokens mafi ƙanƙanta a kan model da ke aiwatar da shi.
Stream kuma na iya ƙarewa da wuri a hanyarsa zuwa gare ku, misali idan hanyar sadarwa ta ɗauke ko yayin da ake sabunta server. Sai ya tsaya ba tare da chunk na ƙarshe ba kuma ba tare da data: [DONE] ba. Ku ɗauki wannan amsa a matsayin wadda ba ta cika ba kuma ku sake aika request ɗin.
Karanta stream ba tare da SDK ba
Mai karatu daidai yana yin abubuwa biyar: yana tura kurakuran da ke zuwa kafin stream zuwa gudanar da kurakuransa, yana raba body zuwa layuka, yana tsallake layukan sharhi, yana tsayawa a data: [DONE], kuma yana duba kowane chunk don 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); Samfurin Python yana amfani da fakitin requests. Samfurin JavaScript yana gudana a Node.js 18 ko sama.
Streams na sauran tsare-tsare
Endpoints na Responses da Messages ma suna yin streaming. Frames ɗinsu suna ɗauke da layin event: mai sunan event da layin data: mai JSON ɗinsa. Kowane shafi yana lissafa events ɗinsa bisa tsari.
| A cikin stream | Chat Completions | Responses | Messages |
|---|---|---|---|
| Frames | Layukan data: | Layukan event: da data: | Layukan event: da data: |
| Reasoning yana zuwa a cikin | delta.reasoning_content | response.reasoning_summary_text.delta | thinking_delta |
| Rubutun amsa yana zuwa a cikin | delta.content | response.output_text.delta | text_delta |
| Usage yana zuwa a cikin | Chunk na ƙarshe | response.completed | message_delta |
| Stream yana ƙarewa da | Chunk na ƙarshe, sannan data: [DONE] | response.completed | message_stop |