- Streamlit es una forma rápida de crear interfaces personalizadas para chatbots de IA, pero necesita más flexibilidad que los componentes de chat integrados.
- La Chat API de Botpress gestiona la lógica del chatbot, la recuperación de información y los flujos de trabajo, todo accesible desde un cliente Python personalizado.
- La app de Streamlit gestiona las conversaciones, muestra respuestas en tiempo real e integra sesiones de usuario dinámicas.
Hasta donde sé, Streamlit es la forma más rápida de lanzar una web-app personalizable. Si quieres crear un chatbot de IA y desplegarlo en tu propio front-end, no se me ocurre mejor opción.
La única limitación es la librería de elementos de chat. Está bastante orientada a la API de OpenAI y su cliente de Python.
Lo cual está bien: unas pocas líneas de código para interactuar con una de las tecnologías más avanzadas disponibles es, bueno... genial.
Pero no es todo.
¿Y si quieres tener más control sobre tu bot? Por ejemplo, tal vez quieras un flujo de trabajo de varios pasos o generación aumentada por recuperación (RAG). Estas capas adicionales de funcionalidad suelen implicar lidiar con bibliotecas y todo tipo de dependencias.
¿O sí?
En este tutorial, voy a crear un cliente de chatbot alojado en Streamlit. Te mostraré una interfaz para chatbots personalizables y de iteración rápida. Después, aprenderás a integrar el chatbot usando un cliente Python personalizado al estilo OpenAI.
Si estás prototipando, las dependencias y detalles técnicos no deberían frenarte.
Y, en la línea de prototipar rápido, si quieres saltarte el tutorial y empezar a probar, el código está en GitHub.
¡Bombas fuera 💣!
Paso 1: Crea la lógica del chatbot
Ya sea para automatizar flujos de trabajo o un chatbot para reservar citas, aquí tienes total libertad.
Te animo a explorar la variedad de casos de uso de chatbots GenAI si buscas inspiración. Por simplicidad, volveré a usar a mi ya casi famosa sumiller, Winona.
Nuestro sofisticado y útil bot se puede crear en solo unos pasos. Seré breve, pero tienes muchos tutoriales extensos y muy útiles para consultar.
1. Dale instrucciones
En el studio, ve a Home en la barra lateral izquierda.

Deberías ver la sección Instructions en el centro. Haz clic para añadir o modificar las instrucciones en texto plano.

Esto le da directrices, personalidad y límites a nuestro bot. Usando lenguaje natural, puedes guiarlo fácilmente hacia el comportamiento que buscas. Haz que suene más humano y
2. Crea el flujo
Aquí es donde vive la esencia del bot: acceso a información específica, pasos rígidos, ejecución de código, etc.
No subestimes el poder de lo simple. Un solo nodo autónomo puede igualar la funcionalidad de agentes de razonamiento. Yo tengo uno conectado a mi Base de Conocimientos (KB).

3. Añade la Base de Conocimientos
Si las instrucciones son sobre el tono, la KB trata de hechos concretos. En mi caso, los datos son los vinos del conjunto de datos de Wine Reviews, una lista de vinos, descripciones y precios. Lo usaré como inventario de vinos para nuestro bot sumiller.
Haz clic en Tables en el panel izquierdo y pulsa New Table arriba a la izquierda, dándole un nombre descriptivo.

Haz clic en el icono de tres puntos verticales (⋮) arriba a la derecha y selecciona Import.

Arrastra tu archivo .csv al modal que aparece y sigue los pasos en pantalla.
Para que la tabla esté accesible para tu bot, ve a Knowledge Bases en la barra lateral izquierda.

Haz clic en el pequeño icono de tabla verde y selecciona la fuente correspondiente. Pulsa Add tables.

Asegúrate de que tu flujo tenga acceso a la Base de Conocimientos y listo.

Paso 2: Añade la integración con la Chat API
El punto de contacto entre el bot y nuestro cliente local es la Chat API. Para añadirla a nuestro bot, baja hasta Communication Channels y haz clic en … More.

Puedes revisar las integraciones si quieres. Nosotros buscamos Chat. Tuve que bajar un poco para encontrarla.

Haz clic en la integración y pulsa Install Integration en el modal que aparece.

