- O Streamlit é uma forma rápida de criar interfaces de chatbot com IA personalizadas, mas precisa de flexibilidade para além dos componentes de chat incorporados.
- A API Botpress Chat permite a lógica, a recuperação e os fluxos de trabalho do chatbot, expostos através de um cliente Python personalizado.
- A aplicação Streamlit gere as conversas, transmite as respostas e integra-se em sessões de utilizador dinâmicas.
Tanto quanto sei, o Streamlit é a forma mais rápida de lançar uma aplicação web personalizável. Se procura criar um chatbot de IA e implementá-lo no seu próprio front-end, não consigo pensar numa opção melhor.
O único obstáculo é a biblioteca de elementos de chat. Eles são muito especificamente ajustados à API do OpenAIe ao cliente Python
O que é ótimo - algumas linhas de código para interagir com alguma da mais prestigiada tecnologia disponível é, bem... ótimo.
Mas não é tudo.
E se quiser ter mais controlo sobre o seu bot? Por exemplo, pode querer um fluxo de trabalho de várias etapas ou geração aumentada por recuperação (RAG). Essas camadas adicionais de funcionalidade geralmente significam a organização de bibliotecas com todos os tipos de dependências.
Ou será que não?
Neste tutorial, vou construir um cliente de chatbot hospedado no Streamlit. Mostrarei uma interface para iteração rápida e chatbots altamente personalizáveis. Em seguida, você aprenderá como integrar o chatbot usando um cliente Python personalizado OpenAI.
Se estiver a criar protótipos, as dependências e os aspectos técnicos não o devem impedir.
E, no espírito da prototipagem rápida, se quiser saltar o tutorial e começar a mexer, o código está no GitHub.
Bombas à distância 💣
Etapa 1: criar a lógica do Chatbot
Quer se trate de automatização do fluxo de trabalho ou de um chatbot de marcação de consultas, o mundo é realmente a sua ostra.
Aconselho-o a explorar a variedade de casos de utilização dos chatbots GenAI se estiver à procura de inspiração. Por uma questão de simplicidade, vou voltar a falar-vos da minha esperançosamente agora famosa sommelier, Winona.
O nosso pequeno bot sofisticado e útil pode ser alcançado em apenas alguns passos. Vou ser breve, mas há muitos tutoriais extensos e muito úteis que podem ser consultados.
1. Dar-lhe instruções
No estúdio, navegaremos para Início na barra lateral esquerda.

Deverá ver a secção Instruções no centro da página. Clique nela para adicionar ou modificar as instruções em texto simples.

Isto dá ao nosso bot diretivas, personalidade e guardrails. Usando linguagem simples, pode orientar o seu bot de forma bastante eficaz para o comportamento desejado. Faça-o parecer mais humano, e
2. Construir o fluxo
É aqui que residem os aspetos essenciais da personalidade do bot: acesso a informações específicas, passos rígidos, execução de código, etc.
Não subestime o poder da simplicidade. Um único nó autónomo rivaliza com a funcionalidade dos agentes de raciocínio. Eu tenho um ligado à minha Base de Dados de Conhecimento (KB).

3. Adicionar a base de conhecimentos
Se as instruções são sobre vibrações, a KB é sobre factos concretos. No meu caso, os factos em questão são os vinhos no conjunto de dados Wine Reviews, uma lista de vinhos, descrições e preços. Vou tratar isto como um inventário de vinhos de facto para o nosso bot Sommelier-ize.
Clico em Tables (Tabelas ) no painel esquerdo e carrego em New Table (Nova tabela) no canto superior esquerdo da página e dou-lhe um nome descritivo.

Clique nas elipses verticais (⋮) no canto superior direito e prima Importar.

Arraste o seu .csv para o modal que aparece e siga os passos no ecrã.
Para tornar a tabela acessível ao seu bot, navegue até Bases de Conhecimento na barra lateral esquerda.

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

Certifique-se de que o seu fluxo tem acesso à base de dados de conhecimento e está pronto para começar.

Etapa 2: adicionar a integração da API Chat
O ponto de contacto entre o bot e o nosso cliente local é a API Chat . Para adicionar isso ao nosso bot, vou até Communication Channels (Canais de comunicação) e carrego em ... Mais.

Se quiser, pode consultar as integrações. Estamos atrás de Chat. Tive de percorrer um pouco para o encontrar.

Clique na integração e prima Instalar integração no modal que aparece.

