Todos los recursos

Langfuse es un almacén de trazas con UI, auto-hospedable, para apps LLM: registra cada prompt, completion, tool call, conteo de tokens, costo y latencia como una traza anidada, más versiones de prompts y scores de evals. Es la diferencia entre depurar un agente de verdad y andar adivinando con puros prints, solo que el self-host ahora pide Postgres Y ClickHouse, y eso te cambia las cuentas en un solo VPS.

Langfuse: tracing open-source para apps LLM

En resumen

  • Langfuse convierte una llamada al LLM en un árbol de trazas estructurado: arriba la corrida del agente, y debajo cada llamada al modelo y cada tool como spans anidados, con entradas, salidas, tokens, costo y latencia en cada nodo.
  • Sácalo en cuanto la app pase de una sola llamada. Una traza te ahorra horas de estar mirando logs tratando de reconstruir qué fue lo que el modelo realmente vio e hizo.
  • También guarda versiones de prompts y scores de evals (de un humano o de un juez LLM), así puedes ver de verdad si la calidad mejoró cuando cambiaste un prompt, y no solo creer que sí.
  • El costo real del self-host: las versiones actuales piden Postgres Y ClickHouse, no un contenedorcito. En un solo VPS, calcula bien la RAM o arranca en su tier de cloud mientras lo validas.
  • El SDK es async y dispara-y-olvida por diseño. Móntalo antes del primer resultado raro en producción, no después. Ponerse a instrumentar tracing en plena caída es el peor momento para aprender la API.

Los logs de toda la vida se diseñaron para código determinista: misma entrada, misma salida, así que un stack trace más la entrada te reproducen el bug. Las apps LLM rompen esa promesa. El mismo prompt puede devolver otra respuesta, una tool dispara en una corrida y en la siguiente no, y el fallo casi nunca es una excepción, es una respuesta segura pero equivocada que se veía bien hasta que un usuario se quejó. Langfuse existe para cerrar esa brecha: captura cada llamada al modelo y cada ejecución de tool como un span dentro de una traza, así abres una corrida y lees de punta a punta exactamente qué vio e hizo el modelo. En este artículo vamos a ver qué es Langfuse en realidad, cuándo vale la pena frente a armar tu propia tabla o irte a un competidor hosteado, un quickstart real que puedes pegar en un servicio TypeScript, y las concesiones que nadie pone en el README, sobre todo la dependencia de ClickHouse que te cambia por completo un deploy en un solo VPS.

01 · Qué es en realidad

Langfuse son dos cosas bajo un mismo logo: un SDK con el que envuelves tus llamadas al LLM, y un servidor (UI más almacenamiento) que recibe y renderiza las trazas resultantes. El modelo mental viene del distributed tracing, acotado al trabajo con LLM.

  • Una traza es una operación lógica: un turno de chat, una corrida de agente, una ronda de negociación.
  • Una generation (un tipo de span) es una llamada al modelo dentro de ella: entrada, salida, id del modelo, params, uso de tokens y costo.
  • Un span es cualquier otro paso: la ejecución de una tool, un retrieval, un paso de parseo.

Anidados bajo una traza, forman un árbol. Abre la traza de una corrida de agente que falló y vas a ver la llamada del planner, la tool de búsqueda que invocó, el resultado vacío que le volvió, y la siguiente llamada donde alucinó para tapar ese vacío, todo en orden, con tiempos y costo de tokens en cada nodo. Ese árbol es el producto. Todo lo demás (gestión de prompts, evals, dashboards) cuelga de ahí.

Nota

Langfuse es open-source (el núcleo va con licencia MIT) y auto-hospedable, y también corre como cloud gestionado. El SDK y el formato de trazas son los mismos en ambos casos, así que puedes prototipar en cloud y migrar a self-host después sin reescribir la instrumentación, una salida de emergencia que de verdad sirve.

02 · Por qué importa en agentes

Un solo chat completion rara vez necesita una traza; un agente de varios pasos siempre. Los agentes fallan de maneras que los logs de toda la vida esconden por su propia estructura. Una tool devolvió basura tres pasos atrás y el modelo siguió construyendo encima tan tranquilo. Un bucle de reintentos disparó cuatro veces y quemó tokens en silencio. Un retrieval volvió vacío y el modelo llenó el hueco inventando. Ninguno de estos casos lanza una excepción. En un log plano son una pared de líneas sin relación padre-hijo, así que no hay forma de saber qué llamada causó cuál.

