Tsallake zuwa abun ciki
Yawo

Yawo

Ku saita stream zuwa true kuma amsar tana zuwa a matsayin server-sent events yayin da model ke rubuta ta: reasoning da farko, sannan amsar, sannan chunk na ƙarshe mai dalilin ƙarewa da usage. Ku yi amfani da shi duk lokacin da mutum yake jiran rubutun, da kuma don amsoshi masu tsawo.

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

OpenAI SDKs suna ba ku chunks ɗaya bayan ɗaya. Ku karanta kowane chunk ta abin da yake ɗauka: guntun reasoning, guntun amsa, kiran tool, ko ƙarshen amsar.

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

Yadda aka tsara stream

  • Amsar tana da status 200 da headers content-type: text/event-stream da cache-control: no-cache.
  • Kowane event layi ɗaya ne da ya fara da data: kuma layi mara komai yana biye da shi. Rubutun da ke bayan data: chunk ɗaya ne na JSON. Babu layukan event: ko id:.
  • Layin da ya fara da colon, kamar : ping, sharhi ne da ke riƙe haɗin a buɗe. Ku tsallake shi.
  • Stream yana ƙarewa da data: [DONE]. Stream da ya tsaya ba tare da shi ba bai cika ba.

Chunks bisa tsari

Kowane chunk object ne na 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
    }
  ]
}

Dukkan chunks na stream ɗaya suna ɗauke da id, created da model iri ɗaya. choices koyaushe yana ɗauke da shigarwa ɗaya. delta ɗinsa yana ɗauke da abin da ke sabo, kuma finish_reason shi ne null har zuwa chunk na ƙarshe.

Key a cikin delta Nau'i Bayani Wanda ya aika
role string Koyaushe assistant. Yana zuwa sau ɗaya, a farkon stream. Hosted open-weight models, shannon-2-lite, shannon-2-pro
reasoning_content string Guntun reasoning na model. Ku haɗa gunduwoyin bisa tsari. Hosted open-weight models, iyalin Shannon 3, shannon-1.6-pro, shannon-coder-1
content string Guntun amsar. Ku haɗa gunduwoyin bisa tsari. Dukkan models
tool_calls array Cikakken kiran tool ɗaya. Duba Tool call deltas. Dukkan models

Reasoning yana zuwa da farko, sannan amsar, sannan duk wani kiran tool. Ku karanta chunk ta keys da ke cikin delta ɗinsa, ba ta wurinsa a cikin stream ba: delta na iya ɗaukar role tare da guntun rubutu na farko, kuma na ƙarshe babu komai a cikinsa.

Cikakken stream yadda yake tafiya. Don layukan su gajarta, an bar id, object, created da model daga kowane chunk a nan.

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 na reasoning

Model da ke yin reasoning yana aika reasoning ɗinsa a cikin delta.reasoning_content kafin amsar. Ku raba rubutun biyu: ku nuna reasoning a matsayin ɓangare na daban mai ruɓewa, ko ku bar shi.

Hosted open-weight models ba sa aika reasoning idan reasoning_effort shi ne off, kuma ba sa aikawa idan request yana da response_format.

shannon-2-lite da shannon-2-pro ma suna yin reasoning kafin su amsa. A wannan endpoint suna aika layukan sharhi na : thinking yayin da suke yi, sannan amsar.

reasoning_content ba ya cikin typed models na OpenAI SDKs. A Python ku karanta shi da getattr(delta, "reasoning_content", None); a JavaScript delta.reasoning_content yana aiki yadda yake.

Deltas na kiran tool

Kiran tool yana zuwa cikakke: chunk ɗaya a kowane kira, wanda delta ɗinsa yana ɗauke da kiran tare da cikakken string na arguments. index yana ƙirga kiran amsar daga 0. Code da ke haɗa arguments guntu-guntu yana aiki ba tare da canji ba, domin yana haɗa guntu ɗaya.

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

Bayan kiran, chunk na ƙarshe yana da finish_reason tool_calls.

Idan request yana da tools, shannon-1.6-lite, shannon-1.6-pro da shannon-coder-1 suna aika rubutun amsa a matsayin delta ɗaya a ƙarshen amsar.

Chunk na ƙarshe

Chunk na ƙarshe kafin data: [DONE] yana da delta mara komai, finish_reason da usage na request ɗin, duka a chunk ɗaya. Kowane stream yana da shi; ba kwa buƙatar 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
  }
}

A hosted open-weight models usage yana kuma da prompt_tokens_details.cached_tokens da completion_tokens_details.reasoning_tokens.

