Observabilidade de LLMs em Produção: Langfuse vs Helicone vs Arize em 2026

Langfuse (MIT, self-host) vs Helicone (proxy 5 min) vs Arize Phoenix (eval rigoroso): comparação prática de observabilidade LLM em 2026, com código OpenTelemetry, métricas e o dashboard que você vai desejar ter construído primeiro.

Observabilidade LLM: Langfuse vs Helicone 2026

Atualizado: 10 de julho de 2026

Observabilidade de LLM em produção é a prática de coletar traces, métricas e evals de cada chamada (prompt, tokens, latência, custo e qualidade da resposta) para que você consiga responder por que aquele request de 28 segundos aconteceu às 3h da manhã, e não apenas que aconteceu. Em 2026, as três ferramentas que dominam essa decisão são Langfuse (open-source, MIT, self-host completo), Helicone (proxy drop-in, setup em 5 minutos) e Arize/Phoenix (rigor de eval vindo do mundo ML). Este guia compara as três, mostra o código de instrumentação com OpenTelemetry e lista o dashboard que você vai desejar ter construído primeiro.

  • Langfuse é o padrão open-source seguro: MIT em todas as features, self-host com Postgres + ClickHouse + Redis + S3, e endpoint OTLP nativo em /api/public/otel.
  • Helicone é o mais rápido de instalar (troca de URL base do SDK), mas enxerga só HTTP e não modela spans internos de agentes multi-turn.
  • Arize Phoenix traz a melhor primitiva de eval e drift detection porque nasceu do ML observability tradicional; a UI LLM-específica ainda amadurece.
  • Meça p50, p95 e p99 separadamente, segmentados por modelo e versão de prompt. A média mente, e o p99 sem contexto de tokens é um número perigoso.
  • Adote as OpenTelemetry GenAI Semantic Conventions: os atributos de span (gen_ai.request.model, gen_ai.usage.input_tokens) são estáveis desde 2024 e portáveis entre backends.
  • Um SDK bem projetado adiciona menos de 5 ms de CPU por chamada. Se o seu ficou mais lento, você está serializando payload no caminho crítico.

Observabilidade de LLM: o que é (e por que APM tradicional não basta)

Observabilidade de LLM é a prática de instrumentar cada chamada ao modelo (captura do prompt final, tokens de entrada e saída, latência, custo estimado, ferramentas invocadas, resposta bruta e scores de qualidade) e correlacionar tudo isso em traces que atravessam retrieval, reranking, chamadas ao modelo e pós-processamento. Você faz isso porque APM tradicional foi projetado para sistemas determinísticos: o mesmo request produz o mesmo response, um 500 é um 500, e latência é dominada por tempo de CPU e I/O. Em aplicações LLM, o mesmo prompt pode retornar respostas diferentes a cada chamada, a latência varia com o número de tokens gerados, e um 200 OK não significa absolutamente nada sobre a qualidade da resposta.

Isso força três mudanças. Primeiro, você precisa registrar o corpo das requisições e respostas, não só metadados. Sem o prompt final e a saída, você não consegue reproduzir um bug (eu passei duas noites tentando, aprenda com meu erro). Segundo, você precisa de spans hierárquicos, porque um agente que chama três ferramentas e faz cinco chamadas ao modelo produz um trace com dez a vinte spans; agrupar por trace ID é a única forma de ver o fluxo real. Terceiro, você precisa de avaliações contínuas (LLM-as-judge ou similar) rodando sobre traces de produção, porque a única forma de detectar regressão de qualidade quando a Anthropic ou a OpenAI empurram uma atualização de modelo silenciosa é medir a saída, não o status code.

Segundo dados agregados por fornecedores em 2026, o mercado de observabilidade LLM cresceu para cerca de US$ 2,69 bilhões, com projeção de US$ 9,26 bilhões até 2030. Não é hype: 85% dos projetos de IA falham antes de atingir escala, e ausência de visibilidade sobre alucinação, custo descontrolado e degradação de latência aparece em cima da lista de causas. Se você quer contexto sobre como avaliar qualidade fora do runtime, veja também nosso guia de avaliação de LLMs com DeepEval e Ragas. Observabilidade e eval são as duas metades do mesmo problema.