Una vez instalada, verás el Chat API ID al final de la URL del webhook. Lo necesitarás más adelante.
Paso 3: Escribe el cliente en Python
La Chat API expone varios endpoints para realizar operaciones CRUD sobre usuarios, conversaciones y mensajes. Como prometí, los agruparé en un cliente Python que puede sustituir al cliente de OpenAI.
1. Añade tus credenciales
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,
}
Puedes poner tu Chat API ID en un archivo .env; ayuda a depurar, pero no es imprescindible. Nos ocuparemos del API ID y la clave de usuario al crear la app de Streamlit.
Yo guardo BASE_URI y HEADERS en un archivo aparte llamado constants.py, para mantener el orden.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Crea los métodos de petición
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 mencioné, casi todos corresponden a un endpoint de la API. Solo los estoy agrupando en una clase.
3. Crea un listener SSE
Aquí está el truco. Para escuchar actualizaciones de la conversación y conectarlas con el front-end de Streamlit, el cliente necesita un método para recibir y emitir eventos enviados por el servidor desde nuestro 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 función recibe el conversation_id (que se obtiene programáticamente en la app) y va mostrando los datos entrantes en tiempo real.
Paso 4: Crea la app de Streamlit
Con todo listo, es momento de construir el chatbot. Ten en cuenta que sigo la guía oficial de Streamlit para crear una app de chat con LLM, pero con algunas mejoras.
1. Adapta el código base
En teoría, puedes hacer que la app funcione con mínimos cambios sobre el ejemplo base de 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}
)
Aquí leemos variables secretas. Así que crea un archivo .streamlit/secrets.toml y coloca tus variables dentro:
CHAT_API_ID = ”YOUR_API_ID”
USER_KEY = ”YOUR_USER_KEY”La parte principal ocurre en:
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}
)
donde el cliente se conecta a los elementos de chat para enviar y recibir mensajes.
Esto funciona, pero no es lo ideal por varias razones:
- Tienes que haber creado una conversación nueva por separado.
- Los mensajes antiguos se formatean diferente a los nuevos, porque no tienen el rol asignado (usuario o asistente).
- No puedes alternar entre conversaciones.
2. Crea conversaciones dinámicamente
Desde cero, crearé automáticamente una conversación nueva o abriré la más reciente:
# 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"]
Ten en cuenta que he modificado las claves secretas para poder guardar varios usuarios. Deberás modificar tu archivo .streamlit/secrets.toml para reflejarlo:
[[users]]
key = "your_user_key"Puedes repetir este bloque tantas veces como quieras, guardando usuarios como un array de tablas.
3. Permite a los usuarios crear y alternar entre conversaciones
Como dice el título, esto crea un menú desplegable arriba con un botón para elegir la conversación.
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. Asigna el rol correcto a los mensajes anteriores
Solucionaremos el problema de formato anterior asignando el rol de usuario o asistente a cada mensaje antiguo:
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})Así adaptamos nuestro código a la estructura que espera Streamlit.
5. Añade la lógica de mensajería
Esto es prácticamente igual que antes, pero adaptado a la nueva estructura.
# 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. Crea un usuario
La lógica está lista, pero necesitas crear un usuario para ejecutar la app. Yo decidí añadir esto por separado para simular el registro en un servicio. Por suerte, también escribí un 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)
Si tienes tu Chat API ID, puedes ejecutar:
python create_user.py –name TU_NOMBRE –id ALGUN_ID_DE_USUARIO –chat_api_id TU_CHAT_API_ID
Esto se encargará de crear el usuario y añadirlo a tu archivo de secretos.
Paso 5: Ejecuta la aplicación
Con tu lógica lista y tu usuario creado, es momento de probar esta aplicación. Instala las dependencias y ejecuta:
streamlit run app.py
Y así de fácil, verás nuestro bot en todo su esplendor.

Prueba un chatbot con Streamlit hoy mismo
Si estás creando prototipos con Streamlit, sabes que la personalización no debería sacrificar la facilidad de uso. Los chatbots están para resolver problemas, no para crearlos.
Botpress incluye un constructor visual de arrastrar y soltar, decenas de integraciones oficiales y puntos de acceso API accesibles. Así puedes crear, iterar y desplegar en múltiples canales de comunicación.
Empieza a construir hoy. Es gratis.
Preguntas frecuentes
¿Por qué elegiría Streamlit sobre otros frameworks de front-end para crear un chatbot?
Elegirías Streamlit para crear un chatbot si buscas una solución rápida basada en Python que te permita prototipar aplicaciones interactivas rápidamente sin necesidad de experiencia en front-end, ya que gestiona elementos de interfaz como componentes de chat y manejo de estados con poco código.
¿Un chatbot de Streamlit es adecuado para uso en producción o solo para prototipos?
Un chatbot con Streamlit es ideal para prototipos y herramientas internas, pero para aplicaciones de producción públicas con mucho tráfico o estilos avanzados, podrías necesitar capas adicionales como proxies inversos, refuerzo de seguridad y posiblemente un framework de front-end más robusto para manejar la escala.
¿Qué tan personalizable es el aspecto y la experiencia de un chatbot creado con Streamlit?
Aunque Streamlit permite ajustar estilos básicos como colores, fuentes y disposición, es menos flexible que los frameworks web tradicionales; para diseños realmente personalizados, tendrías que incorporar HTML/CSS o JavaScript personalizados, lo cual es posible pero añade complejidad en comparación con los widgets integrados de Streamlit.
¿Puedo integrar un chatbot de Streamlit en un sitio web existente, o debe ejecutarse de forma independiente?
Un chatbot de Streamlit normalmente funciona como una aplicación web independiente en su propia URL, pero puedes integrarlo en un sitio web existente mediante un iframe, aunque esto requiere gestionar el estilo y la seguridad para que la experiencia integrada sea fluida para los usuarios.
¿Cuánto cuesta desplegar un chatbot de Streamlit para uso público?
Desplegar un chatbot de Streamlit puede ser gratis si se aloja localmente o en Streamlit Community Cloud para aplicaciones pequeñas, pero para uso público a gran escala, los costos varían entre aproximadamente 5 y 50 dólares estadounidenses al mes en plataformas en la nube como Heroku, AWS o DigitalOcean, según el tráfico y los requisitos de disponibilidad.





.webp)
