Tracing
Learn how to use the @trace and @span decorators to instrument your AI agents and capture the full execution flow.
The @trace Decorator
The @trace decorator creates a new trace for each function invocation. Use it on your top-level agent functions:
from mindreef import trace
@trace
async def customer_support_agent(message: str) -> str:
"""Handle a customer support request."""
# Your agent logic here
return response
Trace Options
Customize trace behavior with options:
@trace(
name="support-agent", # Custom trace name
capture_input=True, # Log function inputs
capture_output=True, # Log function outputs
tags={"team": "support"} # Custom tags
)
async def customer_support_agent(message: str) -> str:
...
The @span Decorator
The @span decorator creates child spans within an existing trace. Use it for operations you want to track separately:
from mindreef import trace, span
@trace
async def research_agent(query: str):
# Each of these creates a child span
context = await search_knowledge_base(query)
analysis = await analyze_results(context)
response = await generate_response(analysis)
return response
@span(name="search", span_type="retrieval")
async def search_knowledge_base(query: str):
# Search logic here
...
@span(name="analyze")
async def analyze_results(context: str):
# Analysis logic here
...
@span(name="generate", span_type="llm")
async def generate_response(analysis: str):
# LLM call here
...
Manual Span Creation
For more control, create spans manually using the context manager:
from mindreef import trace, Span
@trace
async def complex_agent(query: str):
with Span(name="preprocessing") as span:
span.set_attribute("query_length", len(query))
processed = preprocess(query)
with Span(name="main_logic") as span:
result = await process(processed)
span.set_attribute("result_type", type(result).__name__)
return result
Adding Attributes
Add custom attributes to spans for richer debugging:
from mindreef import get_current_span
def process_order(order_id: str):
span = get_current_span()
span.set_attribute("order_id", order_id)
span.set_attribute("order_value", 99.99)
# Process the order...
Recording Events
Log discrete events within a span:
from mindreef import get_current_span
def handle_request(request):
span = get_current_span()
# Log an event
span.add_event("validation_complete", {
"valid": True,
"checks_passed": 5
})
# Process request...
Error Handling
Exceptions are automatically captured and associated with the current span:
@trace
async def risky_agent(query: str):
try:
result = await process(query)
return result
except Exception as e:
# Error is automatically recorded on the span
raise # Re-raise to preserve stack trace
Async Support
Both @trace and @span work seamlessly with async functions:
@trace
async def async_agent(queries: list[str]):
# Parallel execution - each task gets its own span
tasks = [process_query(q) for q in queries]
results = await asyncio.gather(*tasks)
return results
@span
async def process_query(query: str):
# This span is correctly parented to the trace
...