Volver a la página principal
martes 24 febrero 2026
1

Uso de LangChain Expression Language (LCEL)

El LangChain Expression Language (LCEL) es una forma declarativa y composable de construir cadenas (chains) en LangChain usando el operador | (pipe), lo que permite conectar componentes como si estuviéramos creando una tubería de procesamiento.

En lugar de crear objetos complejos o clases personalizadas, LCEL permite escribir flujos de trabajo de forma mucho más clara, modular y reutilizable.

Desde que lo uso, he notado tres mejoras claras:

  • Código más limpio
  • Mayor legibilidad
  • Fácil reutilización de componentes

Y lo mejor: funciona de manera natural con async, streaming y paralelización. 🔥

¿Por qué LCEL es importante en LangChain?

Antes de LCEL, construir cadenas en LangChain implicaba definir LLMChain, SequentialChain y otras estructuras que podían volverse verbosas rápidamente.

Con LCEL podemos hacer algo como esto:

from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("Explica qué es {topic}")

model = ChatOpenAI()

chain = prompt | model

response = chain.invoke({"topic": "LangChain"})
print(response)

Así de simple.

LCEL convierte los flujos de LLM en algo más cercano a la programación funcional que a la programación orientada a objetos.

Y eso, desde mi punto de vista, lo hace mucho más potente y mantenible. 💡

Cuando trabajo con LCEL, suelo pensar en bloques conectables. Cada bloque implementa la interfaz Runnable.

1️⃣ Runnable

Todo en LCEL es un Runnable. Puede ser:

  • Un prompt
  • Un modelo
  • Un parser
  • Una función personalizada
  • Una cadena completa

Lo interesante es que puedes combinarlos usando el operador |.

Ejemplo:

chain = prompt | model | output_parser

2️⃣ El operador Pipe (|)

El operador | es el corazón de LCEL.

Permite:

  • Encadenar procesos
  • Transformar datos
  • Crear pipelines complejos
  • Reutilizar componentes

Personalmente, cuando empecé a usarlo, sentí que estaba trabajando con algo similar a Unix pipes o a flujos de datos en frameworks funcionales. ⚙️

3️⃣ invoke(), batch() y stream()

Una de las cosas que más me gusta de LCEL es que todas las cadenas soportan:

invoke()

Para ejecutar una sola entrada:

chain.invoke({"topic": "Inteligencia Artificial"})

batch()

Para múltiples entradas:

chain.batch([
    {"topic": "Python"},
    {"topic": "Machine Learning"}
])

stream()

Para recibir resultados en tiempo real:

for chunk in chain.stream({"topic": "LangChain"}):
    print(chunk)

Si estás trabajando con aplicaciones en tiempo real (chatbots, asistentes, dashboards), stream() cambia completamente la experiencia de usuario. 🚀

Voy a mostrarte cómo lo utilizo normalmente en producción.

Ejemplo 1: Prompt + Modelo + Parser

from langchain.schema.output_parser import StrOutputParser

prompt = ChatPromptTemplate.from_template(
    "Resume el siguiente texto en una frase:\n\n{text}"
)

model = ChatOpenAI(temperature=0)
parser = StrOutputParser()

chain = prompt | model | parser

resultado = chain.invoke({
    "text": "LangChain es un framework para construir aplicaciones basadas en modelos de lenguaje..."
})

print(resultado)

Aquí estamos:

  • Creando el prompt
  • Enviándolo al modelo
  • Parseando la salida

Todo en una sola línea declarativa.

Desde mi experiencia, estas son las principales ventajas:

✅ 1. Composición modular

Puedes crear piezas reutilizables y combinarlas como bloques LEGO.

✅ 2. Mejor rendimiento con paralelización

LCEL permite ejecutar componentes en paralelo usando RunnableParallel.

Ejemplo:

from langchain.schema.runnable import RunnableParallel

chain = RunnableParallel({
    "explicacion": prompt | model,
    "resumen": otro_prompt | model
})

Esto es increíblemente útil cuando necesitas múltiples respuestas en una sola llamada. ⚡

✅ 3. Código más declarativo

En lugar de escribir:

chain = LLMChain(llm=model, prompt=prompt)

Ahora simplemente:

chain = prompt | model

Mucho más limpio.

Si trabajas con aplicaciones web (FastAPI, Django, Node backend, etc.), LCEL tiene soporte nativo para asincronía.

await chain.ainvoke({"topic": "LangChain"})

Esto hace que escalar aplicaciones con LLM sea mucho más sencillo.

Yo lo he integrado en APIs REST y la diferencia en rendimiento es notable cuando trabajas con muchas solicitudes concurrentes. 📈

Después de varios proyectos, estas son mis recomendaciones:

🔹 Mantén tus prompts separados

No mezcles lógica de negocio con definición de prompts.

🔹 Usa parsers siempre

Aunque el modelo parezca devolver texto simple, un OutputParser te da mayor control.

🔹 Modulariza tus chains

Divide procesos complejos en subcadenas reutilizables.

🔹 Controla la temperatura

En producción suelo usar:

ChatOpenAI(temperature=0)

Para obtener resultados más deterministas.

Característica Enfoque clásico LCEL
-------------- --------------- -----------
Sintaxis Verbosa Declarativa
Composición Más rígida Flexible
Async Limitado Nativo
Streaming Más complejo Integrado

Desde mi punto de vista, LCEL no es solo una mejora, es prácticamente la dirección futura de LangChain. 🔮

Te recomiendo usar LCEL si:

  • Estás creando aplicaciones LLM modernas
  • Necesitas streaming
  • Trabajas con múltiples modelos
  • Buscas código más limpio
  • Quieres escalar en producción

Si solo estás haciendo pruebas simples, puede parecer innecesario, pero en cuanto el proyecto crece… LCEL se vuelve imprescindible.

Después de varios meses utilizándolo, puedo decir que LangChain Expression Language ha cambiado completamente mi forma de construir aplicaciones con modelos de lenguaje.

Es:

  • Más limpio
  • Más potente
  • Más escalable
  • Más profesional

Si estás trabajando con IA generativa en 2026 y aún no estás usando LCEL, te recomiendo empezar hoy mismo.

En mi caso, ya no concibo construir pipelines sin el operador |. Se siente natural, elegante y extremadamente poderoso. 💙

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer