CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/API & SDK
API & SDK/2026-04-26Advanced

Replay-Driven Testing for Claude API: A Production Pattern for Recording and Replaying Responses

A production-grade design for stabilizing Claude API tests by recording and replaying real responses. Covers cassettes for Messages, Streaming, Tool Use, CI integration, and incident replay.

api-sdk13testing6production111claude-api81ci-cd8

Premium Article

"My tests come back red because Claude phrased the answer slightly differently again, and I can't tell whether something actually broke or the model just had a different mood today." Most teams who put Claude API into production hit this wall. I have personally spent half a day chasing a refactor regression that turned out to be a one-word change in Claude's response — the test was checking the wrong thing, but I didn't know that until I had pulled the entire stack apart.

This article walks through the cassette-based testing pattern that Ruby's VCR, Python's VCR.py, and JavaScript's Polly.js made famous, adapted for every Claude API surface: Messages, Streaming, and Tool Use. Instead of mocking, you call the real Claude API exactly once, save the response to disk, and replay it forever after. The result is deterministic tests, near-zero CI cost, and the ability to reproduce production failures locally.

Why ordinary mocks fall short

The first instinct is to patch messages.create with unittest.mock and return a hand-written response object. I started there too. After three months of operating a multi-agent system on top of it, I gave up. There are three concrete reasons why hand-rolled mocks don't scale.

Mocked responses drift from reality. Claude's response shape gets extended regularly. New stop_reason values appear, content blocks get new types, the usage object gains fields. A hand-written mock is a snapshot frozen in time, so it lies to your tests every time the SDK ships an update. Tests stay green while production breaks — the worst possible failure mode.

Tool Use sequences are tedious to fake. A single tool-using test typically involves at least two round trips: Claude asks for a tool call, your code runs the tool, you send the result back, Claude returns the final answer. Hand-mocking that flow forces you to manually thread tool_use_id, role ordering, and content block types — every one of which is easy to get subtly wrong.

Streaming responses are nearly impossible to mock by hand. Producing a faithful sequence of message_start, content_block_start, content_block_delta, content_block_stop, message_delta, and message_stop events in the right order is so error-prone that recording an actual stream and replaying it byte-for-byte is dramatically safer.

The cassette pattern dissolves all three problems with one rule: hit the real API once, save what came back, and replay it for the rest of the test's life.

The cassette architecture, top to bottom

Before any code, here is the layered design I use in production. Three layers, each replaceable.

The cassette store is just a directory of .json or .jsonl files under tests/cassettes/, one per test. The one-test-one-cassette rule is non-negotiable: it makes "what does this test record?" a grep query.

The interceptor patches your Anthropic client at runtime. If a recording exists for the request, return it; otherwise call the real API and persist the response. A record_mode flag — once, new_episodes, or none — lets you control whether new recordings are allowed.

The request matcher decides which recorded response matches the current request when a cassette holds multiple recordings. I hash the messages array, model name, and tool definitions into a short key. This makes tests order-independent and keeps the cassette readable.

Keeping these layers separate matters when you later want to change the cassette format, relax the matcher, or add encryption — none of those forces you to rewrite the tests themselves.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Teams who were burned out by flaky CI runs caused by LLM response drift will be able to write deterministic tests using recorded responses
You will learn how to apply the cassette pattern from VCR.py and Polly.js to every Claude API surface — Messages, Streaming, and Tool Use — with working code
You'll get a workflow for replaying production failures locally, so untouchable 'I can't reproduce it' bugs become reproducible in minutes
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

API & SDK2026-05-05
The Real Cost of Claude API Extended Thinking in Production — ROI Data by Task Type
Three months of measured cost, quality, and speed data for Extended Thinking across five task categories. Learn exactly when extended thinking is worth it—and when it's not.
API & SDK2026-04-12
Testing Claude API Applications — Unit, Integration, and E2E Patterns That Hold Up Against Probabilistic Output
Solve the 'AI output changed and broke my tests' problem for good. Learn to combine mocks, semantic assertions, and snapshot testing into a practical test design pattern for Claude API applications.
API & SDK2026-04-01
Building Production-Ready AI Apps with Claude API × Supabase — pgvector RAG, Realtime Sync & Row Level Security Integration Guide
Build production AI apps with Claude API and Supabase. Implement RAG with pgvector, multi-tenant RLS, and real-time streaming in one integrated architecture.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →