~/beer-and-code
▪ próximo evento Workshop: Jev na Prática para Devs · 14 Out · 19h — duração de 2h a 3h, ao vivo via Google Meet garantir vaga ›
~ / tutoriais / observabilidade-agentes-ia-langsmith-langfuse-helicone $
Tutoriais

Observabilidade de agentes de IA: LangSmith vs Langfuse vs Helicone (e o que cada um NÃO faz)

LS Lucas Souza · · 19 min de leitura
Observabilidade de agentes de IA: LangSmith vs Langfuse vs Helicone (e o que cada um NÃO faz)

Você colocou um agente em produção semana passada.

Hoje, o time de produto te chama porque ele está respondendo errado. Você abre o log da aplicação, encontra um JSON gigante de request e outro de response, e fica olhando pra tela tentando entender por que o agente chamou search_db três vezes seguidas antes de devolver uma resposta vazia. Log não te diz isso. Log nunca disse.

Observabilidade de agente nasceu pra cobrir esse vão. Não é log estruturado com level=info. É tracing de loop — capturar cada turno, cada decisão, cada tool call, cada stop_reason, cada token gasto, cada retry. O mercado consolidou em torno de três nomes: LangSmith, Langfuse e Helicone. Só que um deles foi adquirido e entrou em maintenance mode, e isso muda quem você deve escolher hoje.

Neste post vou mostrar o mapa frio das três opções, quando cada uma faz sentido, o que cada uma honestamente não faz, o esquema de tracing mínimo pra reconstruir a decisão do agente sem plataforma nenhuma, e na prática como subir Langfuse self-hosted ligado num projeto Laravel — mais três métricas de agente que mudam o jogo quando você começa a olhar pra elas.

TL;DR

  • O que é: comparativo direto entre LangSmith, Langfuse e Helicone + o tracing mínimo sem plataforma + setup Langfuse self-hosted em Laravel.
  • Stack/Modelos: PHP 8.1+, Laravel 10/11/12, Docker Compose, OpenTelemetry, qualquer LLM (Claude, GPT, Gemini).
  • Custo/Acesso: Langfuse é open-source (self-host free) e tem cloud paga — tabela oficial. LangSmith tem free tier de traces e plano por seat — tabela oficial. Helicone em maintenance mode desde março de 2026.
  • Repositório/Link útil: docker-compose oficial do Langfuse e CuracelDev/langfuse-laravel.

Observabilidade de agente não é log estruturado

Chatbot é fácil de observar. Pergunta entra, resposta sai, você loga input e output, conta tokens, marca latência. Pronto.

Agente é outro animal.

Um agente é um loop. Recebe um goal, decide uma ação, chama uma tool, lê o resultado, decide a próxima ação, chama outra tool, descobre que errou, faz retry com prompt diferente, chama uma terceira tool, e só então responde. Cada uma dessas etapas é um span. Cada span tem custo, latência, payload e uma decisão por trás. Quando alguma coisa quebra, você precisa ver a sequência inteira pra entender se o problema foi o prompt do passo 1, a tool do passo 2, ou o modelo desistindo no passo 4.

Por isso ferramentas de LLM observability não nasceram como APM tradicional. Elas nasceram pra modelar o que Mostafa Ibrahim chama de "anatomia do loop": trace por turno, decisão registrada, tool call com input/output/erro, stop reason explícita e custo agregado por outcome.

Quatro pilares na prática: tracing (a estrutura do loop), métricas (loop length, tool error rate, cost per successful task), evals (avaliação offline contra um dataset) e alertas (loop infinito, custo por task acima do esperado, tool error rate subindo).

Quem entrega isso bem? Três players sobraram em pé.

As três opções na mesa — e o critério que não expira

Comparativo de ferramenta envelhece rápido: preço muda, tier muda, empresa é adquirida. Então antes dos nomes, os quatro critérios que continuam valendo depois que a tabela de preços mudar:

  1. Quem mantém e com que fôlego. Projeto com mantenedor único, adquirido ou sem commit recente é dívida futura, não economia.
  2. Portabilidade do dado. Se a ferramenta fala OpenTelemetry, trocar de plataforma é reapontar um endpoint. Se ela só fala SDK proprietário, trocar é reescrever a instrumentação.
  3. Onde o trace mora. Trace tem prompt e output, e prompt e output frequentemente têm PII. Ou você tem self-host, ou você tem uma conversa com o jurídico.
  4. Custo por trace no seu volume real. Free tier medido em traces por mês estoura rápido em agente ativo — um loop de 6 passos é 6 spans, não 1.

Com isso na mão, o mapa:

LangSmith — quando você vive dentro do LangChain

