Ruka hadi kwenye maudhui
Kutiririsha

Kutiririsha

Weka stream kuwa true na jibu hufika kama server-sent events model inapoliandika: reasoning kwanza, kisha jibu, kisha chunk ya mwisho yenye sababu ya kumaliza na usage. Itumie kila wakati mtu anasubiri maandishi, na kwa majibu marefu.

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

SDK za OpenAI zinakupa chunks moja moja. Soma kila chunk kwa kile inachobeba: kipande cha reasoning, kipande cha jibu, wito wa tool, au mwisho wa jibu.

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

Jinsi stream inavyopangwa kwa frames

  • Jibu lina hali 200 na headers content-type: text/event-stream na cache-control: no-cache.
  • Kila tukio ni mstari mmoja unaoanza na data: na kufuatiwa na mstari mtupu. Maandishi baada ya data: ni chunk moja ya JSON. Hakuna mistari ya event: wala id:.
  • Mstari unaoanza na nukta mbili, kama : ping, ni maoni yanayoweka muunganisho wazi. Uruke.
  • Stream huisha na data: [DONE]. Stream inayosimama bila hiyo haijakamilika.

Chunks kwa mpangilio

Kila chunk ni kitu cha 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 zote za stream moja hubeba id, created na model zile zile. choices daima ina entry moja. delta yake ina kipya, na finish_reason ni null hadi chunk ya mwisho.

Key kwenye delta Aina Maelezo Hutumwa na
role string Daima assistant. Hufika mara moja, mwanzoni mwa stream. Model za open-weight zinazopangishwa, shannon-2-lite, shannon-2-pro
reasoning_content string Kipande cha reasoning ya model. Unganisha vipande kwa mpangilio. Model za open-weight zinazopangishwa, familia ya Shannon 3, shannon-1.6-pro, shannon-coder-1
content string Kipande cha jibu. Unganisha vipande kwa mpangilio. Model zote
tool_calls array Wito mmoja kamili wa tool. Tazama Deltas za wito wa tool. Model zote

Reasoning huja kwanza, kisha jibu, kisha wito wowote wa tools. Soma chunk kwa keys zilizo kwenye delta yake, si kwa mahali pake kwenye stream: delta inaweza kuwa na role pamoja na kipande cha kwanza cha maandishi, na ya mwisho ni tupu.

Stream nzima kama inavyosafiri. Ili kuweka mistari mifupi, id, object, created na model zimeachwa nje ya kila chunk hapa.

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

Model inayofikiri hutuma reasoning yake kwenye delta.reasoning_content kabla ya jibu. Weka maandishi hayo mawili kando: onyesha reasoning kama sehemu tofauti inayokunjika, au iache.

Model za open-weight zinazopangishwa hazitumi reasoning wakati reasoning_effort ni off, wala ombi likiwa na response_format.

shannon-2-lite na shannon-2-pro pia hufikiri kabla ya kujibu. Kwenye endpoint hii hutuma mistari ya maoni : thinking zinapofanya hivyo, kisha jibu.

reasoning_content haimo kwenye typed models za SDK za OpenAI. Kwenye Python isome kwa getattr(delta, "reasoning_content", None); kwenye JavaScript delta.reasoning_content inafanya kazi kama ilivyo.

Deltas za wito wa tool

Wito wa tool hufika mzima: chunk moja kwa kila wito, ambayo delta yake ina wito pamoja na string kamili ya arguments. index hupa wito wa jibu namba kuanzia 0. Code inayounganisha arguments kipande kwa kipande inafanya kazi bila mabadiliko, kwa sababu inaunganisha kipande kimoja.

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

Baada ya wito, chunk ya mwisho ina finish_reason tool_calls.

Ombi likiwa na tools, shannon-1.6-lite, shannon-1.6-pro na shannon-coder-1 hutuma maandishi ya jibu kama delta moja mwishoni mwa jibu.

Chunk ya mwisho

Chunk ya mwisho kabla ya data: [DONE] ina delta tupu, finish_reason na usage ya ombi, vyote kwenye chunk ile ile. Kila stream inayo; huhitaji 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
  }
}

Kwenye model za open-weight zinazopangishwa usage pia ina prompt_tokens_details.cached_tokens na completion_tokens_details.reasoning_tokens.

