All documentation

Instrument / guide 03

Python SDK

Instrument Python agents with a decorator and nested spans.

Copy or share.

Python SDK

Use the Python SDK for agents built with plain functions, async code, or frameworks like LangGraph. It works with sync and async functions, and concurrent runs in threads or asyncio tasks stay in separate traces.

Install and configure

bash
pip install tracify-sdk

Set TRACIFY_API_KEY in the environment where your agent runs. Configure the rest on the decorator:

python
from tracify import trace_agent

@trace_agent(name="support-agent", environment="production", release="2026-10-15")
def answer(question: str):
    return llm.complete(question, context=search_docs(question))

The decorator accepts client, name, environment, release, deployment_id, session_id, end_user_id and tags. Use session and user fields when those dimensions matter to debugging, for example to find every run for one customer.

Each call of the decorated function is one trace. A key belongs to one region, EU or US, and the client refuses a mismatched configuration instead of sending data to the wrong place.

Record steps with span and observe

Use span for a block of work and observe for a function. Steps started inside another step become its children.

python
import tracify

@tracify.observe(type="tool")
def search_docs(query):
    return search(query)

@tracify.trace_agent()
def answer(question):
    for turn in range(5):
        with tracify.span("think", type="agent"):
            with tracify.span("chat", type="llm", input=question) as step:
                reply = call_model(question)
                step.set_output(reply.text)
                step.set(
                    model="your-model-id",
                    input_tokens=reply.usage.input,
                    output_tokens=reply.usage.output,
                )
            if reply.done:
                return reply.text
            search_docs(reply.query)

type is one of agent, llm, tool, retrieval or span. Exceptions are recorded with their type and message and then raised again. observe also accepts name, capture_input=False and capture_output=False when arguments or results should stay out of the trace.

Record finished calls directly

python
from tracify import llm_call, tool_call

llm_call(
    input_data=question,
    output_data=reply.text,
    model_id="your-model-id",
    cost_usd=0.002,
    latency_ms=800,
    input_tokens=reply.usage.input,
    output_tokens=reply.usage.output,
)

tool_call(
    tool_name="web_search",
    input_data={"q": question},
    output_data=results,
    latency_ms=1200,
)

Wrap provider clients

tracify.wrap_openai, tracify.wrap_anthropic and tracify.langgraph_callback() record provider calls without changing your code. See OpenAI, Anthropic and LangGraph.

What the SDK sends

Inputs and outputs have obvious secrets removed and are capped at 10,000 characters. Do not record anything you would not want stored. Delivery problems never interrupt your agent.

Feedback, scores and prompts

Create a TracifyClient with project_id to attach feedback and scores. See Feedback and scores. To resolve a deployed prompt, see Prompt deployment.