LangSmith é da própria LangChain. E é exatamente isso que ela faz melhor: se você roda LangChain ou LangGraph, o trace já vem com diff de state node a node, o execution graph do agente desenhado, breakdown de cada chamada de modelo e tool, e replay contra uma versão diferente do modelo sem refazer o código.

Preço: tem free tier de traces com retenção curta e um plano por seat com traces inclusos mais overage por mil traces. Os números mudam com frequência — confira a tabela oficial antes de decidir. O que não muda é a estrutura da cobrança: você paga por assento e por volume de trace, e agente gera muito mais trace que chatbot. Self-hosted existe, mas só no Enterprise — pra times que precisam de data residency, prepare-se pra negociar.

O que LangSmith não faz bem: se você não roda LangChain, perde a maior parte do valor. Ela suporta SDKs framework-agnostic, sim, mas o que justifica o preço é o entendimento profundo da framework. Em stack Python crua, Anthropic SDK direto, ou qualquer coisa fora do ecossistema da LangChain, você está pagando por feature que não usa.

Langfuse — o líder open-source

Langfuse virou o default open-source. Self-host via Docker Compose, seis serviços rodando (langfuse-web na 3000, langfuse-worker na 3030, ClickHouse pra analítica, MinIO pra blobs, Redis pra fila, Postgres 17). Cloud com tier gratuito pra começar e planos pagos por uso.

O que faz Langfuse ganhar não é só o preço. É a arquitetura: ela aceita OpenTelemetry nativo no endpoint /api/public/otel. Qualquer stack que fale OTLP/HTTP — Python, JS, Go, Java, PHP via OTel SDK — entrega trace direto sem precisar de SDK proprietário. Isso destrava integração com basicamente todo mundo, inclusive Laravel. E é o que faz o critério 2 lá de cima passar: se amanhã você quiser sair, o exportador continua o mesmo.

Inclui prompt management com versionamento, A/B e rollback dentro da plataforma. Não é addon caro.

O que Langfuse não faz: integração nativa fora de Python e TypeScript. Tem pacotes da comunidade pra PHP, Go, Elixir — mas a maioria depende do caminho OTel. E auto-hospedar significa operar ClickHouse, o que não é trivial se ninguém no time já mexeu com OLAP.

Helicone — o proxy que parou no tempo

Helicone era a opção mais barata de instalar: você trocava o base URL da OpenAI pelo proxy do Helicone e tinha observability instantânea, sem mexer no código.

Era.

Em 3 de março de 2026 a Mintlify anunciou a aquisição e a Helicone entrou em maintenance mode. Citação direta do anúncio:

"Helicone's services will remain live for the foreseeable future in maintenance mode. This means security updates, new models, bug & performance fixes all keep shipping."

Traduzindo: continua de pé. Não vai cair amanhã. Bug fix sai, modelo novo entra, security patch também. Mas o roadmap morreu. Não vai ter feature nova. Não vai ter melhoria de evals. Não vai ter integração com o framework que aparecer no mês que vem.

Se você já tem produção em cima do Helicone, dá pra continuar tranquilo enquanto migra com calma — e vale conferir o blog e o changelog deles antes de qualquer decisão grande, porque status de produto adquirido muda sem aviso nos dois sentidos. Se você está começando um projeto agora, não escolha Helicone. Os próprios founders, no anúncio, indicaram que vão ajudar quem quiser migrar pra alternativas.

E o Datadog?

Datadog entrou no jogo com LLM Observability: tem free tier medido em spans por mês e planos pagos por volume de span. AI Agent Monitoring foi pra GA em junho de 2025.

O caso de uso é claro: se seu time já é shop Datadog, já paga pelo APM, já tem dashboards e alerting montados, faz sentido adicionar LLM Observability ali em vez de subir mais uma ferramenta. A integração é ótima.

O contra é honesto: relatos consistentes apontam aumento de 40 a 200% na conta quando o time adiciona monitoramento de LLM no Datadog, porque spans de LLM são muito mais densos que spans de HTTP. Se você não está disposto a engolir esse aumento, vá de Langfuse.

Tracing sem plataforma: o mínimo viável em qualquer stack

Antes de escolher SaaS, monte o registro. Toda plataforma desta lista é, no fundo, um leitor bonito de eventos que a sua aplicação emite. Se os eventos não existirem, nem Langfuse nem LangSmith inventam. E se eles existirem num formato decente, trocar de plataforma depois vira reapontar um exportador num sábado à tarde.

