Receber por email
← Voltar para o catálogo

ai-observability-langfuse

LLM observability with Langfuse — OpenTelemetry-based tracing, evaluations, prompt management, datasets, and production best practices

11estrelas
Atualizado há 7 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add agents-inc/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/ai-observability-langfuse/svg)](https://www.skillteca.com.br/skills/ai-observability-langfuse)

Skills relacionadas

Ver todas de Dados e Análise →

Alerta por categoria

Receba novas skills de Dados e Análise toda segunda

1 email curto, só com as skills novas de Dados e Análise. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Langfuse Observability Patterns

Quick Guide: Use the Langfuse TypeScript SDK (built on OpenTelemetry) to add observability to LLM applications. Install @langfuse/tracing, @langfuse/otel, and @opentelemetry/sdk-node for core tracing. Use startActiveObservation() for automatic context propagation or observe() to wrap functions. Use @langfuse/openai with observeOpenAI() for zero-config OpenAI tracing. Use LangfuseClient from @langfuse/client for prompt management, scores, and datasets. Always call forceFlush() or sdk.shutdown() in short-lived processes.

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST import and register instrumentation.ts at the top of your entry point BEFORE any other imports -- OpenTelemetry must instrument modules before they are loaded)

(You MUST call forceFlush() or sdk.shutdown() in short-lived processes (serverless, scripts, CLI tools) -- events are batched and will be lost without explicit flushing)

(You MUST use @langfuse/openai with observeOpenAI() for OpenAI SDK tracing -- do NOT manually create generation observations for OpenAI calls when the wrapper handles it automatically)

(You MUST set LANGFUSE_SECRET_KEY, LANGFUSE_PUBLIC_KEY, and LANGFUSE_BASE_URL via environment variables -- never hardcode credentials)

(You MUST use startActiveObservation() or observe() for nested tracing -- manual startObservation() requires explicit .end() calls and does NOT propagate context automatically)

</critical_requirements>

Auto-detection: Langfuse, langfuse, @langfuse/tracing, @langfuse/otel, @langfuse/client, @langfuse/openai, LangfuseSpanProcessor, LangfuseClient, startActiveObservation, startObservation, observeOpenAI, langfuse.score, langfuse.prompt, langfuse.dataset, LANGFUSE_SECRET_KEY, LANGFUSE_PUBLIC_KEY, forceFlush

When to use:

  • Adding observability and tracing to LLM application code (any provider)
  • Wrapping OpenAI SDK calls for automatic token/cost tracking
  • Managing prompt templates with versioning, labels, and variable compilation
  • Evaluating LLM output quality with scores (numeric, categorical, boolean)
  • Running experiments against datasets for regression testing
  • Tracking sessions, users, and metadata across multi-turn conversations
  • Monitoring LLM costs and token usage in production

Key patterns covered:

  • OpenTelemetry setup with LangfuseSpanProcessor
  • Tracing with startActiveObservation, observe, and manual startObservation
  • Observation types (span, generation, agent, tool, retriever, evaluator, embedding, chain, guardrail)
  • OpenAI SDK auto-instrumentation with observeOpenAI()
  • Prompt management (get, compile, text vs chat prompts, versioning)
  • Scores and evaluations (numeric, categorical, boolean)
  • Datasets and experiments for testing
  • Flush, shutdown, and lifecycle management

When NOT to use:

  • You only need basic console.log debugging -- Langfuse is for structured production observability
  • You want provider-specific tracing built into an AI SDK -- check if your framework has native observability
  • You need APM/infrastructure monitoring (CPU, memory, HTTP latency) -- use a general-purpose observability tool

Examples Index

  • [Core: Setup & Configuration](examples/core.md) -- OpenTelemetry setup, instrumentation file, client init, flush/shutdown
  • [Tracing](examples/tracing.md) -- startActiveObservation, observe, manual tracing, nesting, observation types, metadata
  • [OpenAI Integration](examples/openai-integration.md) -- observeOpenAI wrapper, streaming, token tracking, custom attributes
  • [Prompt Management](examples/prompt-management.md) -- getPrompt, compile, text vs chat, versioning, caching
  • [Scores & Datasets](examples/scores-datasets.md) -- Numeric/categorical/boolean scores, datasets, experiments
  • [Quick API Reference](reference.md) -- Package index, environment variables, observation types, score methods

<philosophy>

Philosophy

Langfuse provides open-source LLM observability built on OpenTelemetry. The SDK (v4+, August 2025) is a ground-up rewrite using OTel as the tracing backbone, meaning traces integrate naturally with the broader observability ecosystem.

Core principles:

  1. OpenTelemetry-native -- Built on OTel spans and context propagation. Langfuse observations are wrappers around OTel spans with LLM-specific attributes (model, tokens, cost). This means any OTel-compatible instrumentation library works alongside Langfuse.
  2. Zero-latency tracing -- All trace events are queued locally and flushed in background batches. Your application's response time is not affected by observability.
  3. Modular packages -- @langfuse/tracing for instrumentation, @langfuse/client for prompts/scores/datasets, @langfuse/openai for OpenAI auto-instrumentation. Install only what you need.
  4. Context-first -- startActiveObservation() automatically propagates parent-child relationships. Nested observations inherit context without manual ID threading.
  5. Observation types -- LLM-specific types (generation, agent, tool, retriever, evaluator, embedding) provide semantic meaning to traces, enabling richer dashboard views and filtering.

</philosophy>

<patterns>

Core Patterns

Pattern 1: OpenTelemetry Setup

Create an instrumentation.ts file and import it at the top of your entry point.

// instrumentation.ts
import { NodeSDK } from "@opentelemetry/sdk-node";
import { LangfuseSpanProcessor } from "@langfuse/otel";

const sdk = new NodeSDK({
  spanProcessors: [new LangfuseSpanProcessor()],
});

sdk.start();

export { sdk };
// index.ts -- import instrumentation FIRST
import "./instrumentation";
// All other imports AFTER instrumentation
import { startActiveObservation } from "@langfuse/tracing";

Why good: OTel must instrument modules before they are loaded; importing instrumentation first ensures all subsequent imports are traced automatically

// BAD: importing instrumentation after other modules
import { startActiveObservation } from "@langfuse/tracing";
import "./instrumentation"; // TOO LATE -- tracing won't capture earlier imports

Why bad: Auto-instrumentation of LLM SDKs requires OTel to be initialized before those modules are imported

See: [examples/core.md](examples/core.md) for environment variables, sampling, masking, and production configuration

Pattern 2: Tracing with startActiveObservation

The primary instrumentation pattern. Creates an observation, makes it the active context, and automatically ends it when the callback completes.

import { startActiveObservation } from "@langfuse/tracing";

async function handleRequest(query: string): Promise<string> {
  return await startActiveObservation("handle-request", async (span) => {
    span.update({ input: { query } });

    // Nested observation -- automatically becomes a child
    const result = await startActiveObservation(
      "process-query",
      async (child) => {
        child.update({ input: { query } });
        const answer = await callLLM(query);
        child.update({ output: { answer } });
        return answer;
      },
    );

    span.update({ output: { result } });
    return result;
  });
}

Why good: Automatic context propagation, automatic end on callback completion, nesting creates parent-child hierarchy without manual ID management

// BAD: using startObservation without ending it
import { startObservation } from "@langfuse/tracing";

const span = startObservation("my-span");
await doWork();
// span.end() never called -- observation stays open forever

Why bad: Manual startObservation requires explicit .end() calls; forgetting creates open-

Compartilhar X LinkedIn