Skip to content
47% off: the complete course for $79 (reg. $149)Order now →
AI Builder
Module 2Full course11 min read

Managing Conversation History and State

Store, replay, trim, and summarize multi-turn conversations; keep app state out of the transcript; and avoid the bugs that come from editing history.

The first time you build a multi-turn feature, it's surprising to learn that the model doesn't remember the conversation. Every request starts from nothing. The "memory" users experience is your code replaying the transcript on every turn, and every bug in how you store, replay, or trim that transcript shows up as the AI "forgetting," contradicting itself, or failing with a 400 error halfway through a session.

This lesson treats conversation history as data you own. You'll design storage that keeps transcripts valid, separate the transcript from live app state so the model never acts on stale facts, trim and summarize long conversations without breaking them, and avoid the subtle bugs that come from editing history after the fact. The examples use Deskmate's in-app assistant, but the patterns apply to any multi-turn feature.

The API remembers nothing

As you saw in Anatomy of a Model API Call, the Messages API is stateless. Here's what that means on the third turn of a conversation: every previous message goes back in, every time.

scripts/three-turns.ts
import Anthropic from "@anthropic-ai/sdk";
 
const anthropic = new Anthropic();
 
const messages: Anthropic.MessageParam[] = [
  { role: "user", content: "How do I add a teammate to Deskmate?" },
  { role: "assistant", content: "Go to Settings → Team and click Invite. You'll need admin rights." },
  { role: "user", content: "I'm not an admin. Who is?" },
];
 
const response = await anthropic.messages.create({
  model: "claude-sonnet-5-5",
  max_tokens: 4000,
  output_config: { effort: "low" },
  system: "You are Deskmate's in-app help assistant.",
  messages,
});

Three consequences follow from this, and each one shapes the rest of the lesson.

You decide what the model remembers. Whatever you put in messages is the conversation, as far as the model knows. That's power (you can trim, summarize, and inject) and responsibility (you can also corrupt it).

Cost grows with every turn. Turn 20 re-sends turns 1 through 19. The total input tokens over a conversation grow roughly with the square of its length, so long sessions get expensive faster than intuition suggests. Prompt caching softens this considerably, since the replayed prefix is identical from one turn to the next; Prompt Caching in Practice shows how to set it up.

The server should own the transcript. If your browser client sends the full history with each request, a user can edit it, including inventing assistant messages that "agreed" to things. Have the client send only the conversation ID and the new message, and load the history from your database.