O mínimo viável é uma linha por passo do loop, num lugar que você consiga consultar: uma tabela no Postgres, um NDJSON por dia, um índice no seu stack de logs. Um trace_id por execução do agente, um step incremental, e o resto do payload descrevendo o que aconteceu naquele passo. Em Laravel, isso é uma migration de dez minutos:

Schema::create('agent_steps', function (Blueprint $table) {
    $table->id();
    $table->ulid('trace_id')->index();
    $table->unsignedSmallInteger('step');
    $table->string('kind');                 // llm_call | tool_call | decision | final
    $table->string('model')->nullable();
    $table->string('prompt_version')->nullable();
    $table->string('prompt_hash', 64)->nullable();
    $table->unsignedInteger('prompt_tokens')->default(0);
    $table->string('tool')->nullable();
    $table->json('tool_args')->nullable();          // já redigido
    $table->text('tool_result_preview')->nullable(); // truncado
    $table->string('outcome')->nullable();          // ok | error | timeout
    $table->string('stop_reason')->nullable();
    $table->unsignedInteger('output_tokens')->default(0);
    $table->unsignedInteger('cost_micros')->default(0);
    $table->unsignedInteger('latency_ms')->default(0);
    $table->timestamps();
});

O que registrar em cada passo, sem exceção: o input que entrou naquele turno, a identidade do prompt final (versão + hash + tamanho em tokens do que foi realmente enviado, não o template), o nome da tool chamada, os argumentos com que ela foi chamada, o resultado dela com um campo de outcome separado do texto, a decisão que o modelo tomou depois de ler esse resultado, o stop_reason e o custo. Custo eu guardo em micros de dólar como inteiro — float pra dinheiro é bug esperando data.

O que não registrar: PII crua (CPF, e-mail, telefone passam por redator antes de ir pro banco), credencial de qualquer tipo — inclusive a que veio dentro do argumento de uma tool — e o payload inteiro de retorno de API. Um tool_result_preview truncado em 2 KB resolve 90% da investigação; se você precisa do corpo completo, joga o blob no object storage e guarda só o ponteiro. Sem esse corte, a tabela de trace vira a maior do banco em duas semanas, e você acaba desligando o tracing justamente quando ele começaria a servir.

Reconstruir a decisão é o teste de qualidade do log: select * from agent_steps where trace_id = ? order by step tem que te dar uma narrativa legível sem abrir o código. "Entrou pedido do usuário X, prompt v7, o modelo pediu consultar_pedido com {'id': 8891}, a tool voltou 404, o modelo pediu de novo com {'id': '8891'}, voltou ok, ele respondeu." Se a leitura em ordem não conta essa história, falta campo. Volume alto? Amostre por outcome, não por sorteio: 100% dos traces com erro, 5 a 10% dos que deram certo, retenção quente de 30 dias e o resto pro frio.

São quatro os pontos onde o agente costuma quebrar, e os quatro só aparecem se estiverem no log. Um: o prompt final não é o que você acha que é — histórico truncado, resultado de tool gigante empurrando a instrução pra fora da janela, template renderizado com variável vazia; por isso o hash e a contagem de tokens do enviado, não do template. Dois: o argumento da tool — o modelo devolve {"pedido_id": "o número do pedido"}, um enum que não existe ou o tipo errado; logue os args crus antes da validação e o erro de validação depois. Três: o resultado que o agente não consegue ler — sua integração devolve um 500 como string, o agente interpreta aquilo como conteúdo e tenta de novo com outro argumento, em loop; daí o campo de outcome separado do texto. Quatro: a parada — stop_reason de max_tokens no meio de um JSON, ou o loop batendo no teto de iterações; sem stop_reason e contagem de passos, isso chega pro usuário como "resposta estranha" e pra você como nada.

Cada um desses quatro pontos mora numa peça diferente do harness: estado, roteador de tools, validação de I/O e limite do loop. Se essa separação não estiver clara no código, o log vai ficar tão confuso quanto o agente — escrevi a anatomia de um agent harness justamente pra separar essas peças antes de instrumentar qualquer coisa.

Quando vale plugar plataforma: quando você quer diff entre versões de prompt, eval offline contra dataset, alerta automático em cima de métrica agregada, ou quando mais de duas pessoas precisam olhar trace sem pedir acesso ao banco. Quando é overhead: um agente, um tipo de task, poucas centenas de execuções por dia. Subir seis containers e operar ClickHouse pra visualizar 200 traces/dia é engenharia de vitrine. Comece pela tabela, migre quando doer.

