- Streamlit to szybki sposób na tworzenie niestandardowych interfejsów użytkownika chatbota AI, ale wymaga elastyczności wykraczającej poza wbudowane komponenty czatu.
- Botpress Chat API obsługuje logikę chatbota, wyszukiwanie i przepływy pracy, udostępniane za pośrednictwem niestandardowego klienta Python.
- Aplikacja Streamlit zarządza konwersacjami, strumieniuje odpowiedzi i integruje się z dynamicznymi sesjami użytkowników.
O ile wiem, Streamlit to najszybszy sposób na stworzenie konfigurowalnej aplikacji internetowej. Jeśli chcesz zbudować chatbota AI i wdrożyć go na własnym front-endzie, nie wyobrażam sobie lepszej opcji.
Jedyną przeszkodą jest biblioteka elementów czatu. Są one dość specyficznie dostosowane do API OpenAIi klienta Pythona
Co jest świetne - kilka linijek kodu do interakcji z najbardziej prestiżową dostępną technologią jest... świetne.
Ale to nie wszystko.
A co jeśli chcesz mieć większą kontrolę nad swoim botem? Na przykład, możesz chcieć wieloetapowego przepływu pracy lub generowania rozszerzonego o pobieranie (RAG). Te dodatkowe warstwy funkcjonalności zazwyczaj oznaczają łączenie bibliotek z różnego rodzaju zależnościami.
A może jednak?
W tym samouczku zbuduję klienta chatbota hostowanego przez Streamlit. Pokażę ci interfejs do szybkiej iteracji i wysoce konfigurowalnych chatbotów. Następnie dowiesz się, jak zintegrować chatbota za pomocą niestandardowego klienta Python OpenAI.
Jeśli prototypujesz, zależności i kwestie techniczne nie powinny Cię powstrzymywać.
A w duchu szybkiego prototypowania, jeśli chcesz pominąć samouczek i zacząć majstrować, kod znajduje się na GitHub.
Bomby daleko 💣
Krok 1: Zbuduj logikę chatbota
Niezależnie od tego, czy chodzi o automatyzację przepływu pracy, czy chatbota do rezerwacji spotkań, świat naprawdę jest tutaj twoją ostrygą.
Zachęcam do zapoznania się z szeroką gamą przypadków użycia chatbotów GenAI, jeśli szukasz inspiracji. Dla uproszczenia, wrócę do ciebie z moim, mam nadzieję, teraz sławnym sommelierem, Winoną.
Nasz wyrafinowany, pomocny mały bot może być osiągnięty w zaledwie kilku krokach. Będę się streszczał, ale istnieje wiele długich, bardzo pomocnych samouczków, które można przejrzeć.
1. Przekaż mu instrukcje
W studiu przejdziemy do strony głównej na lewym pasku bocznym.

Sekcja Instrukcje powinna znajdować się na pierwszym planie. Kliknij ją, aby dodać lub zmodyfikować instrukcje w postaci zwykłego tekstu.

Daje to naszemu botowi dyrektywy, osobowość i bariery ochronne. Używając prostego języka, można dość skutecznie kierować bota w stronę pożądanego zachowania. Niech brzmi bardziej ludzko, a
2. Zbuduj przepływ
Jest to miejsce, w którym znajdują się najważniejsze elementy osobowości bota: dostęp do określonych informacji, sztywne kroki krok po kroku, wykonywanie kodu itp.
Nie lekceważ potęgi prostoty. Pojedynczy autonomiczny węzeł rywalizuje z funkcjonalnością agentów rozumujących. Mam jeden podłączony do mojej bazy wiedzy (KB).

3. Dodaj bazę wiedzy
Jeśli instrukcje dotyczą wibracji, KB dotyczy zimnych, twardych faktów. W moim przypadku fakty, o których mowa, to wina w zbiorze danych Wine Reviews, lista win, opisy i ceny. Będę traktował to jako faktyczny spis win dla naszego bota do sommelierskiej obróbki.
Klikam na Tables w lewym panelu, wybieram New Table w lewym górnym rogu strony i nadaję jej opisową nazwę.

Kliknij pionową elipsę (⋮) w prawym górnym rogu i naciśnij Importuj.

Przeciągnij plik .csv do wyskakującego okna modalnego i postępuj zgodnie z instrukcjami wyświetlanymi na ekranie.
Aby udostępnić tabelę botowi, przejdź do sekcji Bazy wiedzy na pasku bocznym po lewej stronie.

