Saltar al contenido principal

Chainlit: Una guía con ejemplos prácticos

Aprende qué es Chainlit, cómo instalarlo y cómo ejecutarlo para crear interfaces interactivas para aplicaciones basadas en LLM.
Actualizado 19 may 2025  · 8 min de lectura

Chainlit es un potente framework de Python de código abierto que te permite crear interfaces interactivas para tus aplicaciones basadas en LLM con un código mínimo y sin complicaciones.

En este tutorial, te guiaré:

  1. Instalar y configurar Chainlit.
  2. Comprender sus conceptos básicos, como las acciones, el ciclo de vida del chat y las configuraciones.
  3. Construir dos aplicaciones de ejemplo: 
    • Un chatbot estático "Sorpréndeme" utilizando botones
    • Un bot "Sorpréndeme" impulsado por Ollama

Desarrollar aplicaciones de IA

Aprende a crear aplicaciones de IA utilizando la API OpenAI.
Empieza a hacer Upskilling gratis

¿Qué es Chainlit?

Chainlit te ayuda a crear frontends para chatbots de IA, herramientas y flujos de trabajo LLM. Abstrae la complejidad del front-end y te permite centrarte en la lógica de Python, a la vez que proporciona soporte para añadir botones, controles deslizantes, soporte para subir archivos o incluso conectarte a herramientas que utilicen el protocolo de contexto de modelo (MCP).

Chainlit es ideal para:

  • Prototipos de aplicaciones basadas en LLM
  • Crear herramientas internas
  • Construir demostraciones educativas
  • Conectar tus modelos a herramientas o API externas

Componentes Chainlit

Todas las aplicaciones de Chainlit se basan en unas pocas características esenciales:

  1. Ganchos del ciclo de vida del chat: Te permiten controlar lo que ocurre en las distintas fases de un chat. Por ejemplo:
    • @cl.on_chat_start se ejecuta cuando se inicia un chat.
    • @cl.on_message se ejecuta cuando el usuario envía un mensaje.
    • @cl.on_chat_end se ejecuta cuando finaliza el chat.
  2. Acciones de IU: Chainlit te permite añadir botones con cl.Action y manejarlos con @cl.action_callback. Son geniales para crear interfaces de usuario limpias e interactivas sin necesidad de que el usuario introduzca texto.
  3. Transmisión de mensajes: Con los LLM que admiten la transmisión de tokens, puedes transmitir respuestas en tiempo real utilizando stream=True, haciendo que tu aplicación parezca más dinámica y receptiva.
  4. Configuración con config.toml: Este archivo te permite activar funciones como la persistencia del chat, la carga de archivos, la personalización del tema y los ajustes de usabilidad, todo ello sin modificar tu código Python.

Explicaré cada concepto con un ejemplo práctico de código para que puedas ver exactamente cómo funciona y cómo integrarlo en tus aplicaciones Chainlit. Empecemos por el primer paso.

Requisitos previos

Asegúrate de que tienes Python 3.8+ instalado, luego instala Chainlit utilizando pip. También utilizaremos Langchain para la demostración de Ollama, así que asegúrate de instalarlo. Ejecuta el siguiente comando en el terminal:

pip install chainlit langchain langchain-community

Comprender los fundamentos de Chainlit mediante ejemplos

En esta sección, cubriremos los componentes básicos de Chainlit, que formarán el núcleo de cualquier proyecto.

Ganchos del ciclo de vida del chat

Cada vez que un usuario se conecta a tu aplicación Chainlit, se crea una sesión de chat. Puedes aprovechar las distintas fases de esa sesión utilizando los decoradores que proporciona Chainlit. Entre ellas están:

Construir con @cl.on_chat_start

Este gancho se ejecuta cuando se inicia una nueva sesión de chat. Puedes utilizarlo para saludar al usuario, mostrar un mensaje de bienvenida o inicializar el estado de la sesión.

import chainlit as cl
@cl.on_chat_start
def on_chat_start():
    print("A new chat session has started!")

@cl.on_chat_start chainlit output

Construir con @cl.on_message

Este gancho de mensaje se ejecuta cuando el usuario envía un nuevo mensaje. Lo utilizamos para procesar la entrada del usuario, llamar a un LLM o devolver una respuesta.

import chainlit as cl
@cl.on_message
async def on_message(msg: cl.Message):
    print("The user sent:", msg.content)
    await cl.Message(content=f"You said: {msg.content}").send()

@cl.on_message Output

Construyendo con @cl.on_stop

El gancho on_stop se ejecuta cuando el usuario pulsa el botón de parada (⏹) durante una tarea en ejecución. Sirve para cancelar operaciones de larga duración o limpiar sesiones interrumpidas.

import chainlit as cl
import asyncio
@cl.on_chat_start
async def start():
    await cl.Message("Type anything and I'll pretend to work on it.").send()
