Skip to content
Volver al blog
Open Source

La observabilidad de agentes IA esta rota. Esto es lo que construimos en su lugar.

Vstorm · · 8 min de lectura
Disponible en: Deutsch · English · Polski
Tabla de contenidos

Despliegas un agente IA en produccion. Comienza a tomar decisiones extranyas. El cliente dice “el agente me dio el precio equivocado.” Abres tu dashboard de observabilidad y ves… 50.000 spans. Trazas anidadas. Llamadas a herramientas dentro de llamadas a herramientas. Contadores de tokens. Latencias. Un oceano de datos sin forma obvia de encontrar que salio mal.

TL;DR

  • Los dashboards estandar fallan para agentes IA - las trazas LLM son anidadas, ramificadas y dependientes del contexto. La observabilidad estilo HTTP no es suficiente.
  • Lenguaje natural a SQL es la abstraccion correcta - pregunta “por que el agente hizo X” y obtiene automaticamente la respuesta SQL a traves de un asistente Logfire potenciado por IA.
  • Una extension de Chrome inyecta el contexto de la traza - sin copiar IDs de trazas. El asistente ya sabe que traza estas viendo.
  • La seleccion multi-span permite analisis comparativo - selecciona varios spans y compara uso de tokens, latencia o patrones de llamadas a herramientas.
  • Memoria basada en archivos + consultas estructuradas superan a los dashboards - el objetivo es responder “que salio mal?” en lenguaje natural, no construir mas graficos.

El estado de la observabilidad de agentes IA

Este es el estado de la observabilidad de agentes IA en 2026. Las herramientas estan construidas para servicios web - peticion/respuesta, codigos de estado HTTP, tasas de error. Pero los agentes IA no siguen patrones de peticion/respuesta. Hacen bucles, se ramifican, llaman herramientas que llaman otras herramientas. Un solo mensaje de usuario puede generar 15 spans a traves de 3 sub-agentes.

Hemos instrumentado cada agente de produccion que hemos construido en Vstorm usando Pydantic Logfire. Logfire es excelente capturando los datos - cada llamada LLM, cada invocacion de herramienta, cada token. Pero consultar esos datos con dashboards SQL es como leer codigo ensamblador. Necesitas una capa de traduccion.

Asi que construimos una: un asistente Logfire potenciado por IA que traduce preguntas en lenguaje natural a consultas SQL contra tus datos de Logfire.

El problema: SQL no es como se depuran los agentes

Logfire almacena todo en un formato consultable por SQL. Puedes escribir:

SELECT span_name, duration, attributes
FROM records
WHERE trace_id = '0af7651916cd43dd8448eb211c80319c'
AND span_name LIKE '%tool_call%'
ORDER BY start_timestamp;

Pero cuando estas depurando “por que el agente recomendo el producto equivocado”, no quieres escribir SQL. Quieres preguntar: “Muestrame todas las llamadas a herramientas de la ultima hora donde el agente llamo a la herramienta de precios con parametros incorrectos.”

Eso es exactamente lo que hace nuestro asistente Logfire. Lenguaje natural de entrada, consultas SQL de salida, resultados formateados como tablas o graficos.

Arquitectura: NL a SQL a graficos

El asistente es un agente Pydantic AI con acceso a la API de consultas de Logfire:

class LogfireAgent:
def __init__(self):
self.agent = Agent(
model=model,
system_prompt=self._build_system_prompt(),
)
def _build_system_prompt(self):
return f"""You are a Logfire data analyst.
You have access to the Logfire database with these tables:
{schema}
Current environment: {environment}
Time range: {time_range}
When the user asks about their agent's behavior:
1. Translate their question into SQL
2. Execute the query against Logfire
3. Format results clearly
4. Generate chart specs if appropriate
"""

El prompt del sistema se construye dinamicamente con el esquema real de la base de datos, el entorno actual y el rango de tiempo seleccionado. Esto asegura que el agente escriba SQL valido contra la estructura real de las tablas.

