કન્ટેન્ટ પર જાઓ
સ્ટ્રીમિંગ

સ્ટ્રીમિંગ

stream ને true કરો અને મોડેલ લખતું જાય તેમ જવાબ server-sent events તરીકે આવે છે: પહેલાં રીઝનિંગ, પછી જવાબ, પછી finish reason અને usage સાથેનો છેલ્લો chunk. જ્યારે કોઈ વ્યક્તિ ટેક્સ્ટની રાહ જોતી હોય ત્યારે અને લાંબા જવાબો માટે તેનો ઉપયોગ કરો.

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

OpenAI SDKs તમને chunks એક પછી એક આપે છે. દરેક chunk ને તે જે લઈને આવ્યો છે તેના આધારે વાંચો: રીઝનિંગનો ટુકડો, જવાબનો ટુકડો, ટૂલ કોલ, અથવા જવાબનો અંત.

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 chunk છે. event: કે id: લાઇન્સ નથી.
  • કોલનથી શરૂ થતી લાઇન, જેમ કે : ping, કનેક્શન ખુલ્લું રાખતી કોમેન્ટ છે. તેને છોડી દો.
  • સ્ટ્રીમ data: [DONE] સાથે પૂરો થાય છે. તેના વિના અટકી જતો સ્ટ્રીમ અધૂરો છે.

Chunks ક્રમમાં

દરેક chunk એક 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
    }
  ]
}

એક સ્ટ્રીમના બધા chunks માં એ જ id, created અને model હોય છે. choices માં હંમેશાં એક એન્ટ્રી હોય છે. તેનું delta જે નવું છે તે ધરાવે છે, અને છેલ્લા chunk સુધી finish_reason null રહે છે.

delta માં કી પ્રકાર વર્ણન કોણ મોકલે છે
role string હંમેશાં assistant. તે સ્ટ્રીમની શરૂઆતમાં એક જ વાર આવે છે. હોસ્ટેડ open-weight મોડેલ્સ, shannon-2-lite, shannon-2-pro
reasoning_content string મોડેલના રીઝનિંગનો એક ટુકડો. ટુકડાઓને ક્રમમાં જોડો. હોસ્ટેડ open-weight મોડેલ્સ, Shannon 3 પરિવાર, shannon-1.6-pro, shannon-coder-1
content string જવાબનો એક ટુકડો. ટુકડાઓને ક્રમમાં જોડો. બધા મોડેલ્સ
tool_calls array એક પૂરો ટૂલ કોલ. Tool call deltas જુઓ. બધા મોડેલ્સ

પહેલાં રીઝનિંગ, પછી જવાબ, પછી ટૂલ કોલ્સ (જો હોય). chunk ને સ્ટ્રીમમાંની તેની જગ્યાથી નહીં, પણ તેના delta ની કીઝથી વાંચો: delta માં ટેક્સ્ટના પહેલા ટુકડા સાથે role હોઈ શકે છે, અને છેલ્લો ખાલી હોય છે.

આખો સ્ટ્રીમ જેમ મુસાફરી કરે છે તેમ. લાઇનો ટૂંકી રાખવા અહીં દરેક 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]

રીઝનિંગ deltas

રીઝનિંગ કરતું મોડેલ જવાબ પહેલાં તેનું રીઝનિંગ delta.reasoning_content માં મોકલે છે. બંને ટેક્સ્ટ અલગ રાખો: રીઝનિંગને અલગ, ફોલ્ડ થઈ શકે તેવા ભાગ તરીકે બતાવો, અથવા છોડી દો.

reasoning_effort off હોય ત્યારે હોસ્ટેડ open-weight મોડેલ્સ રીઝનિંગ મોકલતા નથી, અને રિક્વેસ્ટમાં response_format હોય ત્યારે પણ નહીં.

shannon-2-lite અને shannon-2-pro પણ જવાબ આપતા પહેલાં રીઝનિંગ કરે છે. આ એન્ડપોઇન્ટ પર તેઓ રીઝનિંગ દરમિયાન : thinking કોમેન્ટ લાઇન્સ મોકલે છે, અને પછી જવાબ.

reasoning_content OpenAI SDKs ના typed મોડેલ્સમાં નથી. Python માં તેને getattr(delta, "reasoning_content", None) થી વાંચો; JavaScript માં delta.reasoning_content જેમ છે તેમ ચાલે છે.

Tool call deltas

ટૂલ કોલ આખો આવે છે: દરેક કોલ માટે એક chunk, જેના delta માં પૂરા arguments સ્ટ્રિંગ સાથેનો કોલ હોય છે. index જવાબના કોલ્સને 0 થી ક્રમાંક આપે છે. arguments ને ટુકડે ટુકડે જોડતો કોડ બદલાવ વિના ચાલે છે, કારણ કે તે એક જ ટુકડો જોડે છે.

