सामग्रीमा जानुहोस्
स्ट्रिमिङ

स्ट्रिमिङ

stream लाई true सेट गर्नुहोस् र मोडलले लेख्दै गर्दा जवाफ सर्भर-सेन्ट इभेन्टका रूपमा आउँछ: पहिले रिजनिङ, त्यसपछि उत्तर, त्यसपछि समाप्ति कारण र usage सहितको अन्तिम चङ्क। कुनै व्यक्तिले टेक्स्टको प्रतीक्षा गरिरहेको बेला र लामा जवाफहरूका लागि यसलाई प्रयोग गर्नुहोस्।

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

OpenAI SDK हरूले तपाईंलाई चङ्कहरू एक-एक गरी दिन्छन्। हरेक चङ्कलाई त्यसले के बोक्छ त्यसैअनुसार पढ्नुहोस्: रिजनिङको टुक्रा, उत्तरको टुक्रा, टुल कल, वा जवाफको अन्त्य।

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}")

स्ट्रिमको फ्रेमिङ कसरी हुन्छ

  • जवाफको स्टेटस 200 हुन्छ र हेडरहरू content-type: text/event-stream र cache-control: no-cache हुन्छन्।
  • हरेक इभेन्ट data: बाट सुरु हुने एउटा लाइन हो र त्यसपछि खाली लाइन आउँछ। data: पछिको टेक्स्ट एउटा JSON चङ्क हो। event: वा id: लाइनहरू हुँदैनन्।
  • : ping जस्तो कोलनबाट सुरु हुने लाइन कनेक्सन खुला राख्ने कमेन्ट हो। यसलाई छोड्नुहोस्।
  • स्ट्रिम data: [DONE] मा सकिन्छ। त्यसबिना रोकिने स्ट्रिम अपूर्ण हो।

क्रमैसँग चङ्कहरू

हरेक चङ्क chat.completion.chunk अब्जेक्ट हो:

JSON
{
  "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। यो स्ट्रिमको सुरुमा एक पटक आउँछ। होस्ट गरिएका ओपन-वेट मोडलहरू, shannon-2-lite, shannon-2-pro
reasoning_content string मोडलको रिजनिङको एक टुक्रा। टुक्राहरू क्रमैसँग जोड्नुहोस्। होस्ट गरिएका ओपन-वेट मोडलहरू, Shannon 3 परिवार, shannon-1.6-pro, shannon-coder-1
content string उत्तरको एक टुक्रा। टुक्राहरू क्रमैसँग जोड्नुहोस्। सबै मोडलहरू
tool_calls array एउटा पूरा टुल कल। टुल कल डेल्टाहरू हेर्नुहोस्। सबै मोडलहरू

पहिले रिजनिङ आउँछ, त्यसपछि उत्तर, त्यसपछि कुनै टुल कल। चङ्कलाई स्ट्रिममा यसको स्थानले होइन, यसको delta का कुञ्जीहरूले पढ्नुहोस्: delta मा पहिलो टेक्स्ट टुक्रासँगै role हुन सक्छ, र अन्तिम खाली हुन्छ।

पूरै स्ट्रिम जसरी यात्रा गर्छ। लाइनहरू छोटो राख्न यहाँ हरेक चङ्कबाट 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]

रिजनिङ डेल्टाहरू

रिजनिङ गर्ने मोडलले उत्तर अघि आफ्नो रिजनिङ delta.reasoning_content मा पठाउँछ। दुई टेक्स्टलाई अलग राख्नुहोस्: रिजनिङ छुट्टै, पट्ट्याउन मिल्ने भागका रूपमा देखाउनुहोस्, वा छोड्नुहोस्।

reasoning_effort off हुँदा होस्ट गरिएका ओपन-वेट मोडलहरूले रिजनिङ पठाउँदैनन्, र अनुरोधमा response_format हुँदा पनि पठाउँदैनन्।

shannon-2-lite र shannon-2-pro ले पनि जवाफ दिनु अघि रिजनिङ गर्छन्। यो इन्डपोइन्टमा तिनले रिजनिङ गर्दा : thinking कमेन्ट लाइनहरू पठाउँछन्, त्यसपछि उत्तर।