Langfuse vs Helicone vs Arize: comparação rápida

As três ferramentas resolvem o mesmo problema por caminhos diferentes: Langfuse via SDK ou OpenTelemetry, Helicone via proxy HTTP, Arize/Phoenix via SDK OTel-first. A escolha certa depende de onde você quer instrumentação, quão profundo precisa do trace, e se dados podem sair do seu ambiente.

Dimensão Langfuse Helicone Arize / Phoenix
ArquiteturaSDK + OTel (OTLP)Proxy HTTP (troca de URL)SDK OTel-first
Licença open-sourceMIT, todas as featuresParcialPhoenix (Elastic License 2.0)
Self-host de produçãoSim (Postgres + ClickHouse + Redis + S3)LimitadoSim (Phoenix)
Tempo de setup~30 min (SDK) ou 5 min (OTel)~5 min (URL swap)~30 min
Traces de agentes multi-turnBom (session grouping)Raso (só HTTP)Bom
Evals nativosHooks + LLM-as-judgeMínimoMais rigoroso (drift, embeddings)
Prompt management / versioningSim, com cacheNãoParcial
Preço de entrada (cloud)Free / US$ 29/mêsFree / US$ 79/mêsFree (Phoenix) / US$ 50/mês (AX)
Ideal paraData residency, OSS, agentesCost tracking OpenAI-only rápidoEval rigor, times ML+LLM

Um resumo honesto do que você recebe. Langfuse ganha em traços profundos e em licença: a MIT cobre todas as features, incluindo playground, experiments e human annotation, sem edição enterprise separada. Helicone ganha em velocidade de setup e em ser um gateway (roteamento, failover, cache) de brinde. Arize/Phoenix ganha quando você já tem MLOps montado e precisa de detecção de drift e análise de embeddings com estatística séria.

Quais métricas monitorar em LLMs em produção?

Existem quatro camadas de métricas que uma stack de observabilidade LLM séria captura. Ignorar qualquer uma delas produz o clássico "sistema verde, usuários furiosos".

1. Latência: TTFT, p50, p95, p99, sempre segmentados

Time to First Token (TTFT) é a métrica que mais afeta percepção de qualidade em UIs com streaming; total response time é o que quebra timeouts em pipelines batch. Meça os dois. E meça em percentis: a média esconde caudas. Um p99 de 28 segundos em uma stream que normalmente entrega o primeiro token em 400 ms significa que algum request está gerando 4000 tokens de saída, ou que o provedor teve um incidente regional. Você só sabe se segmentar o percentil por modelo e por versão de prompt.

Uma dica que me custou dois meses de plantão para aprender: alerte em desvio sustentado por 15 minutos ou mais, não em picos transitórios. Um p99 dobrando por 90 segundos é ruído. Um p99 20% acima da baseline por meia hora é um incidente de provedor, ou uma mudança silenciosa no seu prompt.

2. Consumo de tokens e custo por request

Honestamente, este é o alerta que mais paga por si mesmo. Um workflow rodando a 30 RPM pode custar mais de US$ 3.600 por mês se o consumo de tokens crescer inesperadamente (mudança de modelo, prompt novo com um exemplo grande, ou um bug em RAG puxando 20 documentos em vez de 5). Registre input_tokens e output_tokens por span, e calcule custo em atributo derivado usando o preço do modelo daquele mês. Alerte em custo por trace, não só em custo agregado. O agregado esconde traces patológicos.

Se você ainda não implementou cache de prompt, ela é a alavanca de custo mais barata de puxar. Veja o guia de cache de prompts em Claude, GPT-5 e Gemini para os detalhes de implementação. Cortes de 60 a 90% em input tokens são comuns.

3. Taxa de erro, com granularidade

Um bucket único de "erro" é inútil. Separe: rate limits (429), erros de servidor do provedor (500/502/503), timeouts do seu client, content filter blocks (finish reason = content_filter), e JSON malformado quando você está usando structured outputs. Cada um pede um tratamento diferente. 429 pede backoff exponencial e fallback para modelo secundário; content_filter pede revisão do prompt; JSON malformado pede function calling em vez de "please respond in JSON".

