Claude Academy
Sign in

Multi-Turn Conversations

The stateless model

Every API call must include the full conversation. The server keeps no session. This affects:

  • Cost. Each turn pays for all prior turns as input tokens.
  • Latency. Long histories slow down requests unless cached.
  • Memory design. You are the storage layer.

Turn structure rules

  • First message must be user.
  • Roles strictly alternate userassistantuser → ...
  • Tool results are sent as user turns containing tool_result blocks (not a separate role).
  • A single turn's content is an array of blocks (text, tool_use, tool_result, image, etc.).

Conversation compaction

When the history grows too large:

  1. Summarize older turns into a compact assistant message ("Here's what we've discussed so far: ...").
  2. Drop verbose tool results that are no longer needed; keep the summary.
  3. Keep a state object (e.g., JSON in the system prompt or first turn) representing canonical state, then prune old messages.
  4. Slide the window — keep the last N turns + a running summary.

This is a classic CCA-F exam topic: which compaction strategy is best for which scenario.

State object pattern

Instead of replaying the whole conversation, keep a compact JSON state:

{
  "user": {"name": "Chris", "tier": "premium"},
  "cart": [{"sku": "X", "qty": 2}],
  "open_question": "Confirm shipping address"
}

Update it after each turn. Pass it in system prompt or initial user turn. The conversation becomes thin around a stable state.

Caching long histories

Mark the trailing-most cacheable boundary (e.g., after the last assistant turn) with cache_control. Each new user turn appends to that prefix. As long as the prefix stays stable, you get cache hits.

Common bugs

BugCauseFix
400 invalid_request_error: messages must alternateTwo user or two assistant in a rowMerge them or insert proper turn
Context window exhaustedConversation too longCompact / summarize
Lost reasoning across turnsStripped thinking blocksKeep them with signatures
Tool calls forgottenDropped tool_use/tool_result pairAlways keep matching pairs

See also