Memahami Pengaliran Token
Pahami cara API pengaliran mengirimkan penyelesaian parsial saat dihasilkan, cara kerja parameter OpenAI stream=True, dan kapan pengaliran meningkatkan pengalaman pengguna.
Memahami Pengaliran Token adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Mengapa Streaming Penting bagi Pengalaman Pengguna
Tanpa streaming, aplikasi Anda harus menunggu LLM menghasilkan respons lengkap sebelum menampilkan apa pun — sering kali 5–30 detik untuk jawaban yang panjang. Dengan streaming, token pertama muncul dalam 200–500 md setelah permintaan dikirim, dan token berikutnya masuk saat dihasilkan. Hal ini mengubah pengalaman pengguna yang dirasakan dari sekadar menunggu menjadi efek pembuatan langsung yang menarik, sehingga secara drastis meningkatkan responsivitas yang dirasakan meskipun total waktu pembuatan tetap sama.
Cara LLM Menghasilkan Token
LLM bersifat autoregresif: LLM menghasilkan teks satu token setiap kali, dengan setiap token baru bergantung pada semua token sebelumnya. Saat API menerima permintaan, GPU mulai mengambil sampel token pertama segera setelah prompt selesai diproses. Setiap token berikutnya memerlukan waktu yang kurang lebih sama. Streaming mengirimkan setiap token kepada klien segera setelah token tersebut diambil sampelnya, alih-alih menampung semua token lalu mengirimkan string lengkap di akhir.
# Conceptual model of autoregressive generation
prompt = 'The capital of France is'
# Step 1: process full prompt, predict next token
# token_1 = sample(logits) → ' Paris'
# Step 2: append token_1 to context, predict next
# token_2 = sample(logits) → '.'
# Step 3: append token_2 to context, predict next
# token_3 = sample(logits) → '<|end|>'
# Total time: time_to_process_prompt + n_tokens * time_per_token
# With streaming: first token arrives after time_to_process_prompt (TTFT)
# Without streaming: everything arrives after TTFT + n_tokens * time_per_tokenTTFT dan TPOT: Dua Metrik Latensi
Streaming memperkenalkan dua konsep latensi yang berbeda. TTFT (Time to First Token) adalah jeda sejak permintaan dikirim hingga token pertama diterima — sebagian besar dipengaruhi oleh waktu pemrosesan prompt. TPOT (Time Per Output Token) adalah waktu antara token-token yang berurutan — ditentukan oleh ukuran model dan perangkat keras. TTFT memengaruhi seberapa cepat UI merespons; TPOT memengaruhi kelancaran streaming teks. Keduanya harus dilacak secara terpisah dalam tumpukan pemantauan Anda.
import time
from openai import OpenAI
client = OpenAI()
def measure_streaming_latency(prompt: str):
t_start = time.perf_counter()
t_first_token = None
token_times = []
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
t_now = time.perf_counter()
if t_first_token is None:
t_first_token = t_now
print(f'TTFT: {(t_first_token - t_start) * 1000:.0f}ms')
else:
token_times.append(t_now - token_times[-1] if token_times else t_now - t_first_token)
token_times.append(t_now)
print(f'TPOT avg: {1000 * (token_times[-1] - t_first_token) / max(len(token_times)-1, 1):.1f}ms')Parameter stream=True
Mengaktifkan streaming dalam OpenAI SDK memerlukan pengaturan stream=True dalam pemanggilan chat.completions.create. Jenis respons berubah dari objek ChatCompletion menjadi iterator Stream[ChatCompletionChunk]. Setiap chunk berisi delta dengan fragmen string content atau None ketika token tersebut merupakan panggilan alat atau streaming sedang berakhir.
from openai import OpenAI
client = OpenAI()
# Non-streaming: wait for complete response
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'Explain RAG in one paragraph.'}],
)
full_text = response.choices[0].message.content
# Streaming: receive tokens incrementally
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'Explain RAG in one paragraph.'}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta: # delta can be None for non-content chunks
print(delta, end='', flush=True)
print() # newline at endMengakumulasi Respons Lengkap
Dalam banyak alur aplikasi, Anda memerlukan keduanya: melakukan streaming token ke UI agar responsif dan mengakumulasi teks respons lengkap untuk pemrosesan lanjutan seperti logging, caching, atau langkah pipeline berikutnya. Polanya sederhana: lakukan iterasi pada stream, cetak atau hasilkan setiap chunk kepada klien, dan secara bersamaan gabungkan konten menjadi satu string lengkap.
def stream_and_accumulate(prompt: str) -> str:
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
stream=True,
)
full_text = ''
finish_reason = None
for chunk in stream:
choice = chunk.choices[0]
delta = choice.delta.content
if delta:
print(delta, end='', flush=True) # real-time display
full_text += delta # accumulate
if choice.finish_reason:
finish_reason = choice.finish_reason
print() # newline
print(f'Finished: {finish_reason}, total chars: {len(full_text)}')
return full_textStreaming dengan Statistik Penggunaan
Secara default, respons streaming tidak menyertakan statistik penggunaan token (token prompt, token penyelesaian). Untuk menyertakannya, teruskan stream_options={'include_usage': True}. Data penggunaan tiba dalam chunk terakhir setelah stream konten berakhir. Hal ini penting untuk melacak biaya dan memantau batas laju pada aplikasi produksi.
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'What is a vector database?'}],
stream=True,
stream_options={'include_usage': True}, # include token counts
)
full_text = ''
usage = None
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
full_text += chunk.choices[0].delta.content
if chunk.usage: # arrives in the final chunk
usage = chunk.usage
if usage:
print(f'Prompt tokens: {usage.prompt_tokens}')
print(f'Completion tokens: {usage.completion_tokens}')
print(f'Total tokens: {usage.total_tokens}')Kapan Tidak Menggunakan Streaming
Streaming tidak selalu merupakan pilihan yang tepat. Hindari streaming ketika: (1) Anda memerlukan respons lengkap sebelum melakukan apa pun terhadapnya, seperti mengurai JSON atau mendeteksi panggilan alat; (2) respons sangat singkat (kurang dari 30 token), sehingga biaya tambahan streaming menambah lebih banyak jeda daripada yang dihemat; atau (3) Anda memproses banyak permintaan secara berkelompok dan throughput lebih penting daripada latensi respons individual. Dalam kasus ini, pemanggilan standar tanpa streaming lebih sederhana dan sama cepatnya.
Streaming dengan API Anthropic dan Gemini
Streaming tersedia pada semua API penyedia LLM utama, bukan hanya OpenAI. Polanya serupa, tetapi antarmuka SDK sedikit berbeda. SDK Python milik Anthropic menggunakan client.messages.stream() sebagai pengelola konteks, sedangkan Gemini menggunakan generate_content(stream=True). Saat membangun aplikasi yang tidak bergantung pada penyedia tertentu, abstraksikan antarmuka streaming di balik fungsi generator umum.
import anthropic
ant_client = anthropic.Anthropic(api_key='YOUR_KEY')
# Anthropic streaming
with ant_client.messages.stream(
model='claude-sonnet-4-5',
max_tokens=1024,
messages=[{'role': 'user', 'content': 'Explain hybrid search briefly.'}],
) as stream:
for text in stream.text_stream:
print(text, end='', flush=True)
# Final message with usage stats
final_msg = stream.get_final_message()
print(f'\nInput tokens: {final_msg.usage.input_tokens}')
print(f'Output tokens: {final_msg.usage.output_tokens}')Antarmuka Streaming Berbasis Generator
Pola arsitektur yang rapi membungkus streaming dalam fungsi generator Python yang menghasilkan string token. Hal ini memisahkan logika streaming dari logika konsumsi — pemanggil dapat melakukan iterasi pada generator, menulis ke file, meneruskan ke WebSocket, atau mengakumulasi ke dalam string tanpa kode streaming perlu mengetahui bagaimana outputnya digunakan. Inilah dasar sebagian besar API streaming produksi.
from typing import Generator
def stream_completion(
messages: list[dict],
model: str = 'gpt-4o-mini',
**kwargs,
) -> Generator[str, None, None]:
stream = client.chat.completions.create(
model=model,
messages=messages,
stream=True,
**kwargs,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
yield delta
# Usage: pipe to stdout
for token in stream_completion([{'role': 'user', 'content': 'Hello!'}]):
print(token, end='', flush=True)
# Usage: accumulate
full = ''.join(stream_completion([{'role': 'user', 'content': 'Hello!'}]))Streaming dalam Aplikasi Terminal dan CLI
Dalam aplikasi terminal, output yang dialirkan terlihat sama seperti pengetikan — setiap karakter langsung muncul saat dihasilkan. Persyaratan utamanya adalah menggunakan flush=True dalam setiap pemanggilan print. Tanpa flush, Python menampung output hingga newline, sehingga tujuan streaming tidak tercapai. Anda juga dapat menggunakan sys.stdout.write(token) yang diikuti sys.stdout.flush() untuk mendapatkan kontrol lebih besar atas pemformatan output.
import sys
def stream_to_terminal(messages: list[dict]):
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=messages,
stream=True,
)
token_count = 0
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
sys.stdout.write(delta) # no newline added
sys.stdout.flush() # MUST flush or output buffers
token_count += 1
print() # final newline
print(f'({token_count} tokens generated)')Streaming dan Pemulihan dari Error
Streaming mempersulit penanganan error karena kegagalan dapat terjadi di tengah stream setelah Anda mengirimkan beberapa token kepada klien. Pola yang disarankan adalah membungkus iterasi stream dalam blok try/except dan saat terjadi error, mengirim penanda error kepada klien atau menutup stream dengan bersih. Selalu terapkan timeout pada keseluruhan stream untuk menangani kasus ketika server mulai melakukan streaming, tetapi kemudian berhenti di tengah pembuatan.
import signal
def stream_with_timeout(messages, timeout_seconds=30):
def timeout_handler(signum, frame):
raise TimeoutError('LLM stream timed out')
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout_seconds)
try:
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=messages,
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
yield delta
except TimeoutError:
yield '\n[Response timed out]'
except Exception as e:
yield f'\n[Error: {str(e)}]'
finally:
signal.alarm(0) # cancel timeoutPemeriksaan Singkat
Uji pemahaman Anda tentang streaming token LLM dari pelajaran ini.
Ringkasan Pelajaran
Dalam pelajaran ini Anda telah mempelajari: streaming mengirim setiap token yang dihasilkan ke klien segera setelah token tersebut diambil sampelnya, sehingga secara signifikan meningkatkan responsivitas yang dirasakan; TTFT dan TPOT adalah dua metrik latensi utama yang perlu dilacak secara terpisah; dan stream=True mengubah respons OpenAI SDK menjadi iterator potongan yang Anda konsumsi dengan perulangan for. Bungkus stream dalam fungsi generator agar memiliki antarmuka yang bersih dan dapat digunakan kembali. Selanjutnya, kita akan menerapkan streaming asinkron dengan Python SDK.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Memahami Pengaliran Token” gratis?
Ya — teks lengkap “Memahami Pengaliran Token” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Memahami Pengaliran Token”?
Pahami cara API pengaliran mengirimkan penyelesaian parsial saat dihasilkan, cara kerja parameter OpenAI stream=True, dan kapan pengaliran meningkatkan pengalaman pengguna. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?
Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.
Berapa lama pelajaran “Memahami Pengaliran Token” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?
Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Memahami Pengaliran Token
- Mengonsumsi Aliran dengan Python SDK
- Pengaliran di FastAPI dengan Peristiwa yang Dikirim Server
- Menangani Pemanggilan Alat dalam Respons yang Dialirkan