> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnao.io/llms.txt
> Use this file to discover all available pages before exploring further.

# LLM Observability

> Send traces of every LLM call to Langfuse

nao can export a trace of every LLM call to [Langfuse](https://langfuse.com): prompt, response, latency, tokens, cost, model, and tool calls. It's off by default; running without it needs no action.

## Configuration

| Variable              | Description                              |
| --------------------- | ---------------------------------------- |
| `LANGFUSE_PUBLIC_KEY` | Project public key, starts with `pk-lf-` |
| `LANGFUSE_SECRET_KEY` | Project secret key, starts with `sk-lf-` |
| `LANGFUSE_BASE_URL`   | Where to send traces                     |

All three are required. If any is missing, tracing stays off and nao starts normally. `LANGFUSE_BASE_URL` has no default by design, so traces are never sent to a destination you didn't name.

On Langfuse Cloud, use the host shown in your project settings - keys are region-bound, so a URL from another region fails authentication.

Self-hosted Langfuse works identically - use your instance URL, including an internal one like `http://langfuse-web:3000`. It must be version 3.63.0 or newer.

<Warning>
  Traces include the **full text** of prompts and responses, so user questions and query results are sent to whichever instance you configure. Self-host Langfuse if that data can't leave your infrastructure. A Langfuse secret key also grants API access to read the project's traces - treat it as sensitive.
</Warning>

## Set the variables

**`nao chat`** - add them to a `.env` file in your project folder. nao loads it on startup and passes it to the agent:

```bash theme={null}
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com
```

**Docker** - add `-e` flags:

```bash theme={null}
docker run -d \
  --name nao \
  -p 5005:5005 \
  -e BETTER_AUTH_URL=http://localhost:5005 \
  -e LANGFUSE_PUBLIC_KEY=pk-lf-... \
  -e LANGFUSE_SECRET_KEY=sk-lf-... \
  -e LANGFUSE_BASE_URL=https://cloud.langfuse.com \
  getnao/nao:latest
```

**Docker Compose** - same three lines in the `.env` file next to `docker-compose.yml`, which already forwards them. Then run `docker compose up -d`.

## Verify

On startup nao logs `✓ Langfuse tracing enabled → <url>`. Send a message in the chat and a `nao-agent` trace appears in your Langfuse project.

<Info>
  Traces are batched and ingested asynchronously, so one can take a little while to show up. That delay is normal.
</Info>

## What you see in Langfuse

Traces are named after the operation that produced them:

| Trace name              | What it covers                                                                          |
| ----------------------- | --------------------------------------------------------------------------------------- |
| `nao-agent`             | The main chat agent: every user message, including its tool calls                       |
| `nao-generate-title`    | Automatic chat title generation                                                         |
| `nao-compaction`        | History compaction when a conversation grows long                                       |
| `nao-memory-extraction` | Extraction of [memories](/nao-agent/chat/capabilities/memory) from a conversation       |
| `nao-automation-title`  | Title generation for [automations](/nao-agent/chat/capabilities/automations)            |
| `nao-live-story`        | [Story](/nao-agent/chat/capabilities/stories) refreshes                                 |
| `nao-cron-nlp`          | Parsing a natural-language schedule into a cron expression                              |
| `nao-test-verification` | Answer verification during [evaluation](/nao-agent/context-engineering/evaluation) runs |

Each trace carries the chat as the Langfuse **session** (so Sessions groups a whole conversation), the nao user as the **user**, and the model provider as a **tag**. Model name and any custom sampling settings (temperature, top-p, top-k) are attached as metadata.
