C.W.K.
Stream
Lesson 04 of 06 · published

스트리밍: time-to-first-token이 중요해

~16 min · streaming, sse, events

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

왜 stream하나

Non-streaming Messages 호출은 응답 전체 생성될 때까지 블록. 긴 완성이면 그게 몇 초 dead UX. 스트리밍은 모델이 토큰 만드는 대로 Server-Sent Events 반환, 인지 지연을 last-token이 아니라 first-token까지로 떨어뜨림.

실제로 다루는 이벤트 타입

SDK가 SSE wire format을 typed 이벤트로 추상화. 첫날에 알 가치 있는 다섯 — message_start(초기 응답 shell), content_block_start(새 텍스트 또는 tool 블록 시작), content_block_delta(증분 텍스트), content_block_stop(블록 닫힘), message_stop(응답 완료). Tool use는 자기 delta 모양 가진 별도 블록 타입으로 stream.

스트리밍은 보이는 것보다 어려워

스트림 중간 disconnect는 partial output에 자동 retry 없음. Token 카운트는 message_stop에서만 확정. Tool-use 블록은 parse 전에 delta에서 재조립해야 함. 스트리밍은 더 빠른 피드백 주는 대신 더 많은 애플리케이션 코드를 요구해.

원칙: User가 기다리고 있으면 stream. 아니면 buffer. '할 수 있어서' stream하지 마.

Code

Python SDK 헬퍼로 스트리밍·python
with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=2048,
    messages=[{"role": "user", "content": "Explain prompt caching in three short paragraphs."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    final_message = stream.get_final_message()

print()
print("usage:", final_message.usage)
직접 짠 이벤트 처리 (TypeScript)·typescript
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();

const stream = await client.messages.stream({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'List three SSE pitfalls.' }],
});

for await (const event of stream) {
  if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
    process.stdout.write(event.delta.text);
  }
  if (event.type === 'message_stop') {
    process.stdout.write('\n');
  }
}

const final = await stream.finalMessage();
console.log('usage:', final.usage);

External links

Exercise

Messages 응답을 stream하고 각 delta를 stdout이랑 JSONL 파일에 그 순서로 쓰는 작은 CLI 만들어. 프로세스를 stream 중간에 죽이고 JSONL에 print된 모든 토큰이 그대로 있는지 확인.
Hint
파일을 line-buffered 모드로 열고 매 write 후 flush() 호출 — SIGTERM이 마지막 라인 안 잃게.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.