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

Стриминг

stream'ди true кылыңыз, жооп модель аны жазып жатканда server-sent events катары келет: адегенде reasoning, андан кийин жооп, андан кийин аяктоо себеби жана usage бар акыркы чанк. Аны адам текстти күтүп жатканда жана узун жооптор үчүн колдонуңуз.

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

OpenAI SDK'лары чанктарды бирден берет. Ар бир чанкты эмнени алып келгенине жараша окуңуз: reasoning бөлүгү, жооп бөлүгү, курал чалуусу же жооптун аягы.

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 Модельдин reasoning'инин бир бөлүгү. Бөлүктөрдү тартиби менен бириктириңиз. Хостингдеги ачык салмактуу моделдер, Shannon 3 үй-бүлөсү, shannon-1.6-pro, shannon-coder-1
content string Жооптун бир бөлүгү. Бөлүктөрдү тартиби менен бириктириңиз. Бардык моделдер
tool_calls array Бир толук курал чалуусу. Курал чалуу дельталарын караңыз. Бардык моделдер

Адегенде reasoning, андан кийин жооп, андан кийин курал чалуулары келет. Чанкты стримдеги орду боюнча эмес, анын 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]

Reasoning дельталары

Reasoning жүргүзгөн модель өзүнүн reasoning'ин жооптун алдында delta.reasoning_content ичинде жөнөтөт. Эки текстти бөлүп кармаңыз: reasoning'ди өзүнчө, жыйыла турган бөлүк катары көрсөтүңүз, же койбой коюңуз.

Хостингдеги ачык салмактуу моделдер reasoning_effort off болгондо reasoning жөнөтпөйт, ошондой эле сурамда response_format болгондо да жөнөтпөйт.

shannon-2-lite жана shannon-2-pro да жооп бергенге чейин reasoning жүргүзөт. Бул 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
  }
}

Хостингдеги ачык салмактуу моделдерде 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 Хостингдеги ачык салмактуу моделдер Модель иштеп жатканда ар 15 секунд сайын.
: thinking shannon-2-lite, shannon-2-pro Модель reasoning жүргүзүп жатканда.

Стримдин ичиндеги каталар

Стрим башталгандан кийин анын статусу 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 Сүйлөшүү модельдин контекст терезесинен узун. Кайра жөнөтүүдөн мурун аны кыскартыңыз. Билдирүү тексти ар башка.

Хостингдеги ачык салмактуу моделдер 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: саптары
Reasoning келет delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
Жооп тексти келет delta.contentresponse.output_text.deltatext_delta
Usage келет Акыркы чанкresponse.completedmessage_delta
Стрим аяктайт Акыркы чанк, андан кийин data: [DONE]response.completedmessage_stop