ຂ້າມໄປຫາເນື້ອຫາ
ສະຕຣີມມິ້ງ

ສະຕຣີມມິ້ງ

ຕັ້ງ stream ເປັນ true ແລ້ວຄຳຕອບຈະມາເປັນ server-sent events ໃນຂະນະທີ່ model ຂຽນມັນ: reasoning ກ່ອນ, ແລ້ວຄຳຕອບ, ແລ້ວ chunk ສຸດທ້າຍທີ່ມີເຫດຜົນທີ່ຈົບ ແລະ usage. ໃຊ້ມັນທຸກຄັ້ງທີ່ມີຄົນລໍຖ້າຂໍ້ຄວາມ, ແລະ ສຳລັບຄຳຕອບຍາວ.

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

SDK ຂອງ OpenAI ໃຫ້ chunk ແກ່ທ່ານເທື່ອລະອັນ. ອ່ານແຕ່ລະ chunk ຕາມສິ່ງທີ່ມັນມີ: ສ່ວນຂອງ reasoning, ສ່ວນຂອງຄຳຕອບ, ການເອີ້ນ tool, ຫຼື ຈຸດຈົບຂອງຄຳຕອບ.

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

stream ຖືກຈັດ frame ແນວໃດ

  • ຄຳຕອບມີ status 200 ແລະ header content-type: text/event-stream ແລະ cache-control: no-cache.
  • ແຕ່ລະ event ແມ່ນໜຶ່ງແຖວທີ່ເລີ່ມດ້ວຍ data: ແລະ ຕາມດ້ວຍແຖວວ່າງ. ຂໍ້ຄວາມຫຼັງ data: ແມ່ນ chunk JSON ໜຶ່ງອັນ. ບໍ່ມີແຖວ event: ຫຼື id:.
  • ແຖວທີ່ເລີ່ມດ້ວຍຈ້ຳສອງຈຸດ, ເຊັ່ນ : ping, ແມ່ນ comment ທີ່ຮັກສາການເຊື່ອມຕໍ່ໃຫ້ເປີດຢູ່. ຂ້າມມັນ.
  • stream ຈົບດ້ວຍ data: [DONE]. stream ທີ່ຢຸດໂດຍບໍ່ມີມັນແມ່ນບໍ່ສົມບູນ.

Chunk ຕາມລຳດັບ

ທຸກ chunk ແມ່ນ object 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
    }
  ]
}

ທຸກ chunk ຂອງ stream ດຽວມີ id, created ແລະ model ດຽວກັນ. choices ມີໜຶ່ງລາຍການສະເໝີ. delta ຂອງມັນເກັບສິ່ງໃໝ່, ແລະ finish_reason ເປັນ null ຈົນຮອດ chunk ສຸດທ້າຍ.

Key ໃນ delta ປະເພດ ຄຳອະທິບາຍ ສົ່ງໂດຍ
role string ເປັນ assistant ສະເໝີ. ມັນມາເທື່ອດຽວ, ຕອນເລີ່ມ stream. Hosted open-weight models, shannon-2-lite, shannon-2-pro
reasoning_content string ສ່ວນໜຶ່ງຂອງ reasoning ຂອງ model. ຕໍ່ສ່ວນຕ່າງໆຕາມລຳດັບ. model open-weight ທີ່ host ໄວ້, ຕະກູນ Shannon 3, shannon-1.6-pro ແລະ shannon-coder-1
content string ສ່ວນໜຶ່ງຂອງຄຳຕອບ. ຕໍ່ສ່ວນຕ່າງໆຕາມລຳດັບ. ທຸກ model
tool_calls array ການເອີ້ນ tool ທີ່ຄົບຖ້ວນໜຶ່ງອັນ. ເບິ່ງ Tool call deltas. ທຸກ model

