OpenTelemetry for AI Applications and AI Agents: A Beginner’s Guide

Before We Begin

When you first start developing an AI application, your main concern is usually whether the model can answer. Once the system enters a real environment, the questions quickly become:

  • Why did this request fail?
  • Was the problem in retrieval, the model, a tool, or the database?
  • Why did the agent call the same tool repeatedly?
  • Which step was the slowest or most expensive?
  • When a user task crosses an API, a queue, and a worker, how can the entire execution be connected?

OpenTelemetry provides an open standard and toolset for building the shared observability foundation needed to answer these questions.


1. OpenTelemetry in One Sentence

OpenTelemetry, often abbreviated as OTel, is an open standard and toolchain for producing, correlating, processing, and exporting telemetry data.

Telemetry is data produced while a program runs to help us understand the state of the system. OpenTelemetry’s mature core signals are traces, metrics, and logs. Baggage carries contextual information across services, while profiles remain at the Alpha stage:

  • Trace: what happened during one request;
  • Metric: how the system behaved over a period of time;
  • Log: what event occurred at a particular moment;
  • Baggage: which contextual information should travel with the call chain;
  • Profile: where a program consumed CPU, memory, and other resources; this signal is still evolving.

OpenTelemetry usually does not provide long-term storage, querying, or visualization itself. It is better understood as a unified set of collection specifications, SDKs, and transport mechanisms. Platforms such as Langfuse, LangSmith, Phoenix, Grafana Tempo, Prometheus, Loki, and Datadog receive, store, analyze, or present the resulting data.


2. Understanding OpenTelemetry Through a Delivery-Service Analogy

Imagine the observability data produced by one AI agent request as parcels in a delivery network:

OpenTelemetry conceptDelivery-service analogyActual role
InstrumentationPacking an item and attaching a labelAdds collection logic to a program
Trace / Metric / LogDifferent kinds of parcelsDifferent telemetry signals
APIStandard shipping interfaceDefines how application code creates telemetry
SDKThe delivery company’s operating systemSamples, processes, aggregates, and exports data
ExporterDelivery vehicleSends data elsewhere
OTLPTransport protocolDefines how telemetry is encoded and transmitted
CollectorSorting centerReceives, redacts, filters, samples, batches, and forwards data
BackendWarehouse and control consoleStores, queries, visualizes, and analyzes data
Trace ContextParcel tracking numberPreserves one call chain across services
ResourceSender informationIdentifies the service, version, and environment that produced the data
Semantic ConventionsShared field dictionaryStandardizes names for attributes and operations

The most important distinction is:

OpenTelemetry is not a monitoring dashboard and is not a competing product to Langfuse. It is a standardized intermediate layer between applications and observability backends.


3. Where OpenTelemetry Sits in an AI Agent Architecture

A common architecture looks like this:

User request
FastAPI / Web service
AI Agent / RAG Pipeline
├── Query rewriting
├── Retriever
├── Reranker
├── LLM
├── Tool Call
└── Database / external API

Inside the application:
├── Automatic instrumentation: HTTP, FastAPI, database, Redis, and so on
├── Manual instrumentation: Agent, RAG, LLM, Tool, and other business steps
├── Metrics: request volume, latency, error rate, tokens, and so on
└── Structured Logs
          ↓ OTLP
OpenTelemetry Collector
├── Redaction
├── Filtering
├── Sampling
├── Batching and retries
└── Fan-out to multiple backends
       ├── Langfuse / LangSmith / Phoenix: AI traces and evaluation
       ├── Tempo / Datadog: general distributed tracing
       ├── Prometheus / Grafana: metrics and alerts
       └── Loki / logging platform: log queries

This architecture can be divided into two planes:

  1. Instrumentation Plane: runs inside the application and produces data.
  2. Pipeline Plane: usually implemented by the Collector and responsible for moving and processing data.

4. The Core Components That Are Most Often Confused

4.1 Specification

The specification is OpenTelemetry’s rulebook. It defines how concepts such as traces, metrics, logs, context, and OTLP should work. It is not code; it is the shared contract that language SDKs and tools are expected to implement.

4.2 API: The Interface Used by Application Code

The API defines how telemetry is created. For example:

tracer.start_as_current_span("rag.retrieve")

The API aims to remain stable and lightweight. A library can depend only on the API without deciding where its data will ultimately be sent.

4.3 SDK: The Implementation That Actually Collects and Exports Data