Un árbol de trazas te devuelve la causalidad. Dejas de preguntarte "por qué el modelo está tan bruto" y empiezas a leer "la búsqueda no devolvió nada y entonces el planner se inventó un resultado", que es un bug común y corriente, perfectamente arreglable, no un misterio.

Scores y versiones, no corazonadas

La segunda razón por la que Langfuse importa es la medición. Puedes adjuntar un score a cualquier traza, de un revisor humano o de un juez LLM, y puedes registrar una versión de prompt para que cada traza guarde con qué versión se generó. Juntas, te dejan responder la pregunta que todo cambio de prompt trae consigo: ¿de verdad mejoró la calidad, o solo se sintió mejor en los tres ejemplos que probé? Cuando ajusto un prompt para algo como la práctica de negociación de Proyección, la única respuesta honesta sale de los scores adjuntos a las trazas a lo largo de las versiones, no de mi instinto después de un puñado de corridas.

03 · Cuándo usarlo (y cuándo no)

Usa Langfuse cuando:

  1. Tu app tiene más de una llamada al modelo por request, agentes, cadenas, flujos con retrieval.
  2. Necesitas costo y latencia por paso, no solo la factura mensual del proveedor.
  3. Quieres comparar versiones de prompts o correr evals sobre tráfico real de producción, no sobre un set de pruebas estático.

Usa otra cosa cuando:

  • Es un solo completion y ya guardas registros estructurados. Una tabla en Postgres con el prompt resuelto, la respuesta cruda, tokens y latencia quizás sea todo lo que necesitas. No metas ClickHouse para tracear una sola llamada.
  • Vives metido por completo en el tooling de un cloud. Si tu equipo ya vive dentro de un producto de observabilidad hosteado, un segundo panel puede costarte más en cambio de contexto del que te ahorra.
  • No te da el presupuesto operativo. Auto-hospedar Langfuse no sale gratis ni en RAM ni en atención; mira la sección 05.

Consejo

Un punto medio que funciona: mantén tu propio log estructurado y liviano como sistema de registro siempre activo (barato, en tu base de datos, fácil de consultar con SQL), y monta Langfuse encima para la UI rica de trazas y los evals. No son excluyentes, y ese log liviano es tu plan B si el almacén de trazas se llega a caer.

04 · Quickstart

El SDK de TypeScript es la vía más rápida para ver el valor por ti mismo. Instálalo, apúntalo a tu instancia con variables de entorno, y envuelve una llamada. Configura las llaves con LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY y LANGFUSE_BASEURL (esta última apunta a tu servidor self-hosted o al host de su cloud).

npm install langfuse

Luego crea una traza, registra una generation dentro de ella, y cierra el span con la salida. El hábito que vale la pena agarrar es una traza por corrida lógica, con cada llamada al modelo y cada tool como span hijo debajo.

import { Langfuse } from "langfuse"
import Anthropic from "@anthropic-ai/sdk"

const lf = new Langfuse()
const anthropic = new Anthropic()

async function negotiationTurn(userId: string, input: string) {
  const trace = lf.trace({ name: "negotiation-run", userId })

  const gen = trace.generation({
    name: "draft-reply",
    model: "claude-sonnet-4-5",
    input,
  })

  const res = await anthropic.messages.create({
    model: "claude-sonnet-4-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: input }],
  })

  gen.end({
    output: res.content,
    usage: {
      input: res.usage.input_tokens,
      output: res.usage.output_tokens,
    },
  })

  await lf.flushAsync()
  return res
}

Dos cosas que conviene grabarse. Primero, el SDK agrupa y envía en segundo plano, así que en contextos de vida corta (una función serverless, un script) tienes que llamar a flushAsync antes de que el proceso termine, o vas a perder la cola de tus trazas. Segundo, pásale a end el uso real de tokens que viene en la respuesta del proveedor, Langfuse puede estimar el costo, pero darle los conteos reales hace que tu dashboard de costo sea confiable y no apenas aproximado.

Importante

Trata la secret key como cualquier otra credencial: va en tu secrets manager, nunca en código de cliente ni en un archivo env subido al repo. En nuestro stack eso significa vaulting estilo Infuse, no un .env subido al repo. Si se te filtra una secret key de Langfuse, cualquiera puede escribir trazas en tu proyecto y también leerlas, y las trazas vienen llenas de prompts y respuestas en crudo.

05 · Las concesiones que nadie pone en el README

Los problemas honestos, ordenados por qué tan seguido te muerden.