4. Qualidade da resposta (evals)

A métrica que APM tradicional não te dá. Rode LLM-as-judge sobre uma amostra de traces de produção (1% costuma ser suficiente para detectar regressão), pontuando faithfulness (o retrieval foi usado?), relevance (a resposta cobre a pergunta?), e safety (a saída viola políticas?). Langfuse, Phoenix e LangSmith rodam evals nativamente. Helicone não, e essa é a maior lacuna dele.

Como instrumentar sua aplicação com OpenTelemetry

OpenTelemetry é o padrão da indústria para instrumentação LLM em 2026. As GenAI Semantic Conventions do OpenTelemetry definem atributos de span padrão (gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.response.finish_reasons) e atingiram estabilidade nos atributos core em 2024. Instrumentar via OTel te dá portabilidade: mesmo código exporta para Langfuse, Phoenix, Datadog, ou qualquer collector.

O exemplo abaixo mostra instrumentação manual de uma chamada Anthropic Claude, exportando para Langfuse self-hosted via OTLP. Roda em Python 3.11+.

import os
import base64
from anthropic import Anthropic
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
    OTLPSpanExporter,
)

# Auth para Langfuse cloud ou self-hosted: pk + sk em Basic Auth
PK = os.environ["LANGFUSE_PUBLIC_KEY"]
SK = os.environ["LANGFUSE_SECRET_KEY"]
HOST = os.environ.get("LANGFUSE_HOST", "https://cloud.langfuse.com")
AUTH = base64.b64encode(f"{PK}:{SK}".encode()).decode()

provider = TracerProvider()
provider.add_span_processor(
    BatchSpanProcessor(
        OTLPSpanExporter(
            endpoint=f"{HOST}/api/public/otel/v1/traces",
            headers={"Authorization": f"Basic {AUTH}"},
        )
    )
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("aiworkflowlab.support-bot")

client = Anthropic()

def answer(question: str, user_id: str) -> str:
    with tracer.start_as_current_span("llm.chat") as span:
        span.set_attribute("gen_ai.system", "anthropic")
        span.set_attribute("gen_ai.request.model", "claude-opus-4-8")
        span.set_attribute("gen_ai.request.max_tokens", 1024)
        span.set_attribute("user.id", user_id)          # atributo custom
        span.set_attribute("prompt.version", "v7")       # versionamento

        resp = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=1024,
            messages=[{"role": "user", "content": question}],
        )

        # Atributos GenAI padrao - lidos por Langfuse, Phoenix e Datadog
        span.set_attribute("gen_ai.usage.input_tokens", resp.usage.input_tokens)
        span.set_attribute("gen_ai.usage.output_tokens", resp.usage.output_tokens)
        span.set_attribute("gen_ai.response.finish_reasons", [resp.stop_reason])

        # Custo estimado como atributo derivado (Opus 4.8: $15 / $75 por MTok)
        cost = (resp.usage.input_tokens * 15 + resp.usage.output_tokens * 75) / 1_000_000
        span.set_attribute("gen_ai.usage.cost_usd", round(cost, 6))

        return resp.content[0].text

Três coisas a notar. Primeiro, os atributos gen_ai.* são o vocabulário padrão. Qualquer backend OTel-compliant vai renderizá-los como painel LLM sem configuração adicional. Segundo, o BatchSpanProcessor serializa em thread separada, então a instrumentação não bloqueia o request; se você medir e o SDK adicionar mais de 5 ms, é porque está serializando payload no caminho crítico e precisa mover para pós-response. Terceiro, prompt.version como atributo custom vai te salvar quando alguém alterar o system prompt e você precisar responder "quando mudou?" em cima de traces históricos. Sério, coloque desde o dia zero.

Se você prefere instrumentação zero-código, o OpenLLMetry e o endpoint OTLP nativo do Langfuse auto-instrumentam OpenAI, Anthropic, LangChain, LlamaIndex e mais de 40 outras bibliotecas via monkey-patching. Instale, defina OTEL_EXPORTER_OTLP_ENDPOINT, e você tem traces sem tocar no código de aplicação.

