- Streamlit é uma forma rápida de criar interfaces personalizadas para chatbots de IA, mas pode exigir mais flexibilidade do que os componentes de chat nativos oferecem.
- A Chat API do Botpress gerencia a lógica do chatbot, buscas e fluxos de trabalho, acessível por meio de um cliente Python personalizado.
- O app Streamlit gerencia as conversas, transmite respostas e integra sessões dinâmicas de usuários.
Até onde sei, Streamlit é a maneira mais rápida de colocar um web-app personalizável no ar. Se você quer criar um chatbot de IA e implantá-lo no seu próprio front-end, não consigo pensar em opção melhor.
O único porém é a biblioteca de elementos de chat. Ela é bem ajustada para a API da OpenAI e o cliente Python deles.
O que é ótimo — algumas linhas de código para interagir com uma das tecnologias mais avançadas disponíveis é, realmente... ótimo.
Mas não é tudo.
Normalmente, adicionar essas camadas de funcionalidade significa lidar com várias bibliotecas e todo tipo de dependências.
Ou será que não?
Neste tutorial, vou construir um cliente de chatbot hospedado no Streamlit. Vou mostrar uma interface para criar chatbots rapidamente e com alta personalização. Depois, você vai aprender a integrar o chatbot usando um cliente Python personalizado no estilo OpenAI.
Se você está prototipando, dependências e detalhes técnicos não devem ser um obstáculo.
E, no espírito de prototipagem rápida, se quiser pular o tutorial e começar a testar, o código está no GitHub.
Mãos à obra 💣
Passo 1: Crie a lógica do chatbot
Seja para automação de fluxos ou um chatbot de agendamento, aqui você tem liberdade total.
Recomendo que explore a variedade de casos de uso para chatbots GenAI se estiver buscando inspiração. Para simplificar, vou usar minha (espero que agora famosa) sommelière, Winona.
Nosso bot sofisticado e prestativo pode ser criado em poucos passos. Vou ser breve, mas há muitos tutoriais longos e super úteis que você pode conferir.
1. Dê instruções ao bot
No Studio, vamos até Início na barra lateral à esquerda.

Você deve ver a seção Instruções em destaque. Clique nela para adicionar ou modificar as instruções em texto simples.

Isso dá ao bot diretrizes, personalidade e limites. Usando linguagem simples, você pode direcionar o bot de forma eficiente para o comportamento desejado. Deixe-o mais humano e
2. Construa o fluxo
Aqui é onde está o núcleo da personalidade do bot: acesso a informações específicas, etapas rígidas, execução de código, etc.
Não subestime o poder da simplicidade. Um único nó autônomo pode rivalizar com agentes de raciocínio. Eu conectei um à minha Base de Conhecimento (KB).

3. Adicione a Base de Conhecimento
Se as instruções tratam do tom, a KB trata de fatos concretos. No meu caso, os fatos são os vinhos do conjunto de dados Wine Reviews, uma lista de vinhos, descrições e preços. Vou tratar isso como um inventário de vinhos para nosso bot atuar como sommelière.
Vou clicar em Tabelas no painel à esquerda e depois em Nova Tabela no canto superior esquerdo da página, dando um nome descritivo.

Clique nos três pontos verticais (⋮) no canto superior direito e selecione Importar.

Arraste seu arquivo .csv para o modal que aparecer e siga as instruções na tela.
Para tornar a tabela acessível ao seu bot, vá até Bases de Conhecimento na barra lateral esquerda.

Clique no pequeno ícone de tabela verde e selecione a fonte desejada. Clique em Adicionar tabelas.

Certifique-se de que seu fluxo tem acesso à Base de Conhecimento e pronto.

Passo 2: Adicione a integração com a Chat API
O ponto de contato entre o bot e nosso cliente local é a Chat API. Para adicioná-la ao bot, role até Canais de Comunicação e clique em … Mais.

Explore as integrações se quiser. O que buscamos é Chat. Precisei rolar um pouco para encontrar.

Clique na integração e depois em Instalar Integração no modal que aparecer.