Reasoning ມາກ່ອນ, ແລ້ວຄຳຕອບ, ແລ້ວການເອີ້ນ tool ຖ້າມີ. ອ່ານ chunk ຕາມ key ໃນ delta ຂອງມັນ, ບໍ່ແມ່ນຕາມຕຳແໜ່ງໃນ stream: delta ອາດມີ role ພ້ອມກັບຂໍ້ຄວາມສ່ວນທຳອິດ, ແລະ ອັນສຸດທ້າຍວ່າງ.

stream ທັງໝົດຕາມທີ່ມັນເດີນທາງ. ເພື່ອໃຫ້ແຖວສັ້ນ, id, object, created ແລະ model ຖືກຕັດອອກຈາກແຕ່ລະ chunk ໃນທີ່ນີ້.

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

model ທີ່ຄິດຫາເຫດຜົນສົ່ງ reasoning ຂອງມັນໃນ delta.reasoning_content ກ່ອນຄຳຕອບ. ແຍກສອງຂໍ້ຄວາມອອກຈາກກັນ: ສະແດງ reasoning ເປັນສ່ວນແຍກທີ່ພັບໄດ້, ຫຼື ຕັດມັນອອກ.

Hosted open-weight models ບໍ່ສົ່ງ reasoning ເມື່ອ reasoning_effort ເປັນ off, ແລະ ບໍ່ສົ່ງເມື່ອຄຳຮ້ອງຂໍມີ response_format.

shannon-2-lite ແລະ shannon-2-pro ກໍຄິດຫາເຫດຜົນກ່ອນຕອບເຊັ່ນກັນ. ໃນ endpoint ນີ້ພວກມັນສົ່ງແຖວ comment : thinking ໃນຂະນະທີ່ເຮັດ, ແລ້ວຈຶ່ງສົ່ງຄຳຕອບ.

reasoning_content ບໍ່ຢູ່ໃນ typed model ຂອງ SDK ຂອງ OpenAI. ໃນ Python ໃຫ້ອ່ານດ້ວຍ getattr(delta, "reasoning_content", None); ໃນ JavaScript delta.reasoning_content ໃຊ້ໄດ້ຕາມທີ່ມັນເປັນ.

Delta ຂອງການເອີ້ນ tool

ການເອີ້ນ tool ມາທັງກ້ອນ: ໜຶ່ງ chunk ຕໍ່ການເອີ້ນ, ທີ່ delta ເກັບການເອີ້ນພ້ອມ string arguments ຄົບຖ້ວນ. index ນັບການເອີ້ນຂອງຄຳຕອບຕັ້ງແຕ່ 0. ໂຄ້ດທີ່ຕໍ່ arguments ເທື່ອລະສ່ວນເຮັດວຽກໂດຍບໍ່ຕ້ອງປ່ຽນ, ເພາະມັນຕໍ່ພຽງສ່ວນດຽວ.

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

ຫຼັງຈາກການເອີ້ນ, chunk ສຸດທ້າຍມີ finish_reason tool_calls.

ເມື່ອຄຳຮ້ອງຂໍມີ tools, shannon-1.6-lite, shannon-1.6-pro ແລະ shannon-coder-1 ສົ່ງຂໍ້ຄວາມຄຳຕອບເປັນ delta ດຽວທ້າຍຄຳຕອບ.

Chunk ສຸດທ້າຍ

chunk ສຸດທ້າຍກ່ອນ data: [DONE] ມີ delta ວ່າງ, finish_reason ແລະ usage ຂອງຄຳຮ້ອງຂໍ, ທັງໝົດໃນ chunk ດຽວກັນ. ທຸກ stream ມີມັນ; ທ່ານບໍ່ຕ້ອງການ 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 models usage ຍັງມີ prompt_tokens_details.cached_tokens ແລະ completion_tokens_details.reasoning_tokens ນຳ.

