Traces in Galileo are collections of related Spans that represent complete interactions or workflows in your AI application. They provide a holistic view of how your application processes requests, from initial input to final output, capturing all the intermediate steps along the way.A trace is essentially a record of a complete user interaction or system process, showing the full journey of data through your application. Traces organize individual spans (discrete operations like LLM calls, retrievals, or tool executions) into a coherent, hierarchical structure that makes it easy to understand the flow and relationships between different parts of your application.
Traces are foundational to effective AI system monitoring and optimization for several reasons:
Context Preservation: Traces maintain the relationship between different operations, preserving the context that might be lost when looking at individual spans in isolation.
Causal Analysis: They enable causal analysis by showing the sequence of events that led to a particular outcome.
System-Level Insights: Traces provide insights at the system level, helping you understand how different components interact.
Debugging Efficiency: When debugging issues, traces reduce the time needed to understand what happened by providing a complete picture of the interaction.
Optimization Opportunities: By analyzing traces, you can identify opportunities to optimize your AI workflows for better performance and resource utilization.
from galileo import GalileoLogger# Initialize the loggerlogger = GalileoLogger(project="my-project", log_stream="my-log-stream")# Start a new tracetrace = logger.start_trace(input="What's the weather in San Francisco?")# Add spans to the tracellm_span = logger.add_llm_span( input="What's the weather in San Francisco?", output="The weather in San Francisco is currently sunny with a temperature of 72°F.", model="gpt-4o", temperature=0.7)# Conclude the tracelogger.conclude(output="The weather in San Francisco is currently sunny with a temperature of 72°F.")# Flush the trace to Galileologger.flush()
import osfrom galileo import galileo_contextfrom galileo.openai import openai# Initialize the OpenAI client using the Galileo wrapper and your OpenAI API keyclient = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))with galileo_context(): response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "What is the capital of France?"}] ) print(response.choices[0].message.content)
from galileo import log, galileo_context@logdef process_query(query): # Your processing logic here return result# This will create a trace for the function call with a workflow span representing the `process_query` functionwith galileo_context(): result = process_query("What is the capital of France?")
When working with traces, follow these best practices:
Trace Granularity: Create traces at an appropriate level of granularity - too fine-grained and you’ll have too many traces to manage, too coarse-grained and you’ll miss important details.
Meaningful Span Names: Use descriptive names for spans to make traces easier to understand.
Include Relevant Metadata: Add tags and metadata that will be useful for filtering and analysis.
Handle Errors Gracefully: Log errors in spans to help with debugging and analysis.
Flush Traces Appropriately: In long-running applications, flush traces at appropriate points to ensure data is sent to Galileo.
from galileo import GalileoLoggerlogger = GalileoLogger()# Start a tracetrace = logger.start_trace(input="Tell me a joke about programming")# Add an LLM spanlogger.add_llm_span( input="Tell me a joke about programming", output="Why do programmers prefer dark mode? Because light attracts bugs!", model="gpt-4o", temperature=0.7)# Conclude the tracelogger.conclude(output="Why do programmers prefer dark mode? Because light attracts bugs!")# Flush the trace to Galileologger.flush()
from galileo import GalileoLoggerlogger = GalileoLogger()# Start a trace for a RAG applicationtrace = logger.start_trace(input="What were the major causes of World War I?")# Start a workflow span for the retrieval processretrieval_workflow = logger.start_workflow_span(name="Document Retrieval")# Add a retriever span for the querylogger.add_retriever_span( input="What were the major causes of World War I?", documents=[ {"content": "The assassination of Archduke Franz Ferdinand...", "metadata": {"source": "history.txt"}}, {"content": "Militarism, alliances, imperialism, and nationalism...", "metadata": {"source": "causes.txt"}} ])# End the retrieval workflowlogger.end_workflow_span(retrieval_workflow, output="Retrieved 2 documents")# Add an LLM span for generating the responselogger.add_llm_span( input="Based on these documents, what were the major causes of World War I? Documents: [...]", output="The major causes of World War I included the assassination of Archduke Franz Ferdinand, militarism, alliances, imperialism, and nationalism...", model="gpt-4o", temperature=0.3)# Conclude the tracelogger.conclude(output="The major causes of World War I included...")# Flush the trace to Galileologger.flush()
from galileo import GalileoLoggerlogger = GalileoLogger()def process_chat_message(user_id, message, conversation_history): # Start a trace for this chat interaction trace = logger.start_trace( input=message, tags=["chat"], metadata={"user_id": user_id, "conversation_length": len(conversation_history)} ) try: # Add an LLM span for generating the response prompt = f"Conversation history: {conversation_history}\nUser: {message}\nAssistant:" logger.add_llm_span( input=prompt, output="I'd be happy to help with that...", model="gpt-4o", temperature=0.7 ) # Conclude the trace response = "I'd be happy to help with that..." logger.conclude(output=response) return response except Exception as e: # Log the error logger.add_tool_span( name="Error Handler", input=message, error=str(e) ) logger.conclude(error=str(e)) raise finally: # Flush the trace to Galileo logger.flush()