- Streamlit è un modo veloce per costruire interfacce utente personalizzate per chatbot AI, ma necessita di una flessibilità che vada oltre i componenti di chat integrati.
- L'API Botpress Chat alimenta la logica, il recupero e i flussi di lavoro dei chatbot, esposti tramite un client Python personalizzato.
- L'applicazione Streamlit gestisce le conversazioni, lo streaming delle risposte e si integra con le sessioni dinamiche degli utenti.
Per quanto ne so, Streamlit è il modo più veloce per far decollare una web-app personalizzabile. Se volete costruire un chatbot AI e distribuirlo sul vostro front-end, non riesco a pensare a un'opzione migliore.
L'unico ostacolo è la libreria degli elementi di chat. Sono specificamente adattati all'API di OpenAIe al client Python.
Il che è fantastico: un paio di righe di codice per interagire con alcune delle più prestigiose tecnologie disponibili è, beh... fantastico.
Ma non è tutto.
E se si desidera un maggiore controllo sul bot? Ad esempio, potreste volere un flusso di lavoro in più fasi o una generazione aumentata dal reperimento (RAG ). Questi livelli aggiuntivi di funzionalità comportano generalmente la creazione di librerie con ogni tipo di dipendenza.
O forse sì?
In questo tutorial, costruirò un client chatbot ospitato da Streamlit. Vi mostrerò un'interfaccia per chatbot ad iterazione rapida e altamente personalizzabili. Poi, imparerete come integrare il chatbot utilizzando un client Python personalizzato OpenAI.
Se state facendo una prototipazione, le dipendenze e i tecnicismi non dovrebbero ostacolarvi.
E, nello spirito della prototipazione rapida, se volete saltare il tutorial e iniziare a smanettare, il codice è su GitHub.
Bombe a volontà 💣
Fase 1: Creare la logica del chatbot
Che si tratti di automazione del flusso di lavoro o di un chatbot per la prenotazione di appuntamenti, il mondo è davvero la vostra ostrica.
Vi invito a esplorare l'ampia gamma di casi d'uso dei chatbot GenAI se siete in cerca di ispirazione. Per semplicità, tornerò da voi con la mia, spero ormai famosa, sommelier Winona.
Il nostro sofisticato e utile bot può essere realizzato in pochi passi. Sarò breve, ma ci sono molti tutorial lunghi e molto utili che potete consultare.
1. Dare istruzioni
Nello studio, ci spostiamo su Home nella barra laterale di sinistra.

Si dovrebbe vedere la sezione Istruzioni in primo piano. Fare clic su di essa per aggiungere o modificare le istruzioni in testo semplice.

Questo dà al nostro bot direttive, personalità e guardrail. Utilizzando un linguaggio semplice, è possibile indirizzare il bot in modo abbastanza efficace verso il comportamento desiderato. Rendetelo più umano e
2. Costruire il flusso
È qui che risiedono i dettagli della personalità del bot: accesso a informazioni specifiche, passaggi rigidi, esecuzione di codice, ecc.
Non sottovalutate il potere della semplicità. Un singolo nodo autonomo può competere con le funzionalità degli agenti di ragionamento. Io ne ho uno collegato alla mia Knowledge Base (KB).

3. Aggiungere la Knowledge Base
Se le istruzioni riguardano le vibrazioni, la KB riguarda i fatti concreti. Nel mio caso, i fatti in questione sono i vini del dataset Wine Reviews, un elenco di vini, descrizioni e prezzi. Lo tratterò come un inventario di vini de-facto per il nostro bot che dovrà diventare Sommelier.
Faccio clic su Tabelle nel pannello di sinistra e clicco su Nuova tabella in alto a sinistra della pagina, assegnandole un nome descrittivo.

Fare clic sull'ellissi verticale (⋮) in alto a destra e premere Importa.

