ස්ට්රීමිං
stream true ලෙස සකසන්න, එවිට model එක ලියන අතරතුර පිළිතුර server-sent events ලෙස පැමිණේ: මුලින් තර්කනය, ඉන්පසු පිළිතුර, ඉන්පසු finish reason එක සහ usage සහිත අවසාන chunk එකක්. පෙළ සඳහා පුද්ගලයෙකු බලා සිටින සෑම විටම, සහ දිගු පිළිතුරු සඳහා එය භාවිතා කරන්න.
POST https://api.shannon-ai.com/v1/chat/completions
OpenAI SDKs ඔබට chunks එකින් එක දෙයි. සෑම chunk එකක්ම එය රැගෙන යන දෙයින් කියවන්න: තර්කනයේ කොටසක්, පිළිතුරේ කොටසක්, tool call එකක්, හෝ පිළිතුරේ අවසානය.
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 එකක් රාමු කරන ආකාරය
- පිළිතුරේ status
200සහcontent-type: text/event-streamහාcache-control: no-cacheheaders ඇත. - සෑම event එකක්ම
data:වලින් ආරම්භ වන එක පේළියක් වන අතර ඉන්පසු හිස් පේළියක් ඇත.data:ට පසුව ඇති පෙළ එක JSON chunk එකකි.event:හෝid:පේළි නැත. : pingවැනි කොලන් එකකින් ආරම්භ වන පේළියක් සම්බන්ධතාව විවෘතව තබන comment එකකි. එය මඟ හරින්න.- 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 හි සෑම විටම එක entry එකක් ඇත. එහි delta අලුත් දේ රඳවන අතර, finish_reason අවසාන chunk එක දක්වා null වේ.
| delta හි Key | වර්ගය | විස්තරය | යවන්නේ |
|---|---|---|---|
role | string | සෑම විටම assistant. එය stream එකේ ආරම්භයේදී එක වරක් පැමිණේ. | අපගේ සේවාදායකවල ධාවනය වන open-weight models, shannon-2-lite, shannon-2-pro |
reasoning_content | string | Model එකේ තර්කනයේ කොටසක්. කොටස් පිළිවෙලින් එකට සම්බන්ධ කරන්න. | අපගේ සේවාදායකවල ධාවනය වන open-weight models, Shannon 3 පවුල, shannon-1.6-pro, shannon-coder-1 |
content | string | පිළිතුරේ කොටසක්. කොටස් පිළිවෙලින් එකට සම්බන්ධ කරන්න. | සියලු models |
tool_calls | array | එක සම්පූර්ණ tool call එකක්. Tool call deltas බලන්න. | සියලු models |
මුලින් තර්කනය, ඉන්පසු පිළිතුර, ඉන්පසු tool calls ඇත්නම් ඒවා. 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] තර්කන deltas
තර්ක කරන model එකක් පිළිතුරට පෙර එහි තර්කනය delta.reasoning_content හි යවයි. පෙළ දෙක වෙන් කර තබන්න: තර්කනය වෙනම, නැවිය හැකි කොටසක් ලෙස පෙන්වන්න, නැතහොත් එය ඉවත් කරන්න.
අපගේ සේවාදායකවල ධාවනය වන open-weight models reasoning_effort off වන විට තර්කනයක් නොයවන අතර, ඉල්ලීමේ response_format ඇති විටත් නොයවයි.
shannon-2-lite සහ shannon-2-pro ද පිළිතුරු දීමට පෙර තර්ක කරයි. මෙම endpoint හි ඒවා තර්ක කරන අතරතුර : thinking comment පේළි යවන අතර, ඉන්පසු පිළිතුර යවයි.
reasoning_content OpenAI SDKs වල typed models වල නැත. Python හි එය getattr(delta, "reasoning_content", None) සමඟ කියවන්න; JavaScript හි delta.reasoning_content එලෙසම ක්රියා කරයි.
Tool call deltas
Tool call එකක් සම්පූර්ණයෙන් පැමිණේ: call එකකට එක chunk එකක්, එහි delta හි සම්පූර්ණ arguments string එක සහිත call එක ඇත. index පිළිතුරේ calls 0 සිට අංක කරයි. arguments කෑලි කෑලිවලින් සම්බන්ධ කරන code එක වෙනසක් නොමැතිව ක්රියා කරයි, මන්ද එය සම්බන්ධ කරන්නේ එක කෑල්ලකි.
{
"tool_calls": [
{
"index": 0,
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
} Calls වලින් පසුව, අවසාන 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 models මත usage හි prompt_tokens_details.cached_tokens සහ completion_tokens_details.reasoning_tokens ද ඇත.
web_search: true සහිත, සෙවීමෙන් යමක් සොයාගත් ඉල්ලීමකින් පසු, අවසාන chunk එකේ sources ද ඇත, එයට පෙර chunk එකක් උපුටා දැක්වීමේ සලකුණු delta.annotations ලෙස රැගෙන එයි. වෙබ් සෙවීම
| finish_reason | විස්තරය | යවන්නේ |
|---|---|---|
stop | Model එක තම පිළිතුර අවසන් කළා, නැතහොත් stop string එකක් මතු විය. | සියලු models |
tool_calls | පිළිතුරේ tool calls එකක් හෝ කිහිපයක් ඇත. | සියලු models |
length | පිළිතුර output සීමාවේදී කපා හරින ලදී. | Shannon 3 පවුල, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
usage හි fields endpoint එක සමඟ විස්තර කර ඇත. Chat Completions
Keep-alive පේළි
Model එක වැඩ කරමින් තවමත් යැවීමට කිසිවක් නැති අතරතුර, stream එක comment පේළි රැගෙන යයි. ඒවායේ දත්ත නැත. SSE parser එකක් ඒවා තනිවම මඟ හරියි; අමු පේළි කියවන code එක කොලන් එකකින් ආරම්භ වන සෑම පේළියක්ම මඟ හැරිය යුතුය.
| පේළිය | යවන්නේ | කවදාද |
|---|---|---|
: ping | Shannon 3 පවුල, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | තත්පර 15කට වරක්. |
: keepalive | අපගේ සේවාදායකවල ධාවනය වන open-weight models | Model එක වැඩ කරන අතරතුර තත්පර 15කට වරක්. |
: thinking | shannon-2-lite, shannon-2-pro | Model එක තර්ක කරන අතරතුර. |
Stream එකක් තුළ දෝෂ
Stream එකක් ආරම්භ වූ පසු එහි status එක 200 වේ, එබැවින් අසාර්ථකත්වයක් stream එක තුළ පැමිණේ: choices තිබිය යුතු තැන error member එකක් සහිත 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] දෝෂ chunk එකට පසුව, finish_reason සහ usage සහිත අවසාන chunk එක සහ data: [DONE] තවමත් පැමිණේ. සෑම chunk එකක්ම error සඳහා පරීක්ෂා කරන්න. ඒ පරීක්ෂාව නොමැතිව අතරමගදී අසාර්ථක වූ පිළිතුරක් සම්පූර්ණ ලෙස පෙනේ.
| Type | Code | පණිවිඩය | කවදාද |
|---|---|---|---|
api_error | The model backend failed to answer. Please retry. | Model එක අසාර්ථක විය, නැතහොත් කිසිවක් ලිව්වේ නැත. ඉල්ලීම නැවත යවන්න. | |
rate_limit_error | Shannon routes are temporarily busy. Please retry. | මෙම මොහොතේ model එක කාර්යබහුලයි. තත්පර කිහිපයක් රැඳී සිට ඉල්ලීම නැවත යවන්න. | |
invalid_request_error | context_length_exceeded | සංවාදය model එකේ context window එකට වඩා දිගය. නැවත යැවීමට පෙර එය කෙටි කරන්න. පණිවිඩයේ පෙළ වෙනස් වේ. |
අපගේ සේවාදායකවල ධාවනය වන open-weight models error member එක යවන්නේ type සහ message පමණි.
OpenAI Python සහ JavaScript SDKs ඔබ iterate කරන අතරතුර දෝෂ chunk එකක් API දෝෂයක් ලෙස raise කරයි, එබැවින් loop එක ඔබේ සුපුරුදු දෝෂ හැසිරවීමෙන් ඔතන්න.
Status codes, දෝෂ body එක සහ නැවත උත්සාහ කළ යුතු දේ සඳහා තමන්ගේම පිටුවක් ඇත. දෝෂ
සම්බන්ධතාව වැසීම
සම්බන්ධතාව වැසීමෙන් නවතින්නේ බෙදාහැරීම මිස ඉල්ලීම නොවේ. Model එක පිළිතුර අවසානය දක්වා ලියන අතර, ඔබ සියල්ල කියවා ඇති ආකාරයටම ඉල්ලීම අය කෙරේ. අඩුවෙන් ගෙවීමට, අඩුවෙන් ඉල්ලන්න: එය ක්රියාත්මක කරන model එකක අඩු max_tokens සකසන්න.
ඔබ වෙත එන ගමනේදී stream එකක් කලින් අවසන් විය හැක, උදාහරණයක් ලෙස network බිඳවැටීමකදී හෝ server එකක් යාවත්කාලීන වන අතරතුර. එවිට එය අවසාන chunk එක සහ data: [DONE] නොමැතිව නවතී. එම පිළිතුර අසම්පූර්ණ ලෙස සලකා ඉල්ලීම නැවත යවන්න.
SDK එකක් නොමැතිව stream එකක් කියවීම
නිවැරදි reader එකක් දේවල් පහක් කරයි: stream එකට පෙර පැමිණෙන දෝෂ එහි දෝෂ හැසිරවීමට යවයි, body එක පේළි වලට බෙදයි, comment පේළි මඟ හරියි, 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) ගැන
Responses සහ Messages endpoints ද stream කරයි. ඒවායේ frames හි event එකේ නම සහිත event: පේළියක් සහ එහි JSON සහිත data: පේළියක් ඇත. සෑම පිටුවක්ම එහි events පිළිවෙලින් ලැයිස්තුගත කරයි.
| Stream එකේ | Chat Completions | Responses | Messages |
|---|---|---|---|
| Frames | data: පේළි | event: සහ data: පේළි | event: සහ data: පේළි |
| තර්කනය පැමිණෙන්නේ | 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 |