MÓDULO 6 · OBSERVABILIDAD · LECCIÓN 02 · 25 MIN

Cuatro rutas de instrumentación

Instrumentar no es "añadir logs". Es elegir en qué capa te enganchas. El wrapper ve las llamadas al modelo, el decorador ve tus funciones, el callback ve los pasos internos del framework y las variables de entorno no ven nada que el framework no exponga ya. Elegir mal no rompe nada: te deja un árbol sin ramas.
01 — Los cuatro enganches
Dónde se conecta cada uno
# 1. Wrapper del cliente — cambia el import, nada más
from langfuse.openai import openai
client = openai.OpenAI()

# 2. Decorador — convierte TU función en un nodo de la traza
@observe()                       # LangFuse
def contar_historia(tema): ...

@traceable(run_type="chain")     # LangSmith
def mi_pipeline(texto): ...

# 3. Callback — objeto pasivo que escucha a LangChain
chain.invoke(entrada, config={"callbacks": [handler]})

# 4. Entorno — LangChain ya viene instrumentado; solo enciendes el envío
# (variables LANGSMITH_* en .env, cero código)

El wrapper registra cada llamada al modelo con tokens y coste sin tocar una línea más, pero no sabe dónde empiezan y acaban tus funciones: te da hojas sueltas, no un árbol. El decorador es justo lo contrario: es la ruta que da estructura, porque la función decorada pasa a ser la raíz y todo lo que ocurra dentro cuelga de ella.

02 — El árbol de decisión
Empieza por si usas framework o no
¿Tu flujo lo orquesta LangChain / LangGraph?  ├─ SÍ → ¿quién te lo da más barato?  │  ├─ LangSmith → variables de entorno (cero código)  │  └─ LangFuse  → CallbackHandler (en cada invoke)  └─ NO, es Python a pelo → combina las dos que quedan     ├─ decorador ← te da la raíz y la forma     └─ wrapper del cliente ← te da tokens y coste
03 — La tabla que decide
Qué ve cada ruta
WrapperDecoradorCallbackEntorno
Llamadas al modelo, tokens y costesísolo si dentro hay un cliente instrumentadosísí
Fronteras de tus funcionesnosínono
Pasos internos del frameworknonosísí
Cambios en tu códigoun importun decorador por funciónun argumento por invocaciónninguno
Sirve sin LangChainsísínono
// la fila que decide casi siempre es la última: sin framework no hay eventos que escuchar.
04 — Combinarlas
Una pareja natural y un solape

Wrapper y decorador se complementan: el decorador da la raíz y la forma del árbol, el wrapper rellena las hojas con el detalle caro — prompt final, tokens, coste. Es la combinación por defecto fuera de LangChain.

El solape
Callback y decorador sí compiten: los dos quieren ser la raíz de la traza. La guía lo menciona de pasada — "elegir uno u otro evita duplicidad, aunque pueden convivir" — y merece más énfasis, porque el síntoma de mezclarlos es un árbol con la mitad de los pasos repetidos y ninguna alarma.
05 — El fallo característico
Cómo se rompe cada ruta
RutaCómo se rompe, sin dar error
WrapperAlguien "arregla" el import a import openai y la traza pierde todas las generations
DecoradorSolo trazas lo que decoraste; lo que llames desde fuera queda huérfano
CallbackHay que pasarlo en cada invocación; olvidarlo en una ruta la deja invisible
EntornoSolo cubre lo que el framework instrumenta; tu Python puro no aparece

El del callback es el primer caso del troubleshooting de la guía, y tiene sentido: es el único que depende de acordarse en cada punto de llamada en vez de una sola vez al arrancar.

Auditoría

Todo el bloque de LangFuse de la guía importa por rutas de la versión 2 del SDK: from langfuse.decorators import observe, from langfuse.callback import CallbackHandler, langfuse.trace(...), langfuse.score(...). Y la instrucción de instalación es pip install langfuse, sin fijar versión.

¿Qué versión mayor instala hoy ese comando, y siguen existiendo esas rutas en ella? Si el paquete ha pasado a una v3, from langfuse.decorators import observe fallaría con ImportError en la primera línea de casi todos los ejemplos del módulo. El arreglo no sería tuyo: sería fijar la versión o traducir los imports. Merece la pena resolverlo antes de empezar los ejercicios, no en mitad del tercero.

En la misma línea, la guía usa handler.auth_check() como test de humo de la conexión. Comprueba que ese método existe en la versión que tengas instalada antes de fiarte de lo que imprima.

06 — Ahora tú
Traza la misma función dos veces

Coge una función tuya que llame al modelo y trázala dos veces: primero solo con el wrapper del cliente, después añadiendo el decorador encima de la función.

Abre las dos trazas una al lado de la otra. La pregunta que tienes que poder contestar mirándolas: ¿cuántos niveles tiene cada árbol, y qué nombre lleva la raíz en cada caso? Ahí está, literalmente dibujada, la diferencia entre las dos rutas.