ObservabilityPython

Manual integration

In the previous section, we explored the quick integration of Maxim observability using decorators. However, there are scenarios where you might need finer control over your code's tracing. This section will guide you through the process of manually integrating Maxim observability into your codebase, providing you with more flexibility and granular control over your observability implementation.

Tracing one shot logs

Creating a trace
from maxim.logger import TraceConfig
 
trace = logger.trace(TraceConfig(id="trace-id",name="trace-name",tags={"key":"value"}))

Tracing multi-turn logs

Creating a session and adding a trace to it
from maxim.logger import SessionConfig, TraceConfig
 
session = logger.session(SessionConfig(id="session-id",name="session-name",tags={"key":"value"}))
trace = session.trace(TraceConfig(id="trace-id"))

Using custom ids for Traces/Sessions

Using custom ids allows you to fetch a trace in any function using the same id. This can be useful in updating trace across your workflow.

Trace

Using custom ids for Traces
from maxim.logger.components.trace import TraceConfig
# ... in function 1
trace = logger.trace(TraceConfig(id="trace-id"))
# ... in function 2
trace = logger.trace(TraceConfig(id="trace-id"))
# it returns the same trace object
trace.add_tag({"key":"value"})

Session

Using custom ids for Sessions
# ... in function 1
session = logger.session(SessionConfig(id="session-id"))
# ... in function 2
session = logger.trace(SessionConfig(id="session-id"))
# it returns the same session object
session.add_tag({"key":"value"})

Elements of Traces

Once you have a Trace object, you can add

Span

A Span (short for timespan), groups a bunch of items (Events, Retrieval, Generation, Feedback).

Adding a Span to a Trace
from maxim.logger import SpanConfig
 
span = trace.span(SpanConfig(id=str(uuid4()), name="Test Span"))
span.event("event-id","event-name")
span.end()

Event

An event is a point in time when something happened in the system.

Adding an Event to a Trace
trace.event("event-id", "event name", {})

Retrieval

A Retrieval is a special type of Span in Maxim, which represents a retrieval query to a knowledge base or vector database.

Adding a retrieval to a span
from maxim.logger import RetrievalConfig
 
retrieval = span.retrieval(RetrievalConfig(id="retrieval-id", name="Test Retrieval"))
retrieval.input("How many PTO days do I have?")
retrieval.output(["doc1", "doc2"])
retrieval.end()

Generation

A Generation is a special type of Span in Maxim, which represents a call to an LLM.

generation.result expects result to be in OpenAI response format. Here is the reference to the OpenAI response format

Adding a Generation to a Span
from maxim.logger import GenerationConfig
 
generationConfig = GenerationConfig(
					id=str(uuid4()),
					name="gen1",
					provider="openai",
					model="gpt-3.5-turbo-16k",
					model_parameters={"temperature": 3},
					messages=[{
						"role": "user",
						"content": "Hello, how can I help you today?"
					}])
generation = trace.generation(generationConfig)
generation.result({
	"id": "cmpl-uN1k3lnZkTlZg8GHt4Vtd1aB",
	"object": "text_completion",
	"created": 1718393286,
	"model": "gpt-3.5-turbo-16k",
	"choices": [
		{
			"index": 0,
			"text": "\n Here is the response\n",
			"logprobs": None,
			"finish_reason": "stop",
		},
	],
	"usage": {
		"prompt_tokens": 7,
		"completion_tokens": 105,
		"total_tokens": 112,
	},
})

Feedback

A Feedback is a special type of event in Maxim, which is a point in time when Feedback was given in the system.

Adding a Feedback to a Trace
from maxim.logger.components import Feedback
 
trace.feedback(feedback=Feedback(score=5, comment="Great job!"))

On this page