Məzmuna keç
Axın

Axın

Stream-i true təyin edin və cavab model onu yazarkən server-sent events kimi gəlir: əvvəl reasoning, sonra cavab, sonra bitmə səbəbi və usage ilə son chunk. Mətni insan gözlədikdə və uzun cavablar üçün istifadə edin.

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

OpenAI SDK-ları chunk-ları sizə bir-bir verir. Hər chunk-ı daşıdığına görə oxuyun: reasoning hissəsi, cavab hissəsi, alət çağırışı və ya cavabın sonu.

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

Axın necə çərçivələnir

  • Cavabın statusu 200, başlıqları isə content-type: text/event-stream və cache-control: no-cache-dir.
  • Hər hadisə data: ilə başlayan və ardınca boş sətir gələn bir sətirdir. data: sonrakı mətn bir JSON chunk-dır. event: və ya id: sətirləri yoxdur.
  • : ping kimi iki nöqtə ilə başlayan sətir bağlantını açıq saxlayan şərhdir. Onu keçin.
  • Axın data: [DONE] ilə bitir. Onsuz dayanan axın tamamlanmamışdır.

Chunk-lar ardıcıllıqla

Hər chunk chat.completion.chunk obyektidir:

JSON
{
  "id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
  "object": "chat.completion.chunk",
  "created": 1791625200,
  "model": "shannon-3",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "Server-sent"
      },
      "finish_reason": null
    }
  ]
}

Bir axının bütün chunk-ları eyni id, created və model daşıyır. choices həmişə bir element saxlayır. Onun delta-sı yenini saxlayır və finish_reason son chunk-a qədər null-dır.

Delta-da açar Tip Təsvir Göndərən
role string Həmişə assistant. Axının əvvəlində bir dəfə gəlir. Host edilən açıq çəkili modellər, shannon-2-lite, shannon-2-pro
reasoning_content string Modelin reasoning-inin bir hissəsi. Hissələri ardıcıllıqla birləşdirin. Host edilən açıq çəkili modellər, Shannon 3 ailəsi, shannon-1.6-pro, shannon-coder-1
content string Cavabın bir hissəsi. Hissələri ardıcıllıqla birləşdirin. Bütün modellər
tool_calls array Bir tam alət çağırışı. Alət çağırışı delta-larına baxın. Bütün modellər

Əvvəl reasoning, sonra cavab, sonra hər hansı alət çağırışları gəlir. Chunk-ı axındakı yerinə görə yox, delta-dakı açarlara görə oxuyun: delta role-u mətnin ilk hissəsi ilə birlikdə saxlaya bilər, sonuncusu isə boşdur.

Bütöv axın getdiyi kimi. Sətirlər qısa qalsın deyə burada hər chunk-dan id, object, created və model çıxarılıb.

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 delta-ları

Reasoning edən model reasoning-ini cavabdan əvvəl delta.reasoning_content-də göndərir. İki mətni ayrı saxlayın: reasoning-i ayrıca, yığıla bilən hissə kimi göstərin və ya buraxın.

Host edilən açıq çəkili modellər reasoning_effort off olduqda reasoning göndərmir, sorğuda response_format olduqda da göndərmir.

shannon-2-lite və shannon-2-pro da cavab verməzdən əvvəl reasoning edir. Bu endpoint-də onlar reasoning edərkən : thinking şərh sətirləri, sonra cavabı göndərir.

reasoning_content OpenAI SDK-larının tipli modellərində yoxdur. Python-da onu getattr(delta, "reasoning_content", None) ilə oxuyun; JavaScript-də delta.reasoning_content olduğu kimi işləyir.

Alət çağırışı delta-ları

Alət çağırışı bütöv gəlir: hər çağırış üçün bir chunk, onun delta-sı çağırışı tam arguments sətri ilə saxlayır. index cavabın çağırışlarını 0-dan nömrələyir. arguments-i hissə-hissə birləşdirən kod dəyişmədən işləyir, çünki bir hissə birləşdirir.

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

Çağırışlardan sonra son chunk-da finish_reason tool_calls olur.

Sorğuda tools olduqda shannon-1.6-lite, shannon-1.6-pro və shannon-coder-1 cavab mətnini cavabın sonunda bir delta kimi göndərir.

Son chunk

data: [DONE]-dan əvvəlki son chunk-da boş delta, finish_reason və sorğunun usage-i var, hamısı eyni chunk-da. Hər axında o var; stream_options lazım deyil.

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

Host edilən açıq çəkili modellərdə usage həmçinin prompt_tokens_details.cached_tokens və completion_tokens_details.reasoning_tokens saxlayır.

