Chat Completions streaming 은 sequence 의 chunk 로 와. 첫 chunk 보통 delta.role: "assistant" 만 — 'I'm starting' signal. Mid-stream chunks 는 delta.content 점진적. 마지막 chunk 는 finish_reason + 빈 content. 그 다음 literal data: [DONE] 으로 stream 종료.
delta.content 가 None/empty 가능
첫 chunk 는 role 만, 마지막 chunk 는 finish_reason 만 carry 가능. Concat 전 항상 체크. if chunk.choices[0].delta.content: 가 표준 가드.
Tool-calling stream 은 다른 shape
Tool 사용 시 delta.tool_calls[i].function.arguments 가 JSON fragment 로 도착 — 개별로는 valid JSON 아냐. Concat, 그 다음 parse — Function Call Streaming lesson 에서 자세히.
Lifecycle 외워두면 디버깅 쉬워
매 chunk 마다 어떤 필드가 나오는지 그려보면 — role, content, finish_reason, [DONE] — streaming 디버깅에서 'why is content None?' 같은 질문이 사라져.