LangChain Expression Language (LCEL)

Intermedio
LangChain
LangChain
Actualizado: 09/07/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Qué es LCEL

LangChain Expression Language (LCEL) es el lenguaje de expresiones declarativo que constituye el núcleo moderno de LangChain. Representa un cambio fundamental en la forma de construir aplicaciones de IA, alejándose de las cadenas imperativas tradicionales hacia un enfoque declarativo que prioriza la composición y la legibilidad.

LCEL utiliza el operador pipe (**|**) como elemento central para conectar componentes de manera fluida. Este operador permite encadenar diferentes elementos como prompts, modelos y parsers de salida, creando flujos de procesamiento que se leen de forma natural de izquierda a derecha.

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# Ejemplo básico de LCEL
prompt = ChatPromptTemplate.from_template("Explica {topic} en términos simples")
model = ChatOpenAI(model="gpt-4")

# Composición declarativa usando el operador pipe
chain = prompt | model

Características fundamentales de LCEL

La sintaxis declarativa de LCEL permite expresar qué queremos lograr en lugar de cómo hacerlo paso a paso. Esto contrasta con enfoques imperativos donde debemos especificar cada operación secuencialmente.

# Enfoque declarativo con LCEL
chain = prompt_template | model | output_parser

# Equivalente imperativo (más verboso)
def process_input(input_data):
    formatted_prompt = prompt_template.format(**input_data)
    model_response = model.invoke(formatted_prompt)
    parsed_output = output_parser.parse(model_response)
    return parsed_output

LCEL proporciona composabilidad nativa, permitiendo que cualquier componente que implemente la interfaz Runnable pueda combinarse con otros. Esta característica hace que los componentes sean intercambiables y reutilizables.

# Los componentes son intercambiables
chain_openai = prompt | ChatOpenAI(model="gpt-4")
chain_anthropic = prompt | ChatAnthropic(model="claude-3")

# Ambas cadenas tienen la misma interfaz
result1 = chain_openai.invoke({"topic": "machine learning"})
result2 = chain_anthropic.invoke({"topic": "machine learning"})

Ventajas del enfoque LCEL

El paralelismo automático es una de las ventajas más significativas de LCEL. Cuando es posible, el framework ejecuta operaciones en paralelo sin requerir configuración adicional, optimizando el rendimiento de manera transparente.

La gestión de errores integrada proporciona manejo robusto de excepciones a lo largo de toda la cadena, con capacidades de reintentos y recuperación automática.

# LCEL maneja automáticamente errores y reintentos
chain = prompt | model.with_retry(stop_after_attempt=3)

LCEL incluye observabilidad nativa, facilitando el debugging y monitoreo de aplicaciones complejas. Cada paso de la cadena puede ser inspeccionado y trazado sin instrumentación adicional.

Interfaz Runnable

Todos los componentes LCEL implementan la interfaz Runnable, que define métodos estándar para la ejecución:

  • **invoke()**: Ejecuta la cadena con una entrada específica
  • **batch()**: Procesa múltiples entradas en paralelo
  • **stream()**: Proporciona resultados en tiempo real
  • **ainvoke()**: Versión asíncrona de invoke
# Diferentes formas de ejecutar una cadena LCEL
result = chain.invoke({"topic": "Python"})
results = chain.batch([{"topic": "Python"}, {"topic": "JavaScript"}])

# Ejecución con streaming
for chunk in chain.stream({"topic": "React"}):
    print(chunk, end="")

Esta interfaz unificada garantiza que todos los componentes se comporten de manera consistente, independientemente de su complejidad interna. Un prompt simple y una cadena compleja de múltiples pasos exponen exactamente los mismos métodos de ejecución.

LCEL representa la evolución natural de LangChain hacia un framework más maduro y expresivo, donde la construcción de aplicaciones de IA se vuelve más intuitiva y mantenible. Su diseño declarativo no solo mejora la legibilidad del código, sino que también habilita optimizaciones automáticas que serían difíciles de implementar en enfoques imperativos tradicionales.

Flujo LCEL habitual: prompt, model y output parser

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

El patrón más común en LCEL sigue una estructura de tres componentes que forman la base de la mayoría de aplicaciones de IA: un template de prompt, un modelo de lenguaje y un parser de salida. Esta arquitectura modular permite construir flujos de procesamiento robustos y mantenibles.

Construcción básica: prompt y modelo

El flujo mínimo en LCEL combina un template de prompt con un modelo de lenguaje. 

Ejemplo:

El template estructura la entrada del usuario, mientras que el modelo genera la respuesta correspondiente.

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# Definición del template de prompt
prompt_template = ChatPromptTemplate([
    ('system', 'Eres experto en programación con {technology} y solo puedes responder preguntas de {technology} en idioma {locale}.'),
    ('user', "{human_message}"),
])

# Configuración del modelo
model = ChatOpenAI(model="gpt-4")

# Composición de la cadena básica
chain = prompt_template | model

# Ejecución de la cadena
response = chain.invoke({
    "technology": "Angular",
    "locale": "en_US",
    "human_message": "Indica si el punto y coma es obligatorio en JavaScript."
})

Esta configuración básica ya proporciona funcionalidad completa, donde el prompt formatea la entrada según los parámetros proporcionados y el modelo genera una respuesta contextualizada. El resultado es un objeto AIMessage que contiene la respuesta del modelo junto con metadatos adicionales.