Trascinate il vostro .csv nella finestra di dialogo che si apre e seguite i passaggi sullo schermo.
Per rendere la tabella accessibile al vostro bot, andate su Basi di conoscenza nella barra laterale sinistra.

Fare clic sull'icona della piccola tabella verde e selezionare la fonte pertinente. Fare clic su Aggiungi tabelle.

Assicuratevi che il vostro flusso abbia accesso alla Knowledge Base e sarete pronti a partire.

Passo 2: Aggiungere l'integrazione API di Chat
Il punto di contatto tra il bot e il nostro client locale è l'API Chat . Per aggiungerla al nostro bot, scorriamo fino a Canali di comunicazione e premiamo ... Altro.

Se volete, date un'occhiata alle integrazioni. Noi cerchiamo Chat. Ho dovuto scorrere un po' per trovarla.

Fare clic sull'integrazione e premere Installa integrazione nella finestra di dialogo che si apre.

Una volta installato, si vedrà l'ID APIChat alla fine dell'URL del webhook . Ne avrete bisogno in seguito.
Passo 3: Scrivere il client Python
L'API di Chat espone una serie di endpoint per eseguire operazioni crude su utenti, conversazioni e messaggi. Come promesso, li inserirò in un client Python che possa sostituire un client OpenAI .
1. Aggiungere le credenziali
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,
}
È possibile aggiungere l'ID API della Chat a un file .env; è utile per il debug, ma non è strettamente necessario. Ci occuperemo dell'ID API e della chiave utente quando costruiremo l'applicazione Streamlit.
Continuo a BASE_URI
e RUBRICHE
in una sezione separata costanti.py
per il disordine.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Creare i metodi di richiesta
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")
Come si è detto, quasi tutti questi elementi corrispondono a un endpoint dell'API. Li sto solo avvolgendo in una classe.
3. Creare un ascoltatore SSE
Questo è il limite dell'hacking. Per ascoltare gli aggiornamenti delle conversazioni e inserire un loop in un front-end Streamlit, il client ha bisogno di un metodo per ascoltare gli eventi inviati dal server dal nostro bot e per ottenerli.
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"]}
Questa funzione prende l'ID conversazione (a cui si accederà programmaticamente all'interno dell'applicazione) e restituisce i dati in arrivo man mano che si presentano.
Fase 4: Creare l'applicazione Streamlit
Con le carte in regola, è il momento di costruire il chatbot. Si noti che sto seguendo la guida di Streamlit sulla costruzione di un'app di chat LLM ,con alcune caratteristiche aggiuntive.
1. Adattare il codice boilerplate
In teoria, è possibile far funzionare l'applicazione con modifiche minime al boilerplate dell'esempio 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}
)
Qui stiamo leggendo variabili segrete. Creare quindi un file .streamlit/secrets.toml e inserirvi le variabili:
CHAT_API_ID = "TUO_API_ID"
CHIAVE UTENTE = "TUA_CHIAVE_UTENTE"
Il lavoro pesante si svolge in:
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}
)
dove il client si aggancia agli elementi di chat per consegnare e ricevere messaggi.
Funziona, ma non è l'ideale per alcuni motivi:
- È necessario aver creato una nuova conversazione separatamente.
- I vecchi messaggi saranno formattati in modo diverso da quelli nuovi, perché non hanno la designazione del ruolo (utente o assistente).
- Non è possibile alternare le conversazioni.
2. Creare conversazioni in modo dinamico
Partendo da zero, creerò automaticamente una nuova conversazione o aprirò quella più 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"]
Si noti che ho modificato le chiavi segrete per poter memorizzare più utenti. Si dovrà modificare la propria chiave .streamlit/secrets.toml
per rifletterlo:
[[utenti]]
chiave = "chiave_utente"
Si può ripetere questo blocco quanto si vuole, memorizzando gli utenti come array di tabelle.
3. Consentire agli utenti di creare e alternare le conversazioni
Come dice l'intestazione, questo crea un menu a tendina in alto con un pulsante che consente di scegliere la conversazione.
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. Assegnare il ruolo corretto per i messaggi passati
Risolveremo il problema della formattazione di cui sopra assegnando il ruolo di utente o assistente a ciascuno dei messaggi passati:
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})
In questo modo il nostro codice è conforme alla struttura che Streamlit si aspetta.
5. Aggiungere la logica di messaggistica
Si tratta più o meno della stessa cosa di prima, adattata alla nuova struttura.
# 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. Creare un utente
La logica è pronta, ma è necessario creare un utente per eseguire l'applicazione. Ho scelto di aggiungerlo separatamente per simulare l'esperienza di iscrizione a un servizio. Fortunatamente per voi, ho scritto anche uno 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)
A condizione che si disponga dell'ID API della Chat , è possibile eseguire:
python create_user.py -name YOUR_NAME -id SOME_USER_ID -chat_api_id YOUR_CHAT_API_ID
Questa operazione si occuperà di creare l'utente e di aggiungerlo al file dei segreti.
Passo 5: Eseguire l'applicazione
Dopo aver costruito la logica e creato l'utente, è il momento di fare un giro su questa applicazione. Installate le dipendenze ed eseguite:
streamlit run app.py
E così vedrete il nostro bot in tutto il suo splendore.