El self-host ahora son dos bases de datos, no una. Las versiones actuales de Langfuse separan el almacenamiento: Postgres para los datos transaccionales y ClickHouse para la parte analítica, la que da agregaciones rápidas sobre millones de spans. Arquitectónicamente es una decisión sólida, pero significa que el footprint del self-host es un stack de varios contenedores (Postgres, ClickHouse, el servidor web, un worker, casi siempre Redis y blob storage), no una sola imagen chiquita. En un solo VPS te toca calcular la RAM a conciencia, ClickHouse en particular consume mucha memoria.

El SDK de dispara-y-olvida puede botar trazas en silencio. Ese mismo diseño async que mantiene el logging fuera del camino del request también hace que un flush que se te olvidó o una cola saturada pierdan trazas sin lanzar ningún error. Es la concesión correcta, que el request del usuario se complete pesa más que capturar su traza, pero quiere decir que Langfuse es una ayuda de observabilidad, no un libro contable apto para facturar. Guarda los números de costo de referencia en algún lado que tú controles.

Las trazas son un pasivo de privacidad por defecto. Una traza contiene el prompt y la respuesta en crudo, lo que para la mayoría de apps significa datos personales metidos en tu almacén analítico. Enmascara o hashea los campos sensibles antes de que salgan de tu servicio, ponle una ventana de retención, y cierra quién puede leer el proyecto. Un almacén de trazas sin proteger es una de las brechas más fáciles en las que caer, justamente porque se siente como "son solo logs".

El desfase de versión entre SDK y servidor es real. Como el formato va evolucionando, un SDK demasiado nuevo contra un servidor self-hosted viejo puede dejarte huecos confusos. Fija las versiones y sube el servidor y el SDK juntos en vez de dejar que se desfasen.

Langfuse es la herramienta que quiero montada antes del primer resultado raro en producción, no atornillada a las apuradas durante el incidente. El árbol de trazas se paga solo la primera vez que convierte un "el modelo está actuando raro" en un bug de una línea que puedes señalar con el dedo. Eso sí, entra con los ojos bien abiertos: el SDK es fácil, el self-host es un stack en serio, y las trazas son datos sensibles que ahora son tuyos.

Puntos clave

  • Langfuse convierte las llamadas al LLM en un árbol de trazas anidado, corrida del agente, llamadas al modelo, ejecuciones de tools, con tokens, costo y latencia en cada nodo, y eso es lo que vuelve depurables a los agentes en vez de un misterio.
  • Móntalo antes del primer resultado raro en producción, no en plena caída; el SDK es async y dispara-y-olvida, así que siempre haz flush en contextos de vida corta.
  • Apóyate en los scores y las versiones de prompt para responder si la calidad de verdad mejoró tras un cambio de prompt, en vez de fiarte de unos pocos ejemplos revisados a mano.
  • Auto-hospedar las versiones actuales implica Postgres Y ClickHouse más un worker, un stack real de varios contenedores. Calcula bien la RAM en un solo VPS, o arranca en cloud mientras lo validas.
  • Las trazas guardan prompts y respuestas en crudo, así que trata el almacén como datos sensibles: enmascara o hashea, ponle retención, cierra las lecturas, y guarda tus números de costo oficiales en algún lado que controles.

Preguntas frecuentes

¿Tengo que auto-hospedar, o hay opción cloud?

Existen las dos y usan el mismo SDK y el mismo formato de trazas. El cloud gestionado es la vía más rápida para validar si Langfuse encaja en tu flujo, sin tener que levantar Postgres y ClickHouse de entrada. Si más adelante necesitas residencia de datos o quieres tenerlo todo en tu propio VPS, migras a self-host sin reescribir la instrumentación, las llamadas en tu código quedan idénticas. Prototipa en cloud, y pásate a self-host cuando el valor ya esté probado y el presupuesto operativo se justifique.

¿Por qué el self-host necesita Postgres y ClickHouse a la vez?

Hacen trabajos distintos. Postgres guarda los datos transaccionales, proyectos, usuarios, definiciones de prompts, donde lo que quieres es consistencia. ClickHouse es una base de datos analítica columnar que vuelve rápidas las agregaciones sobre millones de spans (costo en el tiempo, percentiles de latencia, tendencias de scores), algo que a Postgres se le complica a escala. Es una separación sólida, pero sí implica que el footprint del self-host es un stack de varios contenedores, no una sola imagen chiquita. En un solo VPS, calcula la RAM a conciencia, sobre todo la de ClickHouse.

¿En qué se diferencia Langfuse de escribir mi propia tabla de trazas?

