အကြောင်းအရာသို့ ကျော်သွားရန်
စตรีမင်း

စตรีမင်း

stream ကို true ဟု သတ်မှတ်လျှင် model ရေးနေစဉ် ပြန်ကြားချက်သည် server-sent events အဖြစ် ရောက်လာသည်- reasoning ကို ပထမ၊ ထို့နောက် အဖြေ၊ ထို့နောက် finish reason နှင့် usage ပါသော နောက်ဆုံး chunk။ လူတစ်ဦးက စာသားကို စောင့်နေသည့်အခါနှင့် ရှည်လျားသော ပြန်ကြားချက်များအတွက် အသုံးပြုပါ။

POST https://api.shannon-ai.com/v1/chat/completions

OpenAI SDK များသည် chunk များကို တစ်ခုချင်း ပေးသည်။ chunk တစ်ခုစီကို ၎င်းသယ်ဆောင်သည့်အရာဖြင့် ဖတ်ပါ- reasoning အပိုင်းတစ်ခု၊ အဖြေအပိုင်းတစ်ခု၊ 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}")

stream ကို မည်သို့ frame ခွဲသည်

  • ပြန်ကြားချက်တွင် status 200 နှင့် header content-type: text/event-stream နှင့် cache-control: no-cache တို့ ပါသည်။
  • event တစ်ခုစီသည် data: ဖြင့်စပြီး စာကြောင်းလွတ်တစ်ကြောင်း နောက်လိုက်သော စာကြောင်းတစ်ကြောင်း ဖြစ်သည်။ data: နောက်ရှိ စာသားသည် JSON chunk တစ်ခုဖြစ်သည်။ event: သို့မဟုတ် id: စာကြောင်း မရှိပါ။
  • : ping ကဲ့သို့ colon ဖြင့်စသော စာကြောင်းသည် ချိတ်ဆက်မှုကို ဖွင့်ထားစေသော comment ဖြစ်သည်။ ကျော်သွားပါ။
  • stream သည် data: [DONE] ဖြင့် အဆုံးသတ်သည်။ ၎င်းမပါဘဲ ရပ်သွားသော stream သည် မပြည့်စုံပါ။

အစီအစဉ်အတိုင်း Chunks

chunk တိုင်းသည် chat.completion.chunk object တစ်ခု ဖြစ်သည်-

JSON
{
  "id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
  "object": "chat.completion.chunk",
  "created": 1791625200,
  "model": "shannon-3",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "Server-sent"
      },
      "finish_reason": null
    }
  ]
}

stream တစ်ခု၏ chunk အားလုံးတွင် တူညီသော id၊ created နှင့် model ပါသည်။ choices တွင် entry တစ်ခုသာ အမြဲရှိသည်။ ၎င်း၏ delta တွင် အသစ်ဖြစ်သည့်အရာ ပါပြီး နောက်ဆုံး chunk အထိ finish_reason သည် null ဖြစ်သည်။

delta ထဲရှိ Key Type ဖော်ပြချက် ပို့သူ
role string အမြဲတမ်း assistant။ stream အစတွင် တစ်ကြိမ်သာ ရောက်လာသည်။ Host လုပ်ထားသော open-weight မော်ဒယ်များ၊ shannon-2-lite၊ shannon-2-pro
reasoning_content string model ၏ reasoning အပိုင်းတစ်ခု။ အပိုင်းများကို အစီအစဉ်အတိုင်း ပေါင်းပါ။ Host လုပ်ထားသော open-weight မော်ဒယ်များ၊ Shannon 3 မိသားစု၊ shannon-1.6-pro၊ shannon-coder-1
content string အဖြေ၏ အပိုင်းတစ်ခု။ အပိုင်းများကို အစီအစဉ်အတိုင်း ပေါင်းပါ။ Model အားလုံး
tool_calls array ပြည့်စုံသော tool call တစ်ခု။ Tool call deltas ကို ကြည့်ပါ။ Model အားလုံး

reasoning ကို ပထမ၊ ထို့နောက် အဖြေ၊ ထို့နောက် tool calls များ လာသည်။ chunk ကို stream အတွင်း ၎င်း၏နေရာဖြင့် မဟုတ်ဘဲ ၎င်း၏ delta ထဲရှိ key များဖြင့် ဖတ်ပါ- delta တစ်ခုတွင် ပထမစာသားအပိုင်းနှင့်အတူ role ပါနိုင်ပြီး နောက်ဆုံးတစ်ခုသည် အလွတ်ဖြစ်သည်။

ကြိုးပေါ်တွင် သွားသည့်အတိုင်း stream တစ်ခုလုံး။ စာကြောင်းများ တိုစေရန် ဤနေရာတွင် chunk တစ်ခုစီမှ id၊ object၊ created နှင့် model ကို ချန်လှပ်ထားသည်။

200 text/event-stream
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 လုပ်သော model သည် ၎င်း၏ reasoning ကို အဖြေမတိုင်မီ delta.reasoning_content တွင် ပို့သည်။ စာသားနှစ်ခုကို ခွဲထားပါ- reasoning ကို သီးခြား ခေါက်သိမ်းနိုင်သော အပိုင်းအဖြစ် ပြပါ၊ သို့မဟုတ် ချန်ထားပါ။

Host လုပ်ထားသော open-weight models များသည် reasoning_effort သည် off ဖြစ်လျှင် reasoning မပို့ပါ၊ request တွင် response_format ပါလျှင်လည်း မပို့ပါ။

shannon-2-lite နှင့် shannon-2-pro တို့သည်လည်း မဖြေမီ reasoning လုပ်သည်။ ဤ endpoint တွင် ၎င်းတို့ reasoning လုပ်နေစဉ် : thinking comment စာကြောင်းများကို ပို့ပြီး ထို့နောက် အဖြေကို ပို့သည်။

reasoning_content သည် OpenAI SDK များ၏ typed model များတွင် မပါပါ။ 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 သည် အပိုင်းတစ်ခုတည်းကို ပေါင်းသဖြင့် မပြောင်းလဲဘဲ အလုပ်လုပ်သည်။

delta
{
  "tool_calls": [
    {
      "index": 0,
      "id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{\"city\":\"Paris\"}"
      }
    }
  ]
}

calls ပြီးနောက် နောက်ဆုံး chunk တွင် finish_reason tool_calls ပါသည်။

request တွင် tools ပါလျှင် shannon-1.6-lite၊ shannon-1.6-pro နှင့် shannon-coder-1 တို့သည် အဖြေစာသားကို ပြန်ကြားချက်အဆုံးတွင် delta တစ်ခုအဖြစ် ပို့သည်။

နောက်ဆုံး chunk

data: [DONE] မတိုင်မီ နောက်ဆုံး chunk တွင် အလွတ် delta၊ finish_reason နှင့် request ၏ usage တို့ကို chunk တစ်ခုတည်းတွင် ပါသည်။ stream တိုင်းတွင် ၎င်းရှိသည်၊ stream_options မလိုအပ်ပါ။

JSON
{
  "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
  }
}

Host လုပ်ထားသော open-weight models များတွင် usage တွင် prompt_tokens_details.cached_tokens နှင့် completion_tokens_details.reasoning_tokens လည်း ပါသည်။

ရှာဖွေမှုတွင် တစ်စုံတစ်ရာ တွေ့ခဲ့သော web_search: true request ပြီးနောက် နောက်ဆုံး chunk တွင် sources လည်း ပါပြီး ၎င်းမတိုင်မီ chunk တစ်ခုက ကိုးကားမှု အမှတ်အသားများကို delta.annotations အဖြစ် သယ်ဆောင်သည်။ ဝဘ်ရှာဖွေမှု

finish_reason ဖော်ပြချက် ပို့သူ
stop model သည် ၎င်း၏ အဖြေကို ပြီးအောင်ရေးခဲ့သည်၊ သို့မဟုတ် stop string တစ်ခု ပေါ်လာခဲ့သည်။ Model အားလုံး
tool_calls ပြန်ကြားချက်တွင် tool call တစ်ခု သို့မဟုတ် တစ်ခုထက်ပို၍ ပါသည်။ Model အားလုံး
length ပြန်ကြားချက်ကို output limit တွင် ဖြတ်တောက်ခဲ့သည်။ Shannon 3 မိသားစု၊ shannon-1.6-lite၊ shannon-1.6-pro၊ shannon-coder-1

usage ၏ field များကို endpoint နှင့်အတူ ဖော်ပြထားသည်။ Chat Completions

Keep-alive စာကြောင်းများ

model အလုပ်လုပ်နေပြီး ပို့စရာ မရှိသေးစဉ် stream တွင် comment စာကြောင်းများ ပါသည်။ ၎င်းတို့တွင် data မပါပါ။ SSE parser က ၎င်းတို့ကို ကိုယ်တိုင်ကျော်သွားသည်၊ raw စာကြောင်းများကို ဖတ်သော code သည် colon ဖြင့်စသော စာကြောင်းတိုင်းကို ကျော်ရမည်။

စာကြောင်း ပို့သူ ဖြစ်ပေါ်ချိန်
: ping Shannon 3 မိသားစု၊ shannon-1.6-lite၊ shannon-1.6-pro၊ shannon-coder-1 15 စက္ကန့်တိုင်း။
: keepalive Host လုပ်ထားသော open-weight မော်ဒယ်များ model အလုပ်လုပ်နေစဉ် 15 စက္ကန့်တိုင်း။
: thinking shannon-2-lite, shannon-2-pro model သည် reasoning လုပ်နေစဉ်အတွင်း။

Stream အတွင်းရှိ အမှားများ

stream စတင်ပြီးသည်နှင့် ၎င်း၏ status သည် 200 ဖြစ်သဖြင့် ကျရှုံးမှုသည် stream အတွင်း ရောက်လာသည်- choices ရှိရာနေရာတွင် error member ပါသော chunk တစ်ခု။

200 text/event-stream
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 ရှိမရှိ စစ်ဆေးပါ။ ထိုစစ်ဆေးမှုမရှိလျှင် တစ်ဝက်တွင် ကျရှုံးသော ပြန်ကြားချက်သည် ပြည့်စုံသကဲ့သို့ ထင်ရမည်။

Type Code မက်ဆေ့ချ် ဖြစ်ပေါ်ချိန်
api_error The model backend failed to answer. Please retry. model ကျရှုံးခဲ့သည်၊ သို့မဟုတ် ဘာမျှ မရေးခဲ့ပါ။ request ကို ပြန်ပို့ပါ။
rate_limit_error Shannon routes are temporarily busy. Please retry. ယခုအချိန်တွင် model အလုပ်များနေသည်။ စက္ကန့်အနည်းငယ်စောင့်ပြီး request ကို ပြန်ပို့ပါ။
invalid_request_error context_length_exceeded စကားပြောဆိုမှုသည် model ၏ context window ထက် ပိုရှည်သည်။ ပြန်မပို့မီ တိုစေပါ။ မက်ဆေ့ချ်စာသား ကွဲပြားနိုင်သည်။

Host လုပ်ထားသော open-weight models များသည် type နှင့် message သာပါသော error member ကို ပို့သည်။

OpenAI Python နှင့် JavaScript SDK များသည် သင်ထပ်ခါထပ်ခါ ဖတ်နေစဉ် error chunk ကို API error အဖြစ် ပစ်ထုတ်သဖြင့် loop ကို သင့်ပုံမှန် error handling ဖြင့် ထုပ်ပိုးပါ။

Status code များ၊ error body နှင့် ပြန်ကြိုးစားရမည့်အရာများတွင် ကိုယ်ပိုင်စာမျက်နှာရှိသည်။ အမှားကိုင်တွယ်မှု

ချိတ်ဆက်မှုကို ပိတ်ခြင်း

ချိတ်ဆက်မှုကို ပိတ်ခြင်းသည် ပေးပို့မှုကို ရပ်စေသော်လည်း request ကို မရပ်စေပါ။ model သည် ပြန်ကြားချက်ကို အဆုံးထိ ရေးပြီး request ကို သင် အားလုံးဖတ်ခဲ့သကဲ့သို့ ကျသင့်ငွေတောင်းသည်။ ပိုနည်းနည်း ပေးချေလိုပါက ပိုနည်းနည်း တောင်းပါ- ၎င်းကို အသုံးပြုသော model တွင် max_tokens ကို နိမ့်နိမ့် သတ်မှတ်ပါ။

stream သည် သင့်ဆီသို့ လာစဉ် ကွန်ရက်ပြတ်တောက်ခြင်း သို့မဟုတ် server ကို update လုပ်နေစဉ်ကဲ့သို့ အကြောင်းများကြောင့် စောစီးစွာ ပြီးဆုံးနိုင်သည်။ ထိုအခါ နောက်ဆုံး chunk နှင့် data: [DONE] မပါဘဲ ရပ်သွားသည်။ ထိုပြန်ကြားချက်ကို မပြည့်စုံဟု သဘောထားပြီး request ကို ပြန်ပို့ပါ။

SDK မပါဘဲ stream ကို ဖတ်ခြင်း

မှန်ကန်သော reader သည် အရာငါးခု လုပ်ဆောင်သည်- stream မတိုင်မီ ရောက်လာသော အမှားများကို ၎င်း၏ error handling သို့ ပို့သည်၊ 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))

Python နမူနာသည် requests package ကို သုံးသည်။ JavaScript နမူနာသည် Node.js 18 သို့မဟုတ် ထို့ထက်နောက်ပိုင်းတွင် run သည်။

အခြား format များအတွက် stream များ

Responses နှင့် Messages endpoint များသည်လည်း stream လုပ်သည်။ ၎င်းတို့၏ frame များတွင် event အမည်ပါသော event: စာကြောင်းနှင့် ၎င်း၏ JSON ပါသော data: စာကြောင်း ပါသည်။ စာမျက်နှာတစ်ခုစီတွင် ၎င်း၏ events များကို အစီအစဉ်အတိုင်း စာရင်းပြထားသည်။

Stream ထဲတွင် Chat CompletionsResponsesMessages
Frames data: စာကြောင်းများevent: နှင့် data: စာကြောင်းများevent: နှင့် data: စာကြောင်းများ
Reasoning ရောက်လာရာ delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
အဖြေစာသား ရောက်လာရာ delta.contentresponse.output_text.deltatext_delta
Usage ရောက်လာရာ နောက်ဆုံး chunkresponse.completedmessage_delta
stream ၏ အဆုံးသတ် နောက်ဆုံး chunk၊ ထို့နောက် data: [DONE]response.completedmessage_stop