Using context to customize spans#
In order to customize spans that are created via auto-instrumentation, The Otel Context can be used to set span attributes created during a block of code (think child spans or spans under that block of code). Our openinference packages offer convenient tools to write and read from the OTel Context. Phoenix re-exports those helpers directly from arize-phoenix-otel (Python, >=0.16.0) and @arizeai/phoenix-otel (TypeScript), so you can register tracing and manage context attributes from the same package. The benefit of this approach is that OpenInference auto instrumentors will pass (e.g. inherit) these attributes to all spans underneath a parent trace.
Supported Context Attributes include:
-
Session ID* Unique identifier for a session
-
User ID* Unique identifier for a user.
-
Metadata Metadata associated with a span.
-
Tags* List of tags to give the span a category.
-
Prompt Template
-
Template Used to generate prompts as Python f-strings.
-
Version The version of the prompt template.
-
Variables key-value pairs applied to the prompt template.
-
Install Phoenix OTEL#
Requires arize-phoenix-otel 0.16.0 or later to import the context managers directly from phoenix.otel. On older versions, import them from openinference.instrumentation instead.
Phoenix does not ship a phoenix-otel-go wrapper. Use the OpenInference Go instrumentation package directly to store context attributes on context.Context. See Go integrations for tracer-provider setup.
Specifying a session#
We provide a using_session context manager to add session a ID to the current OpenTelemetry Context. OpenInference auto instrumentators will read this Context and pass the session ID as a span attribute, following the OpenInference semantic conventions. Its input, the session ID, must be a non-empty string.
It can also be used as a decorator:
We provide a setSession function which allows you to set a sessionId on context. You can use this utility in conjunction with context.with to set the active context. OpenInference auto instrumentations will then pick up these attributes and add them to any spans created within the context.with callback.
Use instrumentation.WithSession to attach a session ID to the context. OpenInference Go auto-instrumentors (OpenAI Go, Anthropic Go) automatically read this from context.Context and add session.id to every LLM span descended from it.
Specifying users#
We provide a using_user context manager to add user ID to the current OpenTelemetry Context. OpenInference auto instrumentators will read this Context and pass the user ID as a span attribute, following the OpenInference semantic conventions. Its input, the user ID, must be a non-empty string.
It can also be used as a decorator:
We provide a setUser function which allows you to set a userId on context. You can use this utility in conjunction with context.with to set the active context. OpenInference auto instrumentations will then pick up these attributes and add them to any spans created within the context.with callback.
Use instrumentation.WithUser to attach a user ID to the context. OpenInference Go auto-instrumentors automatically read this from context.Context and add user.id to every LLM span descended from it.
Specifying Metadata#
We provide a using_metadata context manager to add metadata to the current OpenTelemetry Context. OpenInference auto instrumentators will read this Context and pass the metadata as a span attribute, following the OpenInference semantic conventions. Its input, the metadata, must be a dictionary with string keys. This dictionary will be serialized to JSON when saved to the OTEL Context and remain a JSON string when sent as a span attribute.
It can also be used as a decorator:
We provide a setMetadata function which allows you to set a metadata attributes on context. You can use this utility in conjunction with context.with to set the active context. OpenInference auto instrumentations will then pick up these attributes and add them to any spans created within the context.with callback. Metadata attributes will be serialized to a JSON string when stored on context and will be propagated to spans in the same way.
Use instrumentation.WithMetadata to attach a JSON-encoded metadata string to the context. OpenInference Go auto-instrumentors automatically read this from context.Context and add metadata to every LLM span descended from it.
Specifying Tags#
We provide a using_tags context manager to add tags to the current OpenTelemetry Context. OpenInference auto instrumentators will read this Context and pass the tags as a span attribute, following the OpenInference semantic conventions. The input, the tag list, must be a list of strings.
It can also be used as a decorator:
We provide a setTags function which allows you to set a list of string tags on context. You can use this utility in conjunction with context.with to set the active context. OpenInference auto instrumentations will then pick up these attributes and add them to any spans created within the context.with callback. Tags, like metadata, will be serialized to a JSON string when stored on context and will be propagated to spans in the same way.
Use instrumentation.WithTags (variadic strings) to attach a list of tags to the context. OpenInference Go auto-instrumentors automatically read this from context.Context and add tag.tags to every LLM span descended from it.
Customizing Attributes#
We provide a using_attributes context manager to add attributes to the current OpenTelemetry Context. OpenInference auto instrumentators will read this Context and pass the attributes fields as span attributes, following the OpenInference semantic conventions. This is a convenient context manager to use if you find yourself using many of the previous ones in conjunction.
The previous example is equivalent to doing the following, making using_attributes a very convenient tool for the more complex settings.
It can also be used as a decorator:
We provide a setAttributes function which allows you to add a set of attributes to context. You can use this utility in conjunction with context.with to set the active context. OpenInference auto instrumentations will then pick up these attributes and add them to any spans created within the context.with callback. Attributes set on context using setAttributes must be valid span attribute values.
You can also use multiple setters at the same time to propagate multiple attributes to the span below. Since each setter function returns a new context, they can be used together as follows.
You can also use setAttributes in conjunction with the OpenInference Semantic Conventions to set OpenInference attributes manually.
Go has no single-shot equivalent of using_attributes — compose the With* helpers instead. Each returns a new context; chain them to attach session, user, metadata, and tags together. Auto-instrumentors pick up all four from context.Context.
For prompt-template attributes (llm.prompt_template.*), set them directly on the LLM span using semconv.LLMPromptTemplate / LLMPromptTemplateVersion / LLMPromptTemplateVariables from github.com/Arize-ai/openinference/go/openinference-semantic-conventions — see Prompt Templates.
Span Processing#
The tutorials and code snippets in these docs default to the SimpleSpanProcessor. A SimpleSpanProcessor processes and exports spans as they are created. This means that if you create 5 spans, each will be processed and exported before the next span is created in code. This can be helpful in scenarios where you do not want to risk losing a batch, or if you’re experimenting with OpenTelemetry in development. However, it also comes with potentially significant overhead, especially if spans are being exported over a network - each time a call to create a span is made, it would be processed and sent over a network before your app’s execution could continue.
The BatchSpanProcessor processes spans in batches before they are exported. This is usually the right processor to use for an application in production but it does mean spans may take some time to show up in Phoenix.
In production we recommend the BatchSpanProcessor over SimpleSpanProcessor when deployed and the SimpleSpanProcessor when developing.