Una tabla casera es excelente como sistema de registro siempre activo y para consultas SQL que tú controlas, y para un solo completion quizás sea todo lo que necesitas. Lo que Langfuse suma es la UI del árbol de trazas (spans anidados que lees de punta a punta), los rollups de costo y tokens ya listos, el versionado de prompts, y una capa de evals/scores que de otra forma tendrías que armar tú mismo. La respuesta pragmática casi siempre es usar las dos: mantén un log estructurado y liviano como plan B, y monta Langfuse encima para la UI rica y los evals.

¿El tracing va a frenar o romper mis requests de producción?

Por diseño no debería: el SDK agrupa y envía en segundo plano, fuera del camino del request, así que un servidor de trazas lento o caído no se le propaga a la llamada del usuario. La contraparte es que las trazas se pueden botar en silencio si no haces flush en un contexto de vida corta o si la cola se satura, por eso es una ayuda de observabilidad, no un libro contable apto para facturar. En serverless o en scripts, llama a flushAsync antes de que el proceso termine, y guarda tus números de costo oficiales en algún lado que controles del todo.

¿Mis trazas no vienen llenas de datos personales que no debería estar guardando?

Sí, y ese es justo el riesgo que la gente subestima porque se siente como que "son solo logs". Una traza guarda el prompt y la respuesta en crudo, lo que para la mayoría de apps significa datos personales metidos en tu almacén analítico. Enmascara o hashea los campos sensibles antes de que salgan de tu servicio, ponle una ventana de retención forzada con un delete programado, y cierra quién puede leer el proyecto. Trata el almacén de trazas como cualquier otra tabla de datos sensibles, porque es exactamente eso.

¿Cuándo es Langfuse demasiado?

Cuando tu app es una sola llamada al modelo por request y ya guardas registros estructurados, o cuando tu equipo vive metido por completo en el tooling de observabilidad de un cloud y un segundo panel cuesta más en cambio de contexto del que ahorra. Langfuse vale la pena en agentes de varios pasos, cadenas y flujos con retrieval, donde las relaciones entre llamadas son toda la historia. Para un solo completion, no te montes un stack de dos bases de datos solo para tracearlo, una tabla simple es la herramienta correcta.

Abrir recurso (abre en pestaña nueva)

¿Prefieres que lo hagamos por ti?

Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.

Escríbenos por WhatsApp

Escríbenos por WhatsApp

Escanéalo con tu teléfono para escribirnos por WhatsApp.

Escanéalo con tu teléfono para escribirnos por WhatsApp.

¿Estás desde el teléfono y no puedes escanear? Escríbenos a info@ilustrari.com

Primera conversación gratis. Te responde el fundador.

Recursos relacionados

ToolLiteLLM

LiteLLM: un solo gateway para todos tus modelos

LiteLLM unifica más de 100 proveedores de modelos detrás de una sola API con la forma de OpenAI, y su proxy convierte las llaves, presupuestos, fallbacks y logs dispersos por todos lados en un único plano de control al que apunta todo tu stack. Aquí va qué es, cuándo un gateway justifica su existencia frente a un SDK nativo, un quickstart que puedes copiar tal cual, y las concesiones sin maquillaje, incluyendo cómo la normalización va aplanando sin avisar las funciones del proveedor de las que quizá dependes.

3 abr 202612 min de lectura
GuíaTypeScript

Observabilidad en apps de LLM: registrar lo que de verdad importa

Cuando una función de LLM falla a las 2am, "dio una respuesta rara" no te dice nada. Esta guía te muestra cómo instrumentar cada llamada al modelo como una traza estructurada (el prompt resuelto, la respuesta cruda, la secuencia de tool calls, tokens y latencia) para que puedas reconstruir con exactitud qué vio e hizo el modelo, y luego enmascarar lo sensible para que tu tabla de trazas no termine siendo tu próxima filtración de datos.

26 abr 202612 min de lectura
ToolOllama

Ollama: modelos locales con un comando

Ollama baja modelos de pesos abiertos cuantizados y los sirve en localhost detrás de una API REST limpia y un endpoint compatible con OpenAI. Así clasificar, enrutar y redactar te sale a costo marginal cero y sin que los datos salgan de la máquina. Acá va qué es, cuándo conviene un modelo local en lugar de uno de frontera, un quickstart listo para pegar y las concesiones sin maquillaje, incluyendo las cuentas de RAM que deciden si tu VPS termina muriéndose a fuerza de swap.

8 abr 202611 min de lectura