Quando o time pergunta "por que ele fez isso?" e a única resposta é abrir o banco e ler o trace na mão, o gargalo deixou de ser o modelo e passou a ser a arquitetura. Responder "por que ele fez isso" é o módulo 9 do Lab: tracing, evals e custo por task em cima do mesmo loop de tool calling, roteamento, memória e grounding que a gente monta ao vivo. AI Engineering Lab 3ª edição, 19 e 20/09/2026, das 9h às 13h, online ao vivo via Google Meet, Lote 1 por R$ 37 — ver a agenda completa.

▪ Clã Beer and Code

Tutorial te mostra o caminho — no Clã você constrói junto. Aula ao vivo toda semana, projetos reais de Engenharia de IA, ao lado de quem já está em produção.

Entrar no Clã

Setup Langfuse self-hosted num projeto Laravel

Vamos sair da teoria. Cenário: você tem um app Laravel rodando IA (Prism, chamada direta ao Anthropic SDK PHP, qualquer coisa) e quer ver os traces. Quatro passos.

Passo 1: subir o Langfuse local

Clone o repo e levante o docker-compose:

git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up -d

Depois de 2 a 3 minutos o langfuse-web loga Ready. Abre http://localhost:3000, cria a primeira conta (vai virar admin), cria um projeto. Antes de subir pra qualquer ambiente compartilhado, troque todos os secrets marcados com # CHANGEME no docker-compose — o setup default é pra brincar, não pra prod.

Passo 2: gerar as API keys

Na UI do projeto, vai em Settings → API Keys → Create new API key. Anota a public key (pk-lf-...) e a secret key (sk-lf-...). Vão pro .env do Laravel.

Passo 3: instalar o pacote Laravel

Existe mais de uma opção. Pra começar, CuracelDev/langfuse-laravel é o caminho mais direto (PHP 8.1+, Laravel 10/11/12):

composer require curaceldev/langfuse-laravel
php artisan vendor:publish --provider="Curacel\Langfuse\LangfuseServiceProvider" --tag="langfuse-config"

No .env:

LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=http://langfuse.local:3000
LANGFUSE_ENABLED=true

Apontar o LANGFUSE_HOST pro container self-hosted é o que separa cloud de on-prem. Se você for cloud, troca por https://cloud.langfuse.com.

Pra times que já tem OpenTelemetry rodando no Laravel, a alternativa é o mliviu79/laravel-langfuse-prism: exporta via OTel não-bloqueante, com queue do Laravel pra não bloquear request. Mais setup, mas integra com o resto da observabilidade do app.

Passo 4: instrumentar uma chamada de agente

Trace mínimo num service que orquestra um agente:

use Curacel\Langfuse\Facades\LangFuse;
use Curacel\Langfuse\DTO\TraceConfig;

class AtendimentoAgent
{
    public function handle(string $userMessage): string
    {
        $langfuse = LangFuse::tracing();

        $trace = $langfuse->trace(
            TraceConfig::create('atendimento-agent')
                ->withUserId(auth()->id())
                ->withMetadata(['canal' => 'whatsapp'])
        );

        $span = $trace->span(name: 'classificar-intencao');

        $span->generation(
            name: 'gpt-classify',
            model: 'gpt-4o-mini',
            modelParameters: ['temperature' => 0.0],
            input: $userMessage,
        );

        $intent = $this->classify($userMessage);

        $resposta = match ($intent) {
            'pedido_status' => $this->consultarPedido($trace, $userMessage),
            'reclamacao'    => $this->abrirChamado($trace, $userMessage),
            default         => $this->fallback($trace, $userMessage),
        };

        $trace->end(['input' => $userMessage, 'output' => $resposta]);
        $langfuse->syncTraces();

        return $resposta;
    }
}

Cada span que você cria no trace vira um nó na visualização. Cada generation registra modelo, parâmetros, input e output — Langfuse calcula custo automaticamente pelos preços tabelados. Em $langfuse->syncTraces() você dá o flush, mas em produção isso vai pra job assíncrono — bloquear o request HTTP esperando a ingestão do trace é o tipo de coisa que mata a latência sem necessidade.

Passo 5: ver no dashboard

Abre o projeto na UI do Langfuse. Cada execução do agente aparece como um trace, expansível em árvore. Você vê o userMessage, vê a decisão de intent, vê qual branch foi seguida, vê quanto custou e quanto demorou. Quando o agente quebrar amanhã às três da manhã, é nessa árvore que você vai olhar primeiro.

Três métricas de agente que mudam o jogo

Subir tracing é metade do trabalho. A outra metade é olhar pras métricas certas. Três que aparecem pouco em tutorial e mudam o jogo quando você liga.

1. Loop length médio por tipo de task

