AgentSight y el nuevo tracing de LLMs: zero-instrumentation con eBPF frente a Langfuse, LangSmith, Phoenix y compañía
TL;DR
Observar un agente de LLM en producción en 2026 se divide en dos enfoques con filosofías opuestas. El instrumentado, dominante hasta 2025, vive en herramientas como Langfuse, LangSmith, Arize Phoenix, Helicone, OpenLLMetry/Traceloop o Pydantic Logfire: instalas un SDK, decoras tus llamadas, emites spans con la convención OpenTelemetry GenAI (gen_ai.request.model, gen_ai.usage.input_tokens, etc.) y los exportas a un backend. Profundidad altísima cuando controlas el código; cero visibilidad cuando el agente es un binario opaco que ejecutas sin instrumentar. El zero-instrumentation, que AgentSight ha popularizado en la segunda mitad de 2025, gira la perspectiva 180º: pone hooks eBPF en las uprobes de las bibliotecas SSL/TLS y captura el plaintext de cada petición HTTPS antes del cifrado, sin tocar el código de la app, con menos del 3% de overhead y la garantía de ser tamper-proof (el agente no puede falsificar lo que se ve en el kernel). Combinado con captura BPF de stdio para servidores MCP locales, AgentSight te da observabilidad completa de cualquier agente —incluyendo binarios cerrados como Claude Code, Gemini CLI o Cursor— en un cluster Kubernetes. Las dos familias no son enemigas: la pila de referencia 2026 combina ambas (instrumented para apps propias con LangChain, eBPF para binarios opacos y compliance de tamper-proof) sobre OpenTelemetry GenAI semantic conventions como vocabulario común que el ecosistema está estabilizando este año.
Este es el cuarto y último post de la serie sobre eBPF. Parte 1: eBPF de cero a Cilium. Parte 2: Tetragon: seguridad de runtime. Parte 3: Hubble: observabilidad de red. Aquí cerramos el círculo con la dimensión semántica —qué hace un agente IA, no solo qué red abre o qué syscalls emite—.
La analogía: APM tradicional vs sniffer de red
Quien haya operado aplicaciones empresariales conoce las dos tribus del monitoring. La tribu APM (New Relic, AppDynamics, Datadog APM): instalas un agente o un SDK en cada aplicación, marcas spans, recoges traces con profundidad enorme dentro de cada proceso —líneas de código, queries SQL, métodos de Java—. La tribu wire-level (sniffers de red, herramientas tipo SolarWinds NPM, NetFlow): no toca la aplicación; observa el cable, ve protocolos, latencias, retransmisiones, identifica problemas que la app no sabe que tiene.
Cada una ve cosas distintas y las dos sirven. Quien ha vivido un incidente serio donde APM decía “todo verde” mientras los usuarios sufrían sabe que el wire-level habría detectado el problema (un middlebox saturado, un MTU mal configurado, un timeout de TCP). Quien ha intentado debuggear un memory leak con sniffers sabe que sin APM era imposible.
La observabilidad de agentes LLM en 2026 está exactamente en este punto. El APM-style lleva un par de años montado: Langfuse, LangSmith, Phoenix, OpenLLMetry. Profundidad enorme, requiere instrumentar la app. El wire-level con eBPF acaba de llegar: AgentSight es el primer proyecto que lo lleva a productivo. Profundidad menor en el interior del agente, pero ve cualquier agente sin tocar nada y es tamper-proof. Los dos sirven. La industria está en plena coexistencia.
Por qué observar agentes LLM es distinto
Antes de entrar en herramientas, vale la pena detenerse en qué hace específicos a los agentes LLM como sujetos de observabilidad:
No-determinismo. El mismo input puede producir outputs distintos. Reproducir un incidente requiere capturar exactamente la conversación, el modelo, los parámetros y, idealmente, la seed. Una métrica agregada “latencia p95” se queda corta; lo que necesitas es replay de la traza individual.
Cadena de invocaciones externas. Un agente típico llama LLM → herramientas (tool calling) → MCP servers → otras APIs → vuelta a LLM. Una sesión de chat puede generar decenas de llamadas encadenadas que hay que correlar por trace_id para entender la decisión.
Coste lineal en tokens. Cada llamada se paga en tokens. Sin trazar input/output tokens por petición, no puedes asignar coste a tenant ni equipo, ni detectar bucles que se comen tu presupuesto en una hora.
Riesgo semántico. Prompt injection (un user input que contiene instrucciones para manipular al modelo), jailbreaks, leakage de secretos via tool calls. Es un tipo de problema que no aparece en aplicaciones tradicionales y la observabilidad debe verlo.
Binarios opacos. En 2026, muchos equipos despliegan agentes de terceros —Claude Code, Cursor agent, Aider, Gemini CLI, Codex CLI— como herramientas internas. No son aplicaciones propias; son binarios cerrados que llaman a la API del vendor. Instrumentarlos es imposible. Observarlos requiere otra cosa.
Multi-agent y orquestación. Cada vez más arquitecturas tienen agentes que invocan a otros agentes (planner → executor → critic). La observabilidad debe entender la topología, no solo el span individual.
Con estos cinco puntos en mente, las herramientas que vamos a ver se diferencian principalmente en qué partes del problema cubren bien y qué partes dejan ciegas.
El enfoque instrumentado: cómo funciona
El modelo es directo y conocido:
- Tu código llama al LLM o a herramientas usando una librería oficial:
openai,anthropic,langchain,llama_index,dspy. - Instalas un SDK del tracer (Langfuse, LangSmith, OpenLLMetry, Logfire) que wrappea o monkey-patcha esas librerías.
- Cada llamada emite un span OpenTelemetry con atributos estandarizados: modelo usado, tokens input/output, latencia, parámetros, mensajes, herramienta invocada, resultado.
- Los spans se exportan vía OTLP a un backend que los muestra como un árbol de traces.
# Ejemplo típico con OpenLLMetry + cualquier SDK
from traceloop.sdk import Traceloop
from openai import OpenAI
Traceloop.init(app_name="my-agent", api_endpoint="https://otel-collector:4318")
client = OpenAI()
# este call emite automáticamente un span con
# gen_ai.request.model, gen_ai.usage.input_tokens, etc.
resp = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": "..."}]
)
Lo que ves después: un dashboard con cada conversación como un trace, cada llamada como un span, los prompts y completions completos (si optas in), el coste calculado, latencias por span, errores marcados.
OpenTelemetry GenAI semantic conventions: el vocabulario común
La fragmentación del campo se está mitigando con OpenTelemetry GenAI Semantic Conventions. Es el esfuerzo de la CNCF para que todas las herramientas emitan spans con los mismos nombres de atributos:
gen_ai.system— el proveedor (openai, anthropic, vertex_ai, etc.).gen_ai.request.model— modelo solicitado (gpt-4.1,claude-3-5-sonnet).gen_ai.response.model— modelo realmente usado (a veces difiere, eg fallbacks).gen_ai.usage.input_tokensygen_ai.usage.output_tokens— contadores.gen_ai.request.temperature,gen_ai.request.top_p, etc. — parámetros.gen_ai.response.finish_reasons— por qué terminó (stop, length, content_filter).gen_ai.operation.name— el tipo de operación (chat, embedding, completion).
A principios de 2026, los client spans salieron de experimental a estable. El resto (server spans, multi-agent events) sigue en desarrollo. El significado operacional: si tu SDK emite estos atributos, cualquier backend que entienda OTel GenAI puede consumirlos. Cambiar de Langfuse a Phoenix a Helicone no implica re-instrumentar, solo cambiar el exporter.
La SIG está activamente desarrollando conventions for multi-agent systems: agent teams, tasks, actions, memory, artifact tracking. Esto es lo que falta para que las arquitecturas de agentes complejas tengan vocabulario común. En 2026 está experimental; se espera estabilización a finales de año o principios de 2027.
Herramientas instrumentadas: el panorama 2026
| Herramienta | Licencia | Self-host | Foco | Donde brilla |
|---|---|---|---|---|
| Langfuse | MIT | Sí | LLM observability + evals + prompt mgmt | Mejor balance OSS, suite completa |
| LangSmith | Comercial | No | LangChain/LangGraph nativo | Si usas LangChain, integración cero-config |
| Arize Phoenix | ELv2 (OSS) | Sí | OTel-native, RAG fuerte | Vector DBs, retrieval, embeddings |
| Helicone | Comercial + OSS lite | Sí (lite) | Proxy simple | Setup minutos, OpenAI-only |
| OpenLLMetry / Traceloop | Apache 2.0 | Sí | SDK OTel para LLMs | Vendor-neutral, exporta a cualquier OTel backend |
| Pydantic Logfire | Comercial | No | App + LLM unificado | Si usas Pydantic AI, integración nativa |
| Weights & Biases Weave | Comercial | Limitado | Experimentación + producción | Si ya usas W&B para training |
| Laminar / Braintrust | Comercial | No / Sí | Evals + tracing | Más recientes, foco en evaluación |
Deep dive: Langfuse
Merece detenerse en Langfuse porque es, en 2026, la elección por defecto entre las opciones open-source y la que más equipos han adoptado este año. Es proyecto de YC W23, licencia MIT, y lleva un ritmo de release sostenido con cambios arquitectónicos serios entre versiones.
Cuatro pilares declarados: observability (tracing), evaluations, prompt management, playground/datasets. Cada uno por separado tiene productos comerciales completos detrás; Langfuse los integra en una sola plataforma con un solo backend.
El SDK v4: OTEL-native, no un sustituto
El gran cambio operacional reciente es el SDK v4, una capa fina sobre el cliente oficial de OpenTelemetry. La elección es deliberada: en lugar de mantener un cliente propio que se atrase respecto a las primitives OTel, Langfuse usa el SDK estándar y enriquece los spans con atributos y helpers específicos para LLM. La consecuencia: cualquier código que ya esté instrumentado con OpenTelemetry vainilla (@opentelemetry/sdk-node, opentelemetry-sdk en Python) puede exportar a Langfuse sin cambios mayores, y al revés, si mañana quieres migrar de Langfuse a otro backend OTel, los spans son portables.
En Python el decorador idiomático es @observe:
from langfuse import observe, get_client
langfuse = get_client()
@observe()
def buscar_documentos(query: str):
# cualquier llamada interna también se traza
return vector_store.similarity_search(query)
@observe(as_type="generation")
def llamar_llm(prompt: str):
# marcada como "generation" para que aparezca con metadata LLM
return openai_client.chat.completions.create(...)
@observe()
def pipeline_rag(pregunta: str):
docs = buscar_documentos(pregunta)
return llamar_llm(build_prompt(pregunta, docs))
El árbol de llamadas se captura automáticamente: la traza muestra pipeline_rag como root span, con buscar_documentos y llamar_llm como hijos, anidados. Sin escribir un solo with tracer.start_as_current_span(...) a mano.
En TypeScript el equivalente es modular: instalas @langfuse/tracing, @langfuse/otel y @opentelemetry/sdk-node, y puedes usar decoradores TS, context managers o spans manuales —los tres modelos interoperan—. La consecuencia: bibliotecas terceras que emiten spans OTel (openai, @anthropic-ai/sdk, instrumentaciones de Vercel AI SDK) se ven en Langfuse sin trabajo adicional.
Arquitectura self-host: pensada para producción seria
La arquitectura del backend Langfuse tiene dos decisiones explícitas que distinguen su despliegue self-host:
Persistencia primero en S3/Blob Storage. Cuando un evento de tracing entra, se persiste en object storage antes de tocar la base de datos. Solo cuando el procesado posterior confirma OK se inserta en Postgres/Clickhouse. Si la DB cae temporalmente, los eventos no se pierden; quedan en S3 esperando reproceso. Para producción donde perder traces de un incidente equivale a perder evidencia, esto es load-bearing.
Migraciones largas como background jobs. Los upgrades de schema que en otras plataformas implican ventana de downtime, en Langfuse se ejecutan en background mientras la aplicación sigue sirviendo. El downtime de upgrade se reduce drásticamente.
Los modos de despliegue soportados oficialmente:
- Docker Compose: para desarrollo y POCs. Un comando, todo arriba.
- VM: un único nodo, contenedores, sin orquestación. Para entornos pequeños.
- Kubernetes con Helm: el modo recomendado para producción. Chart oficial mantenido. Soporta external Postgres, external Clickhouse, external S3, HPA.
Las dependencias externas en producción típica: Postgres (metadata, prompts, configuración), Clickhouse (eventos de tracing, queries de alta cardinalidad), S3 o blob compatible (eventos pendientes), Redis (cola entre componentes). Sí, son varias piezas; es lo que sostiene la durabilidad y la escala.
Prompt management como ciudadano de primera clase
Lo que diferencia a Langfuse de las plataformas centradas solo en tracing es que los prompts viven en Langfuse, no en el repo de la aplicación o en hojas de cálculo. Cada prompt tiene:
- Nombre y versión (v1, v2, v3…). Cambiar el prompt no requiere redeploy de la app: la app pide el prompt al SDK, que lo cachea y refresca cuando hay versión nueva.
- Variables tipadas:
{{user_input}},{{context}}. Render con validación. - Tags y labels: por entorno (
production,staging), por equipo, por experimento. - Cache cliente y servidor: el SDK cachea localmente con TTL configurable, evita roundtrip a Langfuse en cada llamada.
- Linkage con traces: cada trace recoge qué versión exacta de qué prompt se usó. Investigar “esta respuesta salió mal” lleva al prompt versión Y, no a “alguna versión del prompt en algún momento”.
from langfuse import get_client
langfuse = get_client()
prompt = langfuse.get_prompt("rag-system-prompt", version=3)
# o por label: langfuse.get_prompt("rag-system-prompt", label="production")
compiled = prompt.compile(context=docs_text, user_input=question)
# 'compiled' es el string final, listo para mandar al LLM
Para equipos que iteran sobre prompts a diario, esto es lo que evita el caos de “qué versión del prompt está corriendo realmente en producción ahora mismo”.
Evaluations: cuatro modelos de evaluación combinables
Langfuse cubre los cuatro patrones de evaluación de respuestas:
- LLM-as-a-judge: configuras un modelo (típicamente GPT-4 o Claude) con una rúbrica y evalúa cada respuesta. Resultado: score numérico (0-1) y justificación. Aplicable a tracing automático (todas las respuestas) o batch (selección de dataset).
- User feedback: la app permite al usuario marcar respuesta como buena/mala. El feedback se asocia al trace y al prompt version, lo que permite ver qué versiones tienen peor rate.
- Manual labeling: una UI donde labelers humanos puntúan respuestas. Útil para datasets dorados y para evaluar el judge.
- Custom evaluators vía API/SDK: evals propios (un test unitario, una métrica de negocio) reportan score vía API. Se integran con CI.
Combinadas, dan regression testing del prompt: cambias de v3 a v4, evalúas el dataset dorado con LLM-as-judge, comparas; si v4 empeora en alguno de los segmentos, el merge falla.
Integraciones
Langfuse no compite con OpenLLMetry, LangChain o LiteLLM: los integra. Las que están testeadas y documentadas:
- OpenTelemetry: cualquier instrumentación OTel emite a Langfuse vía OTLP.
- LangChain y LangGraph: callback nativo que captura toda la cadena.
- LlamaIndex: callback nativo.
- OpenAI SDK (Python y TS): wrapper que añade tracing automáticamente.
- LiteLLM: integración como callback, lo que cubre 100+ proveedores via LiteLLM.
- OpenLLMetry / Traceloop: emiten a Langfuse como cualquier backend OTel.
- MLflow: vía exporter OTel desde MLflow a Langfuse.
- Vercel AI SDK: instrumentación nativa.
La estrategia es clara: Langfuse es backend, no SDK. Tu equipo elige cómo instrumenta; Langfuse acepta cualquier camino. La consecuencia operativa: cambiar de Langfuse a otro backend OTel mañana es viable.
Cuándo Langfuse no es la respuesta
Para no presentarlo como bala de plata:
- Si solo usas LangChain y no tienes recursos para self-host: LangSmith te dará integración más fluida (es el mismo equipo).
- Si tu única necesidad es proxy con cost tracking sin evals: Helicone es más simple.
- Si quieres una solución vendor commercial integrada: Datadog LLM Observability, New Relic AI Monitoring o Dynatrace AI son alternativas Enterprise con soporte 24/7.
- Si tu carga es batch puro de inferencia masiva sin agentes: probablemente no necesitas tracing semántico; Prometheus + Grafana con métricas OTel basta.
Para todo lo demás —apps propias con tracing serio, multi-tenant con cuotas, equipos que iteran prompts a diario, RAG con evaluación continua—, Langfuse es la apuesta segura.
Resumen de elección rápido:
- LangChain → LangSmith (cero esfuerzo, instrumentación automática).
- Aplicaciones propias multi-framework con OSS → Langfuse (MIT, self-host, completo).
- RAG con vector stores → Arize Phoenix (mejor visibilidad de retrieval).
- Proxy simple, presupuesto bajo → Helicone.
- Vendor neutrality estricta → OpenLLMetry/Traceloop.
- Pydantic AI → Logfire (mismo equipo).
Fortalezas y debilidades del modelo instrumentado
Fortalezas:
- Profundidad enorme: spans anidados con todo el contexto (chain steps, retrieval, embeddings, tool calls).
- Vocabulario semántico: SDK conoce el dominio (LLM, vector store, agent).
- Madurez: tres años de evolución, ecosistema rico, dashboards listos.
- Evals integradas: las plataformas top combinan tracing con evaluación (judge LLM, datasets, regression).
Debilidades:
- Requiere control del código: si no puedes instrumentar, no funciona.
- Trust en la app: si la app reporta mal o tiene un bug, la traza también. No es tamper-proof.
- Acoplamiento al SDK: cambios de versión de una librería pueden romper la instrumentación.
- Cobertura desigual: SDKs de Python están maduros; Go, Rust, JS más jóvenes.
El enfoque zero-instrumentation: AgentSight
AgentSight es el proyecto del grupo eunomia-bpf que abandera el enfoque opuesto. Su paper en arxiv (2508.02736), presentado en el Workshop on Practical Adoption Challenges of ML for Systems, formaliza la propuesta. La premisa es directa:
Instead of instrumenting the agent, observe it at the system boundary.
Y “system boundary” significa el límite del kernel: el último punto antes de que un dato salga del proceso hacia la red o el filesystem. Ahí, con eBPF, se ven las cosas tal como son, sin que la aplicación pueda cooperar para esconderlas.
Arquitectura: tres planos
AgentSight monta tres capas:
Plano 1 — SSL/TLS uprobes. eBPF puede atar programas a funciones de bibliotecas userspace (uprobes). Las funciones objetivo son las de cifrado: SSL_write, SSL_read de OpenSSL/BoringSSL, equivalentes en Rustls. AgentSight les pone hooks que capturan los argumentos: el buffer plaintext que la app pasa para que sea cifrado, justo antes de que TLS lo procese. En la recepción, hace lo simétrico: hook después de SSL_read con el plaintext recién descifrado. Resultado: AgentSight ve el contenido completo de cualquier petición HTTPS que la app haga sin necesidad de man-in-the-middle ni certificados ni descifrar tráfico. El payload es plaintext porque se capturó antes de cifrarse.
Esto funciona porque las uprobes son baratas (~100 ns por invocación) y porque las apps usan bibliotecas de TLS comunes. Las pocas apps que implementan su propio TLS (raras en producción) escapan a este hook; para esas hace falta un kprobe diferente o instrumentación manual.
Plano 2 — Kernel events. Paralelamente, AgentSight observa syscalls relevantes a través de tracepoints: execve (qué procesos arrancan), connect/accept (red), read/write con file descriptors (filesystem y stdio), unlink, clone. Cualquier acción del agente que tenga efecto fuera del proceso pasa por aquí. Esto cubre, entre otros, comandos shell ejecutados por el agente —si un agente Claude Code decide ejecutar rm -rf para “limpiar el proyecto”, el execve se ve aunque la API LLM no lo reporte—.
Plano 3 — Correlation engine. Los dos planos anteriores producen streams de eventos asíncronos. AgentSight tiene un componente en userspace que los correlaciona causalmente cross-process: una petición HTTP saliente con bash -c rm -rf puede ser correlada con la respuesta LLM previa que la sugirió, vía PIDs, tiempos y heurísticas. El paper menciona el uso opcional de un LLM secundario (Anthropic Claude por ejemplo) que analiza la secuencia de eventos y produce alertas semánticas: “el agente respondió con una tool call que no estaba en la whitelist”, “la cadena de reasoning lleva 47 iteraciones sin converger”.
stdiocap: capturar stdio de servidores MCP locales
Una pieza específica que merece mención propia es stdiocap, una herramienta BPF separada incluida en el repo. El Model Context Protocol (MCP), popularizado por Anthropic en 2024 y mainstream en 2025-2026, tiene dos modos de transport: HTTP/SSE (red) y stdio (entre el cliente y el server que arranca como subproceso). Los servidores MCP locales —los que corren en la misma máquina y son arrancados por el cliente como hijos vía pipes— comunican por stdin/stdout/stderr con JSON-RPC.
stdiocap engancha read/write/dup sobre los file descriptors de stdin/stdout/stderr de un proceso target y registra todo el tráfico JSON-RPC entre cliente y server MCP. Es la misma idea que la captura SSL pero para stdio: observas la conversación sin que ni el cliente ni el server lo sepan. Caso de uso típico: ver qué tools del MCP server filesystem-mcp ha invocado un agente Claude Code en la última hora, qué argumentos pasó, qué errores recibió. Imposible con instrumentación clásica (los servers MCP suelen ser binarios de terceros).
Garantías: tamper-proof, kernel safety, <3% overhead
Tres propiedades hacen a AgentSight interesante para producción:
- Tamper-proof: la observación ocurre en el kernel (uprobes, syscalls). Una aplicación maliciosa o comprometida no puede falsificar lo que se ve. Comparar con instrumentación: si el agente decide no emitir el span de su acción, no aparece en Langfuse. Aquí no tiene elección.
- Kernel safety: eBPF verifica formalmente que los programas terminen y respeten bounds checks. No puede crashear el kernel. Igual que en el resto de la serie eBPF.
- <3% CPU overhead medido sobre cargas reales de agentes (paper). El número compara favorablemente con instrumentación SDK que típicamente añade 5-10% en aplicaciones intensas.
Lo que detecta out of the box
El paper y la documentación destacan tres clases de detección:
- Prompt injection en tiempo real: el correlation engine puede aplicar reglas o un modelo de detección sobre el plaintext capturado por las uprobes SSL. Si el prompt contiene patrones sospechosos —“ignore all previous instructions”, system prompt embebido en un user input, instrucciones para exfiltrar datos—, marca alerta.
- Reasoning loops que gastan recursos: agentes que entran en bucles infinitos llamando a herramientas sin progresar. Detectables porque la cadena causal no converge a “respuesta final” y los tokens se acumulan. El correlation engine los marca.
- Bottlenecks en multi-agent: cuando varios agentes coordinan, AgentSight ve la matriz de comunicaciones entre todos y puede detectar agentes que se bloquean esperando, deadlocks, fan-out excesivo.
El choque y la coexistencia
Las dos familias parecen competir, pero en realidad ven cosas distintas y se complementan en producción.
Lo que solo el instrumentado ve
- Variables internas del agente que no salen al cable: el estado intermedio de un chain LangChain, los valores antes de pasarlos a una herramienta, el cómo se construye un prompt a partir de un template con vars internos.
- Spans semánticos profundos:
retrieval > embed > vector_search > rerank > format_context > prompt_template > llm. AgentSight ve solo la llamada final al LLM; el camino para construirla es invisible. - Evaluaciones: scoring de respuestas, judge LLMs, regresión de calidad. Esto vive solo en plataformas instrumentadas.
Lo que solo eBPF ve
- Binarios opacos: Claude Code, Cursor, Gemini CLI, agentes de terceros. No tienes el código; no puedes instrumentarlos. Solo eBPF los ve.
- Acciones a nivel sistema: el agente decide ejecutar
git push --forceokubectl delete. La acción se ve en elexecve. La instrumentación del agente puede no reportarla (especialmente si fue un comando que el agente generó como output sin pasar por una “tool” explícita). - Tamper-proof audit: para compliance regulatorio (HIPAA, SOC2, NIS2), tener observación que la app no puede burlar tiene valor formal. eBPF lo da.
- MCP servers locales con stdio: invisibles para instrumentación clásica salvo que cada server emita sus propios spans (raro).
Lo que ambos ven, complementariamente
- Prompts y completions: instrumentado los emite con metadata rica; eBPF los captura del cable. Cross-check perfecto para detectar discrepancias.
- Llamadas a APIs externas: APM lo marca; eBPF lo confirma a nivel kernel.
- Latencia: APM por span; eBPF mide RTT a nivel TCP y conectividad red.
Matriz de decisión
| Caso | Instrumentado | eBPF (AgentSight) |
|---|---|---|
| App propia con LangChain | Sí, primero | Opcional |
| App propia multi-framework | Sí | Opcional |
| Binario de terceros (Claude Code, Cursor) | No funciona | Sí, único camino |
| Cumplimiento normativo tamper-proof | Insuficiente | Sí, requerido |
| Multi-tenant zero-trust | Insuficiente | Sí, requerido |
| Servidores MCP locales (stdio) | Difícil | Sí, con stdiocap |
| Evaluación de calidad de respuestas | Sí, requerido | No (fuera de scope) |
| Profundidad de chain interno | Sí, requerido | No (caja negra para AgentSight) |
| Reasoning loop detection | Posible con plumbing | Sí, integrado |
| Prompt injection en tiempo real | Posible (post-procesado) | Sí, en stream |
La conclusión natural: para apps propias, instrumentado; para binarios opacos o compliance, eBPF; para todo lo importante, ambos.
Arquitectura de referencia 2026
Cuatro recetas que cubren el grueso de los casos reales:
Setup A — Aplicación propia con LangChain o similar
Necesidades: profundidad, evals, equipo cómodo con SDKs.
- Langfuse self-host o LangSmith cloud como backend.
- OpenLLMetry SDK o LangSmith SDK instrumentando el código.
- OpenTelemetry Collector entre la app y el backend para flexibilidad de routing (a Langfuse + Tempo + Loki por ejemplo).
- Hubble para la capa de red en el cluster (latencia inter-pod, drop attribution).
Setup B — Productivizar un binario opaco (Claude Code, Gemini CLI)
Necesidades: observar sin tocar, auditar, controlar coste.
- AgentSight desplegado como DaemonSet sobre el cluster (o standalone en el nodo).
- Grafana con dashboards alimentados por las métricas de AgentSight.
- Exportador OTLP de AgentSight a un backend OTel (Tempo, Jaeger). Los spans usarán las semantic conventions GenAI cuando se estandaricen del todo.
- Tetragon opcional para política sobre qué puede ejecutar el agente (Sigkill si intenta
rm -rfo similar).
Setup C — Plataforma multi-tenant zero-trust
Necesidades: agentes de distintos clientes corriendo en el mismo cluster, auditoría obligatoria, ninguno confía en el otro.
- AgentSight como capa de auditoría tamper-proof. Compliance lo requiere.
- Langfuse multi-tenant para los clientes que sí instrumentan.
- Tetragon con
TracingPolicyNamespacedpor tenant (políticas distintas por namespace). - Hubble con flow logs persistentes para forensics.
- Cilium NetworkPolicy para aislar tenants entre sí en red.
Setup D — Servidor MCP local en una workstation
Necesidades: ver qué hace un agente con un MCP server stdio.
- AgentSight stdiocap apuntando al PID del cliente o del server.
- Captura JSON-RPC completo a fichero o a un endpoint OTLP.
- Visualización: Grafana o simplemente
jqsobre el log.
Caso de uso real: si estás integrando un MCP server propio y quieres ver qué tool calls hace un agente Claude Code o Cursor a tu server, stdiocap es la forma más limpia. No necesitas modificar ni cliente ni server.
Trampas operativas
Datos sensibles en prompts (instrumentado)
Por defecto, Langfuse, LangSmith y similares capturan el contenido completo de prompts y completions. Si tu app procesa PII, secretos, datos médicos, eso va a tu backend de observabilidad. Configurar redacción o content-opt-out antes de pasar a producción es obligado. OTel GenAI tiene flags específicos (OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false) para evitarlo.
Datos sensibles en prompts (AgentSight)
Mismo problema, peor: AgentSight captura literalmente lo que va al cable, plaintext. Si el agente conversó con api.openai.com con un prompt que contenía datos sensibles, AgentSight tiene ese plaintext. Hay que cifrar o redactar antes de almacenar.
Certificados pinned o TLS no estándar
Algunas apps de seguridad alta hacen certificate pinning o usan implementaciones de TLS no convencionales (Go’s crypto/tls, BoringSSL custom). En esos casos, las uprobes a libssl no las cubren. AgentSight detecta cuándo no puede observar y reporta gap; igual hay que añadir hooks específicos al SDK alternativo.
Volumen de tokens y storage
Una aplicación con tráfico medio puede generar millones de tokens al día. Si los almacenas todos en Langfuse o Phoenix con retención largos, la base de datos crece deprisa. Estrategias: sampling agresivo, retención corta para sesiones normales y larga solo para errores/anomalías, redaction de contenido y guardar solo metadata.
Tracing con sampling y consistencia
Para reducir coste, muchas instalaciones samplean: solo 1 de cada N traces se persiste. Cuidado con el sampling no consistente: un trace puede llevar varios spans en múltiples servicios, y si la decisión de samplear se toma per-span, acabas con traces incompletos. OTel tiene head sampling (en el SDK al principio) que es consistente, y tail sampling (en el collector al final) que permite reglas más finas. Para LLM, el tail sampling es ideal: muestrea todo, descarta solo las traces “normales” y conserva las que tienen errores, latencia alta o cost alto.
Multi-agent y trace propagation
Cuando agente A llama a agente B, hay que propagar el trace context (W3C Trace Context headers) para que se vea como un árbol único. Si no lo haces, ves dos traces inconexos. Las plataformas modernas lo hacen automáticamente con inject/extract, pero si tu transport entre agentes es custom (vía Redis pub/sub, vía DB), tienes que propagar a mano.
Coste de las uprobes en bibliotecas críticas
Hookear libssl añade ~100 ns por invocación. En cargas de tráfico TLS extremo (decenas de miles de conexiones/s por core), eso suma. AgentSight lo mantiene por debajo de 3% en cargas típicas de agentes (que son chatty pero no networking-intensive). Si tu uso fuese sniffing de todo el HTTPS del nodo, podría doler más.
Lo que no hemos cubierto (próxima serie)
- Evals: la siguiente capa después de tracing. Phoenix, Langfuse, LangSmith y compañía ofrecen evaluación de respuestas (judge LLM, datasets, regression). Es un mundo aparte.
- Guardrails y safety: NeMo Guardrails, Llama Guard, Llama Prompt Guard, evaluadores específicos para prompt injection y jailbreaks.
- MCP server observability profunda: cómo OpenTelemetry GenAI conventions están extendiéndose a MCP servers para trace-aware tools.
- eBPF + on-device inference: cuando el LLM corre localmente vía vLLM o llama.cpp, las uprobes pueden ver la cola tokens-output ANTES de que vayan al cliente. Territorio nuevo.
- Análisis estadístico de flows de agentes: detectar drift, outliers, patrones que indican degradación.
Cerrando la serie eBPF
Esta serie de cuatro artículos ha recorrido eBPF desde el primer principio hasta la frontera 2026:
- eBPF de cero a Cilium — qué es eBPF, hooks de networking, cómo Cilium se salta la pila TCP/IP, BGP Control Plane v2.
- Tetragon: seguridad de runtime — observabilidad y enforcement de procesos en el kernel.
- Hubble: observabilidad de red — flow logs L3-L7 y la frontera con los agentes IA.
- Este — AgentSight, tracing de LLMs, instrumentado vs zero-instrumentation.
Si has llegado hasta aquí tienes el mapa para sentarte con un equipo de plataforma, de seguridad o de IA en 2026 y reconocer qué hace cada pieza, qué problema resuelve y por dónde empezar. Toda esa pila —Cilium para CNI y BGP, Tetragon para seguridad de runtime, Hubble para observabilidad de red, AgentSight para agentes IA— compartiendo eBPF como sustrato común, gobernanza Cloud Native y vocabulario OpenTelemetry. Es la arquitectura limpia que la industria pidió hace una década y por fin existe.
Referencias
AgentSight:
- AgentSight GitHub (eunomia-bpf) — el proyecto.
- AgentSight: System-Level Observability for AI Agents Using eBPF (arxiv 2508.02736) — paper formal.
- AgentSight ACM workshop publication.
- AgentSight blog post (eunomia.dev) — descripción accesible.
OpenTelemetry GenAI semantic conventions:
- OpenTelemetry — Semantic conventions for generative AI systems — referencia oficial.
- Semantic conventions for generative client AI spans.
- Semantic conventions for generative AI metrics.
- Inside the LLM Call: GenAI Observability with OpenTelemetry (OTel blog 2026).
- Multi-agent Semantic Conventions (GitHub issue #2664).
Plataformas instrumentadas:
- Langfuse — MIT, self-host + cloud.
- LangSmith — LangChain team.
- Arize Phoenix — OSS, OTel-native.
- Helicone — proxy simple.
- OpenLLMetry (Traceloop) — Apache 2.0, SDK OTel.
- Pydantic Logfire — AI observability.
Comparativas 2026:
- Langfuse alternatives 2026 (Braintrust).
- 7 best LLM tracing tools for multi-agent AI systems (2026).
- LLMOps Observability: LangSmith vs Arize vs Langfuse vs W&B.
- Best LLM Observability Tools in 2026 (Firecrawl).
- LLM Observability on GPU Cloud (Spheron 2026 guide).
Cross-references de la serie:
- eBPF de cero a Cilium.
- Tetragon: seguridad de runtime.
- Hubble: observabilidad de red.
- Serie de inferencia LLM: KV cache, vLLM en Kubernetes, PagedAttention, Operators LLM K8s.