@cl.on_message
async def on_message(msg: cl.Message):
    await cl.Message("Working on it... you can press Stop").send()
    try:
        # Simulate a long task
        await asyncio.sleep(10)
        await cl.Message("Task complete!").send()
    except asyncio.CancelledError:
        print("Task was interrupted!")
        # This is optional, just logs in the server
        raise
@cl.on_stop
async def on_stop():
    print("The user clicked Stop!")

Cuando el usuario envía un mensaje, Chainlit simula una tarea con asyncio.sleep(10). Si el usuario pulsa el botón de parada (⏹), la tarea se cancela y se activa @cl.on_stop para registrar la interrupción.

@cl.on_stop output

Construir con @cl.on_chat_end

Este gancho se activa cuando finaliza la sesión, ya sea porque el usuario actualiza, cierra la pestaña o inicia una nueva sesión. Suele utilizarse para registrar desconexiones o guardar el estado.

import chainlit as cl
@cl.on_chat_start
async def on_chat_start():
    await cl.Message("Welcome! Feel free to leave anytime").send()
@cl.on_chat_end
async def on_chat_end():
    print("The user disconnected!")

Una vez abierto el localhost, puedes trabajar con él. Cuando cierres la pestaña o ventana localhost, el terminal mostrará lo siguiente:

on_chat_end() chainlit output

Acciones de IU (botones)

Chainlit te permite añadir botones interactivos directamente en la interfaz de tu chatbot. Cada botón se define como una acción y se conecta a una función de llamada de retorno de Python. Puedes enviar botones como parte de un Mensaje utilizando el argumento acciones:

import chainlit as cl
@cl.on_chat_start
async def start():
    actions = [
        cl.Action(
            name="hello",
            label="👋 Say Hello",
            icon="smile",
            payload={"value": "hi"}
        )
    ]
    await cl.Message("Click a button!", actions=actions).send()

Así es como puedes gestionar la pulsación de un botón:

@cl.action_callback("hello")
async def on_hello(action: cl.Action):
    await cl.Message("Hello there! 👋").send()

El decorador @cl.action_callback("hello") indica a Chainlit que escuche los clics en un botón con el nombre "hola". Cuando se pulsa, envía un mensaje amistoso al usuario en la interfaz de chat.

@cl.action_callback chainlit salida

Consejo: Puedes personalizar la carga útil con cualquier dato que quieras enviar al servidor.

Transmisión de mensajes 

Chainlit admite la transmisión en tiempo real de las respuestas LLM. Esto significa que puedes enviar contenido al usuario de forma incremental a medida que se genera.

@cl.on_message
async def on_message(message: cl.Message):
    await cl.Message(content="Thinking...").send()
    async for chunk in llm.astream(message.content):
        await cl.Message(content=chunk, author="LLM", stream=True).send()

Vamos a desglosarlo:

  • En primer lugar, muestra inmediatamente un mensaje "Pensando..." para que el usuario sepa que la aplicación está funcionando.
  • Después, envía el mensaje del usuario a un LLM compatible con streaming.
  • A medida que el modelo genera resultados, transmite cada fragmento (chunk) a la interfaz de usuario en tiempo real.
  • El parámetro stream=True garantiza que cada trozo aparezca de forma incremental en lugar de esperar a la respuesta completa.

Nota: Esto funciona mejor con los modelos que admiten streaming.

Configuración de Chainlit (config.toml)

Para desbloquear potentes funciones como la persistencia del chat, la subida de archivos, la tematización y mucho más, puedes personalizar tu aplicación Chainlit utilizando el archivo config.toml. Este archivo reside en la raíz del directorio de tu proyecto (en la carpeta .chainlit ) y te permite ajustar el comportamiento en tiempo de ejecución sin modificar el código.

Persistencia

Este parámetro permite a Chainlit persistir el historial de chat y el estado de la sesión. Activa el gancho @cl.on_chat_resume, por lo que es ideal para aplicaciones en las que los usuarios pueden desconectarse y volver más tarde.

[persistence]
enabled = true

Carga de archivos

Este ajuste permite a los usuarios subir archivos en la interfaz del chat. Puedes restringir los tipos y tamaños de archivo permitidos para garantizar la seguridad y el rendimiento.

[features.spontaneous_file_upload]
enabled = true
accept = ["*/*"] 
max_files = 5
max_size_mb = 500

Aquí tienes algunos tipos de archivos que acepta Chainlit.

# 1. For specific file types:
    # accept = ["image/jpeg", "image/png", "application/pdf"]
# 2. For all files of a certain type:
    #    accept = ["image/*", "audio/*", "video/*"]
# 3. For specific file extensions:
    #    accept = { "application/octet-stream" = [".xyz", ".pdb"] }

Esto te permite adaptar las cargas para casos de uso de seguridad, rendimiento o específicos del dominio.

