Image for post LangSmith desde Cero: Debugging y Observabilidad para tus Aplicaciones LangChain

LangSmith desde Cero: Debugging y Observabilidad para tus Aplicaciones LangChain


Desarrollar aplicaciones impulsadas por Grandes Modelos de Lenguaje (LLMs) es, sin duda, una de las áreas más emocionantes de la programación actual. Sin embargo, la naturaleza no determinista de los LLMs y la complejidad creciente de las cadenas y agentes de frameworks como LangChain, pueden convertir la depuración y el monitoreo en un verdadero dolor de cabeza. ¿Por qué mi agente tomó esa decisión? ¿Qué prompt exacto se envió al modelo? ¿Cuánto costó esta interacción? Las herramientas de depuración tradicionales a menudo se quedan cortas, dejándonos a ciegas sobre el funcionamiento interno de nuestras aplicaciones de IA.

Aquí es donde entra LangSmith, una plataforma desarrollada por el equipo detrás de LangChain, diseñada específicamente para traer claridad, control y confianza al ciclo de vida de desarrollo de aplicaciones con LLMs. LangSmith actúa como un "microscopio" para tus aplicaciones LangChain, permitiéndote observar, depurar y evaluar cada paso de su ejecución, desde el prototipo hasta la producción. [1, 2, 5, 6, 11, 12, 15]

Conceptos Clave en LangSmith

Para aprovechar al máximo LangSmith, es fundamental entender algunos de sus conceptos centrales:

  • Traces (Rastros): Un trace es el registro completo y secuencial de una única ejecución de tu aplicación LangChain. Captura cada llamada a un LLM, cada uso de una herramienta, cada paso de una cadena, y sus respectivas entradas y salidas. [1, 2, 9, 16]
  • Runs (Ejecuciones): Cada componente individual dentro de un trace (una llamada a un LLM, una invocación de una herramienta, un paso de una cadena) se considera un 'run'. LangSmith te permite inspeccionar los detalles de cada run, incluyendo inputs, outputs, latencia y uso de tokens. [1, 2, 14, 20]
  • Projects (Proyectos): LangSmith te permite organizar tus runs en proyectos. Esto es útil para agrupar ejecuciones de diferentes aplicaciones, entornos (desarrollo, staging, producción) o experimentos. [2, 7, 9, 13, 20]
  • Datasets (Conjuntos de Datos): Son colecciones de pares de entrada/salida que puedes usar para probar y evaluar el rendimiento de tu aplicación de manera consistente. [2, 6, 7, 16, 17, 20]
  • Evaluators (Evaluadores): Herramientas que te permiten calificar automáticamente o manualmente los runs de tu aplicación contra un dataset, ayudándote a medir la calidad y la regresión. [2, 6, 17]
  • Prompt Hub (Mencionado brevemente): Un repositorio para gestionar y versionar tus prompts, facilitando la colaboración y la experimentación. [2, 17]

Implementación Paso a Paso: Integrando LangSmith en tu Proyecto LangChain

La integración de LangSmith con LangChain es sorprendentemente sencilla, principalmente a través de variables de entorno. Aquí te mostramos cómo empezar.

Paso 1: Configuración del Entorno

Primero, asegúrate de tener las librerías necesarias instaladas. Necesitarás langchain, langchain-openai (o el proveedor de LLM de tu elección) y langsmith.

pip install langchain langchain-openai langsmith python-dotenv

Luego, necesitarás obtener tus claves API de OpenAI (o tu proveedor de LLM) y de LangSmith. Puedes registrarte en smith.langchain.com para obtener tu LANGCHAIN_API_KEY. [4, 7, 8, 15]

Crea un archivo .env en la raíz de tu proyecto y añade las siguientes variables:

OPENAI_API_KEY="tu_openai_api_key_aqui"
LANGCHAIN_TRACING_V2="true"
LANGCHAIN_API_KEY="tu_langsmith_api_key_aqui"
LANGCHAIN_PROJECT="MiPrimerProyectoLangSmith" # Un nombre para tu proyecto en LangSmith

En tu código Python, carga estas variables de entorno:

import os
from dotenv import load_dotenv

load_dotenv()

# Asegúrate de que las variables de entorno estén configuradas
# (No es necesario asignarlas a variables Python si LangChain las lee directamente del entorno)
# os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# os.environ["LANGCHAIN_TRACING_V2"] = os.getenv("LANGCHAIN_TRACING_V2")
# os.environ["LANGCHAIN_API_KEY"] = os.getenv("LANGCHAIN_API_KEY")
# os.environ["LANGCHAIN_PROJECT"] = os.getenv("LANGCHAIN_PROJECT")

Paso 2: Tu Primera Cadena LangChain con Observabilidad

Con las variables de entorno configuradas, LangChain automáticamente enviará los traces a LangSmith. No necesitas modificar tu código de LangChain para la integración básica. [4, 9]

Vamos a crear una cadena simple:

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# Inicializa el modelo de lenguaje
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

# Define un prompt simple
prompt = ChatPromptTemplate.from_messages([
    ("system", "Eres un asistente útil que responde preguntas de forma concisa."),
    ("user", "{question}")
])

# Crea la cadena
chain = prompt | llm | StrOutputParser()

# Invoca la cadena
print("Invocando cadena simple...")
response = chain.invoke({"question": "¿Cuál es la capital de Francia?"})
print(f"Respuesta: {response}")

print("\nInvocando otra cadena simple...")
response_2 = chain.invoke({"question": "¿Quién escribió 'Cien años de soledad'?"})
print(f"Respuesta: {response_2}")

Ejecuta este script. Después de la ejecución, dirígete a la interfaz de usuario de LangSmith (smith.langchain.com). Deberías ver un nuevo proyecto llamado "MiPrimerProyectoLangSmith" (o el nombre que le hayas dado) y dentro, los traces correspondientes a cada invocación de tu cadena. [8, 13, 20]

Paso 3: Explorando Traces en la UI de LangSmith

En la interfaz de LangSmith, haz clic en uno de los traces. Verás una representación visual de la ejecución de tu cadena. Para una cadena simple, esto mostrará el `ChatPromptTemplate`, la llamada al `ChatOpenAI` y el `StrOutputParser`. Puedes hacer clic en cada paso (run) para ver detalles como:

  • Inputs: El prompt exacto enviado al LLM. [1, 14, 16]
  • Outputs: La respuesta cruda del LLM y la salida parseada. [1, 14, 16]
  • Metadata: Información como el modelo usado, temperatura, etc.
  • Latencia y Tokens: Cuánto tiempo tardó el run y cuántos tokens se consumieron. [1, 14, 20, 25]

Mini Proyecto: Debugging de un Agente con Herramientas

Los agentes son donde la observabilidad de LangSmith realmente brilla, ya que sus ejecuciones pueden ser no deterministas y complejas. Vamos a crear un agente simple con una herramienta y ver cómo LangSmith nos ayuda a entender su comportamiento.

from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Definimos una herramienta simple
@tool
def multiply(a: int, b: int) -> int:
    "Multiplica dos números enteros y devuelve el resultado."
    return a * b

@tool
def add(a: int, b: int) -> int:
    "Suma dos números enteros y devuelve el resultado."
    return a + b

tools = [multiply, add]

# Inicializa el LLM
llm_agent = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# Define el prompt para el agente
prompt_agent = ChatPromptTemplate.from_messages([
    ("system", "Eres un asistente muy útil. Tienes acceso a las siguientes herramientas:"),
    ("system", "{tools}"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}")
])

# Crea el agente
agent = create_tool_calling_agent(llm_agent, tools, prompt_agent)

# Crea el ejecutor del agente
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

print("\nInvocando agente para una multiplicación...")
result_multiply = agent_executor.invoke({"input": "¿Cuánto es 5 por 7?"})
print(f"Resultado del agente (multiplicación): {result_multiply['output']}")

print("\nInvocando agente para una suma...")
result_add = agent_executor.invoke({"input": "Suma 10 y 15."})
print(f"Resultado del agente (suma): {result_add['output']}")

