Skip to main content

Trace your AI agent's LLM calls with one line of code

Project description

spantree

Trace your AI agent's LLM calls with one line of code.

PyPI License: MIT Python 3.9+

Install

pip install spantree-sdk

Quick Start

from spantree import observe
from anthropic import Anthropic

client = observe(Anthropic())

# All calls are now automatically traced
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=1024,
)

That's it. Every LLM call is captured — model, tokens, latency, input/output — and sent to the Spantree dashboard in the background with zero latency impact.

Grouping Calls with trace()

By default, each LLM call creates its own trace. Use trace() to group multiple calls under a single trace — ideal for agent loops, multi-step workflows, and tool-use patterns.

from spantree import observe, trace
from anthropic import Anthropic

client = observe(Anthropic())

with trace("chat-session"):
    messages = []
    while True:
        messages.append({"role": "user", "content": input("> ")})
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            messages=messages,
            max_tokens=1024,
        )
        messages.append({"role": "assistant", "content": response.content[0].text})

All LLM calls inside the with trace(...) block share the same trace_id and appear as spans within a single trace in the dashboard.

Tool use

with trace("agent-task"):
    response = client.messages.create(...)   # span 1
    tool_result = run_tool(response)          # not traced (your code)
    response = client.messages.create(...)   # span 2, same trace

Multi-agent

with trace("research-pipeline"):
    plan = orchestrator.messages.create(...)      # span 1
    research = researcher.messages.create(...)    # span 2
    final = orchestrator.messages.create(...)     # span 3

Nested traces

with trace("pipeline") as t:
    print(t.trace_id)  # access the trace ID
    response = client.messages.create(...)       # child of "pipeline"

    with trace("sub-agent"):
        response = client.messages.create(...)   # child of "sub-agent"

    response = client.messages.create(...)       # child of "pipeline"

Without trace() — unchanged behavior

client = observe(Anthropic())
response = client.messages.create(...)  # trace A
response = client.messages.create(...)  # trace B (independent)

Custom Metadata

Attach arbitrary key-value data to spans for filtering and analysis in the dashboard.

Global metadata (all spans from a client)

client = observe(Anthropic(), metadata={"user_id": "u_123", "env": "prod"})

response = client.messages.create(...)  # span gets {"user_id": "u_123", "env": "prod"}

Per-call metadata

client = observe(Anthropic(), metadata={"user_id": "u_123"})

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=1024,
    spantree_metadata={"session_id": "sess_abc", "feature_flag": "new-flow"},
)
# span gets {"user_id": "u_123", "session_id": "sess_abc", "feature_flag": "new-flow"}

Per-call metadata merges with global metadata. Per-call values win on key conflicts.

On trace spans

with trace("my-workflow") as t:
    t.metadata = {"pipeline": "v2", "run_id": "run_xyz"}
    response = client.messages.create(...)

Configuration

Set your API key via environment variable:

export SPANTREE_API_KEY=sk_your_key_here

Or configure programmatically:

from spantree import configure

configure(
    api_key="sk_your_key_here",
    base_url="https://api.spantree.dev",
)

Supported Providers

Provider Wrapper What's traced
Anthropic observe(Anthropic()) messages.create()
OpenAI observe(OpenAI()) chat.completions.create()

How It Works

  1. observe() detects your LLM client type
  2. Wraps API methods to capture timing, tokens, and I/O
  3. Buffers spans in a background thread (zero latency impact)
  4. Flushes batches to the Spantree API every 5s or 100 spans

No monkey-patching. No import hooks. Just a thin wrapper around your existing client.

Requirements

  • Python 3.9+
  • Only runtime dependency: httpx

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

# Clone and install dev dependencies
git clone https://github.com/spantree-io/spantree-python.git
cd spantree-python
pip install -e ".[dev]"

# Run tests
pytest

# Lint
ruff check .

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spantree_sdk-0.1.0.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spantree_sdk-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file spantree_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: spantree_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for spantree_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e1c09311ac432bfa3e804a0ed37e1b68a224b0c3204b51be63c7fad2ba9b9752
MD5 f83dc32f1197786898ab989cce40ea19
BLAKE2b-256 4332d89741f64c699c90be7cce42ff93707418ed2eedf8255d05e791fe0e46e5

See more details on using hashes here.

File details

Details for the file spantree_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: spantree_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for spantree_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 16486aaea04bcb873e4344ecc96bf32a938d32b3cdde96c2c08c0309b22e3221
MD5 139ee47bf858095667f4174245e5eb1e
BLAKE2b-256 e130a4c34a67bbb73785b4f50d8fce4d06dc2cb51ea8251349a6ed080f794fbe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page