Skip to main content
Langfuse collects traces from live calls. Use it when you want to open one conversation and read what happened in it.

Every key the tracing block takes

agent.yaml
langfuse | coval
required
Which service the spans go to. langfuse is this page. Any other name is refused, with both accepted names in the message, and leaving the whole tracing: block out means the agent exports nothing.
There is no second key. Which Langfuse project a trace lands in is decided by the three environment names below, read at run time, so the same package can point at a test project and a production one with no edit. Tracing compares the two providers side by side.

What you need

Three secrets: LANGFUSE_BASE_URL, LANGFUSE_PUBLIC_KEY, and LANGFUSE_SECRET_KEY. All three are required, and the agent fails at startup if any is missing. That is deliberate. Langfuse is configured once per deployment, so a missing key means the deployment is wrong, and failing loudly is better than running for a week without traces.

Trace and session names

The trace name is <entry-agent>-<agent-name>, where agent-name is the package’s name: joined to the target it was compiled for, the same value a deploy uses as the agent’s identity. Both targets build it the same way, so a trace from either one names the same agent the same way. A local unmute dev run and a deployed run get the same trace name. Unlike Coval tracing, the Langfuse integration adds no -local suffix, so the trace name alone does not tell you which one you are looking at. Each target picks its own session ID from something it already has: Both go on every observation in the call, not only on the top one. Langfuse v4 answers questions over observations, so a session ID that sat only on the root would leave you unable to filter the model calls under it or add up what the session cost.

One call is one trace

A call is one trace, and it is also one session. Open the trace and the root observation holds the whole conversation, so you can read what happened without opening anything. Inside it each exchange is a turn span: what the caller said, what the agent replied, and the model and tool calls that produced it. That shape is deliberate. A trace is the unit Langfuse aggregates over, so a call split into one trace per turn leaves nothing to aggregate and leaves the top of the call empty. Keeping the call whole means you can still deep dive, by opening a turn, without losing the view of the call. An observation-level evaluator can read a turn’s root and get both sides of that exchange, because a v4 evaluator cannot read an observation’s children. The two targets differ in how much work this takes. Pipecat already nests turn inside conversation, so it is left alone. LiveKit has no span covering one exchange, since user_turn closes when the caller stops speaking and agent_turn is its sibling, so that target adds a turn span of its own.

What the spans look like

Agent lifecycle on LiveKit, the starting, handing over and shutting down, hangs off agent_session beside the turns rather than inside one. Every tool call is its own observation, typed as a tool and named after the tool that ran, carrying the arguments and, once the call finishes, the result. Both targets read the same way because both set gen_ai.operation.name and gen_ai.tool.name on the span, which is what Langfuse reads for the type and the name. A task’s structured result is the arguments of its finish call, so it is on that call’s span rather than on the model request that produced it. That call is named finish on livekit, and on pipecat it carries the step name twice over, once for the entry that runs it, as in finish_verify_customer_verify_customer. Every one of them also takes unserved_request, which is empty unless the step handed a request back for the agent that owns it to serve. Pipecat tracing owns the process OpenTelemetry provider and startup fails if another SDK provider is installed first. In the Langfuse v4 data model a trace is only the observations that share a trace ID, so there is no separate place for a trace input or output, and this project writes neither.

What a trace records

Traces can contain caller speech, model input and output, and tool arguments and results. Use only fake identities and fake customer data for release tests.

Checking it works

Starting the worker or exporting a synthetic span proves connectivity only. Complete at least one user turn before you look at the trace, or you will be reading an empty one and concluding the wrong thing.

Where to go next

Coval

Attach spans to the simulation that produced the call.

Optimizing your agent

The settings that make a call faster, and where each one goes.