Incorporación del output parser

Para obtener respuestas más procesables, el flujo se extiende con un parser de salida que transforma la respuesta del modelo en el formato deseado. El parser más común es StrOutputParser, que extrae únicamente el contenido textual de la respuesta.

from langchain_core.output_parsers import StrOutputParser

# Extensión de la cadena con parser de salida
chain = prompt_template | model | StrOutputParser()

# La respuesta ahora es una cadena de texto limpia
response = chain.invoke({
    "technology": "Angular",
    "locale": "en_US",
    "human_message": "Indica si el punto y coma es obligatorio en JavaScript."
})

print(type(response))  # <class 'str'>
print(response)        # Respuesta directa sin metadatos

El StrOutputParser simplifica significativamente el manejo de respuestas, eliminando la necesidad de acceder manualmente al contenido del mensaje. Esto es especialmente útil cuando la aplicación solo necesita el texto de la respuesta sin metadatos adicionales.

Ejemplo:

Variaciones del flujo básico

El patrón prompt → model → parser admite múltiples configuraciones según las necesidades específicas. Los templates pueden incluir diferentes tipos de mensajes y variables dinámicas.

# Template con múltiples variables y contexto
advanced_prompt = ChatPromptTemplate([
    ('system', 'Eres un {role} especializado en {domain}. Tu nivel de experiencia es {experience_level}.'),
    ('user', 'Contexto: {context}'),
    ('user', 'Pregunta: {question}')
])

# Cadena con template más complejo
advanced_chain = advanced_prompt | model | StrOutputParser()

result = advanced_chain.invoke({
    "role": "consultor técnico",
    "domain": "desarrollo web",
    "experience_level": "senior",
    "context": "Estamos migrando una aplicación legacy a React",
    "question": "¿Cuáles son las mejores prácticas para la gestión de estado?"
})

Parsers especializados

Además de StrOutputParser, LCEL ofrece parsers especializados para diferentes tipos de salida estructurada. Estos parsers permiten obtener respuestas en formatos específicos sin procesamiento adicional.

from langchain_core.output_parsers import JsonOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field

# Definición de estructura de datos esperada
class TechnicalRecommendation(BaseModel):
    technology: str = Field(description="Tecnología recomendada")
    pros: list[str] = Field(description="Ventajas principales")
    cons: list[str] = Field(description="Desventajas a considerar")
    difficulty: str = Field(description="Nivel de dificultad: easy, medium, hard")

# Parser para salida JSON estructurada
json_parser = JsonOutputParser(pydantic_object=TechnicalRecommendation)

# Template que solicita formato JSON específico
json_prompt = ChatPromptTemplate([
    ('system', 'Responde únicamente en formato JSON válido siguiendo el esquema proporcionado.'),
    ('user', '{format_instructions}\n\nPregunta: {question}')
])

# Cadena con parser JSON
json_chain = json_prompt | model | json_parser

structured_response = json_chain.invoke({
    "format_instructions": json_parser.get_format_instructions(),
    "question": "Recomienda una tecnología para construir una API REST"
})

Manejo de errores en el flujo

El flujo estándar incluye manejo robusto de errores que se propaga a través de todos los componentes. Cada elemento de la cadena puede fallar independientemente, y LCEL proporciona mecanismos para gestionar estas situaciones.

# Cadena con manejo de errores y reintentos
resilient_chain = (
    prompt_template 
    | model.with_retry(stop_after_attempt=3, wait_exponential_multiplier=1)
    | StrOutputParser()
)

try:
    response = resilient_chain.invoke({
        "technology": "Python",
        "locale": "es_ES",
        "human_message": "Explica las list comprehensions"
    })
except Exception as e:
    print(f"Error en la cadena: {e}")

Optimización del flujo

LCEL optimiza automáticamente la ejecución del flujo, identificando oportunidades de paralelización y cacheo. Cuando múltiples entradas requieren procesamiento, el framework puede ejecutar operaciones en paralelo sin configuración adicional.

# Procesamiento en lote optimizado automáticamente
batch_inputs = [
    {"technology": "React", "locale": "en_US", "human_message": "Explain hooks"},
    {"technology": "Vue", "locale": "es_ES", "human_message": "¿Qué es la reactividad?"},
    {"technology": "Angular", "locale": "fr_FR", "human_message": "Comment utiliser les services?"}
]

# LCEL ejecuta automáticamente en paralelo cuando es posible
batch_results = chain.batch(batch_inputs)

Este patrón fundamental de prompt, modelo y parser constituye la base sobre la cual se construyen aplicaciones más complejas en LangChain. Su simplicidad y flexibilidad lo convierten en el punto de partida ideal para la mayoría de casos de uso, desde chatbots simples hasta sistemas de procesamiento de documentos sofisticados.

Aprendizajes de esta lección

  • Comprender qué es LCEL y su enfoque declarativo frente a los métodos imperativos.
  • Aprender a construir flujos básicos con prompt, modelo y parser usando el operador pipe.
  • Conocer la interfaz Runnable y sus métodos para ejecutar cadenas LCEL.
  • Identificar las ventajas de LCEL como paralelismo automático, manejo de errores y observabilidad.
  • Aplicar parsers especializados para obtener salidas estructuradas y manejar errores en flujos complejos.

Completa LangChain y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración