Pular para o conteúdo principal

Cadeia: Um guia com exemplos práticos

Saiba o que é o Chainlit, como instalá-lo e como executá-lo para criar interfaces interativas para aplicativos com LLM.
Actualizado 19 de mai. de 2025  · 8 min de leitura

Chainlit é uma poderosa estrutura Python de código aberto que permite que você crie interfaces interativas para seus aplicativos com LLM com o mínimo de código e sem complicações de front-end.

Neste tutorial, você verá o que fazer:

  1. Instalação e configuração do Chainlit.
  2. Compreender seus conceitos principais, como ações, ciclo de vida do chat e configurações.
  3. Criando dois aplicativos de exemplo: 
    • Um chatbot estático "Surpreenda-me" usando botões
    • Um bot "Surprise Me" com tecnologia Ollama

Desenvolver aplicativos de IA

Aprenda a criar aplicativos de IA usando a API OpenAI.
Comece a treinar gratuitamente

O que é Chainlit?

O Chainlit ajuda você a criar front-ends para chatbots de IA, ferramentas e fluxos de trabalho de LLM. Ele abstrai a complexidade do front-end e permite que você se concentre na lógica Python, ao mesmo tempo em que oferece suporte para adicionar botões, controles deslizantes, suporte para upload de arquivos ou até mesmo conectar-se a ferramentas usando o protocolo de contexto de modelo (MCP).

Chainlit é ideal para você:

  • Prototipagem de aplicativos baseados em LLM
  • Criação de ferramentas internas
  • Criação de demonstrações educacionais
  • Conectar seus modelos a ferramentas externas ou APIs

Componentes do Chainlit

Todo aplicativo Chainlit é desenvolvido com base em alguns recursos essenciais:

  1. Ganchos do ciclo de vida do chat: Eles permitem que você controle o que acontece em diferentes estágios de um bate-papo. Por exemplo:
    • @cl.on_chat_start é executado quando um bate-papo começa.
    • @cl.on_message é executado quando o usuário envia uma mensagem.
    • @cl.on_chat_end é executado quando o bate-papo termina.
  2. Ações da interface do usuário: O Chainlit permite que você adicione botões com cl.Action e os manipule com @cl.action_callback. Eles são ótimos para criar interfaces de usuário limpas e interativas sem exigir entrada de texto do usuário.
  3. Transmissão de mensagens: Com os LLMs que suportam streaming de token, você pode transmitir respostas em tempo real usando stream=True, tornando seu aplicativo mais dinâmico e responsivo.
  4. Configuração com config.toml: Esse arquivo permite que você ative recursos como persistência de bate-papo, upload de arquivos, personalização de temas e ajustes de usabilidade - tudo isso sem modificar o código Python.

Explicarei cada conceito com um exemplo prático de código para que você possa ver exatamente como ele funciona e como integrá-lo aos seus aplicativos Chainlit. Vamos começar com a primeira etapa.

Pré-requisitos

Certifique-se de que você tenha o Python 3.8+ instalado e, em seguida, instale o Chainlit usando pip. Também usaremos Langchain para a demonstração do Ollama, portanto, certifique-se de instalá-lo. Execute o seguinte comando no terminal:

pip install chainlit langchain langchain-community

Entendendo os fundamentos do Chainlit por meio de exemplos

Nesta seção, abordaremos os principais blocos de construção do Chainlit, que formarão o núcleo de qualquer projeto.

Ganchos do ciclo de vida do chat

Sempre que um usuário se conecta ao seu aplicativo Chainlit, é criada uma sessão de bate-papo. Você pode acessar diferentes estágios dessa sessão usando os decoradores fornecidos pela Chainlit. Isso inclui:

Criando com @cl.on_chat_start

Esse gancho é executado quando uma nova sessão de bate-papo é iniciada. Você pode usá-lo para cumprimentar o usuário, exibir uma mensagem de boas-vindas ou inicializar o estado da sessão.

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

Criação com @cl.on_message

Esse gancho de mensagem é executado quando o usuário envia uma nova mensagem. Nós o usamos para processar a entrada do usuário, chamar um LLM ou retornar uma resposta.

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

Construindo com @cl.on_stop

O gancho on_stop é executado quando o usuário clica no botão de parada (⏹) durante uma tarefa em execução. Ele serve para cancelar operações de longa duração ou limpar sessões interrompidas.

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!")