delta
{
  "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_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
  }
}

હોસ્ટેડ open-weight મોડેલ્સ પર usage માં prompt_tokens_details.cached_tokens અને completion_tokens_details.reasoning_tokens પણ હોય છે.

web_search: true વાળી જે રિક્વેસ્ટની શોધમાં કંઈક મળ્યું હોય, તેના પછી છેલ્લા chunk માં sources પણ હોય છે, અને તેની પહેલાંનો એક chunk ઉલ્લેખ-ચિહ્નોને delta.annotations તરીકે વહન કરે છે. Built‑in Web Search

finish_reason વર્ણન કોણ મોકલે છે
stop મોડેલે તેનો જવાબ પૂરો કર્યો, અથવા stop સ્ટ્રિંગ દેખાઈ. બધા મોડેલ્સ
tool_calls જવાબમાં એક કે વધુ ટૂલ કોલ્સ છે. બધા મોડેલ્સ
length જવાબ આઉટપુટ મર્યાદાએ કપાઈ ગયો. Shannon 3 પરિવાર, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1

usage ના ફીલ્ડ્સનું વર્ણન એન્ડપોઇન્ટ સાથે આપેલું છે. Chat Completions

Keep-alive લાઇન્સ

મોડેલ કામ કરતું હોય અને હજી મોકલવા જેવું કંઈ ન હોય ત્યારે, સ્ટ્રીમ કોમેન્ટ લાઇન્સ મોકલે છે. તેમાં કોઈ ડેટા હોતો નથી. SSE પાર્સર તેમને આપમેળે છોડી દે છે; કાચી લાઇન્સ વાંચતા કોડે કોલનથી શરૂ થતી દરેક લાઇન છોડવી જ જોઈએ.

લાઇન કોણ મોકલે છે ક્યારે
: 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 મોડેલ રીઝનિંગ કરતું હોય ત્યારે.

સ્ટ્રીમની અંદરની એરર્સ

સ્ટ્રીમ શરૂ થયા પછી તેનું સ્ટેટસ 200 હોય છે, તેથી નિષ્ફળતા સ્ટ્રીમની અંદર આવે છે: જ્યાં choices હોત ત્યાં error સભ્ય સાથેનો 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]

એરર 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 વાતચીત મોડેલની કોન્ટેક્સ્ટ વિન્ડો કરતાં લાંબી છે. ફરીથી મોકલતા પહેલાં તેને ટૂંકી કરો. મેસેજનો ટેક્સ્ટ બદલાય છે.

હોસ્ટેડ open-weight મોડેલ્સ error સભ્યમાં ફક્ત type અને message મોકલે છે.

OpenAI Python અને JavaScript SDKs તમે ઇટરેટ કરો ત્યારે એરર chunk ને API એરર તરીકે raise કરે છે, તેથી લૂપને તમારા સામાન્ય એરર હેન્ડલિંગમાં મૂકો.

સ્ટેટસ કોડ્સ, એરર બોડી અને શું ફરી પ્રયાસ કરવો તેનું પોતાનું પેજ છે. ભૂલ સંભાળ

કનેક્શન બંધ કરવું

કનેક્શન બંધ કરવાથી ડિલિવરી અટકે છે, રિક્વેસ્ટ નહીં. મોડેલ જવાબ છેક સુધી લખે છે અને રિક્વેસ્ટનો ચાર્જ એવો લાગે છે જાણે તમે બધું વાંચ્યું હોય. ઓછું ચૂકવવા ઓછું માગો: જે મોડેલ તેને લાગુ કરે છે તેના પર નીચું max_tokens સેટ કરો.

સ્ટ્રીમ તમારા સુધી પહોંચતા પહેલાં રસ્તામાં પણ વહેલો પૂરો થઈ શકે છે, ઉદાહરણ તરીકે નેટવર્ક તૂટે ત્યારે કે સર્વર અપડેટ થતું હોય ત્યારે. ત્યારે તે છેલ્લા chunk વિના અને data: [DONE] વિના અટકી જાય છે. એવા જવાબને અધૂરો ગણો અને રિક્વેસ્ટ ફરીથી મોકલો.

SDK વિના સ્ટ્રીમ વાંચવો

સાચો રીડર પાંચ કામ કરે છે: સ્ટ્રીમ પહેલાં આવતી એરર્સને તેના એરર હેન્ડલિંગમાં મોકલે છે, બોડીને લાઇન્સમાં વહેંચે છે, કોમેન્ટ લાઇન્સ છોડે છે, 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 પેકેજ વાપરે છે. 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 આમાં આવે છે છેલ્લો chunkresponse.completedmessage_delta
સ્ટ્રીમ આનાથી પૂરો થાય છે છેલ્લો chunk, પછી data: [DONE]response.completedmessage_stop