Open source · v0.1.0

Deterministic tests for LLM apps and agents.

retake records the OpenAI, Claude and other LLM API calls your code makes, then replays them in every test run — offline, in milliseconds, byte-for-byte the same. Built for AI agents, tool calling and streaming. One binary. Any language. No code changes.

curl -fsSL https://zecrari.github.io/retake/install.sh | sh

Windows: irm https://zecrari.github.io/retake/install.ps1 | iex · or download a binary

$ retake record -- npm test
● recorded POST /anthropic/v1/messages → 200
● recorded POST /anthropic/v1/messages → 200
  ✓ agent looks up the order (2.8s)
retake: 0 replayed, 2 recorded

$ retake replay -- npm test
  ✓ agent looks up the order (31ms)
retake: 2 replayed, 0 recorded, 0 unmatched

# someone edits the prompt…
$ retake replay -- npm test
no recording matches POST /anthropic/v1/messages
closest: step 1
-  "content": "What is the status of order 1042?"
+  "content": "Where is order 1042?"

Works with

OpenAIAnthropic ClaudeOllamavLLMOpenRouterGroq PythonTypeScriptGoJava.NETRust GitHub Actions

The problem

Testing code that calls an LLM is painful.

Real API calls make every test run slow, costly and different. Hand-written mocks drift from reality and fall apart as soon as an agent makes more than one call.

Flaky

The same prompt returns a different answer on every run, so assertions fail at random and nobody trusts the suite.

Expensive

Every push, every branch and every retry burns real tokens — and CI needs a production API key to run at all.

Slow

Seconds per call add up to minutes per suite. Agents that loop through tools make it far worse.

1 binaryNo Python, Node or Docker
0 code changesStandard base-URL variables
$0 per CI runReplays never reach the API
5 platformsLinux, macOS, Windows · x64 & Arm

How it works

Record once. Replay forever.

retake is a tiny local proxy between your code and the API. It points your SDK at itself through standard environment variables — no plugins, no wrappers, no code changes.

Record a real run

Run your tests through retake with a real key. Every call is forwarded and saved as a readable JSON cassette.

retake record -- pytest

Commit the cassettes

Secrets are stripped automatically. Prompt and response changes show up in pull request diffs.

git add cassettes/

Replay everywhere

Locally and in CI, calls are served from cassettes. Nothing reaches the network, and no key is needed.

retake replay -- pytest

Any language

Works with the SDK you already use.

Because retake speaks plain HTTP, it works the same from Python, TypeScript, Go, Java, .NET, Ruby, Rust or curl. The official OpenAI and Anthropic SDKs read OPENAI_BASE_URL and ANTHROPIC_BASE_URL automatically.

Want one cassette per test? Send an x-retake-session header — that's the only line you'll ever add.

from openai import OpenAI

# Base URL comes from retake. Nothing else changes.
client = OpenAI(default_headers={
  "x-retake-session": "checkout/refund-flow",
})

reply = client.chat.completions.create(
  model="gpt-4.1-mini",
  messages=[{"role": "user", "content": "Refund order 1042"}],
)

Features

Small tool. Sharp edges filed off.

Everything you need to trust LLM tests in CI, and nothing you don't.

Byte-identical streaming

Server-sent events are stored as whole events and replayed exactly. Add --timing realtime to reproduce the original pacing.

Built for agents

Repeated identical calls replay in recorded order; parallel calls match independently. Tool-calling loops just work.

Diffs, not mysteries

An unrecorded call fails with a clear 404 and a diff against the closest recording — never a silent real call or a retried 5xx.

Safe to commit

Request headers are never stored, and keys and tokens in bodies are redacted. retake check guards your repo in CI.

Smart matching

JSON is compared after sorting keys, so formatting never matters. --ignore skips fields like request IDs.

Single static binary

Written in Rust. No Python, Node or Docker required. Prebuilt for Linux, macOS and Windows.

Compared

Mocks, live calls, or a recording?

Recordings give you real model output with the speed and determinism of a mock.

Live API callsHand-written mocksretake
Real model behaviorYesNo — inventedYes — recorded
DeterministicNoYesYes
Cost per CI runTokens every timeFreeFree
SpeedSeconds per callInstantInstant
Works offline / without a keyNoYesYes
Effort for a multi-step agentNoneHigh, and it driftsOne record run

Use cases

Everything that calls a model, under test.

From a single prompt to a 30-step agent: if it speaks HTTP to an LLM API, retake can record it.

AI agent regression tests

Record a full agent run — every tool call and tool result — and replay the exact trajectory. A changed prompt shows up as a diff, not a mystery.

Tool calling & structured outputs

Lock down function-calling and JSON-schema responses so parsers, validators and downstream code are tested against real model output.

RAG pipelines

Replay embeddings and completions together, so retrieval and generation are tested end to end without paying for either.

Prompt changes in code review

Cassettes are readable JSON. Re-record after a prompt change and reviewers see the prompt diff and the new model output side by side.

A fast evals inner loop

Iterate on scoring and post-processing against recorded outputs in milliseconds, and re-record only when you change the model or prompt.

Offline development & demos

Run your app on a plane, in air-gapped CI, or in a live demo where the network can't be trusted — with real responses.

FAQ

Questions, answered.

What is retake?

retake is a free, open-source record and replay proxy for LLM APIs — a “VCR for LLMs”. It records real OpenAI, Anthropic or OpenAI-compatible API calls once, saves them as readable cassette files, and replays them in later test runs so tests are fast, free, offline and deterministic.

Do I need to change my code?

No. retake sets OPENAI_BASE_URL and ANTHROPIC_BASE_URL for the command it runs, and the official SDKs read those variables automatically. Optionally, send an x-retake-session header to use one cassette per test.

Which languages and providers are supported?

Any language, because retake is an HTTP proxy. OpenAI and Anthropic work out of the box, and any OpenAI-compatible API — Ollama, vLLM, LM Studio, Groq, OpenRouter, Azure OpenAI — can be added with --upstream name=url.

Does it support streaming responses?

Yes. Server-sent event streams are stored as whole events and replayed byte-for-byte. Replays are instant by default; --timing realtime reproduces the original pacing when you need to test timeouts or streaming UI.

Is it safe to commit cassettes to git?

retake never stores request headers, so keys sent in headers can't reach a cassette, and it redacts anything in bodies that looks like an API key, token or private key. Run retake check in CI or as a pre-commit hook to catch anything else, and review cassettes for personal data before committing.

What happens when a prompt changes?

In replay mode the request no longer matches, so retake fails it with a 404 and prints a diff against the closest recording. Re-record with retake record, or use retake auto to record only the new calls.

How do I test AI agents with retake?

Run the agent's test once with retake record. Every model call is saved in order, including tool calls. On replay, the first response is identical, so your agent sends the same follow-up requests, which match the recording too — the whole trajectory replays deterministically. Keep your tools deterministic in tests (fixed clocks, seeded data) or ignore volatile fields with --ignore.

Is retake an evals framework?

No. Evals measure how good model output is; retake makes tests repeatable by replaying recorded output. They work well together: replay recorded outputs to iterate on your scoring code quickly, and re-record when you change the model or prompt.

Is retake free?

Yes — free and open source under the MIT license.

Make your LLM tests boring again.

Install in seconds, record once, and never pay for a flaky test run again.