The SDK turns data created through the API into working telemetry. Its responsibilities include:

  • creating providers;
  • sampling;
  • aggregating metrics;
  • batching;
  • invoking exporters;
  • configuring resources;
  • controlling whether and how data is exported.

In short:

API: the methods used to say "I want to record this data"
SDK: how that data is actually processed and sent

4.4 Instrumentation and Instrument Are Different Concepts

These terms are easily confused.

Instrumentation is the overall process of adding observability to code.

with tracer.start_as_current_span("tool.weather"):
    result = call_weather_tool()

An Instrument is a Metrics-specific object, such as a Counter, Histogram, or ObservableGauge.

request_counter = meter.create_counter("agent.requests")

Therefore:

Instrumentation = adding observability logic to a program
Instrument = an object used to record a particular kind of Metric

4.5 Providers, Tracers, and Meters

A TracerProvider is the central entry point and configuration object for tracers. A Tracer creates spans.

TracerProvider → Tracer → Span

A MeterProvider is the central entry point and configuration object for meters. A Meter creates metric instruments.

MeterProvider → Meter → Counter / Histogram / Gauge

Providers are normally initialized once when the application starts, not once per request.

4.6 Exporter

An exporter sends telemetry to an external destination:

OTLP Exporter → Collector
Console Exporter → terminal
Prometheus Exporter → Prometheus-compatible endpoint

An exporter is an output adapter inside an application or Collector, not a storage system.

4.7 OTLP

OTLP stands for OpenTelemetry Protocol. It defines how traces, metrics, logs, and other supported signals are transported between applications, Collectors, and backends.

Application --OTLP--> Collector --OTLP/other protocol--> Backend

OTLP is a protocol, not a service or database.

4.8 Collector

The OpenTelemetry Collector is a standalone telemetry service. Its typical pipeline is:

Receiver → Processor → Exporter
  • A Receiver accepts data.
  • A Processor batches, filters, samples, redacts, or enriches data.
  • An Exporter sends data to one or more backends.

The Collector can also use Connectors to connect pipelines and Extensions to provide supporting capabilities such as health checks and authentication.

4.9 Backend

A backend ultimately stores, queries, presents, or analyzes data. Examples include:

  • Langfuse: AI, LLM, and agent traces, costs, evaluations, and datasets;
  • LangSmith: agent tracing and evaluation;
  • Phoenix: AI observability and evaluation;
  • Tempo: trace storage and querying;
  • Prometheus: metric storage and querying;
  • Loki: log storage and querying.

Their relationship with OpenTelemetry is usually:

OpenTelemetry generates and transports data
The backend stores and uses it

5. OpenTelemetry’s Main Observability Signals

5.1 Trace: The Complete Path of One Request

A trace answers:

“Which steps did this particular request pass through, and in what order?”

An AI agent task can be represented as:

Trace: agent.run
├── Span: auth.check
├── Span: session.load
├── Span: rag.retrieve
│   ├── Span: embedding.create
│   └── Span: vector_db.search
├── Span: reranker.rank
├── Span: llm.plan
├── Span: tool.weather
├── Span: llm.answer
└── Span: result.persist

Span

A span is one unit of work in a trace, such as a database query, model invocation, or tool execution.

A span commonly contains:

  • name: the step name;
  • start/end time: when it started and ended;
  • parent: the parent span;
  • attributes: structured attributes;
  • events: important moments within the step;
  • status: success or error status;
  • links: associations with other traces or spans;
  • trace_id / span_id: the call-chain identity.

Attribute

An attribute is a key-value pair attached to a span:

gen_ai.agent.name = "support-agent"
gen_ai.request.model = "example-model"
gen_ai.tool.name = "search_orders"
app.tool.success = true

The first three fields come from the current, still-evolving GenAI semantic conventions. app.tool.success is a custom attribute used here to illustrate an application field. Production systems should place custom fields under a stable, explicit namespace so that they are not mistaken for official OpenTelemetry fields.

Span Event

An event represents an important moment during the lifetime of a span:

retry_started
rate_limit_received
fallback_model_selected

A parent-child relationship represents the direct continuation of an execution chain. For queues and asynchronous work, a consumer span can still continue the same trace when it extracts the producer context. Use a Link when one task is triggered by multiple upstream operations, a batch combines several messages, or a single parent-child relationship would not correctly express causality.

When to Use Traces

  • Debug one failed request.
  • Analyze an agent loop.
  • Inspect tool selection and arguments.
  • Inspect the RAG retrieval and reranking path.
  • Find the slowest step.
  • Connect APIs, workers, databases, and external services.