Quando o usuário envia uma mensagem, o Chainlit simula uma tarefa com asyncio.sleep(10). Se o usuário clicar no botão parar (⏹), a tarefa será cancelada e o site @cl.on_stop será acionado para registrar a interrupção.

@cl.on_stop output

Criando com @cl.on_chat_end

Esse gancho é acionado quando a sessão termina - ou o usuário atualiza, fecha a guia ou inicia uma nova sessão. Isso geralmente é usado para registrar desconexões ou salvar o 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!")

Quando o localhost estiver aberto, você poderá trabalhar com ele. Quando você fechar a guia ou janela localhost, o terminal exibirá o seguinte:

on_chat_end() chainlit output

Ações da interface do usuário (botões)

O Chainlit permite que você adicione botões interativos diretamente na interface do seu chatbot. Cada botão é definido como uma ação e conectado a uma função de retorno de chamada do Python. Você envia botões como parte de uma mensagem usando o argumento actions:

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()

É assim que você pode tratar um clique de botão:

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

O decorador @cl.action_callback("hello") diz ao Chainlit para ouvir os cliques em um botão com o nome "hello". Quando clicado, ele envia uma mensagem amigável para o usuário na interface de bate-papo.

@cl.action_callback chainlit output

Dica: Você pode personalizar a carga útil com quaisquer dados que queira enviar de volta ao servidor.

Transmissão de mensagens 

O Chainlit oferece suporte ao streaming em tempo real das respostas do LLM. Isso significa que você pode enviar conteúdo para o usuário de forma incremental à medida que ele é gerado.

@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 detalhar isso:

  • Primeiro, ele mostra imediatamente uma mensagem "Thinking..." para que o usuário saiba que o aplicativo está funcionando.
  • Em seguida, ele envia a mensagem do usuário para um LLM compatível com streaming.
  • À medida que o modelo gera saída, ele transmite cada parte (pedaço) de volta para a interface do usuário em tempo real.
  • O parâmetro stream=True garante que cada bloco seja exibido de forma incremental, em vez de você esperar pela resposta completa.

Observação: Isso funciona melhor com modelos que suportam streaming.

Configuração do Chainlit (config.toml)

Para desbloquear recursos avançados, como persistência de bate-papo, uploads de arquivos, temas e muito mais, você pode personalizar o aplicativo Chainlit usando o arquivo config.toml. Esse arquivo reside na raiz do diretório do seu projeto (na pasta .chainlit ) e permite que você ajuste o comportamento do tempo de execução sem modificar o código.

Persistência

Esse parâmetro permite que o Chainlit mantenha o histórico de bate-papo e o estado da sessão. Ele ativa o gancho @cl.on_chat_resume, tornando-o ideal para aplicativos em que os usuários podem se desconectar e voltar mais tarde.

[persistence]
enabled = true

Carregamento de arquivos

Essa configuração permite que os usuários carreguem arquivos na interface de bate-papo. Você pode restringir os tipos e tamanhos de arquivos permitidos para garantir a segurança e o desempenho.

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

Aqui estão alguns tipos de arquivos que são aceitos pelo 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"] }

Isso permite que você adapte os uploads para casos de uso específicos de segurança, desempenho ou domínio.

Personalização da interface do usuário

Essa personalização altera o nome do assistente no parâmetro da interface do usuário e permite que você use a Cadeia de pensamento (CoT) no modo de renderização, o que é útil para raciocínio ou depuração passo a passo.

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

Ajustes de usabilidade

Eles aprimoram a experiência do usuário, rolando automaticamente as novas mensagens para visualização e permitindo a edição de mensagens.

[features]
user_message_autoscroll = true
edit_message = true

Os ajustes de usabilidade acima permitem que o usuário ative a rolagem automática e os recursos de edição de mensagens na interface do usuário.

Projeto: Surprise Me Bot (sem LLM)

Agora que conhecemos os componentes básicos do Chainlit, vamos criar um aplicativo simples baseado na interface do usuário que usa botões para mostrar fatos divertidos predefinidos ou mensagens de motivação do desenvolvedor.

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()