Bayan request mai web_search: true wanda binciken sa ya sami wani abu, chunk na ƙarshe yana ɗauke da sources ma, kuma chunk ɗaya kafin shi yana ɗauke da alamomin ambato a matsayin delta.annotations. Binciken Yanar Gizon da aka Gina

finish_reason Bayani Wanda ya aika
stop Model ya kammala amsarsa, ko kuma string na stop ya bayyana. Dukkan models
tool_calls Amsar tana ɗauke da kiran tool ɗaya ko fiye. Dukkan models
length An yanke amsar a iyakar output. Iyalin Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1

An bayyana fields na usage tare da endpoint. Chat Completions

Layukan keep-alive

Yayin da model ke aiki kuma bai da abin aikawa tukuna, stream yana ɗauke da layukan sharhi. Ba su da data. SSE parser yana tsallake su da kansa; code da ke karanta layuka na asali dole ne ya tsallake kowane layi da ya fara da colon.

Layi Wanda ya aika Yaushe
: ping Iyalin Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 Kowane daƙiƙa 15.
: keepalive Hosted open-weight models Kowane daƙiƙa 15 yayin da model ke aiki.
: thinking shannon-2-lite, shannon-2-pro Yayin da model ke yin reasoning.

Kurakurai a cikin stream

Da zarar stream ya fara, status ɗinsa shi ne 200, don haka gazawa tana zuwa a cikin stream: chunk mai member na error a inda choices zai kasance.

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]

Bayan chunk na kuskure, chunk na ƙarshe, mai finish_reason da usage, da data: [DONE] har yanzu suna biyowa. Ku duba kowane chunk don error. Idan ba a yi wannan dubawa ba, amsar da ta gaza a tsakiya tana kama da cikakkiya.

Nau'i Code Saƙo Yaushe
api_error The model backend failed to answer. Please retry. Model ya gaza, ko bai rubuta komai ba. Ku sake aika request ɗin.
rate_limit_error Shannon routes are temporarily busy. Please retry. Model yana da aiki a wannan lokaci. Ku jira daƙiƙa kaɗan sannan ku sake aika request ɗin.
invalid_request_error context_length_exceeded Tattaunawar ta fi context window na model tsawo. Ku rage ta kafin ku sake aikawa. Rubutun saƙon yana bambanta.

Hosted open-weight models suna aika member na error da type da message kawai.

OpenAI Python da JavaScript SDKs suna jefa chunk na kuskure a matsayin kuskuren API yayin da kuke iterating, don haka ku saka loop ɗin a cikin gudanar da kurakurai na yau da kullun.

Status codes, body na kuskure da abin da za a sake gwadawa suna da shafinsu na kansu. Kuskuren Gudanarwa

Rufe haɗin

Rufe haɗin yana dakatar da isarwa, ba request ɗin ba. Model yana rubuta amsar har ƙarshe kuma ana cajin request kamar kun karanta ta duka. Don biyan ƙasa, ku nemi ƙasa: ku saita max_tokens mafi ƙanƙanta a kan model da ke aiwatar da shi.

Stream kuma na iya ƙarewa da wuri a hanyarsa zuwa gare ku, misali idan hanyar sadarwa ta ɗauke ko yayin da ake sabunta server. Sai ya tsaya ba tare da chunk na ƙarshe ba kuma ba tare da data: [DONE] ba. Ku ɗauki wannan amsa a matsayin wadda ba ta cika ba kuma ku sake aika request ɗin.

Karanta stream ba tare da SDK ba

Mai karatu daidai yana yin abubuwa biyar: yana tura kurakuran da ke zuwa kafin stream zuwa gudanar da kurakuransa, yana raba body zuwa layuka, yana tsallake layukan sharhi, yana tsayawa a data: [DONE], kuma yana duba kowane chunk don 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))

Samfurin Python yana amfani da fakitin requests. Samfurin JavaScript yana gudana a Node.js 18 ko sama.

Streams na sauran tsare-tsare

Endpoints na Responses da Messages ma suna yin streaming. Frames ɗinsu suna ɗauke da layin event: mai sunan event da layin data: mai JSON ɗinsa. Kowane shafi yana lissafa events ɗinsa bisa tsari.

A cikin stream Chat CompletionsResponsesMessages
Frames Layukan data:Layukan event: da data:Layukan event: da data:
Reasoning yana zuwa a cikin delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
Rubutun amsa yana zuwa a cikin delta.contentresponse.output_text.deltatext_delta
Usage yana zuwa a cikin Chunk na ƙarsheresponse.completedmessage_delta
Stream yana ƙarewa da Chunk na ƙarshe, sannan data: [DONE]response.completedmessage_stop