Baada ya ombi lenye web_search: true ambalo utafutaji wake ulipata kitu, chunk ya mwisho pia hubeba sources, na chunk moja kabla yake hubeba alama za marejeo kama delta.annotations. Utafutaji wa wavuti

finish_reason Maelezo Hutumwa na
stop Model imemaliza jibu lake, au string ya stop imeonekana. Model zote
tool_calls Jibu lina wito mmoja au zaidi wa tools. Model zote
length Jibu lilikatwa kwenye kikomo cha output. Familia ya Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1

Fields za usage zimeelezwa pamoja na endpoint. Chat Completions

Mistari ya keep-alive

Model inapofanya kazi na haina cha kutuma bado, stream hubeba mistari ya maoni. Haina data. SSE parser huiruka yenyewe; code inayosoma mistari ghafi lazima iruke kila mstari unaoanza na nukta mbili.

Mstari Hutumwa na Lini
: ping Familia ya Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 Kila sekunde 15.
: keepalive Model za open-weight zinazopangishwa Kila sekunde 15 model inapofanya kazi.
: thinking shannon-2-lite, shannon-2-pro Wakati model inafikiri.

Makosa ndani ya stream

Stream ikishaanza hali yake ni 200, kwa hiyo hitilafu hufika ndani ya stream: chunk yenye member ya error mahali ambapo choices ingekuwa.

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]

Baada ya chunk ya kosa, chunk ya mwisho, yenye finish_reason na usage, na data: [DONE] bado zinafuata. Kagua kila chunk kwa error. Bila ukaguzi huo jibu lililoshindwa katikati linaonekana kamili.

Aina Code Ujumbe Lini
api_error The model backend failed to answer. Please retry. Model ilishindwa, au haikuandika chochote. Tuma ombi tena.
rate_limit_error Shannon routes are temporarily busy. Please retry. Model ina shughuli nyingi kwa sasa. Subiri sekunde chache na utume ombi tena.
invalid_request_error context_length_exceeded Mazungumzo ni marefu kuliko dirisha la muktadha la model. Yafupishe kabla ya kutuma tena. Maandishi ya ujumbe hutofautiana.

Model za open-weight zinazopangishwa hutuma member ya error yenye type na message pekee.

SDK za OpenAI za Python na JavaScript hutoa chunk ya kosa kama API error unapopitia (iterate), kwa hiyo funga loop kwenye ushughulikiaji wako wa kawaida wa makosa.

Status codes, mwili wa kosa na cha kujaribu tena vina ukurasa wake. Ushughulikiaji wa Makosa

Kufunga muunganisho

Kufunga muunganisho husimamisha uwasilishaji, si ombi. Model huandika jibu hadi mwisho na ombi hutozwa kana kwamba ulisoma lote. Ili kulipia kidogo, omba kidogo: weka max_tokens ndogo zaidi kwenye model inayoitumia.

Stream inaweza pia kuisha mapema njiani kwako, kwa mfano kwa kukatika kwa mtandao au wakati seva inasasishwa. Kisha husimama bila chunk ya mwisho na bila data: [DONE]. Chukulia jibu hilo kama lisilokamilika na utume ombi tena.

Kusoma stream bila SDK

Msomaji sahihi hufanya mambo matano: hupeleka makosa yanayofika kabla ya stream kwenye ushughulikiaji wake wa makosa, hugawanya mwili kuwa mistari, huruka mistari ya maoni, husimama kwenye data: [DONE], na hukagua kila chunk kwa 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))

Mfano wa Python unatumia package ya requests. Mfano wa JavaScript unaendeshwa kwenye Node.js 18 au mpya zaidi.

Streams za maumbizo mengine

Endpoint za Responses na Messages pia hufanya stream. Frames zake hubeba mstari wa event: wenye jina la tukio na mstari wa data: wenye JSON yake. Kila ukurasa unaorodhesha matukio yake kwa mpangilio.

Kwenye stream Chat CompletionsResponsesMessages
Frames Mistari ya data:Mistari ya event: na data:Mistari ya event: na data:
Reasoning hufika kwenye delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
Maandishi ya jibu hufika kwenye delta.contentresponse.output_text.deltatext_delta
Usage hufika kwenye Chunk ya mwishoresponse.completedmessage_delta
Stream huisha na Chunk ya mwisho, kisha data: [DONE]response.completedmessage_stop