Decorators
Decorator-based instrumentation for automatic tracing of functions.
@agent_trace
Wrap a function in a Tracium agent trace. Creates a new trace for each function call.
from tracium import agent_trace
@agent_trace(
client: TraciumClient, # Required: Tracium client instance
agent_name: str, # Required: Name for the trace
model_id: str | None = None,
metadata: dict | None = None,
tags: list[str] | None = None,
trace_id: str | None = None,
inject_trace_arg: str | None = None, # Inject trace handle as kwarg
auto_tag: bool = True, # Auto-add @trace:func_name tag
)
def my_function():
passBasic Usage
1234567891011121314import traciumfrom tracium import agent_trace client = tracium.init() @agent_trace(client=client, agent_name="support-bot")def handle_support_request(request: str) -> str: """Each call to this function creates a new trace.""" context = retrieve_context(request) response = generate_response(context) return response # Create a trace automaticallyresult = handle_support_request("How do I reset my password?")Injecting Trace Handle
12345678910111213141516@agent_trace( client=client, agent_name="analyzer", inject_trace_arg="trace" # Inject as keyword argument)def analyze_data(data: dict, trace=None): """Access the trace handle inside the function.""" if trace: trace.add_tags(["analysis", f"data_size:{len(data)}"]) with trace.span(span_type="process", name="analyze") as span: span.record_input({"data": data}) result = do_analysis(data) span.record_output({"result": result}) return resultAsync Functions
@agent_trace(client=client, agent_name="async-agent")
async def async_handler(request: str) -> str:
"""Works with async functions automatically."""
result = await process_async(request)
return result@agent_span
Record a function as a span inside the current active trace.
from tracium import agent_span
@agent_span(
span_type: str, # Required: Type of span
name: str | None = None, # Defaults to function name
metadata: dict | None = None,
tags: list[str] | None = None,
inject_span_arg: str | None = None, # Inject span handle as kwarg
capture_return: bool = False, # Auto-capture return value as output
require_trace: bool = False, # Raise error if no active trace
auto_tag: bool = True, # Auto-add @span:name tag
)
def my_function():
passBasic Usage
123456789101112131415161718192021import traciumfrom tracium import agent_span client = tracium.init() @agent_span(span_type="retrieval")def fetch_documents(query: str) -> list: """Creates a span when called within an active trace.""" # Your retrieval logic return documents @agent_span(span_type="llm", name="generate_response")def generate(context: str) -> str: """Span is named 'generate_response' instead of 'generate'.""" # Your LLM logic return response # Use within a tracewith client.agent_trace(agent_name="rag-pipeline") as trace: docs = fetch_documents("query") # Creates 'retrieval' span result = generate(docs) # Creates 'llm' spanCapturing Return Values
@agent_span(
span_type="tool",
capture_return=True # Automatically record return as output
)
def lookup_user(user_id: str) -> dict:
"""Return value is automatically recorded as span output."""
return {"id": user_id, "name": "John", "email": "[email protected]"}Injecting Span Handle
1234567891011121314151617@agent_span( span_type="retrieval", inject_span_arg="span")def search_database(query: str, span=None) -> list: """Access the span handle for detailed recording.""" span.record_input({"query": query, "index": "main"}) results = db.search(query) span.record_output({ "count": len(results), "took_ms": results.took }) span.set_token_usage(input_tokens=len(query.split())) return resultsBehavior Outside Traces
123456789101112131415# By default, @agent_span runs the function normally if no trace is active@agent_span(span_type="tool")def my_function(): return "result" # This works even without a trace (no span is created)result = my_function() # To require an active trace:@agent_span(span_type="tool", require_trace=True)def must_be_traced(): return "result" # This raises RuntimeError if no trace is activemust_be_traced() # RuntimeError!Combining Decorators
Use @agent_trace at the entry point and @agent_span for internal functions:
12345678910111213141516171819202122232425262728293031323334import traciumfrom tracium import agent_trace, agent_span client = tracium.init() @agent_span(span_type="retrieval", capture_return=True)def get_context(query: str) -> dict: """Creates a span within the parent trace.""" return retrieve_relevant_docs(query) @agent_span(span_type="plan")def create_plan(context: dict, query: str) -> str: """Creates a planning span.""" return analyze_and_plan(context, query) @agent_span(span_type="llm", inject_span_arg="span")def generate_response(plan: str, span=None) -> str: """Creates an LLM span with custom recording.""" span.record_input({"plan": plan}) response = call_llm(plan) span.record_output({"response": response}) span.set_token_usage(input_tokens=100, output_tokens=200) return response @agent_trace(client=client, agent_name="qa-agent")def answer_question(question: str) -> str: """Entry point - creates the trace.""" context = get_context(question) plan = create_plan(context, question) answer = generate_response(plan) return answer # Run the pipeline - creates a trace with 3 nested spansresult = answer_question("What is machine learning?")Error Handling
Decorators are designed to be fail-safe. If tracing fails, your function runs normally:
# If the Tracium API is unavailable, the function still executes
@agent_trace(client=client, agent_name="resilient")
def important_function():
# This will always run, even if tracing fails
return critical_business_logic()
# Exceptions in your code are still raised
@agent_trace(client=client, agent_name="example")
def might_fail():
raise ValueError("Something went wrong")
# The trace is automatically marked as failed
# The exception propagates to your codeBest Practices
Use @agent_trace for Entry Points
Apply @agent_trace to the main entry point of your workflow (e.g., API handlers, main processing functions). This creates the parent trace.
Use @agent_span for Internal Functions
Apply @agent_span to functions called within your workflow. These create child spans within the parent trace.
Keep Span Types Consistent
Use consistent span_type values across your codebase: llm, retrieval, tool, plan, action, etc.
Inject Handles for Complex Logic
Use inject_span_arg when you need to record detailed inputs/outputs or token usage within the function.