web_search: true olan və axtarışı nəsə tapan sorğudan sonra son chunk həmçinin sources daşıyır, ondan əvvəlki bir chunk isə istinad işarələrini delta.annotations kimi daşıyır. Veb axtarışı

finish_reason Təsvir Göndərən
stop Model cavabını bitirdi və ya stop sətri göründü. Bütün modellər
tool_calls Cavab bir və ya bir neçə alət çağırışı saxlayır. Bütün modellər
length Cavab output limitində kəsildi. Shannon 3 ailəsi, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1

usage sahələri endpoint ilə birlikdə təsvir olunub. Chat Completions

Keep-alive sətirləri

Model işləyərkən və hələ göndəriləsi bir şey olmadıqda axın şərh sətirləri daşıyır. Onlarda data yoxdur. SSE parser-i onları özü keçir; xam sətirləri oxuyan kod iki nöqtə ilə başlayan hər sətri keçməlidir.

Sətir Göndərən Nə vaxt
: ping Shannon 3 ailəsi, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 Hər 15 saniyədən bir.
: keepalive Host edilən açıq çəkili modellər Model işlədiyi müddətdə hər 15 saniyədən bir.
: thinking shannon-2-lite, shannon-2-pro Model reasoning edərkən.

Axın daxilindəki xətalar

Axın başladıqdan sonra statusu 200 olur, ona görə uğursuzluq axının içində gəlir: choices-in olacağı yerdə error üzvü olan 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]

Xəta chunk-ından sonra finish_reason və usage olan son chunk və data: [DONE] yenə gəlir. Hər chunk-da error-u yoxlayın. Bu yoxlama olmadan yarı yolda uğursuz olan cavab tam görünür.

Tip Kod Mesaj Nə vaxt
api_error The model backend failed to answer. Please retry. Model uğursuz oldu və ya heç nə yazmadı. Sorğunu yenidən göndərin.
rate_limit_error Shannon routes are temporarily busy. Please retry. Model bu anda məşğuldur. Bir neçə saniyə gözləyin və sorğunu yenidən göndərin.
invalid_request_error context_length_exceeded Söhbət modelin kontekst pəncərəsindən uzundur. Yenidən göndərməzdən əvvəl onu qısaldın. Mesaj mətni dəyişir.

Host edilən açıq çəkili modellər error üzvünü yalnız type və message ilə göndərir.

OpenAI Python və JavaScript SDK-ları siz iterasiya edərkən xəta chunk-ını API xətası kimi qaldırır, ona görə dövrü adi xəta emalınıza bükün.

Status kodları, xəta gövdəsi və nəyi yenidən cəhd etməli olduğunuz ayrıca səhifədədir. Xəta idarəetməsi

Bağlantının bağlanması

Bağlantını bağlamaq çatdırılmanı dayandırır, sorğunu yox. Model cavabı sonuna qədər yazır və sorğu sanki hamısını oxumusunuz kimi hesablanır. Daha az ödəmək üçün daha az istəyin: onu tətbiq edən modeldə daha kiçik max_tokens təyin edin.

Axın sizə çatana qədər də erkən bitə bilər, məsələn şəbəkə kəsilməsində və ya server yenilənərkən. O zaman son chunk-sız və data: [DONE]-suz dayanır. Həmin cavabı tamamlanmamış sayın və sorğunu yenidən göndərin.

Axını SDK olmadan oxumaq

Düzgün oxuyucu beş şey edir: axından əvvəl gələn xətaları öz xəta emalına göndərir, gövdəni sətirlərə bölür, şərh sətirlərini keçir, data: [DONE]-da dayanır və hər chunk-da error-u yoxlayır.

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 nümunəsi requests paketindən istifadə edir. JavaScript nümunəsi Node.js 18 və ya daha yeni versiyada işləyir.

Digər formatların axınları

Responses və Messages endpoint-ləri də axınla işləyir. Onların frame-lərində hadisənin adı olan event: sətri və onun JSON-u olan data: sətri var. Hər səhifə hadisələrini ardıcıllıqla siyahıya alır.

Axında Chat CompletionsResponsesMessages
Frame-lər data: sətirlərievent: və data: sətirlərievent: və data: sətirləri
Reasoning burada gəlir delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
Cavab mətni burada gəlir delta.contentresponse.output_text.deltatext_delta
Usage burada gəlir Son chunkresponse.completedmessage_delta
Axın bununla bitir Son chunk, sonra data: [DONE]response.completedmessage_stop