Transparent agentic telemetry and instrumentation for content-addressable LLM interactions.
About
·
Download
·
Documentation
·
Contributing
tapes is an Agentic telemetry system for content-addressable LLM interactions.
It provides durable storage of agent sessions, plug-and-play OpenTelemetry instrumentation,
and a derived sessions/traces/spans model for querying and exporting past agent work.
Capture is append-only: every intercepted LLM interaction is persisted to an
immutable raw_turns log. A pure, idempotent deriver projects that log into
the read model — sessions → traces → spans (with span links) — and re-running
the deriver simply reproduces the same projection (re-derive prunes anything no
longer present down to 0). Derived IDs are deterministic, so the same raw input
always yields the same sessions, traces, and spans.
Reads happen over that derived surface: list and inspect sessions
(/v1/sessions, cursor-paginated, with model/token/cost/turn-count folds),
browse traces and spans (/v1/traces, /v1/sessions/{id}/traces), aggregate at
span grain (/v1/stats), and run span-grain semantic search (/v1/search/spans).
The original capture is always available verbatim via
/v1/sessions/{id}/raw_turns.
Content addressing (the merkle node layer) is retained internally for provenance and dedup; it is not a user-facing browsing surface.
Install tapes:
curl -fsSL https://download.tapes.dev/install | bashtapes stores sessions in PostgreSQL (with the pgvector extension) and uses an
embedding provider to power tapes search. The quickest way to get a local
Postgres — plus Ollama for embeddings — is the bundled Docker bootstrap (requires Docker):
tapes local uptapes local up pulls the default embeddinggemma model and writes the
Postgres + Ollama connection settings into your .tapes config, so the
commands below need no connection flags.
Then start Tapes. tapes serve runs the whole local pipeline together — the
proxy (capture), the API, and the derive worker (which projects captured turns
into sessions/traces/spans) — so anything you capture becomes browsable
automatically. It also embeds spans for tapes search by default (disable with
--embed-spans=false):
tapes servePrefer OpenAI embeddings? Store an API key and switch the embedding provider
(tapes local up still provides the required Postgres; Ollama just goes unused):
tapes auth openai
tapes config set embedding.provider openai
tapes serveYou can also provide the key with OPENAI_API_KEY instead of tapes auth openai.
When OpenAI is selected without a key, Tapes fails at startup with an authentication
configuration error from the OpenAI embedder.
Start with demo data so every command below has something to show — this path works end to end before you wire up a real agent:
tapes seed --demoList captured sessions and their ids:
tapes sessionsBrowse sessions and drill into a single session in the deck TUI:
tapes deckExport a captured session as JSONL — the API's session→traces→spans projection
verbatim. tapes export is a thin client of GET /v1/sessions/{id}/export, so
it needs a running API (pass --api-target, or start one with tapes serve).
The full span tree is included by default; pass --detail traces for turn
headers only. Pass a full session id or its short prefix:
tapes export <session-id> --api-target http://127.0.0.1:8081 -o session.jsonl
tapes export <session-id> --detail tracesSearch across captured spans (individual main-conversation LLM spans, with
their trace and turn context). tapes serve embeds spans by default, so this
works out of the box:
tapes search "explain the retry logic"Ready for the real thing? Clear the demo data and point your own agent at the proxy:
tapes local down --wipe && tapes local up # recreate the DB, clearing the demo
tapes start claude # or send any client at http://localhost:8080tapes start launches the agent wired to the proxy and tags the session. See
the agent guides for Claude Code, OpenCode, and more.