A metric answers:

“How has the system behaved recently as a whole?”

Examples include:

Requests per minute
Task success rate
Error rate
P95 latency
Total LLM tokens
Cost per successful task
Current queue length
Number of failed tool calls

The core object relationship is:

MeterProvider
Meter
Instrument
Measurement
Aggregated Metric

Measurement

A measurement is one recorded value:

request_counter.add(1)
latency_histogram.record(850)

Both 1 and 850 are measurements.

Common Instruments

InstrumentBehaviorAI application example
CounterCan only increaseTotal requests, errors, or tokens
UpDownCounterCan increase or decreaseNumber of agents currently running
HistogramRecords a distribution of valuesLatency, token count, or document size
ObservableGaugePeriodically reads a current valueQueue length, memory use, or active task count

Observation

An observation is one value returned by the callback of an asynchronous instrument. It is unrelated to Python’s async/await.

For example, OpenTelemetry can periodically invoke a callback to obtain the current queue length:

def observe_queue_size(options):
    yield Observation(queue.qsize(), {"queue": "rag-ingestion"})

When to Use Metrics

  • Dashboards;
  • trend analysis;
  • SLOs and alerts;
  • capacity planning;
  • comparisons before and after a release;
  • cost and throughput monitoring.

Cardinality: A Critical Metric Risk

Cardinality is the number of distinct combinations of attribute values.

Do not attach fields like these directly as Metric Attributes, which often become Labels in backends such as Prometheus:

user_id
session_id
trace_id
Full URL
Raw prompt
Order number

Almost every value is unique, so these fields can create an enormous number of time series and make storage and queries prohibitively expensive. High-cardinality fields belong in traces or logs, not metric attributes.


5.3 Logs: Specific Events at Particular Moments

A log is a timestamped event record. Structured logs are recommended:

{
  "timestamp": "2026-07-16T12:00:00Z",
  "level": "ERROR",
  "event": "tool_call_failed",
  "tool_name": "search_orders",
  "error_type": "timeout",
  "trace_id": "...",
  "span_id": "..."
}

The important property of a structured log is not merely that it looks like JSON. Field names and types must remain consistent so that machines can query them reliably.

Logs are suitable for:

  • exception stack traces;
  • detailed tool errors;
  • business audit events;
  • state changes;
  • Collector or worker runtime information.

Traces and logs should be correlated through trace_id and span_id. Use a metric to detect a problem, open a trace to locate the failing step, and then inspect the associated log for details.


5.4 Profiles: Where Code Consumes CPU and Memory

A profile answers:

“Where does the program spend CPU time, allocate memory, or execute particular call stacks?”

Profiles are more closely associated with performance engineering. The OpenTelemetry Profiles specification is currently Alpha, so profiles should not be the first priority for a new AI agent project. Begin with traces, metrics, and logs.


6. How the Four Signal Types Work Together

A practical mental model is:

Metrics: detect that the system has a general problem
Trace: locate the failing step in a particular request
Logs: inspect the detailed error for that step
Profiles: analyze a code-level performance bottleneck

For example:

Metrics: P95 rose from 3 seconds to 12 seconds
Trace: slow requests all stalled in reranker.rank
Logs: the Reranker API repeatedly timed out and retried
Profile: local preprocessing also contains a CPU hotspot

The signals complement rather than replace one another. They are different views of the same system.


7. Context Propagation: Connecting Cross-Service Calls into One Trace

An AI system often crosses:

FastAPI → Queue → Worker → LLM → Tool Service → Database

If every service creates an unrelated trace, you only see disconnected fragments.

Context Propagation transports the trace_id and current span_id across process boundaries. HTTP commonly uses W3C Trace Context, including the traceparent header. For a message queue, the context must be injected into message properties and extracted by the consumer.

Service A creates a Trace
   ↓ inject traceparent
Service B extracts Context
   ↓ creates a child Span
Service C continues propagation

The Difference Between trace_id, session_id, and request_id

trace_id: one specific execution chain
session_id: a multi-turn conversation
request_id: an application-defined identifier for one API request

A session can contain multiple traces. Do not use session_id as a substitute for trace_id.


8. Resource, Semantic Conventions, and Baggage

Resource

A Resource describes who produced a set of telemetry:

service.name = "rag-api"
service.version = "1.4.2"
deployment.environment.name = "production"
cloud.region = "asia-northeast1"