Kliknij małą zieloną ikonę tabeli i wybierz odpowiednie źródło. Kliknij Dodaj tabele.

Upewnij się, że Twój przepływ ma dostęp do bazy wiedzy i jesteś gotowy do pracy.

Krok 2: Dodanie integracji API Chat
Punktem kontaktowym między botem a naszym lokalnym klientem jest Chat API. Aby dodać go do naszego bota, przewinę do Communication Channels i nacisnę ... Więcej.

Zapoznaj się z integracjami, jeśli chcesz. Jesteśmy za Chat. Musiałem trochę przewinąć, aby go znaleźć.

Kliknij integrację i wybierz opcję Zainstaluj integrację w wyskakującym oknie dialogowym.

Po zainstalowaniu zobaczysz identyfikatorChat API na końcu adresu URL webhook . Będzie on potrzebny później.
Krok 3: Napisanie klienta Python
Chat API udostępnia szereg punktów końcowych do wykonywania skomplikowanych operacji na użytkownikach, konwersacjach i wiadomościach. Zgodnie z obietnicą, opakuję je w klienta Pythona, który może zastąpić klienta OpenAI .
1. Dodaj swoje dane uwierzytelniające
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,
}
Możesz dodać swój identyfikator API Chat do pliku .env - pomaga to w debugowaniu, ale nie jest to absolutnie konieczne. Zajmiemy się identyfikatorem API i kluczem użytkownika podczas tworzenia aplikacji Streamlit.
Trzymam BASE_URI
oraz NAGŁÓWKI
w oddzielnym constants.py
plik, dla bałaganu.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Utwórz metody żądania
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")
Jak wspomniano, prawie wszystkie z nich mapują do punktu końcowego w API. Po prostu opakowuję je w klasę.
3. Tworzenie listenera SSE
To jest zakres hakowania. Aby nasłuchiwać aktualizacji konwersacji i zapętlić się we front-endzie Streamlit, klient potrzebuje metody nasłuchiwania - i uzyskiwania - zdarzeń wysyłanych przez serwer od naszego bota.
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"]}
Ta funkcja pobiera conversation_id (który będzie dostępny programowo w aplikacji) i zwraca przychodzące dane w miarę ich pojawiania się.
Krok 4: Utwórz aplikację Streamlit
Mając już wszystko dopięte na ostatni guzik, nadszedł czas na zbudowanie chatbota. Należy pamiętać, że postępuję zgodnie z przewodnikiem Streamlit na temat tworzenia aplikacji czatu LLM -z kilkoma dodatkowymi funkcjami.
1. Dostosowanie standardowego kodu
Teoretycznie można uruchomić aplikację przy minimalnych zmianach w szablonie w przykładzie 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}
)
Czytamy tutaj tajne zmienne. Utwórz więc plik .streamlit/secrets.toml i umieść w nim swoje zmienne:
CHAT_API_ID = "YOUR_API_ID"
USER_KEY = "YOUR_USER_KEY"
Ciężkie podnoszenie odbywa się w:
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}
)
gdzie klient łączy się z elementami czatu, aby dostarczać i odbierać wiadomości.
To działa, ale nie jest idealne z kilku powodów:
- Musisz utworzyć nową konwersację osobno.
- Stare wiadomości będą formatowane inaczej niż nowe, ponieważ nie mają oznaczenia roli (użytkownik lub asystent).
- Nie można przełączać konwersacji.
2. Dynamiczne tworzenie konwersacji
Zaczynając od zera, automatycznie utworzę nową rozmowę lub otworzę ostatnią:
# 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"]
Zauważ, że zmodyfikowałem tajne klucze, aby móc przechowywać wielu użytkowników. Będziesz chciał zmodyfikować swoje .streamlit/secrets.toml
aby to odzwierciedlić:
[[użytkownicy]]
key = "your_user_key"
Możesz powtarzać ten blok tyle razy, ile chcesz, przechowując użytkowników jako tablicę tablic.
3. Pozwól użytkownikom tworzyć i przełączać się między konwersacjami
Jak mówi nagłówek, tworzy to menu rozwijane u góry z przyciskiem umożliwiającym wybór konwersacji.
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. Przypisywanie właściwej roli dla poprzednich wiadomości
Rozwiążemy powyższy problem z formatowaniem, przypisując rolę użytkownika lub asystenta do każdej z poprzednich wiadomości:
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})
Dostosowuje to nasz kod do struktury oczekiwanej przez Streamlit.
5. Dodaj logikę przesyłania wiadomości
Jest to mniej więcej to samo, co wcześniej, dostosowane do nowej struktury.
# 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. Utwórz użytkownika
Logika jest gotowa, ale musisz utworzyć użytkownika, aby uruchomić aplikację. Zdecydowałem się dodać to osobno, aby zasymulować doświadczenie rejestracji w usłudze. Na szczęście napisałem również skrypt:
# 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)
Pod warunkiem, że masz swój identyfikator Chat API, możesz go uruchomić:
python create_user.py -name YOUR_NAME -id SOME_USER_ID -chat_api_id YOUR_CHAT_API_ID
Spowoduje to utworzenie użytkownika i dodanie go do pliku sekretów.
Krok 5: Uruchomienie aplikacji
Po zbudowaniu logiki i utworzeniu użytkownika nadszedł czas, aby zabrać tę aplikację na przejażdżkę. Zainstaluj zależności i uruchom:
streamlit run app.py
W ten sposób zobaczysz naszego bota w całej okazałości.