Depois de instalado, você verá a ID da APIChat no final do URL webhook . Você precisará dela mais tarde.
Passo 3: Escrever o cliente Python
A API Chat expõe uma série de endpoints para realizar operações em usuários, conversas e mensagens. Como prometido, eu vou envolver isso em um cliente Python que pode substituir um cliente OpenAI .
1. Adicione as 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,
}
Pode adicionar o seu ID da API Chat a um ficheiro .env - ajuda na depuração, mas não é estritamente necessário. Lidaremos com a ID da API e a chave de usuário quando criarmos o aplicativo Streamlit.
Eu mantenho BASE_URI
e CABEÇALHOS
numa constants.py
ficheiro, para a desarrumação.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Criar os métodos Request
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 estes mapeiam para um ponto final na API. Estou apenas a envolvê-los numa classe.
3. Criar um ouvinte SSE
Esta é a extensão do hackerismo. Para ouvir as actualizações da conversa e fazer um loop num front-end Streamlit, o cliente precisa de um método para ouvir - e produzir - 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"]}
Esta função recebe o conversation_id (que será acedido programaticamente dentro da aplicação) e produz os dados de entrada à medida que estes acontecem.
Passo 4: Criar a aplicação Streamlit
Com os nossos patos em fila, é altura de construir o chatbot. Note-se que estou a seguir o guia do Streamlit para criar uma aplicação de chat LLM -com algumas funcionalidades adicionais.
1. Adaptar o código padrão
Em teoria, é possível pôr a aplicação a funcionar com alterações mínimas ao boilerplate no exemplo 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}
)
Estamos a ler variáveis secretas aqui. Portanto, crie um arquivo .streamlit/secrets.toml e coloque suas variáveis dentro dele:
CHAT_API_ID = "SEU_API_ID"
USER_KEY = "SUA_CHAVE_DE_UTILIZADOR"
O trabalho pesado está a ser feito dentro:
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}
)
em que o cliente se agarra aos elementos de conversação para entregar e receber mensagens.
Isto funciona, mas não é o ideal por algumas razões:
- Tem de ter criado uma nova conversa separadamente.
- As mensagens antigas serão formatadas de forma diferente das novas, uma vez que não têm a designação de função (utilizador ou assistente).
- Não é possível alternar as conversas.
2. Criar conversas de forma dinâmica
Começando do zero, crio automaticamente uma nova conversa ou abro 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 utilizadores. Você vai querer modificar seu .streamlit/secrets.toml
para refletir isso:
[[utilizadores]]
chave = "sua_chave_de_utilizador"
Pode repetir este bloco as vezes que quiser, armazenando os utilizadores como uma matriz de tabelas.
3. Permitir que os utilizadores criem e alternem entre conversas
Tal como o título indica, isto cria um menu pendente na parte superior com um botão que lhe permite escolher a sua 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. Atribuir a função correta às mensagens anteriores
Resolveremos o problema de formatação acima, atribuindo a função de utilizador ou assistente a cada uma das mensagens anteriores:
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})
Isto faz com que o nosso código esteja em conformidade com a estrutura que o Streamlit espera.
5. Adicionar a lógica de envio de mensagens
É mais ou menos a mesma coisa que antes, adaptada à 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. Criar um utilizador
A lógica está pronta, mas é necessário criar um utilizador para executar a aplicação. Optei por adicionar isto separadamente para simular a experiência de subscrição de um serviço. Felizmente para si, também 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)
Desde que tenha o seu ID da API Chat , pode executar:
python criar_utilizador.py -nome SEU_NOME -id ALGUM_ID_DO_UTILIZADOR -id_api_do_chat SEU_ID_API_DO_CHAT
Isto irá tratar da criação do utilizador e adicioná-lo ao seu ficheiro de segredos.
Passo 5: Executar a aplicação
Com a sua lógica construída e o seu utilizador criado, está na altura de dar uma volta com esta aplicação. Instale as dependências e execute:
streamlit run app.py
E, sem mais nem menos, verá o nosso bot em toda a sua glória.

Execute um chatbot Streamlit hoje mesmo
Se está a criar protótipos com o Streamlit, sabe que a personalização não deve ser feita à custa da conveniência. Os chatbots existem para resolver problemas - não para os criar.
Botpress vem com um construtor visual de arrastar e soltar, dezenas de integrações oficiais e pontos de extremidade de API acessíveis. Dessa forma, é possível criar, iterar e implantar em vários canais de comunicação.
Comece a construir hoje. É grátis.
FAQs
Porque é que eu escolheria o Streamlit em vez de outras estruturas de front-end para criar um chatbot?
Escolheria o Streamlit para construir um chatbot se quisesse uma solução rápida, baseada em Python, que lhe permitisse criar rapidamente protótipos de aplicações interactivas sem necessitar de conhecimentos de front-end, uma vez que lida com elementos de IU como componentes de chat e gestão de estados com o mínimo de código.
Um chatbot Streamlit é adequado para utilização na produção ou apenas para protótipos?
Um chatbot Streamlit é ótimo para protótipos e ferramentas internas, mas para aplicações de produção viradas para o público com tráfego intenso ou estilo avançado, pode precisar de camadas adicionais como proxies inversos, reforço de segurança e possivelmente uma estrutura de front-end mais robusta para lidar com a escala.
Quão personalizável é o aspeto e a sensação de um chatbot criado com o Streamlit?
Embora o Streamlit permita ajustar o estilo básico, como cores, tipos de letra e disposição, é menos flexível do que as estruturas Web tradicionais; para designs verdadeiramente personalizados, teria de incorporar HTML/CSS ou JavaScript personalizados, o que pode ser feito, mas acrescenta complexidade em comparação com a utilização dos widgets incorporados no Streamlit.
Posso integrar um chatbot Streamlit num sítio Web existente ou tem de funcionar de forma autónoma?
Um chatbot Streamlit é normalmente executado como uma aplicação Web autónoma no seu próprio URL, mas pode ser incorporado num Web site existente através de um iframe, embora isto exija um estilo de manuseamento e considerações de segurança para tornar a experiência incorporada perfeita para os utilizadores.
Quanto custa implementar um chatbot Streamlit para utilização pública?
A implementação de um chatbot Streamlit pode ser gratuita se hospedado localmente ou no Streamlit Community Cloud para aplicativos menores, mas para uso público em escala, os custos variam de cerca de US $ 5 a US $ 50 por mês em plataformas de nuvem como Heroku, AWS ou DigitalOcean, dependendo dos requisitos de tráfego e tempo de atividade.