Inyeccion dinamica de contexto

La clave para que esto funcione es el contexto. El agente necesita saber:

  • Que esquema esta disponible - obtenido del endpoint /v1/schemas de Logfire
  • Que entornos existen - consultado desde deployment_environment en la tabla de registros
  • Que rango de tiempo consultar - configurable, con valores predeterminados inteligentes
  • Que traza esta viendo el usuario - inyectado desde la extension del navegador
async def get_schema(self) -> str:
"""Fetch database schema from Logfire API."""
async with AsyncLogfireQueryClient(
read_token=token,
base_url=self.base_url,
) as client:
response = await client.client.get("/v1/schemas")
schema_data = response.json()
return schema_to_sql(schema_data)
async def get_environments(self, days: int = 7) -> list[str]:
"""Query distinct deployment environments."""
sql = f"""
SELECT DISTINCT deployment_environment
FROM records
WHERE start_timestamp >= now() - INTERVAL '{days} days'
AND deployment_environment IS NOT NULL
ORDER BY deployment_environment
"""
# Execute and cache...

Validacion SQL: seguridad primero

Cada consulta SQL que el agente genera pasa por validacion antes de la ejecucion. El validador asegura:

  • Sin operaciones de escritura (INSERT, UPDATE, DELETE, DROP)
  • Sin funciones peligrosas
  • Las consultas se mantienen dentro del alcance del proyecto del usuario
  • Los rangos de tiempo se respetan

Esto es critico porque el agente tiene acceso de lectura a datos de observabilidad de produccion. Una consulta DELETE alucinada podria eliminar datos de trazas.

La extension de Chrome: depuracion consciente del contexto

La caracteristica mas poderosa es la extension de Chrome. Cuando estas viendo una traza en la interfaz web de Logfire, la extension:

  1. Detecta que estas en una pagina de Logfire
  2. Extrae el ID de traza actual y el contexto del span de la URL
  3. Abre un panel lateral con el asistente IA
  4. Inyecta el contexto de la traza en el prompt del sistema del agente
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
const isLogfirePage =
tab.url.includes('logfire.pydantic.dev') ||
tab.url.includes('logfire-us.pydantic.dev');
if (isLogfirePage && (changeInfo.url || changeInfo.status === 'complete')) {
const context = extractLogfireContext(tab.url);
if (context) {
await chrome.storage.local.set({
[`context_${tabId}`]: context,
});
chrome.runtime.sendMessage({
type: 'CONTEXT_UPDATED',
tabId,
context,
});
}
}
});

Ahora cuando preguntas “por que fallo esta llamada a herramienta?”, el agente ya sabe que traza estas viendo. Sin copiar IDs de trazas.

Seleccion multi-span

La extension soporta seleccionar multiples spans en la interfaz de Logfire para analisis comparativo:

if (message.type === 'SPAN_CONTEXT_TOGGLED') {
const contexts = result[`spanContexts_${tabId}`] || [];
const spanContext = message.spanContext;
let newContexts;
if (message.selected) {
newContexts = [...contexts, spanContext];
} else {
newContexts = contexts.filter(c => c.spanId !== spanContext.spanId);
}
chrome.storage.local.set({ [`spanContexts_${tabId}`]: newContexts });
}

Selecciona 3 spans, pregunta “compara el uso de tokens en estas tres ejecuciones del agente” - el asistente tiene todo el contexto.

Streaming WebSocket con visualizacion de herramientas

El backend transmite respuestas via WebSocket, incluyendo eventos de llamadas a herramientas:

async with logfire_agent.agent.iter(
user_message,
deps=deps,
message_history=model_history,
) as agent_run:
async for node in agent_run:
if Agent.is_model_request_node(node):
async with node.stream(agent_run.ctx) as stream:
async for event in stream:
if isinstance(event, PartDeltaEvent):
await manager.send_event(
websocket, "text_delta",
{"content": event.delta.content_delta},
)
elif Agent.is_call_tools_node(node):
async with node.stream(agent_run.ctx) as stream:
async for event in stream:
if isinstance(event, FunctionToolCallEvent):
await manager.send_event(
websocket, "tool_call",
{"tool_name": event.part.tool_name,
"args": args_value},
)
elif isinstance(event, FunctionToolResultEvent):
await manager.send_event(
websocket, "tool_result",
{"result": str(event.result.content)},
)

El frontend muestra: streaming de texto token por token, consultas SQL siendo construidas, resultados de consultas en tablas formateadas y especificaciones de graficos que se renderizan interactivamente.

Soporte multi-proveedor LLM

El asistente soporta multiples proveedores LLM de forma nativa:

class LLMProvider(str, Enum):
OPENAI = "openai"
OPENROUTER = "openrouter"
PYDANTIC_AI_GATEWAY = "pydantic_ai_gateway"
def get_default_model(has_openai, has_openrouter, has_gateway) -> ModelInfo | None:
"""Get default model. Priority: Gateway Claude > OpenRouter Claude > OpenAI GPT.
Returns a ModelInfo object with model ID, provider, and display name."""
if has_gateway:
return _MODEL_BY_ID.get(DEFAULT_GATEWAY_MODEL_ID)
if has_openrouter:
return _MODEL_BY_ID.get(DEFAULT_OPENROUTER_MODEL_ID)
if has_openai:
return _MODEL_BY_ID.get(DEFAULT_OPENAI_MODEL_ID)
return None

Los usuarios configuran sus claves API en el panel de configuracion. El sistema selecciona automaticamente el mejor modelo disponible.

Que preguntas puedes hacer?

Aqui hay preguntas reales que usamos diariamente para depurar nuestros agentes de produccion:

  • “Muestrame las ejecuciones de agente mas lentas de la ultima hora”
  • “Cuantos tokens gastamos en llamadas a herramientas vs. completions hoy?”
  • “Encuentra todas las ejecuciones donde el agente llamo a la misma herramienta mas de 5 veces”
  • “Cual es la tasa de error para la herramienta de precios esta semana?”
  • “Compara la latencia entre GPT-4o y Claude para el mismo tipo de tarea”
  • “Muestrame todas las ejecuciones donde el agente excedio 100k tokens”

Cada pregunta se traduce a SQL, se ejecuta contra Logfire y se devuelve como una tabla formateada o grafico.

Conclusiones clave

  • Los dashboards estandar fallan para agentes IA. Las trazas LLM son anidadas, ramificadas y dependientes del contexto. Necesitas una interfaz de consulta que entienda patrones de agentes, no solo codigos de estado HTTP.
  • Lenguaje natural a SQL es la abstraccion correcta. Tus datos de Logfire ya son consultables por SQL. El asistente IA cierra la brecha entre “por que el agente hizo X” y el SQL necesario para responder eso.
  • El contexto del navegador hace la depuracion sin esfuerzo. La extension de Chrome inyecta la traza actual en el contexto del asistente. Sin copiar. Sin cambiar de contexto.
  • La seleccion multi-span permite analisis comparativo. Selecciona multiples spans y pide al asistente que los compare - uso de tokens, latencia, patrones de llamadas a herramientas.
  • Esto es observabilidad para humanos, no para dashboards. El objetivo no son mas graficos. Es responder “que salio mal?” en lenguaje natural.

Pruebalo tu mismo

logfire-assistant - asistente Logfire potenciado por IA con consultas en lenguaje natural a SQL, extension de Chrome y analisis multi-span.

Compartir artículo

Artículos relacionados

¿Listo para desplegar tu app de IA?

Elige tus frameworks, genera un proyecto listo para producción y despliega. 75+ opciones, un comando, cero deuda de configuración.

¿Necesitas ayuda construyendo agentes de IA?