Langfuse Integration
NoPII integrates with Langfuse for LLM observability, tracing, and cost monitoring. The integration is opt-in - when enabled, every proxied request generates a trace with spans for each stage of the NoPII pipeline.
Setup
Configure Langfuse in the admin console under your account settings. You'll need:
| Setting | Required | Description |
|---|---|---|
| langfuse_enabled | Yes | Set to true to activate tracing |
| langfuse_public_key | Yes | Your Langfuse project public key |
| langfuse_secret_key | Yes | Your Langfuse project secret key |
| langfuse_host | No | Defaults to https://us.cloud.langfuse.com. Set this if you self-host Langfuse or use the EU region. |
Langfuse keys are securely stored and never appear in logs or the database.
Trace structure
Each proxied request creates a trace with three child spans that map to the NoPII pipeline:
nopii-proxy (root span)
├── sanitize - PII detection + tokenization
├── llm-call - Forwarded request to the LLM provider (generation)
└── desanitize - Response detokenizationRoot span metadata
| Field | Description |
|---|---|
| tenant_id | Your NoPII account identifier |
| session_id | NoPII session ID (from X-NoPII-Session-Id header) |
| provider | LLM provider name (e.g., "openai", "anthropic") |
| model | Model name from the request (e.g., "gpt-4o") |
Sanitize span
Records the PII detection and tokenization step. Output metadata includes entity_count - the number of PII entities detected and tokenized.
LLM call generation
Recorded as a Langfuse generation (not a span), which enables Langfuse's built-in model cost tracking. Includes:
- Sanitized input (request body with PII replaced by tokens)
- Sanitized output (LLM response before detokenization - tokens, not original PII)
- Model name
- Token usage (prompt and completion tokens)
- HTTP status code
What Langfuse sees
Both the input and output logged to Langfuse contain tokenized content - PII is replaced with tokens like [PERSON: aBcDeFgH12]. Original PII values never appear in Langfuse. The output is captured before desanitization specifically to prevent PII from leaking into traces.
Desanitize span
Records the response detokenization step, where tokens in the LLM response are replaced with original PII values.
Streaming vs. non-streaming
Both streaming and non-streaming requests log the full sanitized input and sanitized output in the generation. For streaming requests, the output is assembled from the streamed chunks before being sent to Langfuse. In both cases, all content is tokenized - tokens, not original PII.
Distributed tracing
NoPII supports the W3C Trace Context standard via the traceparent header. This allows you to connect NoPII traces to your existing distributed tracing pipeline.
Format
traceparent: 00-{trace_id(32hex)}-{parent_span_id(16hex)}-{flags(2hex)}Example
import openai
import uuid
# Generate a trace context for your application
trace_id = uuid.uuid4().hex # 32 hex characters
span_id = uuid.uuid4().hex[:16] # 16 hex characters
traceparent = f"00-{trace_id}-{span_id}-01"
client = openai.OpenAI(base_url="https://api.nopii.co")
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Summarize the case for John Smith"}],
extra_headers={"traceparent": traceparent}
)
# The NoPII trace in Langfuse will appear as a child of your traceWhen a valid traceparent header is present, NoPII creates its trace as a child of the specified parent span via OpenTelemetry context propagation. This lets you see the full request lifecycle - from your application through NoPII to the LLM - in a single trace view.
Performance and reliability
Tracing never blocks or slows down your proxy requests. If Langfuse is unreachable or returns an error, NoPII continues normally - your requests are never affected by tracing issues.
When Langfuse is not configured or disabled:
- No performance impact
- No errors if credentials are invalid or the service is down
- You can enable and disable Langfuse at any time without any disruption
Related
- How It Works - Understand the full tokenization pipeline that Langfuse traces
- API Reference - The traceparent header is documented here