Rastreando agentes multi-turn e cadeias RAG

Aqui é onde o Helicone perde e as ferramentas SDK-first ganham. Um agente que chama três ferramentas e faz cinco chamadas ao modelo produz um trace com dez a vinte spans; agrupar por trace_id é a única forma de responder "por que este usuário recebeu a resposta errada?". Em agentes, cada chamada isolada pode ser 200 OK, JSON válido, dentro do SLA de latência, e o resultado final ser errado ou perigoso. Rastreando apenas chamadas isoladas você perde a falha composta.

O padrão em Langfuse e Phoenix é session > trace > span: uma sessão agrupa a conversa multi-turn, um trace agrupa um turno (input do usuário até resposta final), e spans capturam cada operação atômica dentro do turno. O código abaixo mostra o padrão em Python para uma cadeia RAG:

with tracer.start_as_current_span("rag.answer") as root:
    root.set_attribute("session.id", session_id)
    root.set_attribute("user.id", user_id)

    with tracer.start_as_current_span("rag.retrieve") as span:
        docs = vector_store.query(question, k=5)
        span.set_attribute("retrieval.k", 5)
        span.set_attribute("retrieval.doc_ids", [d.id for d in docs])
        span.set_attribute("retrieval.top_score", docs[0].score)

    with tracer.start_as_current_span("rag.rerank") as span:
        docs = reranker.rerank(question, docs, top_n=3)
        span.set_attribute("rerank.model", "bge-reranker-v2-m3")

    with tracer.start_as_current_span("llm.answer") as span:
        span.set_attribute("gen_ai.request.model", "claude-sonnet-5")
        resp = client.messages.create(
            model="claude-sonnet-5",
            max_tokens=800,
            messages=build_prompt(question, docs),
        )
        span.set_attribute("gen_ai.usage.input_tokens", resp.usage.input_tokens)
        span.set_attribute("gen_ai.usage.output_tokens", resp.usage.output_tokens)
        return resp.content[0].text

No painel do Langfuse, esse trace aparece como uma árvore: rag.answer na raiz, três filhos, cada um com timing e atributos. Quando um usuário reclama de resposta ruim, você abre o trace, olha os retrieval.doc_ids, verifica se os documentos certos foram recuperados, e se sim, olha o prompt final montado antes da chamada ao modelo. Debugging vai de horas para minutos. Se você está construindo o pipeline RAG do zero, o guia de pipelines RAG em produção cobre a arquitetura antes da instrumentação. Vale a leitura antes de sair instrumentando.

Qual ferramenta de observabilidade LLM escolher?

Depois de rodar as três em produção, meu guia de decisão é o seguinte. Vá de Langfuse se você quer open-source com licença permissiva (MIT), precisa de self-host por data residency (LGPD, GDPR, dados sensíveis) e roda agentes multi-turn ou cadeias RAG. É a escolha segura. O trade-off é operacional: você precisa gerenciar Postgres, ClickHouse, Redis e S3-compatible storage. Isso não é um docker run, é um deploy Kubernetes com Helm chart. A documentação de deploy no repositório oficial do Langfuse tem o Helm chart e a lista de variáveis de ambiente.

Vá de Helicone se sua aplicação é chamadas isoladas ao OpenAI (ou Anthropic), você quer setup em minutos, e observabilidade profunda de spans internos não é prioridade. É a escolha certa para "eu preciso ver quanto estou gastando por endpoint até amanhã de manhã". O bônus é o gateway: roteamento entre provedores, failover automático e cache semântico embutido. A limitação real: o proxy vê HTTP, não estado interno. Para agentes com cinco chamadas encadeadas você vai ver cinco requests soltos, não uma árvore.

Vá de Arize Phoenix se seu time já opera modelos ML tradicionais em produção, você quer detecção de drift em embeddings com estatística séria, e OpenTelemetry-first é requisito duro. O Phoenix é a melhor primitiva de eval das três, herdada de anos de rigor ML observability. O trade-off: a UI LLM-específica ainda amadurece (o polimento está atrás de LangSmith e Langfuse), e você paga em curva de aprendizado.