A Resource is usually configured when the application starts and exported with telemetry produced by that Provider. The supported signals depend on the SDK and signal implementation for the chosen language.

Semantic Conventions

Semantic Conventions provide standardized field names. When teams use the same conventions for HTTP, databases, messaging, and GenAI operations, backends can query and present the data consistently.

Think of them as:

Semantic conventions are not a transport protocol. They are the shared dictionary for telemetry fields.

OpenTelemetry is developing dedicated semantic conventions for GenAI clients, agents, MCP, and selected model providers. At the time of publication, these conventions have moved into a separate GenAI semantic-conventions repository and remain at Development status. Fields and span structures may continue to change, so implementations should pin the semantic-convention version they adopt.

Baggage

Baggage consists of business key-value pairs propagated with Context:

tenant.tier = "enterprise"
experiment.group = "prompt-v2"

Baggage does not automatically become a span attribute. An application must read and use it explicitly.

Do not put API keys, personal information, complete prompts, or other sensitive data in Baggage. It may propagate into downstream or even third-party services.


9. The Special Value of OpenTelemetry in AI and Agent Systems

A traditional web request often follows a relatively fixed path:

HTTP → Service → Database → Response

An agent’s execution path is more dynamic:

User question
→ Model planning
→ Retrieval
→ Tool A
→ Another model decision
→ Tool B
→ Retry or fallback
→ Final answer

AI observability therefore needs to capture:

  • the model and provider;
  • the prompt or prompt version;
  • input, output, and cached tokens;
  • model latency and finish reasons;
  • agent nodes and state transitions;
  • tool names, argument schemas, and execution results;
  • retrievers, rerankers, Top K, and document IDs;
  • guardrails;
  • retries, fallbacks, and handoffs;
  • cost and the business outcome of the task.

OpenTelemetry places these steps in one trace model and connects them to conventional infrastructure calls such as HTTP, databases, and queues.

GenAI Semantic Conventions

OpenTelemetry’s GenAI semantic conventions define how spans, metrics, and events should be named for AI clients, agents, MCP, and model invocations. This makes telemetry from different frameworks easier for a shared backend to understand. The conventions are still at Development status, however, and should not be treated as a fully stable long-term contract.

OpenInference

OpenInference is an AI-specific convention and instrumentation ecosystem built on OpenTelemetry concepts. It covers frameworks including OpenAI, Anthropic, LangChain, LlamaIndex, Google ADK, and MCP. It can provide AI-specific traces quickly when official OTel GenAI instrumentation is not yet convenient for a particular integration.

Langfuse, LangSmith, and Phoenix

These are AI observability and evaluation backends, not replacements for OpenTelemetry. They can receive OpenTelemetry traces directly or indirectly and add interfaces, cost analysis, datasets, experiments, and evaluations designed for LLM and agent workloads.


10. Observability and Evaluation Are Not the Same

OpenTelemetry mainly answers:

“What did the agent do?”

Evaluation mainly answers:

“Did the agent do it well?”

For example:

OpenTelemetry:
Called search_orders
Used order_id=123
Took 800 ms
Completed without an error

Evaluation:
Should the agent have called this tool?
Was order_id correct?
Was the user's refund task actually completed?
Was the answer faithful to the tool result?

A mature system usually connects the two:

Production Trace
→ Score with rules, user feedback, or an LLM judge
→ Add failed samples to a Dataset
→ Modify the Prompt / model / Workflow
→ Run an offline Experiment
→ Run CI regression tests
→ Roll out gradually

A trace supplies data for evaluation, but the trace itself is not a quality judgment.


A useful default is: one user task or one agent run corresponds to one trace.

Trace: agent.run
├── request.validate
├── context.load
├── rag.retrieve
│   ├── query.embed
│   ├── dense.search
│   ├── sparse.search
│   ├── rrf.fuse
│   └── reranker.rank
├── llm.plan
├── tool.call
├── guardrail.check
├── llm.answer
└── result.persist

Create spans only for steps with diagnostic value. Turning every small function into a span fills traces with noise and increases cost.

Service identity belongs primarily in the Resource:

service.version
deployment.environment.name

The agent-run span should carry information about this execution. Use official fields when a convention exists, and an application-specific namespace otherwise:

gen_ai.agent.name
gen_ai.agent.version
gen_ai.conversation.id
app.release.git_sha
app.prompt.version
app.knowledge_base.version

Recommended model-span fields include:

gen_ai.provider.name
gen_ai.request.model / gen_ai.response.model
gen_ai.usage.input_tokens / gen_ai.usage.output_tokens
gen_ai.response.finish_reasons
error.type
app.retry_count

Span start and end times already express latency. Record a separate metric only when latency also needs to be aggregated independently. The availability of cached-token and other extended fields depends on the semantic-convention version and instrumentation implementation in use.

Recommended tool-span fields include:

gen_ai.tool.name
gen_ai.tool.type
error.type
app.tool.version
app.tool.success

Recommended RAG-span fields include:

app.rag.index.name
app.rag.index.version
app.rag.top_k
app.rag.retrieved_document_ids
app.rag.reranker.name
app.rag.result_count

The app.rag.* names above are illustrative custom attributes, not an official OpenTelemetry RAG semantic convention.

Do not record complete prompts, private user documents, raw tool results, or hidden chain-of-thought by default.


Development

Python AI App
├── OpenTelemetry automatic instrumentation
├── A small number of manual Agent Spans
├── JSON stdout Logs
└── OTLP Exporter
Langfuse / Phoenix / LangSmith

This is suitable for fast validation and does not always require a Collector.

Preproduction and Production

Python AI App
   ↓ OTLP
OpenTelemetry Collector
├── memory_limiter
├── batch
├── redaction / transform
├── sampling
└── exporters (sending queue / retry)
       ├── Langfuse / LangSmith / Phoenix
       ├── Tempo / Datadog
       ├── Prometheus
       └── Logs backend

The Collector provides several important benefits:

  • decouples the application from backend vendors;
  • centralizes redaction;
  • centralizes sampling;
  • provides batching and retries;
  • sends one stream of data to multiple platforms;
  • reduces application changes when the backend changes.

13. Production Best Practices

13.1 Combine Automatic and Manual Instrumentation

Automatic instrumentation covers general calls such as FastAPI, HTTP clients, databases, and Redis. Manual instrumentation adds agent tasks, RAG, tools, guardrails, and business outcomes.

13.2 Observability Failures Must Not Take Down the Business

Use batching and asynchronous export. Configure the Collector’s Sending Queue, exponential-backoff retries, and persistence where needed on exporters. When the telemetry backend is temporarily unavailable, the AI application should continue running whenever possible. Queue capacity, dropped data, and disk consumption must also be monitored.

13.3 Do Not Unconditionally Record Complete Inputs and Outputs in Production

Redact sensitive content before it leaves the application, then apply a second layer of filtering in the Collector. Protect at least:

Authorization / Cookie / API Key
Email addresses, phone numbers, identity documents
Private user documents
Sensitive fields returned by a database
Complete prompts and model outputs

13.4 Do Not Record Hidden Chain-of-Thought

Record auditable, structured results:

selected_tool
route
state_transition
validation_result
policy_decision

Do not depend on or store a model’s hidden chain-of-thought.

13.5 Control Metric Cardinality

Use only low-cardinality Metric Attributes:

model_family
environment
status
tool_name
error_type

Put high-cardinality values such as user IDs, trace IDs, and prompts in traces or logs.

13.6 Do More Than Fixed Random Sampling

Keeping 100% of traces is reasonable in development. In production, keep a random subset of normal requests and use Tail Sampling to preferentially retain:

Error traces
Slow traces
High-cost traces
High-risk tool operations
Abnormal loops

Head Sampling decides when a request begins and has low overhead. Tail Sampling decides after seeing more of the complete trace and enables more precise policies, but it requires the Collector to maintain state and is more complex. Feedback such as a user’s negative rating usually arrives after the Tail Sampling decision has already completed. Associate that feedback through the Trace ID with later evaluation data or use a separate retention mechanism instead of assuming it can affect the completed decision.

13.7 Propagate Context Consistently

HTTP context propagation is generally mature. Queues, scheduled jobs, and database jobs often require explicit context injection and extraction. Without it, worker traces become disconnected from the entry request.

13.8 Use Resource and Version Information

Set at least:

service.name
service.version
deployment.environment.name

AI applications should also record gen_ai.agent.version and use a custom namespace for app.prompt.version, app.knowledge_base.version, and app.release.git_sha. These fields make release regressions easier to compare.

13.9 Monitor the Collector Itself

The Collector can suffer from queue buildup, insufficient memory, export failures, and dropped data. Production systems must monitor its received volume, send failures, queue capacity, and dropped items.


14. A Minimal Python Trace Example

The following example can run independently. Install the dependencies first:

pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http