Uruchom chatbota Streamlit już dziś
Jeśli prototypujesz za pomocą Streamlit, wiesz, że personalizacja nie powinna odbywać się kosztem wygody. Chatboty są po to, by rozwiązywać problemy, a nie je tworzyć.
Botpress jest wyposażony w wizualny kreator typu "przeciągnij i upuść", dziesiątki oficjalnych integracji i dostępne punkty końcowe API. W ten sposób można tworzyć, iterować i wdrażać w wielu kanałach komunikacji.
Zacznij budować już dziś. To nic nie kosztuje.
Najczęściej zadawane pytania
Dlaczego miałbym wybrać Streamlit zamiast innych front-endowych frameworków do budowy chatbota?
Wybierz Streamlit do budowy chatbota, jeśli chcesz szybkiego, opartego na Pythonie rozwiązania, które pozwala szybko prototypować interaktywne aplikacje bez konieczności posiadania wiedzy front-endowej, ponieważ obsługuje elementy interfejsu użytkownika, takie jak komponenty czatu i zarządzanie stanem przy minimalnym kodzie.
Czy chatbot Streamlit nadaje się do użytku produkcyjnego, czy tylko do prototypów?
Chatbot Streamlit świetnie nadaje się do prototypów i narzędzi wewnętrznych, ale w przypadku publicznych aplikacji produkcyjnych o dużym natężeniu ruchu lub zaawansowanej stylizacji, możesz potrzebować dodatkowych warstw, takich jak odwrotne serwery proxy, wzmocnienie bezpieczeństwa i być może bardziej niezawodny framework front-end do obsługi skali.
Jak konfigurowalny jest wygląd chatbota zbudowanego za pomocą Streamlit?
Streamlit pozwala dostosować podstawowe stylizacje, takie jak kolory, czcionki i układ, ale jest mniej elastyczny niż tradycyjne frameworki internetowe; w przypadku naprawdę niestandardowych projektów konieczne byłoby osadzenie niestandardowego kodu HTML / CSS lub JavaScript, co można zrobić, ale zwiększa złożoność w porównaniu do korzystania z wbudowanych widżetów Streamlit.
Czy mogę zintegrować chatbota Streamlit z istniejącą stroną internetową, czy musi on działać samodzielnie?
Chatbot Streamlit zazwyczaj działa jako samodzielna aplikacja internetowa pod własnym adresem URL, ale można go osadzić w istniejącej witrynie internetowej za pomocą ramki iframe, choć wymaga to obsługi stylizacji i względów bezpieczeństwa, aby osadzone doświadczenie było płynne dla użytkowników.
Ile kosztuje wdrożenie chatbota Streamlit do użytku publicznego?
Wdrożenie chatbota Streamlit może być bezpłatne, jeśli jest hostowane lokalnie lub w Streamlit Community Cloud dla mniejszych aplikacji, ale w przypadku publicznego użytku na dużą skalę koszty wahają się od około 5 do 50 USD miesięcznie na platformach chmurowych, takich jak Heroku, AWS lub DigitalOcean, w zależności od ruchu i wymagań dotyczących czasu pracy.