Muitos times sérios rodam dois de uma vez: Helicone como gateway na frente para roteamento e failover, Langfuse ou Phoenix atrás para tracing profundo e evals. É a arquitetura que eu recomendo se você tem tráfego suficiente para justificar. Para times pequenos, escolha um só e itere. Sério, não complique cedo demais.

O dashboard e os alertas que você vai desejar ter construído primeiro

Este é o painel que eu monto no primeiro dia de qualquer stack LLM em produção. Depois de dois incidentes de custo e um de qualidade, você chega na mesma lista.

Painéis (top-level)

  • Requests por segundo, segmentado por modelo. Detecta shift de tráfego para modelo caro após um deploy.
  • p50, p95, p99 de TTFT e total latency, segmentados por modelo e versão de prompt. As três linhas juntas mostram se caudas estão inflando ou se é degradação uniforme.
  • Custo acumulado do dia, projetado para o mês. Compare contra orçamento. É a régua honesta de "estamos ok?".
  • Tokens médios de saída por request, segmentados por endpoint. Sobe do nada? Alguém mexeu no prompt, ou o modelo mudou de comportamento.
  • Taxa de erro por tipo (429, 5xx, content_filter, JSON parse fail). Buckets separados, não um número agregado.
  • Score médio da eval (LLM-as-judge sobre amostra de 1%). Baixou? Regressão de qualidade em produção.

Alertas (sempre com janela de sustentação)

  • p99 de TTFT > 2× baseline por 15 min: provedor ou prompt.
  • Custo por hora > 1,5× média das últimas 24h: tokens explodindo em algum endpoint.
  • Taxa de 429 > 2% por 10 min: subir rate limit ou acionar fallback.
  • content_filter > 0,5% por 30 min: prompt está gerando saídas rejeitadas, revisar.
  • Score médio de eval cai 10% comparado à última semana: congelar deploy, investigar.

Configurar essa lista leva uma tarde. Você vai agradecer a si mesmo três meses depois, quando um deploy silencioso do provedor mudar o comportamento do modelo às 4h da manhã e o alerta de qualidade for a primeira coisa a apitar. (Já vi acontecer duas vezes em 2025.)

Perguntas frequentes

Qual a diferença entre observabilidade e monitoramento de LLM?

Monitoramento verifica métricas conhecidas (latência, taxa de erro, uptime); observabilidade te permite responder perguntas que você não sabia que ia fazer, correlacionando traces, prompts, respostas e evals. Em aplicações LLM, monitoramento sozinho não detecta regressão de qualidade nem gasto descontrolado por trace. Observabilidade sim.

O Langfuse é gratuito para uso comercial?

Sim. Todas as features do Langfuse (tracing, evals, prompt management, playground, experiments, human annotation) estão sob licença MIT, sem edição enterprise separada e sem cobrança por usuário no self-host. A versão cloud tem tiers pagos por volume, mas o self-hosted é completo e gratuito.

OpenTelemetry funciona para observabilidade de LLM?

Sim, e é o padrão da indústria em 2026. As GenAI Semantic Conventions do OpenTelemetry definem atributos de span (gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.response.finish_reasons) e são suportadas nativamente por Langfuse (endpoint OTLP), Phoenix e Datadog. Instrumentar via OTel te dá portabilidade entre backends.

Como reduzir custo de tokens em produção?

Três alavancas na ordem de retorno: cache de prompt (60 a 90% de corte em input tokens repetidos), roteamento para modelo menor em requests simples (classificador na frente), e cap em max_tokens por endpoint com fallback controlado. Observabilidade é pré-requisito, você precisa medir para saber onde cortar.

Preciso de eval automatizado se já tenho tracing?

Sim. Tracing responde "o que aconteceu?"; eval responde "a resposta foi boa?". Um trace 200 OK com JSON válido pode conter uma alucinação que passa despercebida sem LLM-as-judge ou revisão humana. Rode eval sobre 1% de amostra de produção para detectar regressão de qualidade sem custo proibitivo.

Cara Donovan
Sobre o Autor Cara Donovan

AI operations lead at a B2B SaaS. Builds the unglamorous infrastructure that keeps prod LLM apps from melting.