Skip to main content

OpenTelemetry Integration

Adjudon accepts OTLP/HTTP traces and maps GenAI spans to Adjudon traces. This lets you use any OTEL-instrumented LLM library — OpenLLMetry, LangSmith OTEL, custom spans — and have all GenAI decisions flow into Adjudon automatically.

Install

pip install adjudon-otel

Setup

from adjudon_otel import setup_adjudon_otel

provider = setup_adjudon_otel(
api_key="adj_agent_abc123...",
agent_id="my-agent",
)
# All OTEL GenAI spans now flow to Adjudon automatically.

Parameters

api_key: str               — Required. Agent API key.
agent_id: str — Required. Agent identifier.
endpoint: str — Default: "https://api.adjudon.com/otel". OTLP/HTTP endpoint.
service_name: str — Optional. Defaults to "adjudon-traced-service".
service_version: str — Optional. Shown in trace metadata.
batch_kwargs: dict — Optional. Passed to BatchSpanProcessor.

How it works

Adjudon exposes an OTLP/HTTP receiver at POST /otel/v1/traces. Spans are filtered by GenAI Semantic Conventions (v1.27+):

OTEL AttributeAdjudon Field
gen_ai.systemmetadata.framework
gen_ai.request.modelmetadata.model
gen_ai.usage.input_tokensmetadata.input_tokens
gen_ai.usage.output_tokensmetadata.output_tokens
Span events with gen_ai.content.promptinputContext.prompt
Span events with gen_ai.content.completionoutputDecision.text

Non-GenAI spans (database queries, HTTP calls, etc.) are silently dropped — only AI decisions are compliance-relevant.

When to use OTEL vs the SDK

Use OTEL if...Use the SDK directly if...
You already have OpenTelemetry instrumentationYou want explicit control over what gets traced
You use OpenLLMetry or similar OTEL-native librariesYou need policy blocking (AdjudonBlockedException)
You want vendor-neutral instrumentationYou need per-call sample_rate control
You instrument multiple LLMs in one serviceYou want the simplest possible setup

Example: OpenLLMetry

from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from adjudon_otel import setup_adjudon_otel

# adjudon-otel handles all of this automatically:
provider = setup_adjudon_otel(api_key="adj_agent_abc123...", agent_id="my-agent")

# Existing OpenLLMetry instrumentation works unchanged.
from traceloop.sdk import Traceloop
Traceloop.init(exporter=provider)