The example assumes that an OTLP/HTTP-compatible Collector or backend is already listening on local port 4318. A real project will normally add automatic instrumentation, metrics, log correlation, and redaction.

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

resource = Resource.create(
    {
        "service.name": "my-rag-agent",
        "service.version": "1.0.0",
        "deployment.environment.name": "development",
    }
)

provider = TracerProvider(resource=resource)
provider.add_span_processor(
    BatchSpanProcessor(
        OTLPSpanExporter(
            endpoint="http://localhost:4318/v1/traces",
        )
    )
)
trace.set_tracer_provider(provider)

tracer = trace.get_tracer("my-rag-agent")


def retrieve(query: str) -> list[str]:
    return [f"example document for: {query}"]


def generate_answer(query: str, documents: list[str]) -> str:
    return f"answer based on {len(documents)} document(s)"


def run_agent(query: str) -> str:
    with tracer.start_as_current_span("agent.run") as root:
        root.set_attribute("gen_ai.agent.name", "rag-agent")
        root.set_attribute("app.prompt.version", "answer-v3")

        with tracer.start_as_current_span("rag.retrieve") as span:
            documents = retrieve(query)
            span.set_attribute("app.rag.result_count", len(documents))

        with tracer.start_as_current_span("llm.generate") as span:
            answer = generate_answer(query, documents)
            span.set_attribute("gen_ai.request.model", "example-model")

        return answer


if __name__ == "__main__":
    print(run_agent("What is OpenTelemetry?"))
    provider.force_flush()

This produces:

agent.run
├── rag.retrieve
└── llm.generate

You can then add FastAPI automatic instrumentation, HTTPX, databases, queue context, metrics, and log correlation. The example names agent.run, rag.retrieve, llm.generate, and app.rag.result_count are application-defined for teaching purposes. If the project adopts the GenAI semantic conventions, follow the span names and attribute requirements for the pinned version.


15. Common Beginner Misconceptions

“OpenTelemetry Is a Monitoring Platform”

Incorrect. It mainly standardizes collection, correlation, processing, and export. A backend platform provides the actual UI, storage, and analysis.

“OTLP Is the Collector”

Incorrect. OTLP is a transport protocol. The Collector is a service that receives and processes data.

“A Trace and a Log Are the Same Thing”

Incorrect. A trace presents the structured execution chain of one request. A log records a particular event and its details.

“A Metric Is Just Many Traces Added Together”

Not exactly. Metrics have their own data model, instruments, and aggregation system. An application can record them directly, or they can be derived from other data.

“Instrument Means Instrumentation”

Incorrect. Instrumentation is the process of adding observability. An Instrument is a Metrics object such as a Counter or Histogram.

“A Session Is One Trace”

Incorrect. A multi-turn session usually contains several independent traces.

“Having Traces Means Evaluation Is Complete”

Incorrect. A trace records execution facts. Evaluation needs rules, ground truth, an LLM judge, human feedback, or real business outcomes to assess quality.


Stage One: Learn Only Traces

Implement:

One Agent Run = one Trace
LLM, RAG, and Tool = child Spans

First learn to inspect one complete request in the backend interface.

Stage Two: Add Metrics and Structured Logs

Add:

Request count
Error rate
Latency Histogram
Tokens and cost
JSON logs + trace_id/span_id

Stage Three: Add a Collector

Centralize:

Batching
Redaction
Sampling
Retries
Fan-out to multiple backends

Stage Four: Connect Evaluation

Associate user feedback, task success, tool correctness, and LLM-judge scores with traces, then feed failed cases into datasets and CI regression tests.


Conclusion

For an AI application developer, the most important goal is not to memorize every OpenTelemetry term at once. Start with this flow:

The application produces Traces, Metrics, and Logs through instrumentation
The SDK processes them and exports them through OTLP
The Collector receives, transforms, and distributes them
Backends such as Langfuse, Tempo, and Prometheus store, present, and analyze them

Distinguish the three core signals with one sentence each:

Trace: what happened during this request
Metrics: how the system has behaved recently as a whole
Logs: what happened at a particular moment

For an AI agent, OpenTelemetry’s core value is that it places models, retrieval, tools, databases, queues, and external services in one traceable chain. Platforms such as Langfuse, LangSmith, and Phoenix then add AI-specific analysis and evaluation.

A mature solution does not record everything indiscriminately. Instead, it:

Records data with diagnostic value, uses consistent semantics, protects sensitive information, controls cost, and continually turns observability data into better evaluation and improvement.


Official References