Мазмұнға өту
Стриминг

Стриминг

Stream мәнін true етіп орнатыңыз, сонда жауап модель жазып жатқанда server-sent events ретінде келеді: алдымен пайымдау, содан кейін жауап, одан кейін аяқталу себебі мен 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. Ол стримнің басында бір рет келеді. Hosted open-weight модельдер, shannon-2-lite, shannon-2-pro
reasoning_content string Модель пайымдауының бір бөлігі. Бөліктерді ретімен біріктіріңіз. Hosted open-weight модельдер, 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 болғанда hosted open-weight модельдер пайымдауды жібермейді.

shannon-2-lite және shannon-2-pro да жауап бермес бұрын пайымдайды. Бұл endpoint-те олар пайымдап жатқанда : 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
  }
}

Hosted open-weight модельдерде 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 өрістері endpoint-пен бірге сипатталған. Chat Completions

Keep-alive жолдары

Модель жұмыс істеп жатып, жіберетін ештеңесі жоқ кезде, стрим түсініктеме жолдарын алып жүреді. Оларда дерек жоқ. SSE парсері оларды өзі өткізіп жібереді; шикі жолдарды оқитын код қос нүктеден басталатын әр жолды өткізіп жіберуі керек.

Жол Жіберетін Қашан
: ping Shannon 3 тобы, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 Әр 15 секунд сайын.
: keepalive Hosted open-weight модельдер Модель жұмыс істеп жатқанда әр 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 Сөйлесу модельдің контекст терезесінен ұзын. Қайта жібермес бұрын оны қысқартыңыз. Хабарлама мәтіні өзгеріп тұрады.

Hosted open-weight модельдер error мүшесін тек type және message арқылы жібереді.

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 endpoint-тері де стримдейді. Олардың кадрларында оқиға атауы бар 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