Build the streaming event dispatch logic for the AnthropicStreamAdapter. Implement the stream_chat async generator that calls client.messages.stream() as an async context manager, iterates over MessageStream events, and dispatches message_start, content_block_delta, and message_stop events into unif
GenAI Application Engineering › Full-Stack GenAI Applications › Chapter 1 · Chat Completion API with Streaming › Implement an Anthropic Claude streaming adapter
5:54
Build the streaming event dispatch logic for the AnthropicStreamAdapter. Implement the stream_chat async generator that calls client.messages.stream() as an async context manager, iterates over MessageStream events, and dispatches message_start, content_block_delta, and message_stop events into unif
Host: Welcome back. You're in Full-Stack GenAI Applications — a course about building complete, production-ready applications that use large language models, the kind of AI that powers chatbots and assistants. This chapter is all about streaming chat responses — making words appear on screen one piece at a time, instead of waiting for a full answer. That's the experience users now expect, and getting it right is a core skill for any team shipping AI features.
Expert: Right, and let me paint the picture for why this matters. Imagine you're on a small engineering team at a company building a customer support assistant. Your product manager looks at the competition and says, "Why does ChatGPT feel instant, but our tool feels sluggish?" The answer is almost always streaming. Without it, your server sits silently for eight or ten seconds, then dumps an entire paragraph. Users think the app is broken. They bounce. With streaming, the first word shows up in under a second, and the illusion of thought is maintained. Now — here's the production wrinkle. Most teams don't use just one AI provider. They use Anthropic's Claude, OpenAI's GPT, Google's Gemini, maybe others, often switching between them for cost or capability reasons. Each provider streams results differently. They send different kinds of update messages, with different shapes and different field names. If your application code has to know all of those details, it becomes a tangled mess. So the job becomes: take the raw stream from one specific provider — in this exercise, Anthropic — and translate it into a single, standard shape that the rest of your app can consume without caring which provider it came from.
Host: So this is exercise two of three in this lab sequence. In the previous exercise, you built the foundation — the piece of code that connects to Anthropic and holds the configuration, plus the shared data shapes that describe a chat message and a stream update. Now you're extending that. So what exactly are we building here?
Expert: You're building the translation engine itself. The piece that actually opens a live streaming connection to Anthropic, listens to the steady flow of updates coming back, and converts each one into your app's standard format. Think of it like a simultaneous interpreter at the United Nations. Anthropic is speaking one language, your app speaks another, and your code stands in the middle translating in real time, one sentence at a time, without ever letting the conversation stall. Here's the key idea. When Anthropic streams a response, it doesn't just send text. It sends a sequence of labeled events — little announcements. One event says "I'm starting a new message." Another says "here's a small piece of text to add." Another says "here's some updated information about how many words I've used." And a final one says "I'm done." Your job is to look at the label on each incoming event, decide what kind of announcement it is, and either extract what you need, track some bookkeeping, or ignore it. The computer-science name for this pattern is event dispatch — routing each event to the right handler based on its type. Once you have this pattern working cleanly, adding support for other providers later becomes straightforward, because you've built the translation mental model.
Host: Okay, before the listener starts coding — what's the tricky part? Where do people get stuck on this one?
Expert: Two things, and they're both about the shape of the data. First, the small text pieces aren't where you'd intuitively expect. When an update event arrives saying "here's more content," the actual text string is nested a couple of layers deep inside the event. People reach for the wrong field, get an empty string or an error, and spend twenty minutes confused. So before you write the extraction logic, take a minute to look carefully at the structure of one of these update events and trace exactly where the text lives. Second — the streaming connection needs to be opened and closed properly. It's a live network connection. If you just grab it and forget about it, you leak resources. The language gives you a clean way to say "open this for the duration of this block, and guarantee it closes when I'm done" — use that pattern. Don't try to manage it by hand.
Host: Great. So when you finish this exercise, what can you actually do, and where does it lead?
Expert: After this, you'll be able to take a live streaming response from Anthropic's Claude and convert it, piece by piece, into a clean unified format that the rest of your application can consume without knowing or caring about Anthropic-specific details. That's a real production building block. Your team can use this pattern as the template for plugging in every other AI provider you support — it's the foundation of a provider-agnostic chat layer, which is exactly how mature AI products are architected. Next, in the third and final exercise of this lab, you'll handle two remaining details — separating out the instructions that set the AI's personality from regular conversation messages, and translating Anthropic's way of saying "I stopped because I hit the length limit" or "I stopped because I finished naturally" into your app's standard vocabulary. Small pieces, but they complete the adapter. Alright — go build it. Thanks for listening.
Want to go deeper? Explore disciplines with hands-on labs, quizzes, and chapter podcasts.