print("\nInvocando agente para una pregunta sin herramienta...")
result_no_tool = agent_executor.invoke({"input": "¿Cuál es el color del cielo en un día despejado?"})
print(f"Resultado del agente (sin herramienta): {result_no_tool['output']}")

Al ejecutar este código, verás la salida detallada en tu consola debido a verbose=True. Pero lo más importante es que en LangSmith, cada invocación del agent_executor generará un trace. Dentro de este trace, podrás ver la secuencia de eventos:

  • La llamada inicial al LLM para decidir qué hacer.
  • Si decide usar una herramienta, verás un run para la tool_code con sus inputs.
  • La salida de la herramienta.
  • Una nueva llamada al LLM para formular la respuesta final basándose en la salida de la herramienta.

Esta visibilidad granular es invaluable para entender por qué un agente eligió una herramienta específica, si los argumentos se pasaron correctamente, o si el LLM tuvo dificultades para interpretar la salida de la herramienta. [1, 14, 16]

Errores Comunes y Depuración con LangSmith

LangSmith es una herramienta poderosa para diagnosticar problemas comunes en aplicaciones LLM:

  • "No veo mis traces en LangSmith": [18]
    • Verifica que LANGCHAIN_TRACING_V2="true" esté configurado correctamente. [9, 18]
    • Asegúrate de que LANGCHAIN_API_KEY sea válida y esté configurada. [9, 18]
    • Confirma que LANGCHAIN_PROJECT esté definido. Si el proyecto no existe, LangSmith debería crearlo automáticamente, pero verifica los permisos si hay problemas. [18]
    • Comprueba la conectividad de red a https://api.smith.langchain.com. [18]
  • "Mi LLM da respuestas inesperadas o incorrectas": [14]
    • Inspecciona el run del LLM en LangSmith para ver el prompt exacto que se envió. A veces, las plantillas de prompt o el formateo pueden introducir errores sutiles. [1, 14, 16]
    • Revisa los inputs de la cadena para asegurarte de que el contexto o la pregunta se estén pasando correctamente. [14]
  • "Mi agente no usa la herramienta correcta o falla al usarla": [14]
    • Examina el trace del agente paso a paso. Verás las "reflexiones" del LLM (si tu agente las expone) y la decisión de llamar a una herramienta. [14, 16]
    • Si una herramienta falla, LangSmith capturará la excepción. Revisa los inputs que el LLM generó para la herramienta; a menudo, el problema es un formato incorrecto de los argumentos. [14]
  • "Mi aplicación es lenta o consume muchos tokens": [14, 20, 25]
    • LangSmith muestra la latencia y el uso de tokens para cada run. Esto te permite identificar cuellos de botella de rendimiento (e.g., una llamada a un LLM que tarda demasiado, o una herramienta externa lenta) y optimizar el uso de tokens. [1, 14, 20, 25]

Aprendizaje Futuro

Este artículo es solo el comienzo de lo que puedes lograr con LangSmith. Para llevar tus habilidades al siguiente nivel, te animo a explorar:

  • Evaluación Avanzada: Utiliza Datasets y Evaluadores (automáticos o con feedback humano) para probar y comparar diferentes versiones de tus cadenas o prompts, asegurando mejoras continuas. [2, 6, 7, 16, 17, 20]
  • Monitoreo en Producción: Configura alertas en LangSmith para ser notificado sobre anomalías en la latencia, tasas de error o puntuaciones de feedback en tus aplicaciones en vivo. [2, 5, 6, 17, 25]
  • Prompt Hub: Gestiona y versiona tus prompts de manera colaborativa, experimentando con diferentes enfoques y comparando resultados directamente en LangSmith. [2, 17]
  • Integración CI/CD: Incorpora pruebas y evaluaciones de LangSmith en tus pipelines de integración continua para detectar regresiones antes de desplegar. [2]

LangSmith transforma la tarea de construir aplicaciones con LLMs de una caja negra a un proceso transparente y controlable. Al dominar sus capacidades de debugging y observabilidad, estarás mucho mejor equipado para desarrollar, optimizar y desplegar soluciones de IA robustas y confiables.