Eseguite oggi stesso un chatbot Streamlit
Se state facendo prototipi con Streamlit, sapete che la personalizzazione non deve andare a scapito della comodità. I chatbot servono a risolvere i problemi, non a crearli.
Botpress è dotato di un costruttore visuale drag-and-drop, di decine di integrazioni ufficiali e di endpoint API accessibili. In questo modo è possibile costruire, iterare e distribuire su molti canali di comunicazione.
Iniziate a costruire oggi stesso. È gratuito.
Domande frequenti
Perché scegliere Streamlit rispetto ad altri framework front-end per costruire un chatbot?
Scegliete Streamlit per costruire un chatbot se volete una soluzione veloce, basata su Python, che vi permetta di prototipare rapidamente applicazioni interattive senza bisogno di competenze di front-end, poiché gestisce elementi dell'interfaccia utente come i componenti della chat e la gestione degli stati con un codice minimo.
Un chatbot Streamlit è adatto per la produzione o solo per i prototipi?
Un chatbot Streamlit è ottimo per i prototipi e gli strumenti interni, ma per le applicazioni di produzione rivolte al pubblico, con un traffico intenso o uno stile avanzato, potrebbero essere necessari livelli aggiuntivi come i reverse proxy, l'hardening della sicurezza e forse un framework front-end più robusto per gestire la scala.
Quanto è personalizzabile l'aspetto di un chatbot costruito con Streamlit?
Sebbene Streamlit consenta di regolare lo stile di base, come i colori, i caratteri e il layout, è meno flessibile dei framework web tradizionali; per ottenere design veramente personalizzati, è necessario incorporare HTML/CSS o JavaScript personalizzati, cosa che può essere fatta ma che aggiunge complessità rispetto all'uso dei widget integrati di Streamlit.
Posso integrare un chatbot Streamlit in un sito web esistente o deve funzionare in modo autonomo?
Un chatbot Streamlit viene generalmente eseguito come un'applicazione web indipendente sul proprio URL, ma è possibile incorporarlo in un sito web esistente tramite un iframe, anche se questo richiede la gestione dello stile e considerazioni sulla sicurezza per rendere l'esperienza incorporata senza problemi per gli utenti.
Quanto costa distribuire un chatbot Streamlit per uso pubblico?
L'implementazione di un chatbot Streamlit può essere gratuita se ospitata localmente o su Streamlit Community Cloud per le applicazioni più piccole, ma per l'uso pubblico su scala, i costi vanno da circa 5 a 50 dollari al mese su piattaforme cloud come Heroku, AWS o DigitalOcean, a seconda dei requisiti di traffico e uptime.