ஸ்ட்ரீமிங்
stream-ஐ true ஆக அமைத்தால், மாடல் எழுதும்போதே பதில் server-sent events ஆக வந்து சேரும்: முதலில் reasoning, பிறகு பதில், இறுதியாக finish reason மற்றும் usage கொண்ட கடைசி chunk. ஒருவர் உரைக்காகக் காத்திருக்கும்போதும், நீண்ட பதில்களுக்கும் இதைப் பயன்படுத்தவும்.
POST https://api.shannon-ai.com/v1/chat/completions
OpenAI SDK-கள் chunks-ஐ ஒவ்வொன்றாகத் தருகின்றன. ஒவ்வொரு chunk-ஐயும் அது கொண்டுள்ளதன் அடிப்படையில் படிக்கவும்: reasoning துண்டு, பதிலின் துண்டு, tool அழைப்பு, அல்லது பதிலின் முடிவு.
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
}' stream எவ்வாறு வடிவமைக்கப்படுகிறது
- பதிலின் நிலை
200; headerscontent-type: text/event-streamமற்றும்cache-control: no-cache. - ஒவ்வொரு நிகழ்வும்
data:உடன் தொடங்கும் ஒரு வரி, அதைத் தொடர்ந்து ஒரு காலி வரி.data:க்குப் பிறகு உள்ள உரை ஒரு JSON chunk.event:அல்லதுid:வரிகள் இல்லை. : pingபோன்ற, colon-உடன் தொடங்கும் வரி, இணைப்பைத் திறந்து வைக்கும் கருத்து. அதைத் தவிர்க்கவும்.- stream
data: [DONE]உடன் முடியும். அது இல்லாமல் நின்றுவிடும் stream முழுமையற்றது.
வரிசைப்படி chunks
ஒவ்வொரு chunk-ம் ஒரு chat.completion.chunk object:
{
"id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "chat.completion.chunk",
"created": 1791625200,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {
"content": "Server-sent"
},
"finish_reason": null
}
]
} ஒரே stream-ன் அனைத்து chunks-லும் ஒரே id, created மற்றும் model இருக்கும். choices-ல் எப்போதும் ஒரே ஒரு உள்ளீடு இருக்கும். அதன் delta புதியதைக் கொண்டிருக்கும்; கடைசி chunk வரை finish_reason null ஆக இருக்கும்.
| delta-வில் key | வகை | விளக்கம் | அனுப்புவது |
|---|---|---|---|
role | string | எப்போதும் assistant. stream-ன் தொடக்கத்தில் ஒரு முறை வரும். | ஹோஸ்ட் செய்யப்பட்ட 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 | ஒரு முழுமையான tool அழைப்பு. Tool call deltas-ஐப் பார்க்கவும். | அனைத்து மாடல்கள் |
முதலில் reasoning, பிறகு பதில், பிறகு ஏதேனும் tool அழைப்புகள். chunk-ஐ stream-ல் அதன் இடத்தால் அல்ல, அதன் delta-ல் உள்ள keys மூலம் படிக்கவும்: ஒரு delta-ல் முதல் உரைத் துண்டுடன் role-ம் இருக்கலாம், கடைசியில் உள்ளது காலியாக இருக்கும்.
ஒரு முழு stream, அது பயணிக்கும் வடிவில். வரிகளைச் சிறியதாக வைக்க, இங்கு ஒவ்வொரு chunk-லிருந்தும் 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] Reasoning deltas
reasoning செய்யும் மாடல் பதிலுக்கு முன் தனது reasoning-ஐ delta.reasoning_content-ல் அனுப்பும். இரு உரைகளையும் தனித்தனியாக வைக்கவும்: reasoning-ஐ மடிக்கக்கூடிய தனிப் பகுதியாகக் காட்டவும், அல்லது விட்டுவிடவும்.
reasoning_effort off ஆக இருக்கும்போதும், கோரிக்கையில் response_format இருக்கும்போதும் ஹோஸ்ட் செய்யப்பட்ட open-weight மாடல்கள் reasoning அனுப்பாது.
shannon-2-lite மற்றும் shannon-2-pro-உம் பதிலளிக்கும் முன் reasoning செய்கின்றன. இந்த endpoint-ல் அவ்வாறு செய்யும்போது அவை : thinking கருத்து வரிகளையும், பிறகு பதிலையும் அனுப்புகின்றன.
reasoning_content OpenAI SDK-களின் typed models-ல் இல்லை. Python-ல் அதை getattr(delta, "reasoning_content", None) மூலம் படிக்கவும்; JavaScript-ல் delta.reasoning_content அப்படியே செயல்படும்.
Tool call deltas
tool அழைப்பு முழுமையாக வரும்: ஒரு அழைப்புக்கு ஒரு chunk; அதன் delta-ல் முழுமையான arguments string உடன் அழைப்பு இருக்கும். index பதிலின் அழைப்புகளை 0-ல் இருந்து எண்ணிடும். arguments-ஐ துண்டு துண்டாக இணைக்கும் குறியீடு மாற்றமின்றிச் செயல்படும், ஏனெனில் அது ஒரே ஒரு துண்டை இணைக்கிறது.
{
"tool_calls": [
{
"index": 0,
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
} அழைப்புகளுக்குப் பிறகு, கடைசி chunk-ல் finish_reason tool_calls ஆக இருக்கும்.
கோரிக்கையில் tools இருக்கும்போது, shannon-1.6-lite, shannon-1.6-pro மற்றும் shannon-coder-1 பதில் உரையைப் பதிலின் இறுதியில் ஒரே delta ஆக அனுப்பும்.
கடைசி chunk
data: [DONE]-க்கு முந்தைய கடைசி chunk-ல் காலியான delta, finish_reason மற்றும் கோரிக்கையின் usage ஆகிய அனைத்தும் ஒரே chunk-ல் இருக்கும். ஒவ்வொரு stream-க்கும் இது உண்டு; 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 கோரிக்கைக்குப் பிறகு, கடைசி chunk-ல் sources-ம் இருக்கும்; அதற்கு முந்தைய ஒரு chunk மேற்கோள் குறிகளை delta.annotations ஆகக் கொண்டிருக்கும். உள்ளமைக்கப்பட்ட இணைய தேடல்
| finish_reason | விளக்கம் | அனுப்புவது |
|---|---|---|
stop | மாடல் தனது பதிலை முடித்தது, அல்லது ஒரு stop string தோன்றியது. | அனைத்து மாடல்கள் |
tool_calls | பதிலில் ஒன்று அல்லது அதற்கு மேற்பட்ட tool அழைப்புகள் உள்ளன. | அனைத்து மாடல்கள் |
length | வெளியீட்டு வரம்பில் பதில் துண்டிக்கப்பட்டது. | Shannon 3 குடும்பம், shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
usage-ன் புலங்கள் endpoint-உடன் சேர்த்து விவரிக்கப்பட்டுள்ளன. Chat Completions
Keep-alive வரிகள்
மாடல் வேலை செய்துகொண்டிருந்து, இன்னும் அனுப்ப எதுவும் இல்லாதபோது, stream கருத்து வரிகளைக் கொண்டு செல்லும். அவற்றில் தரவு இல்லை. SSE parser அவற்றைத் தானாகத் தவிர்க்கும்; raw வரிகளைப் படிக்கும் குறியீடு colon-உடன் தொடங்கும் ஒவ்வொரு வரியையும் தவிர்க்க வேண்டும்.
| வரி | அனுப்புவது | எப்போது |
|---|---|---|
: 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 செய்யும்போது. |
stream-க்குள் பிழைகள்
stream தொடங்கிவிட்டால் அதன் நிலை 200 ஆகும்; எனவே தோல்வி stream-க்குள்ளேயே வரும்: choices இருக்க வேண்டிய இடத்தில் error உறுப்புடன் ஒரு chunk.
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] error chunk-க்குப் பிறகு, finish_reason மற்றும் usage கொண்ட கடைசி chunk-ம், data: [DONE]-ம் இன்னும் வரும். ஒவ்வொரு chunk-லும் 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 | உரையாடல் மாடலின் context window-ஐ விட நீளமானது. மீண்டும் அனுப்பும் முன் அதைச் சுருக்கவும். செய்தியின் உரை மாறுபடும். |
ஹோஸ்ட் செய்யப்பட்ட open-weight மாடல்கள் error உறுப்பை type மற்றும் message உடன் மட்டுமே அனுப்புகின்றன.
OpenAI Python மற்றும் JavaScript SDK-கள், நீங்கள் iterate செய்யும்போது error chunk-ஐ API பிழையாக raise செய்யும்; எனவே loop-ஐ உங்கள் வழக்கமான பிழை கையாளுதலுக்குள் வைக்கவும்.
நிலைக் குறியீடுகள், பிழை body மற்றும் எதை மீண்டும் முயற்சிக்க வேண்டும் என்பதற்குத் தனிப் பக்கம் உள்ளது. கையாளுவதில் பிழை
இணைப்பை மூடுதல்
இணைப்பை மூடுவது டெலிவரியை நிறுத்தும், கோரிக்கையை அல்ல. மாடல் பதிலை இறுதிவரை எழுதும்; நீங்கள் முழுவதையும் படித்தது போலவே கோரிக்கைக்குக் கட்டணம் விதிக்கப்படும். குறைவாகச் செலுத்த, குறைவாகக் கேளுங்கள்: அதைச் செயல்படுத்தும் மாடலில் குறைந்த max_tokens அமைக்கவும்.
stream உங்களை வந்தடையும் வழியிலும் முன்கூட்டியே முடியலாம், எடுத்துக்காட்டாக நெட்வொர்க் துண்டிப்பு அல்லது சர்வர் புதுப்பிக்கப்படும்போது. அப்போது அது கடைசி chunk இல்லாமலும் data: [DONE] இல்லாமலும் நின்றுவிடும். அந்தப் பதிலை முழுமையற்றதாகக் கருதி, கோரிக்கையை மீண்டும் அனுப்பவும்.
SDK இல்லாமல் stream-ஐப் படித்தல்
சரியான reader ஐந்து காரியங்களைச் செய்கிறது: stream-க்கு முன் வரும் பிழைகளைத் தனது பிழை கையாளுதலுக்கு அனுப்புகிறது, body-ஐ வரிகளாகப் பிரிக்கிறது, கருத்து வரிகளைத் தவிர்க்கிறது, data: [DONE]-ல் நிற்கிறது, மேலும் ஒவ்வொரு chunk-லும் 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 package-ஐப் பயன்படுத்துகிறது. JavaScript மாதிரி Node.js 18 அல்லது அதற்குப் பிந்தைய பதிப்பில் இயங்குகிறது.
பிற வடிவங்களின் streams
Responses மற்றும் Messages endpoints-உம் stream செய்கின்றன. அவற்றின் frames-ல் நிகழ்வின் பெயருடன் ஒரு event: வரியும், அதன் JSON உடன் ஒரு data: வரியும் இருக்கும். ஒவ்வொரு பக்கமும் தனது நிகழ்வுகளை வரிசையாகப் பட்டியலிடுகிறது.
| stream-ல் | Chat Completions | Responses | Messages |
|---|---|---|---|
| Frames | 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 வருவது | கடைசி chunk | response.completed | message_delta |
| stream முடிவது | கடைசி chunk, பிறகு data: [DONE] | response.completed | message_stop |