O código acima define duas listas: "FUN_FACTS" para dicas interessantes da Chainlit e "SUPRISES" para mensagens motivacionais.

  • Quando um novo bate-papo é iniciado, ele exibe dois botões: "Surpreenda-me" e "Você sabia?"-usando cl.Action. '
  • Ao clicar em "Surprise Me", você aciona @cl.action_callback("surprise_button"), which sends a random surprise message.
  • Clicar em "Did You Know?" aciona @cl.action_callback("fact_button")`, que envia um fato divertido aleatório.

Isso cria um chatbot simples e interativo usando botões que não exigem LLMs e é perfeito para que você aprenda como funcionam as ações e os retornos de chamada do Chainlit.

Para executar esse aplicativo, basta executar o seguinte comando no terminal:

chainlit run main.py

Você verá botões interativos na interface do usuário que acionam fatos ou mensagens divertidas!

Surprise Me Bot (no LLM)

Projeto: Surprise Me Bot Powered by Ollama

Agora, vamos automatizar esse processo e gerar as mensagens de surpresa e de fatos usando um LLM local via 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()  

Esse aplicativo Chainlit integra um LLM local (via Ollama com o modelo Mistral) para gerar respostas de forma dinâmica com base nas interações do usuário.

  • Ele define dois botões cl.Action - "Surprise Me" e "Did You Know?" - usando uma função get_action_buttons() reutilizável.
  • Na inicialização do bate-papo (@cl.on_chat_start), você envia uma mensagem com esses botões interativos.
  • Quando o usuário clica no botão "Surprise Me" (Surpreenda-me), o manipulador @cl.action_callback envia um prompt para o LLM solicitando uma mensagem curta e animadora do desenvolvedor. A resposta é limpa com a função .strip() e enviada de volta ao chat.
  • Da mesma forma, ao clicar em "Did You Know?", você invoca o LLM com um prompt solicitando um fato informativo sobre o Chainlit ou os LLMs.
  • Se o LLM falhar, as respostas estáticas de fallback serão retornadas.
  • Após cada interação, os botões são reenviados para manter o ciclo de conversação.

Isso demonstra como combinar a interface de usuário Chainlit com a geração de conteúdo baseada em LLM, oferecendo uma base modular e extensível para aplicativos de bate-papo locais com IA.

Execute o seguinte comando no terminal:

ollama run mistral
chainlit run main.py

Agora você tem um assistente de IA local e ao vivo gerando mensagens automatizadas.

Surprise Me Bot Powered by Ollama

Conclusão

O Chainlit tem grande potencial para criar protótipos de ferramentas baseadas em bate-papo, criar assistentes e integrar resultados de LLM em tempo real, tudo isso sem tocar em JavaScript. Para casos de uso avançados, confira o Livro de receitas do Chainlit.

Para expandir seu aprendizado com novas ferramentas de IA, confira os seguintes blogs:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Sou Google Developers Expert em ML (Gen AI), Kaggle 3x Expert e Women Techmakers Ambassador com mais de 3 anos de experiência em tecnologia. Fui cofundador de uma startup de tecnologia de saúde em 2020 e estou fazendo mestrado em ciência da computação na Georgia Tech, com especialização em machine learning.

Temas

Aprenda IA com estes 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 DetalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado

blog

O que é IA? Um guia rápido para iniciantes

Descubra o que realmente é inteligência artificial com exemplos, opiniões de especialistas e todas as ferramentas de que você precisa para aprender mais.
Matt Crabtree's photo

Matt Crabtree

11 min

Tutorial

Como criar aplicativos LLM com o tutorial LangChain

Explore o potencial inexplorado dos modelos de linguagem grandes com o LangChain, uma estrutura Python de código aberto para criar aplicativos avançados de IA.
Moez Ali's photo

Moez Ali

12 min

Tutorial

Criando agentes LangChain para automatizar tarefas em Python

Um tutorial abrangente sobre a criação de agentes LangChain com várias ferramentas para automatizar tarefas em Python usando LLMs e modelos de bate-papo usando OpenAI.
Bex Tuychiev's photo

Bex Tuychiev

14 min

Tutorial

RAG With Llama 3.1 8B, Ollama e Langchain: Tutorial

Aprenda a criar um aplicativo RAG com o Llama 3.1 8B usando Ollama e Langchain, configurando o ambiente, processando documentos, criando embeddings e integrando um retriever.
Ryan Ong's photo

Ryan Ong

12 min

cursor ai code editor

Tutorial

AI do cursor: Um guia com 10 exemplos práticos

Saiba como instalar o Cursor AI no Windows, macOS e Linux e descubra como usá-lo em 10 casos de uso diferentes.

Tutorial

Um guia para iniciantes na engenharia de prompts do ChatGPT

Descubra como fazer com que o ChatGPT forneça os resultados que você deseja, fornecendo a ele as entradas necessárias.
Matt Crabtree's photo

Matt Crabtree

6 min

Ver maisVer mais