Overview
semantic_tracing is the single tracing surface for all evaluation
workflows. It provides decorators, context managers, and helpers that emit
observations to Langfuse — whether the code is plain Python, Microsoft Agent
Framework, or LangChain.
The problem this module solves
Every framework that supports distributed tracing creates its own
TracerProvider. Without intervention, spans from Microsoft Agent Framework
end up in one trace; Langfuse @observe spans end up in another. The two
trees never meet.
This breaks evaluation workflows in a concrete way: when an executor emits a
trace ID that is later used to build a dataset item, that ID points to a trace
in the Agent Framework tree. Langfuse shows the @observe-based tree. The
IDs do not match, and dataset items reference non-existent observations.
The solution
setup_tracing() promotes Langfuse's internal TracerProvider to the global
OpenTelemetry (OTel) provider. Any framework that reads the global provider
(Agent Framework, OpenLIT, custom OTel-instrumented code) then emits spans
into the same Langfuse trace automatically.
flowchart TD
subgraph Code["Instrumented code — same process"]
direction LR
MAF["Microsoft Agent Framework"]
LC["LangChain"]
App["@step / span() / event()"]
end
subgraph SDK["setup_tracing()"]
direction LR
TP["Langfuse TracerProvider as global OTel provider"]
end
subgraph LF["Langfuse"]
direction LR
T["Single trace per request"]
end
MAF -->|"reads global OTel provider"| TP
LC -->|"via OTel context"| TP
App -->|"@observe and create_span"| TP
TP --> T
style Code fill:#e9ebec,stroke:#273943,stroke-width:2px
style SDK fill:#e5f4fd,stroke:#0098eb,stroke-width:2px
style LF fill:#efe9ed,stroke:#62294b,stroke-width:2px
Call setup_tracing() once at process startup, before any executor or
framework initializes. After that call, all observation primitives —
@step, span(), event(), propagate() — and any framework that reads
the global OTel provider write into one unified trace.
What this module provides
| File in this series | What it covers |
|---|---|
| 00-tracing-overview.md ← you are here | Architecture, the unified TracerProvider concept |
| 01-tracing-setup.md | setup_tracing() — all parameters, startup placement, prod vs. dev, environments |
| 02-tracing-observations.md | @step, span(), event(), propagate(), update_current_step() |
| 03-tracing-generation.md | LLM generation spans — TTFT, extended usage, record_first_token(), wrap_azure_stream() |
| 04-tracing-input-capture.md | What gets captured and how to control it — InputFilter, exclude_args |
| 05-tracing-frameworks.md | Microsoft Agent Framework and LangChain integration |
| 06-tracing-example-maf.md | End-to-end example: MAF order-processing workflow |
| 06-tracing-example-langchain.md | End-to-end example: LangChain RAG pipeline |
| 07-tracing-reader.md | Read-side helpers — fetch_trace, find_observations, as_dict, coerce_text |
| 08-tracing-reference.md | Complete public API table and source file layout |
| 09-tracing-unit-consumption.md | Token and unit consumption tracking |
| 10-tracing-session-sampling.md | Session-consistent sampling, always_send_errors, cost approximation |
| 11-tracing-app-insights-langfuse-cross-reference.md | Bidirectional cross-reference between App Insights and Langfuse — data model, navigation flows, KQL reference, improvements roadmap |
| 12-tracing-local-capture.md | In-process trace mirror for synchronous evaluation reads — an alternative to polling Langfuse with fetch_trace |
| 13-tracing-across-requests.md | Traces that span several requests: resume_trace, record_trace_root, record_observation |
| 14-tracing-model-prices.md | Pricing Azure model deployments in Langfuse: model definitions, Azure's retail meters, python -m semantic_tracing.pricing |