Skip to main content
The Tracer captures your agent’s inputs, outputs, latency, and tool calls — with a single decorator or context manager. Traces appear in the Live Traces tab and can be evaluated against your test datasets.

Decorator

The simplest usage. AgentX captures function arguments as input, the return value as output, and wall-clock time as latencyMs.
from agentx import AgentX

client = AgentX.from_env()
tracer = client.tracer

@tracer.trace("customer-support-agent", framework="langchain", model="gpt-4o")
def handle(query: str) -> str:
    return chain.invoke(query)

handle("How do I reset my password?")
Works with async functions too:
@tracer.trace("async-agent", framework="openai-agents")
async def handle_async(query: str) -> str:
    result = await runner.run(agent, query)
    return result.final_output

Context manager

Use when you need to set input/output manually or record tool calls mid-span.
with tracer.trace("rag-agent", framework="langchain") as span:
    span.input = {"query": query, "user_id": user_id}

    kb_result = search_knowledge_base(query)
    span.add_tool_call("search_knowledge_base", input=query, output=kb_result, latency_ms=190)

    answer = llm.invoke(f"Context: {kb_result}\n\nQuery: {query}")
    span.output = answer

_TraceSpan attributes and methods

NameDescription
span.input = valueOverride the captured input
span.output = valueSet the output (required in context manager mode)
span.add_tool_call(name, *, input, output, latency_ms)Record a tool call made during this span
span.set_error(message)Mark the span as failed with a custom error message

tracer.trace() parameters

ParameterTypeDescription
namestrAgent or operation label shown in the UI
frameworkstr"langchain", "crewai", "openai-agents", "anthropic", or custom
modelstrLLM model used, e.g. "gpt-4o", "claude-sonnet-4-6"
session_idstrGroups traces from the same user session or thread
metadatadictArbitrary key-value metadata (not indexed, max 16 KB)

Framework examples

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from agentx import AgentX

client = AgentX.from_env()

llm = ChatOpenAI(model="gpt-4o")

@client.tracer.trace("support-agent", framework="langchain", model="gpt-4o")
def handle(query: str) -> str:
    return llm.invoke([HumanMessage(content=query)]).content

handle("How do I reset my password?")
client.tracer.flush(timeout=10)

Session grouping

Use session_id to link traces from the same user conversation:
import uuid

session_id = str(uuid.uuid4())

@tracer.trace("support-agent", session_id=session_id)
def handle(query: str) -> str:
    ...

handle("First question")
handle("Follow-up question")
# Both traces appear linked in the UI

Error handling

Exceptions inside a traced function are captured as the error field and re-raised — the trace is still submitted:
@tracer.trace("my-agent")
def risky(query: str) -> str:
    raise ValueError("Model unavailable")

try:
    risky("test")
except ValueError:
    pass
# Trace submitted with error: "Model unavailable"
To set an error manually in context manager mode:
with tracer.trace("my-agent") as span:
    try:
        result = call_agent(query)
        span.output = result
    except Exception as e:
        span.set_error(str(e))
        raise

Flushing

Traces are sent in a background thread. Call flush() before process exit in scripts:
tracer.flush(timeout=5.0)

Evaluating a trace

Score a previously recorded trace against a dataset without re-running the agent:
result = tracer.evaluate_trace(
    trace_id="6876abc123def456789abc01",
    dataset_id="6876ddd222bbb333ccc444ee",
    question_index=0,
)

print(result["rating"])        # 1–5
print(result["justification"]) # LLM explanation

Limits

LimitValue
Traces per minute per API key300
Max tool calls per trace50
Max input / output size1 MB each
Max metadata size16 KB