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.
import traciumfrom tracium import agent_trace
client = tracium.trace()
@agent_trace( client=client, # Required agent_name="support-bot", # Required model_id=None, metadata=None, tags=None, trace_id=None, inject_trace_arg=None, # Inject trace handle as kwarg auto_tag=True, # Auto-add @trace:func_name tag)def my_function(): passBasic Usage
1234567891011121314import traciumfrom tracium import agent_trace
client = tracium.trace()
@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.
import traciumfrom tracium import agent_span
tracium.trace()
@agent_span( span_type="retrieval", # Required name=None, # Defaults to function name metadata=None, tags=None, inject_span_arg=None, # Inject span handle as kwarg capture_return=False, # Auto-capture return value as output require_trace=False, # Raise error if no active trace auto_tag=True, # Auto-add @span:name tag)def my_function(): passBasic Usage
123456789101112131415161718192021import traciumfrom tracium import agent_span
client = tracium.trace()
@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."""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.