ຫຼັງຄຳຮ້ອງຂໍທີ່ມີ web_search: true ເຊິ່ງການຄົ້ນຫາພົບບາງຢ່າງ, chunk ສຸດທ້າຍຍັງມີ sources ນຳ, ແລະ chunk ໜຶ່ງກ່ອນໜ້ານັ້ນມີເຄື່ອງໝາຍການອ້າງອີງເປັນ delta.annotations. ຄົ້ນຫາເວັບ

finish_reason ຄຳອະທິບາຍ ສົ່ງໂດຍ
stop model ຕອບຈົບແລ້ວ, ຫຼື string stop ປາກົດຂຶ້ນ. ທຸກ model
tool_calls ຄຳຕອບມີການເອີ້ນ tool ໜຶ່ງອັນ ຫຼື ຫຼາຍກວ່ານັ້ນ. ທຸກ model
length ຄຳຕອບຖືກຕັດທີ່ຂີດຈຳກັດ output. ຕະກູນ Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1

ຟີລດ໌ຂອງ usage ຖືກອະທິບາຍພ້ອມກັບ endpoint. Chat Completions

ແຖວ Keep-alive

ໃນຂະນະທີ່ model ເຮັດວຽກແລະ ຍັງບໍ່ມີຫຍັງຈະສົ່ງ, stream ມີແຖວ comment. ພວກມັນບໍ່ມີຂໍ້ມູນ. ຕົວແຍກ SSE ຂ້າມພວກມັນເອງ; ໂຄ້ດທີ່ອ່ານແຖວດິບຕ້ອງຂ້າມທຸກແຖວທີ່ເລີ່ມດ້ວຍຈ້ຳສອງຈຸດ.

ແຖວ ສົ່ງໂດຍ ເມື່ອໃດ
: ping ຕະກູນ Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 ທຸກ 15 ວິນາທີ.
: keepalive Hosted open-weight models ທຸກ 15 ວິນາທີໃນຂະນະທີ່ model ເຮັດວຽກ.
: thinking shannon-2-lite, shannon-2-pro ໃນຂະນະທີ່ model ຄິດຫາເຫດຜົນ.

ຂໍ້ຜິດພາດພາຍໃນ stream

ເມື່ອ stream ເລີ່ມແລ້ວ status ຂອງມັນເປັນ 200, ດັ່ງນັ້ນຄວາມລົ້ມເຫຼວມາພາຍໃນ stream: chunk ທີ່ມີສະມາຊິກ error ໃນບ່ອນທີ່ choices ຄວນຢູ່.

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]

ຫຼັງຈາກ chunk ຂໍ້ຜິດພາດ, chunk ສຸດທ້າຍ, ພ້ອມ finish_reason ແລະ usage, ແລະ data: [DONE] ຍັງຕາມມາ. ກວດທຸກ chunk ວ່າມີ error ຫຼືບໍ່. ຖ້າບໍ່ກວດ ຄຳຕອບທີ່ລົ້ມເຫຼວກາງທາງຈະເບິ່ງຄືສົມບູນ.

ປະເພດ Code ຂໍ້ຄວາມ ເມື່ອໃດ
api_error The model backend failed to answer. Please retry. model ລົ້ມເຫຼວ, ຫຼື ບໍ່ໄດ້ຂຽນຫຍັງ. ສົ່ງຄຳຮ້ອງຂໍອີກ.
rate_limit_error Shannon routes are temporarily busy. Please retry. model ກຳລັງຍຸ່ງໃນເວລານີ້. ລໍຖ້າສອງສາມວິນາທີ ແລ້ວສົ່ງຄຳຮ້ອງຂໍອີກ.
invalid_request_error context_length_exceeded ການສົນທະນາຍາວກວ່າ context window ຂອງ model. ເຮັດໃຫ້ມັນສັ້ນລົງກ່ອນສົ່ງອີກ. ຂໍ້ຄວາມປ່ຽນແປງໄດ້.

Hosted open-weight models ສົ່ງສະມາຊິກ error ທີ່ມີສະເພາະ type ແລະ message.

SDK ຂອງ OpenAI ສຳລັບ Python ແລະ JavaScript ຍົກ chunk ຂໍ້ຜິດພາດເປັນ API error ໃນຂະນະທີ່ທ່ານວົນ, ດັ່ງນັ້ນໃຫ້ຫໍ່ loop ດ້ວຍການຈັດການຂໍ້ຜິດພາດປົກກະຕິຂອງທ່ານ.

Status code, body ຂອງຂໍ້ຜິດພາດ ແລະ ສິ່ງທີ່ຄວນລອງໃໝ່ມີໜ້າຂອງຕົນເອງ. ການຈັດການຂໍ້ຜິດພາດ

ການປິດການເຊື່ອມຕໍ່

ການປິດການເຊື່ອມຕໍ່ຢຸດການສົ່ງ, ບໍ່ແມ່ນຄຳຮ້ອງຂໍ. model ຂຽນຄຳຕອບຈົນຈົບ ແລະ ຄຳຮ້ອງຂໍຖືກຄິດເງິນຄືກັບທີ່ທ່ານອ່ານທັງໝົດ. ເພື່ອຈ່າຍໜ້ອຍລົງ, ໃຫ້ຂໍໜ້ອຍລົງ: ຕັ້ງ max_tokens ທີ່ຕ່ຳກວ່າໃນ model ທີ່ນຳໃຊ້ມັນ.

stream ຍັງຈົບກ່ອນເວລາໃນທາງມາຫາທ່ານໄດ້, ຕົວຢ່າງເມື່ອເຄືອຂ່າຍຂາດ ຫຼື ໃນຂະນະທີ່ server ກຳລັງອັບເດດ. ຈາກນັ້ນມັນຢຸດໂດຍບໍ່ມີ chunk ສຸດທ້າຍ ແລະ ບໍ່ມີ data: [DONE]. ຖືວ່າຄຳຕອບນັ້ນບໍ່ສົມບູນ ແລະ ສົ່ງຄຳຮ້ອງຂໍອີກ.

ການອ່ານ stream ໂດຍບໍ່ໃຊ້ SDK

ຕົວອ່ານທີ່ຖືກຕ້ອງເຮັດຫ້າຢ່າງ: ສົ່ງຂໍ້ຜິດພາດທີ່ມາກ່ອນ stream ໄປຫາຕົວຈັດການຂໍ້ຜິດພາດຂອງມັນ, ແຍກ body ເປັນແຖວ, ຂ້າມແຖວ comment, ຢຸດທີ່ data: [DONE], ແລະ ກວດແຕ່ລະ chunk ວ່າມີ 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 ໃຊ້ package requests. ຕົວຢ່າງ JavaScript ຮັນເທິງ Node.js 18 ຫຼື ໃໝ່ກວ່າ.

Stream ຂອງຮູບແບບອື່ນ

endpoint Responses ແລະ Messages ກໍ stream ໄດ້ຄືກັນ. frame ຂອງພວກມັນມີແຖວ event: ທີ່ມີຊື່ຂອງ event ແລະ ແຖວ data: ທີ່ມີ JSON ຂອງມັນ. ແຕ່ລະໜ້າລາຍຊື່ event ຂອງຕົນຕາມລຳດັບ.

ໃນ stream Chat CompletionsResponsesMessages
Frame ແຖວ data:ແຖວ event: ແລະ data:ແຖວ event: ແລະ data:
Reasoning ມາໃນ delta.reasoning_contentresponse.reasoning_summary_text.deltathinking_delta
ຂໍ້ຄວາມຄຳຕອບມາໃນ delta.contentresponse.output_text.deltatext_delta
Usage ມາໃນ chunk ສຸດທ້າຍresponse.completedmessage_delta
stream ຈົບດ້ວຍ chunk ສຸດທ້າຍ, ແລ້ວ data: [DONE]response.completedmessage_stop