Documentation Index
Fetch the complete documentation index at: https://docs.muxx.dev/llms.txt
Use this file to discover all available pages before exploring further.
Tracing helps you understand the flow of operations in your LLM application by grouping related calls together.
Trace Hierarchy
Muxx uses a hierarchical tracing model:
Trace: "process-document"
|-- Span: "parse-document"
|-- Span: "extract-entities"
| |-- Generation: GPT-4o call
|-- Span: "summarize"
| |-- Generation: GPT-4o call
|-- Span: "format-output"
Creating Traces
With Decorators
from muxx import trace
@trace("my-operation")
def my_function():
# All LLM calls inside are grouped under this trace
pass
With Context Manager
from muxx import Muxx
muxx = Muxx()
with muxx.trace("my-operation"):
# All LLM calls inside are grouped under this trace
pass
Manual Trace Management
from muxx import Muxx
muxx = Muxx()
trace = muxx.start_trace("my-operation")
try:
# Your code here
pass
finally:
trace.end()
Creating Spans
Spans represent individual operations within a trace.
With Decorators
from muxx import trace, span
@trace("document-processing")
def process_document(doc: str):
@span("extraction")
def extract():
# LLM call for extraction
pass
@span("summarization")
def summarize(data):
# LLM call for summarization
pass
data = extract()
return summarize(data)
With Context Manager
from muxx import Muxx
muxx = Muxx()
with muxx.trace("document-processing"):
with muxx.span("extraction"):
# Extraction logic
pass
with muxx.span("summarization"):
# Summarization logic
pass
Nested Spans
Spans can be nested to represent sub-operations:
from muxx import trace, span
@trace("complex-operation")
def complex_operation():
@span("step-1")
def step_one():
@span("step-1a")
def sub_step():
# Nested operation
pass
sub_step()
step_one()
To Traces
@trace("user-request", metadata={
"user_id": "user_123",
"session_id": "sess_abc",
"feature": "chat"
})
def handle_request():
pass
To Spans
@span("llm-call", metadata={
"model": "gpt-4o",
"purpose": "summarization"
})
def make_llm_call():
pass
Trace Context
Access the current trace context:
from muxx import get_current_trace, get_current_span
@trace("my-trace")
def my_function():
current_trace = get_current_trace()
print(f"Trace ID: {current_trace.id}")
with span("my-span"):
current_span = get_current_span()
print(f"Span ID: {current_span.id}")
Async Tracing
Tracing works seamlessly with async code:
import asyncio
from muxx import trace, span
@trace("async-operation")
async def async_operation():
@span("async-step")
async def async_step():
await asyncio.sleep(1)
await async_step()
Best Practices
Name traces by user action
Use names like user-signup, document-upload, chat-message rather than technical names.
Each span should represent one logical operation. Don’t create spans that are too broad or too narrow.
Include user IDs, feature flags, and other context that helps with debugging and analytics.
Traces and spans automatically capture errors, but you can add additional context.