LLM observability and trace attribution in Breeze.
Langfuse gives you end-to-end observability over every LLM call. Breeze wraps its OpenAI client with Langfuse's auto-instrumentation, so chat streams and summaries show up in your project without any code changes.
Instrumented either way
Breeze imports the OpenAI SDK through langfuse.openai, so the LLM layer is
always wrapped. With no keys set, a no-op tracer steps in and nothing is sent.
Turning tracing on is purely a matter of adding credentials.
LANGFUSE_SECRET_KEY=
LANGFUSE_PUBLIC_KEY=
LANGFUSE_BASE_URL= # e.g. https://cloud.langfuse.comTracing is enabled only when both the secret and public keys are present. If either is missing you get a warning that tracing is disabled, and the app runs normally.
Two optional headers carry user and session context from the Next.js proxy to the backend:
| Header | Effect |
|---|---|
X-User-Id | Attributes the trace to the signed-in user. |
X-Session-Id | Groups one conversation's traces into a session. |
/api/chat reads these off the incoming request and re-adds them on the
upstream call so they survive the proxy hop. The frontend sets them from the
NextAuth session and the conversation id -- there is nothing to wire up.
Open a conversation and send anything. The trace appears in your Langfuse project under the name below.
| Trace name | Covers |
|---|---|
chat.stream_responses | Chat streaming, with user and session id attached via propagate_attributes. |
tools.stream_responses | The second pass of a web-search turn, so the search round trip and final answer read as one flow. |
| (wrapped client) | Summarisation, through the same instrumented OpenAI client. |
Model, duration and usage for every call.
Prompt, tool call, search results and final answer in a single trace.
Usage grouped by user and by conversation.
Why a reply skipped generative UI, or fell back to another model.
Ollama silently ignores options.num_ctx, so the token counts you see are what
the model actually used -- not what the request asked for. This is the same
quirk behind the context-window trap.
The Langfuse credentials in your local .env are live secrets. Keep them out of
version control -- see Security.