Depois de instalada, você verá o ID da Chat API no final da URL do webhook. Você vai precisar disso depois.
Passo 3: Escreva o cliente Python
A Chat API oferece vários endpoints para realizar operações CRUD em usuários, conversas e mensagens. Como prometido, vou reunir tudo em um cliente Python que pode substituir o cliente da OpenAI.
1. Adicione suas credenciais
class BotpressClient:
def __init__(self, api_id=None, user_key=None):
self.api_id = api_id or os.getenv("CHAT_API_ID")
self.user_key = user_key or os.getenv("USER_KEY")
self.base_url = f"{BASE_URI}/{self.api_id}"
self.headers = {
**HEADERS,
"x-user-key": self.user_key,
}
Você pode adicionar seu ID da Chat API em um arquivo .env — isso ajuda na depuração, mas não é obrigatório. Vamos lidar com o ID da API e a chave do usuário ao construir o app Streamlit.
Eu mantenho BASE_URI e HEADERS em um arquivo separado, constants.py, para evitar bagunça.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Crie os métodos de requisição
def _request(self, method, path, json=None):
url = f"{self.base_url}{path}"
try:
response = requests.request(method, url, headers=self.headers, json=json)
response.raise_for_status()
return response.json()
except requests.HTTPError:
return response.status_code, response.text
# --- Core API Methods ---
def get_user(self):
return self._request("GET", "/users/me")
def create_user(self, name, id):
user_data = {"name": name, "id": id}
return self._request("POST", "/users", json=user_data)
def set_user_key(self, key):
self.user_key = key
self.headers["x-user-key"] = key
def create_and_set_user(self, name, id):
new_user = self.create_user(name, id)
self.set_user_key(new_user["key"])
def create_conversation(self):
return self._request("POST", "/conversations", json={"body": {}})
def list_conversations(self):
return self._request("GET", "/conversations")
def get_conversation(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}")
def create_message(self, message, conversation_id):
payload = {
"payload": {"type": "text", "text": message},
"conversationId": conversation_id,
}
return self._request("POST", "/messages", json=payload)
def list_messages(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}/messages")Como mencionado, quase todos correspondem a um endpoint da API. Só estou encapsulando em uma classe.
3. Crie um listener SSE
Aqui está o truque: para ouvir atualizações da conversa e integrá-las ao front-end Streamlit, o cliente precisa de um método para escutar e receber eventos enviados pelo servidor do nosso bot.
def listen_conversation(self, conversation_id):
url = f"{self.base_url}/conversations/{conversation_id}/listen"
for event in sseclient.SSEClient(url, headers=self.headers):
print(event.data)
if event.data == "ping":
continue
data = json.loads(event.data)["data"]
yield {"id": data["id"], "text": data["payload"]["text"]}Essa função recebe o conversation_id (que será acessado programaticamente no app) e retorna os dados recebidos em tempo real.
Passo 4: Crie o app Streamlit
Com tudo pronto, é hora de montar o chatbot. Note que estou seguindo o guia do Streamlit sobre como criar um app de chat com LLM — com alguns recursos extras.
1. Adapte o código base
Em teoria, você pode fazer o app funcionar com poucas mudanças no exemplo base do Streamlit.
# app.py
from client import BotpressClient
import streamlit as st
from constants import CONVERSATION_ID
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["USER_KEY"]
)
if "messages" not in st.session_state:
messages = client.list_messages(CONVERSATION_ID)
next_token = messages["meta"]["nextToken"]
st.session_state.messages = messages["messages"][::-1]
for message in st.session_state.messages:
with st.chat_message(message["userId"]):
st.markdown(message["payload"]["text"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
client.create_message(prompt, conversation_id=CONVERSATION_ID)
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
Aqui estamos lendo variáveis secretas. Então, crie um arquivo .streamlit/secrets.toml e coloque suas variáveis lá dentro:
CHAT_API_ID = ”YOUR_API_ID”
USER_KEY = ”YOUR_USER_KEY”O principal acontece em:
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
onde o cliente se conecta aos elementos de chat para enviar e receber mensagens.
Funciona, mas não é o ideal por alguns motivos:
- Você precisa ter criado uma nova conversa separadamente.
- Mensagens antigas serão formatadas diferente das novas, pois não têm a designação de papel (usuário ou assistente).
- Não é possível alternar entre conversas.
2. Crie conversas dinamicamente
Começando do zero, vou criar automaticamente uma nova conversa ou abrir a mais recente:
# app.py
from client import BotpressClient
import streamlit as st
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["users"][0]["key"]
)
# user info
user = client.get_user()
user_id = user["user"]["id"]
conversations = client.list_conversations()["conversations"]
conversation_ids = [conv["id"] for conv in conversations]
# conversation
def create_conversation():
res = client.create_conversation()
print(f"Created new conversation: {res}")
conversation_id = res["conversation"]["id"]
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
st.rerun()
if not conversations:
create_conversation()
if "active_conversation" not in st.session_state:
st.session_state["active_conversation"] = conversations[0]["id"]
Note que modifiquei as chaves secretas para poder armazenar vários usuários. Você deve ajustar seu arquivo .streamlit/secrets.toml para isso:
[[users]]
key = "your_user_key"Você pode repetir esse bloco quantas vezes quiser, armazenando usuários como um array de tabelas.
3. Permita que usuários criem e alternem entre conversas
Como o título diz, isso cria um menu suspenso no topo com um botão para escolher a conversa.
col1, col2 = st.columns([5, 1])
with col1:
conversation_id = st.selectbox(
"Select Conversation",
options=[conv["id"] for conv in conversations],
index=conversation_ids.index(st.session_state.active_conversation),
)
with col2:
st.markdown("<div style='height: 1.9em'></div>", unsafe_allow_html=True)
if st.button("➕"):
create_conversation()
selected_conversation = client.get_conversation(conversation_id)4. Atribua o papel correto às mensagens antigas
Vamos resolver o problema de formatação acima atribuindo o papel de usuário ou assistente a cada mensagem antiga:
if (
"messages" not in st.session_state
or st.session_state.get("active_conversation") != conversation_id
):
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
messages = client.list_messages(conversation_id)
next_token = messages["meta"].get("nextToken")
for message in messages["messages"][::-1]:
role = "user" if message["userId"] == user_id else "assistant"
text = message["payload"]["text"]
st.session_state.messages.append({"role": role, "content": text})Assim, nosso código segue a estrutura esperada pelo Streamlit.
5. Adicione a lógica de mensagens
Isso é mais ou menos igual ao anterior, apenas adaptado para a nova estrutura.
# display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
client.create_message(prompt, conversation_id=conversation_id)
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
stream = client.listen_conversation(conversation_id=conversation_id)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})5. Crie um usuário
A lógica está pronta, mas você precisa criar um usuário para rodar o app. Eu optei por adicionar isso separadamente para simular a experiência de cadastro em um serviço. Para facilitar, escrevi um script:
# create_user.py
import argparse
from pathlib import Path
from client import *
from constants import *
secrets_path = Path(".streamlit") / "secrets.toml"
template = """[[users]]
key="{}"
"""
client = BotpressClient()
def create_user(name, id, add_to_secrets=True):
res = client.create_user(name, id)
if not add_to_secrets:
return res
secrets_path.touch(exist_ok=True)
with open(secrets_path, "a") as f:
f.write(template.format(res["user"]["id"], res["key"]))
return res
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Create a Botpress user and optionally store secrets."
)
parser.add_argument("--name", required=True, help="Display name of the user.")
parser.add_argument(
"--id", required=True, help="User ID. If omitted, one is generated by the API."
)
parser.add_argument("--chat_api_id", help="ID for the Botpress Chat API integration. Taken from `.env` file if not provided.")
parser.add_argument(
"--no-secrets",
action="store_true",
help="Do not append to .streamlit/secrets.toml.",
)
args = parser.parse_args()
print(f"Creating user: {args.name} (ID: {args.id or 'auto-generated'})")
result = create_user(name=args.name, id=args.id, add_to_secrets=not args.no_secrets)
print("✅ User created:")
print(result)
Tendo seu ID da Chat API, você pode rodar:
python create_user.py –name SEU_NOME –id ALGUM_ID_DE_USUARIO –chat_api_id SEU_CHAT_API_ID
Isso vai criar o usuário e adicioná-lo ao seu arquivo de segredos.
Passo 5: Execute a aplicação
Com sua lógica pronta e o usuário criado, é hora de testar este aplicativo. Instale as dependências e execute:
streamlit run app.py
E assim, você verá nosso bot em funcionamento.