Personalización de la IU

Esta personalización cambia el nombre del asistente en el parámetro de la IU y activa la Cadena de Pensamiento (CoT) en el modo de representación, que es útil para razonar paso a paso o depurar.

[UI]
name = "Assistant"
cot = "full"

Ajustes de usabilidad

Mejoran la experiencia del usuario desplazando automáticamente los mensajes nuevos a la vista y permitiendo la edición de mensajes.

[features]
user_message_autoscroll = true
edit_message = true

Los ajustes de usabilidad anteriores permiten al usuario activar las funciones de desplazamiento automático y edición de mensajes dentro de la interfaz de usuario.

Proyecto: Sorpréndeme Bot (Sin LLM)

Ahora que conocemos los componentes básicos de Chainlit, vamos a crear una sencilla aplicación basada en una interfaz de usuario que utilice botones para mostrar datos divertidos predefinidos o mensajes de motivación para programadores.

import chainlit as cl
import random
FUN_FACTS = [
    "💡 Did you know? Chainlit supports file uploads and custom themes!",
    "💡 You can add buttons, sliders, and images directly in your chatbot UI!",
    "💡 Chainlit supports real-time tool execution with LangChain and LLMs!",
    "💡 You can customize the look of your chatbot with just a CSS file!",
    "💡 Chainlit lets you connect to tools using Model Context Protocol (MCP)!"
]
SUPRISES = [
    "🎉 Surprise! You're doing great!",
    "🚀 Keep it up, you're making awesome progress!",
    "🌟 Fun fact: Someone out there just smiled because of you. Why not make it two?",
    "👏 Bravo! You just unlocked +10 imaginary developer XP!",
    "💪 Remember: Even bugs fear your debugging skills!"
]
@cl.on_chat_start
async def start():
    actions = [
        cl.Action(
            name="surprise_button",
            label="🎁 Surprise Me",
            icon="gift",
            payload={"value": "surprise"}
        ),
        cl.Action(
            name="fact_button",
            label="💡 Did You Know?",
            icon="lightbulb",
            payload={"value": "fact"}
        )
    ]
    await cl.Message(content="Choose an action:", actions=actions).send()
@cl.action_callback("surprise_button")
async def on_surprise(action: cl.Action):
    suprise = random.choice(SUPRISES)
    await cl.Message(content=suprise).send()
@cl.action_callback("fact_button")
async def on_fact(action: cl.Action):
    fact = random.choice(FUN_FACTS)
    await cl.Message(content=fact).send()

