> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokenlab.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming

> Triển khai phản hồi streaming theo thời gian thực

## Tổng quan

Streaming cho phép bạn nhận đầu ra từng phần ngay khi nó được tạo ra, giúp cải thiện độ trễ cảm nhận và trải nghiệm người dùng.

Đối với các tích hợp kiểu OpenAI mới, hãy ưu tiên **Responses streaming** trước. Nếu framework của bạn vẫn sử dụng Chat Completions streaming, TokenLab cũng hỗ trợ lộ trình tương thích đó.

## Khuyến nghị: Responses Streaming

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.tokenlab.sh/v1/responses \
    -H "Authorization: Bearer sk-your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-5.4",
      "input": "Write a short poem.",
      "stream": true
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="sk-your-api-key",
      base_url="https://api.tokenlab.sh/v1"
  )

  stream = client.responses.create(
      model="gpt-5.4",
      input="Write a short poem.",
      stream=True
  )

  for event in stream:
      if event.type == "response.output_text.delta":
          print(event.delta, end="", flush=True)
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const client = new OpenAI({
    apiKey: 'sk-your-api-key',
    baseURL: 'https://api.tokenlab.sh/v1'
  });

  const stream = await client.responses.create({
    model: 'gpt-5.4',
    input: 'Write a short poem.',
    stream: true
  });

  for await (const event of stream) {
    if (event.type === 'response.output_text.delta') {
      process.stdout.write(event.delta);
    }
  }
  ```
</CodeGroup>

## Phát trực tuyến Chat Completions

Nếu framework của bạn vẫn yêu cầu các chunk SSE từ `/v1/chat/completions`, cách này cũng hoạt động:

```python theme={null}
stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Write a short poem"}],
    stream=True
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="", flush=True)
```

## Điều kiện kết thúc stream

Các điều kiện hoàn tất điển hình:

* `response.completed` cho các stream của Responses API
* `finish_reason: "stop"` cho các stream Chat Completions
* `finish_reason: "length"` khi chạm đến giới hạn token
* các sự kiện gọi tool/function khi model muốn sử dụng tools

## Mẫu cho ứng dụng web

```javascript theme={null}
async function streamChat(message) {
  const response = await fetch('https://api.tokenlab.sh/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk-your-api-key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: message }],
      stream: true
    })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    const lines = chunk.split('\\n').filter(line => line.startsWith('data: '));

    for (const line of lines) {
      const data = line.slice(6);
      if (data === '[DONE]') return;
      const parsed = JSON.parse(data);
      const content = parsed.choices?.[0]?.delta?.content;
      if (content) {
        document.getElementById('output').textContent += content;
      }
    }
  }
}
```

## Thực tiễn tốt nhất

<AccordionGroup>
  <Accordion title="Ưu tiên Responses streaming cho các bản dựng mới">
    Sử dụng `/v1/responses` nếu SDK hoặc ứng dụng của bạn đã hỗ trợ. Giữ lại streaming `/v1/chat/completions` cho các tích hợp cần tương thích.
  </Accordion>

  <Accordion title="Flush đầu ra tăng dần">
    Nối các chunk delta vào UI hoặc terminal ngay khi chúng đến thay vì chờ toàn bộ phản hồi hoàn tất.
  </Accordion>

  <Accordion title="Xử lý ngắt kết nối và thử lại">
    Xem việc rớt mạng và ngắt kết nối từ upstream là các chế độ lỗi bình thường, và kết nối lại một cách cẩn thận cho các phiên chạy dài.
  </Accordion>
</AccordionGroup>
