Effective trace structuring enhances the value of your tracing data, making it easier to debug, analyze, and optimize your LLM applications. This section covers the essential components of trace structuring in Laminar:
Without structure, each LLM call creates an isolated trace, making it difficult to:
Understand the relationships between different LLM calls
Track user journeys through your application
Debug complex multi-step workflows
Find relevant traces quickly
Properly structured traces provide a clear picture of your application’s flow, making it easier to identify bottlenecks, debug issues, and optimize performance.
Start by implementing the observe wrapper or decorator to create parent spans that group your LLM calls into meaningful traces. Then, enhance these traces with sessions, user IDs, and metadata to create a comprehensive tracing structure.
// Example: A well-structured trace implementationimport { Laminar, observe } from '@lmnr-ai/lmnr';// Initialize with your project keyLaminar.initialize({ projectApiKey: process.env.LMNR_PROJECT_API_KEY,});// Set up session and metadata for all traces in this requestLaminar.withSession({ sessionId: `session-${requestId}` }, () => { Laminar.withMetadata({ userId: user.id, environment: process.env.NODE_ENV }, async () => { // Create a parent span for the entire request await observe({ name: 'processUserRequest' }, async () => { // Your LLM calls and other operations will be grouped // under this parent span and inherit the session and metadata }); });});
// Example: A well-structured trace implementationimport { Laminar, observe } from '@lmnr-ai/lmnr';// Initialize with your project keyLaminar.initialize({ projectApiKey: process.env.LMNR_PROJECT_API_KEY,});// Set up session and metadata for all traces in this requestLaminar.withSession({ sessionId: `session-${requestId}` }, () => { Laminar.withMetadata({ userId: user.id, environment: process.env.NODE_ENV }, async () => { // Create a parent span for the entire request await observe({ name: 'processUserRequest' }, async () => { // Your LLM calls and other operations will be grouped // under this parent span and inherit the session and metadata }); });});
import osfrom lmnr import Laminar, observe# Initialize with your project keyLaminar.initialize( project_api_key=os.environ["LMNR_PROJECT_API_KEY"])@observe()def process_user_request(user_id, request_id): # Set session for this request Laminar.set_session(session_id=f"session-{request_id}") # Add metadata to all spans in this trace Laminar.set_metadata({ "userId": user_id, "environment": os.environ.get("ENVIRONMENT", "development") }) # Your LLM calls and other operations will be grouped # under this parent span and inherit the session and metadata # Process the request... # Optionally, clear session and metadata at the end # Laminar.clear_session() # Laminar.clear_metadata()# Example usageprocess_user_request(user_id="user_123", request_id="req_456")
Explore each component in detail through the links above to implement a comprehensive tracing structure for your LLM applications.