Não é só "o agente tá lento". É: pra tarefa X, ele leva quantos passos em média? Se um pedido_status leva 3 passos em 90% dos casos e de repente subiu pra 7, ou o prompt mudou ou a tool mudou ou o modelo mudou. Esse delta é alerta antes de quebrar.

2. Tool call success rate por ferramenta

Agrupe por nome de tool e meça success rate. Tool error rate é o sinal de confiabilidade mais rápido que você tem. Quando consultar_estoque cai de 98% pra 80%, o problema raramente é o LLM. É a integração que pifou, e o agente está tentando entender o erro em vez de gritar pra cima.

3. Cost per successful task

Esquece "cost per request". Mede custo por outcome bem-sucedido. Se você tem 100 atendimentos e 30 falharam, o custo real por sucesso é total_token_cost / 70, não /100. Métrica que conta retry como sucesso te engana. Métrica que ignora retry te quebra no fim do mês.

Essas três você consegue extrair direto do Langfuse via export pra ClickHouse ou via API. LangSmith dá o mesmo. Helicone dá o que já tinha — e é isso que vai continuar tendo. E, se você seguiu a seção anterior, as três saem de um group by na sua própria tabela de passos, sem plataforma nenhuma.

Limitações e pontos de atenção

Antes de comprar a narrativa "Langfuse resolve tudo", olha o que dói.

  • Self-host pesa. Seis serviços, ClickHouse incluso. Se ninguém no time já operou ClickHouse, prepare-se pra aprender — não é Postgres. Pra projeto pequeno, cloud sai mais barato em horas de engenheiro.
  • OTel via PHP exige escolha consciente. Pacote SDK próprio (mais simples) ou pacote OTel não-bloqueante (mais alinhado com observabilidade do app inteiro). Não tem certo. Tem trade-off.
  • Free tier de trace estoura antes do que você imagina. Um loop de 6 passos consome 6 spans. Agente medianamente ativo come a cota mensal em dias, não em meses. Faça a conta em spans, nunca em requests.
  • Privacidade. Trace contém prompt, contém output, frequentemente contém PII. Se você manda pro cloud, manda. Self-host existe pra esse caso e ponto.
  • Não conta com Helicone novo. Qualquer feature que você precisar e o Helicone não tiver hoje, provavelmente não vai ter. Greenfield ali é construir em cima de plataforma que parou.

FAQ rápido

Posso usar Langfuse na cloud sem self-host? Sim. Tem tier gratuito pra começar e planos pagos por uso — tabela oficial aqui. Se não tem requisito de data residency e o time é pequeno, cloud é o caminho prático.

Helicone vai continuar funcionando em produção? Segundo o próprio anúncio da aquisição o serviço fica vivo em maintenance — security, bug fix e modelos novos seguem. Só não conte com feature nova, e cheque o changelog deles antes de apostar algo grande. Pra greenfield, escolha outra coisa.

Posso combinar mais de uma ferramenta? Comum. Langfuse pra tracing de LLM via OTel + Datadog pro APM tradicional do resto do app é setup que funciona. O que você quer evitar é pagar dois SaaS fazendo a mesma coisa.

Tem evals offline ou só tracing? Langfuse e LangSmith têm datasets, execução de eval contra prompt versionado, comparação entre runs. Helicone nunca foi forte aí — eval sempre foi caso de uso secundário pra eles.

Conclusão

O mapa de LLM observability é mais simples do que parece. Se você roda LangChain ou LangGraph, LangSmith ainda é a melhor experiência integrada. Se você quer open-source self-hostable, controle do dado, integração via OpenTelemetry e prompt management dentro da caixa, vá de Langfuse. Se você já vive dentro do Datadog, ative o LLM Observability lá. Helicone seguia sendo a opção mais barata de instalar — só que entrou em maintenance mode, então não comece projeto novo nele.

E se nada disso couber no orçamento ou no calendário desta sprint: comece pela tabela de passos. Trace bom em banco feio vale mais que dashboard bonito sem evento nenhum.

A pergunta que importa não é qual plataforma é a melhor. É: quais três métricas você vai olhar amanhã de manhã, depois que ligar tracing? Loop length, tool success rate e cost per successful task são um bom começo. Sem elas, observability vira dashboard bonito que ninguém abre.

Se esse tipo de discussão prática — qual ferramenta de observability ligar num projeto Laravel rodando IA, qual métrica importa em agente real — é o que te interessa, é exatamente o que rola na Beer and Code, a melhor comunidade de AI engineering em português, com grupo no WhatsApp aberto pra quem está construindo IA em produção.

Lucas Souza
Escrito por
Lucas Souza

{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.

▪ Clã Beer and Code

Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.

Entrar no Clã
Conheça o Clã Beer and Code
tocando