Streaming & Multi-Turn Conversations
- Stream responses token-by-token so users see output immediately
- Understand why the API is stateless and how to carry conversation history yourself
- Continue a multi-turn conversation by resending the full prior exchange
- Keep long conversations from blowing up the context window and cost
Building chat-like experiences on the API comes down to two practical realities: stream so users see output immediately, and manage history yourself because the API is stateless. Master both and your chat UX feels fast and remembers everything.
Streaming
Without streaming, the user waits for the whole reply. With streaming, tokens arrive as they're generated — far better perceived speed.
- Use the SDK's streaming helper instead of parsing raw events by hand — it manages the event lifecycle for you.
- Python
- TypeScript
with client.messages.stream(
model="claude-sonnet-5", max_tokens=1024,
messages=[{"role": "user", "content": "Explain RAG in two sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
const stream = client.messages.stream({
model: "claude-sonnet-5", max_tokens: 1024,
messages: [{ role: "user", content: "Explain RAG in two sentences." }],
});
for await (const event of stream) {
if (event.type === "content_block_delta") process.stdout.write(event.delta.text ?? "");
}
Multi-turn: you hold the history
The API has no memory between calls (why). To continue a conversation, send the whole prior exchange back each time.
Guided walkthrough1 of 4
- Send the first user message in the messages list.
- Read the assistant's response text from the result.
- Add the assistant reply and the next user message to the same messages list.
- Send the complete messages list again — that is how Claude 'remembers' the exchange.
messages = [{"role": "user", "content": "Hi, I'm planning a trip."}]
# ... get assistant reply, then append both turns:
messages.append({"role": "assistant", "content": assistant_text})
messages.append({"role": "user", "content": "Make it 3 days."})
# send the full `messages` list again
Long conversations fill the window
As history grows it eats the context window and cost rises. Strategies to keep it in check:
- Summarize/compact older turns into a short recap you carry forward.
- Trim irrelevant earlier turns.
- Pair with prompt caching to avoid re-paying for a stable prefix.
- Every call resends the entire history — long conversations cost more and can eventually exceed the context window if you never compact or trim.
- Stream tokens for fast perceived speed; the SDK helper handles the event lifecycle.
- The API is stateless — it has no memory between calls.
- Continue a conversation by appending each turn and resending the full messages list.
- Compact, trim, and cache to control the cost and size of long conversations.