El código anterior define dos listas: "FUN_FACTS" para consejos interesantes de Chainlit y "SUPRISES" para mensajes motivadores.

  • Cuando se inicia un nuevo chat, se muestran dos botones: "Sorpréndeme" y "¿Lo sabías?"-utilizando cl.Action. '
  • Al hacer clic en "Sorpréndeme" se activa @cl.action_callback("surprise_button"), which sends a random surprise message.
  • Al hacer clic en "¿Lo sabías?" se activa @cl.action_callback("fact_button")`, que envía un hecho divertido aleatorio.

Esto crea un chatbot sencillo e interactivo mediante botones que no requiere LLM y es perfecto para aprender cómo funcionan las acciones y las llamadas de retorno de Chainlit.

Para ejecutar esta aplicación, simplemente ejecuta el siguiente comando en el terminal:

chainlit run main.py

Verás botones interactivos en la interfaz de usuario que activan datos o mensajes divertidos.

Sorpréndeme Bot (sin LLM)

Proyecto: Bot Sorpréndeme Powered by Ollama

Ahora, vamos a automatizar este proceso y a generar los mensajes de sorpresa y de hecho utilizando un LLM local a través de Ollama.

import chainlit as cl
from langchain_community.llms import Ollama
import random
llm = Ollama(model="mistral", temperature=0.7)  # Use any lightweight local model
# Reusable action buttons
def get_action_buttons():
    return [
        cl.Action(
            name="surprise_button",
            label="🎁 Surprise Me",
            icon="gift",
            payload={"value": "surprise"}
        ),
        cl.Action(
            name="fact_button",
            label="💡 Did You Know?",
            icon="lightbulb",
            payload={"value": "fact"}
        )
    ]

@cl.on_chat_start
async def start():
    await cl.Message(content="Choose an action below to see something fun:").send()
    await cl.Message(content="", actions=get_action_buttons()).send()
@cl.action_callback("surprise_button")
async def on_surprise(action: cl.Action):
    prompt = "Give a short, uplifting surprise message to a developer. Make it fun."
    try:
        surprise = llm.invoke(prompt).strip()
    except Exception:
        surprise = "🎉 Surprise! You're doing great!"
    await cl.Message(content=surprise).send()
    await cl.Message(content="", actions=get_action_buttons()).send()  
@cl.action_callback("fact_button")
async def on_fact(action: cl.Action):
    prompt = "Give a fun and helpful fact about LLMs or Chainlit."
    try:
        fact = llm.invoke(prompt).strip()
    except Exception:
        fact = "💡 Did you know? You can add sliders and buttons to Chainlit with just a few lines of code!"
    await cl.Message(content=fact).send()
    await cl.Message(content="", actions=get_action_buttons()).send()  

Esta app de Chainlit integra un LLM local (a través de Ollama con el modelo Mistral) para generar dinámicamente respuestas basadas en las interacciones del usuario.

  • Define dos botones cl.Action: "Sorpréndeme" y "¿Lo sabías?" utilizando una función reutilizable get_action_buttons().
  • Al inicializar el chat (@cl.on_chat_start) envía un mensaje con estos botones interactivos.
  • Cuando el usuario pulsa el botón "Sorpréndeme", el gestor @cl.action_callback envía un mensaje al LLM solicitando un mensaje breve y edificante de los programadores. La respuesta se limpia con la función .strip() y se devuelve al chat.
  • Del mismo modo, al hacer clic en "¿Sabías que...?" se invoca el LLM con una pregunta que solicita un dato informativo sobre Chainlit o los LLM.
  • Si el LLM falla, se devuelven respuestas estáticas de emergencia.
  • Después de cada interacción, los botones se reenvían para mantener el bucle conversacional.

Esto demuestra cómo combinar Chainlit UI con la generación de contenidos basada en LLM, ofreciendo una base modular y extensible para aplicaciones de chat locales potenciadas por IA.

Ejecuta el siguiente comando en el terminal:

ollama run mistral
chainlit run main.py

Ahora tienes un asistente de IA local y en directo que genera mensajes automatizados.

Bot Sorpréndeme Powered by Ollama

Conclusión

Chainlit tiene un gran potencial para crear prototipos de herramientas basadas en chat, crear asistentes e integrar salidas LLM en tiempo real, todo ello sin tocar JavaScript. Para casos de uso avanzados, consulta el Libro de cocina Chainlit.

Para ampliar tu aprendizaje con nuevas herramientas de IA, consulta los siguientes blogs:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Soy una Google Developers Expert en ML(Gen AI), una Kaggle 3x Expert y una Women Techmakers Ambassador con más de 3 años de experiencia en tecnología. Cofundé una startup de tecnología sanitaria en 2020 y estoy cursando un máster en informática en Georgia Tech, especializándome en aprendizaje automático.

Temas

Aprende IA con estos cursos

Programa

Llama Fundamentals

4hrs hr
Experiment with Llama 3 to run inference on pre-trained models, fine-tune them on custom datasets, and optimize performance.
Ver detallesRight Arrow
Comienza el curso
Ver másRight Arrow
Relacionado
An AI juggles tasks

blog

Cinco proyectos que puedes crear con modelos de IA generativa (con ejemplos)

Aprende a utilizar modelos de IA generativa para crear un editor de imágenes, un chatbot similar a ChatGPT con pocos recursos y una aplicación clasificadora de aprobación de préstamos y a automatizar interacciones PDF y un asistente de voz con GPT.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

12 proyectos LLM para todos los niveles

Descubre 12 ideas de proyectos LLM con guías visuales fáciles de seguir y códigos fuente, adecuados para principiantes, estudiantes de nivel intermedio, estudiantes de último curso y expertos.
Abid Ali Awan's photo

Abid Ali Awan

12 min

Tutorial

Tutorial sobre cómo crear aplicaciones LLM con LangChain

Explore el potencial sin explotar de los grandes modelos lingüísticos con LangChain, un marco Python de código abierto para crear aplicaciones avanzadas de IA.
Moez Ali's photo

Moez Ali

12 min

Tutorial

Construir agentes LangChain para automatizar tareas en Python

Un tutorial completo sobre la construcción de agentes LangChain multiherramienta para automatizar tareas en Python utilizando LLMs y modelos de chat utilizando OpenAI.
Bex Tuychiev's photo

Bex Tuychiev

14 min

Tutorial

RAG Con Llama 3.1 8B, Ollama y Langchain: Tutorial

Aprende a crear una aplicación RAG con Llama 3.1 8B utilizando Ollama y Langchain, configurando el entorno, procesando documentos, creando incrustaciones e integrando un recuperador.
Ryan Ong's photo

Ryan Ong

12 min

Tutorial

Guía para principiantes de LlaMA-Factory WebUI: Ajuste de los LLM

Aprende a afinar los LLM en conjuntos de datos personalizados, evaluar el rendimiento y exportar y servir modelos sin problemas utilizando el marco de trabajo de bajo/ningún código de LLaMA-Factory.
Abid Ali Awan's photo

Abid Ali Awan

12 min

Ver másVer más