reasoning_content OpenAI SDK का टाइप गरिएका मोडलमा छैन। Python मा getattr(delta, "reasoning_content", None) ले पढ्नुहोस्; JavaScript मा delta.reasoning_content जस्ताको तस्तै काम गर्छ।

टुल कल डेल्टाहरू

टुल कल पूरै आउँछ: प्रति कल एउटा चङ्क, जसको delta मा पूरा arguments स्ट्रिङसहितको कल हुन्छ। index ले जवाफका कलहरू 0 देखि गन्छ। arguments टुक्रा-टुक्रा जोड्ने कोड बिना परिवर्तन काम गर्छ, किनकि यसले एउटै टुक्रा जोड्छ।

delta
{
  "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 ले उत्तर टेक्स्ट जवाफको अन्त्यमा एउटै डेल्टामा पठाउँछन्।

अन्तिम चङ्क

data: [DONE] अघिको अन्तिम चङ्कमा खाली delta, finish_reason र अनुरोधको usage हुन्छन्, सबै उही चङ्कमा। हरेक स्ट्रिममा यो हुन्छ; तपाईंलाई 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
  }
}

होस्ट गरिएका ओपन-वेट मोडलहरूमा 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 का फिल्डहरू इन्डपोइन्टसँगै वर्णन गरिएका छन्। Chat Completions

कीप-अलाइभ लाइनहरू

मोडलले काम गरिरहँदा र पठाउन केही नहुँदा स्ट्रिमले कमेन्ट लाइनहरू बोक्छ। तिनमा डेटा हुँदैन। SSE पार्सरले तिनलाई आफैं छोड्छ; कच्चा लाइन पढ्ने कोडले कोलनबाट सुरु हुने हरेक लाइन छोड्नुपर्छ।

लाइन पठाउने कहिले
: ping Shannon 3 परिवार, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 हरेक 15 सेकेन्डमा।
: keepalive होस्ट गरिएका ओपन-वेट मोडलहरू मोडलले काम गरिरहँदा हरेक 15 सेकेन्डमा।
: thinking shannon-2-lite, shannon-2-pro मोडलले रिजनिङ गरिरहँदा।

स्ट्रिमभित्रका त्रुटिहरू

स्ट्रिम सुरु भएपछि यसको स्टेटस 200 हुन्छ, त्यसैले असफलता स्ट्रिमभित्र आउँछ: choices हुने ठाउँमा error सदस्य भएको चङ्क।

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]

त्रुटि चङ्कपछि 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 कुराकानी मोडलको कन्टेक्स्ट विन्डोभन्दा लामो छ। फेरि पठाउनु अघि यसलाई छोट्याउनुहोस्। सन्देशको टेक्स्ट फरक पर्छ।

होस्ट गरिएका ओपन-वेट मोडलहरूले type र message मात्र भएको error सदस्य पठाउँछन्।

OpenAI Python र JavaScript SDK हरूले तपाईंले इटरेट गर्दा त्रुटि चङ्कलाई 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))

Python नमूनाले requests प्याकेज प्रयोग गर्छ। JavaScript नमूना Node.js 18 वा पछिल्लोमा चल्छ।

अन्य ढाँचाका स्ट्रिमहरू

Responses र Messages इन्डपोइन्टहरू पनि स्ट्रिम हुन्छन्। तिनका फ्रेममा इभेन्टको नाम भएको event: लाइन र त्यसको JSON भएको data: लाइन हुन्छ। हरेक पेजले आफ्ना इभेन्टहरू क्रमैसँग सूचीबद्ध गर्छ।

स्ट्रिममा Chat CompletionsResponsesMessages
फ्रेमहरू data: लाइनहरूevent: र data: लाइनहरूevent: र data: लाइनहरू
रिजनिङ यसमा आउँछ delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
उत्तर टेक्स्ट यसमा आउँछ delta.contentresponse.output_text.deltatext_delta
Usage यसमा आउँछ अन्तिम चङ्कresponse.completedmessage_delta
स्ट्रिम यसमा सकिन्छ अन्तिम चङ्क, त्यसपछि data: [DONE]response.completedmessage_stop