Execute um chatbot com Streamlit hoje mesmo
Se você está criando protótipos com Streamlit, sabe que personalização não deve comprometer a praticidade. Chatbots existem para resolver problemas — não para criá-los.
O Botpress oferece um construtor visual de arrastar e soltar, dezenas de integrações oficiais e endpoints de API acessíveis. Assim, você pode criar, iterar e implantar em vários canais de comunicação.
Comece a construir hoje. É grátis.
Perguntas frequentes
Por que eu escolheria Streamlit em vez de outros frameworks front-end para criar um chatbot?
Você escolheria Streamlit para criar um chatbot se quiser uma solução rápida, baseada em Python, que permite prototipar aplicativos interativos rapidamente sem precisar de conhecimento em front-end, já que ele gerencia elementos de interface como componentes de chat e controle de estado com pouco código.
Um chatbot feito com Streamlit é adequado para uso em produção ou apenas para protótipos?
Um chatbot com Streamlit é ótimo para protótipos e ferramentas internas, mas para aplicativos de produção voltados ao público com alto tráfego ou necessidade de personalização avançada, pode ser necessário adicionar camadas extras como proxies reversos, reforço de segurança e talvez um framework front-end mais robusto para lidar com a escala.
Quão personalizável é a aparência de um chatbot criado com Streamlit?
Embora o Streamlit permita ajustar estilos básicos como cores, fontes e layout, ele é menos flexível que frameworks web tradicionais; para designs realmente personalizados, seria necessário incorporar HTML/CSS ou JavaScript próprios, o que é possível, mas adiciona complexidade em comparação com os widgets nativos do Streamlit.
Posso integrar um chatbot Streamlit em um site já existente ou ele precisa rodar de forma independente?
Um chatbot com Streamlit normalmente roda como um aplicativo web independente em sua própria URL, mas pode ser incorporado em um site existente via iframe, embora isso exija cuidados com estilo e segurança para garantir uma experiência integrada ao usuário.
Quanto custa implantar um chatbot Streamlit para uso público?
Implantar um chatbot Streamlit pode ser gratuito se hospedado localmente ou no Streamlit Community Cloud para aplicativos menores, mas para uso público em escala, os custos variam de cerca de $ 25 a $ 250 por mês em plataformas de nuvem como Heroku, AWS ou DigitalOcean, dependendo do tráfego e dos requisitos de disponibilidade.





.webp)
