building-streamlit-chat-ui

Par streamlit · agent-skills

Création d'interfaces de chat avec Streamlit. À utiliser pour concevoir des interfaces conversationnelles, des chatbots ou des assistants IA. Couvre `st.chat_message`, `st.chat_input`, l'historique des messages et les réponses en streaming.

npx skills add https://github.com/streamlit/agent-skills --skill building-streamlit-chat-ui

Interfaces de chat Streamlit

Créez des UIs conversationnelles avec les éléments de chat de Streamlit.

Structure de chat basique

import streamlit as st

if "messages" not in st.session_state:
    st.session_state.messages = []

# Afficher l'historique du chat
for msg in st.session_state.messages:
    with st.chat_message(msg["role"]):
        st.write(msg["content"])

# Gérer la nouvelle entrée
if prompt := st.chat_input("Ask a question"):
    st.session_state.messages.append({"role": "user", "content": prompt})

    with st.chat_message("user"):
        st.write(prompt)

    with st.chat_message("assistant"):
        response = get_response(prompt)  # Your LLM call
        st.write(response)

    st.session_state.messages.append({"role": "assistant", "content": response})

Réponses en streaming

Utilisez st.write_stream pour afficher token par token. Passez n'importe quel générateur qui produit des chaînes, y compris le générateur OpenAI directement :

def get_streaming_response(prompt):
    # Replace with your LLM client (OpenAI, Anthropic, Cortex, etc.)
    for chunk in your_llm_client.stream(prompt):
        yield chunk

with st.chat_message("assistant"):
    response = st.write_stream(get_streaming_response(prompt))

st.session_state.messages.append({"role": "assistant", "content": response})

Avec OpenAI, vous pouvez passer le stream directement :

from openai import OpenAI

client = OpenAI()
with st.chat_message("assistant"):
    stream = client.chat.completions.create(
        model="gpt-4o",
        messages=st.session_state.messages,
        stream=True,
    )
    response = st.write_stream(stream)

Avatars des messages de chat

Streamlit fournit des avatars par défaut pour les rôles « user » et « assistant »—personnalisez uniquement si vous avez un besoin spécifique. Vous pouvez utiliser des icônes ou des images :

# Avec des icônes
with st.chat_message("assistant", avatar=":material/robot:"):
    st.write(assistant_message)

# Avec des images
with st.chat_message("user", avatar="https://example.com/avatar.png"):
    st.write(user_message)

Suggestion chips

Proposez des suggestions cliquables avant le premier message. Les pastilles disparaissent une fois que l'utilisateur envoie un message, créant une expérience d'onboarding nette :

SUGGESTIONS = {
    ":blue[:material/help:] What is Streamlit?": "Explain what Streamlit is",
    ":green[:material/code:] Show me an example": "Show a simple Streamlit example",
}

# Afficher uniquement avant le premier message - elles disparaissent après
if not st.session_state.messages:
    selected = st.pills("Try asking:", list(SUGGESTIONS.keys()), label_visibility="collapsed")
    if selected:
        # Utiliser la sélection comme premier prompt
        prompt = SUGGESTIONS[selected]
        st.session_state.messages.append({"role": "user", "content": prompt})
        st.rerun()

La vérification if not st.session_state.messages garantit que les suggestions n'apparaissent que sur un chat vide. Une fois qu'un message est ajouté, les pastilles disparaissent et la conversation prend le relais.

Uploads de fichiers

Activez les pièces jointes avec accept_file. Lorsqu'elle est activée, st.chat_input retourne un objet de type dictionnaire avec les attributs text et files :

prompt = st.chat_input(
    "Ask about an image",
    accept_file=True,
    file_type=["jpg", "jpeg", "png"],
)

if prompt:
    with st.chat_message("user"):
        if prompt.text:
            st.write(prompt.text)
        if prompt.files:
            st.image(prompt.files[0])

    # Envoyer au modèle de vision
    with st.chat_message("assistant"):
        response = analyze_image(prompt.files[0], prompt.text)
        st.write(response)

Utilisez accept_file="multiple" pour permettre plusieurs fichiers.

Entrée audio

Activez l'enregistrement vocal avec accept_audio. L'audio enregistré est disponible en tant que fichier WAV :

prompt = st.chat_input("Say something", accept_audio=True)

if prompt:
    if prompt.audio:
        st.audio(prompt.audio)
    if prompt.text:
        st.write(prompt.text)

Dictée avec speech-to-text

Convertissez l'audio en texte et réinjectez-le dans l'entrée de chat :

prompt = st.chat_input("Say something", accept_audio=True, key="chat")

if prompt and prompt.audio:
    # Transcrire avec Whisper ou un autre modèle STT
    transcript = openai.audio.transcriptions.create(
        model="whisper-1",
        file=prompt.audio,
    )
    # Définir le texte transcrit comme prochaine entrée
    st.session_state.chat = transcript.text
    st.rerun()

Retour utilisateur

Ajoutez des commentaires pouces vers le haut/bas aux messages de l'assistant. Supporte également les notations "stars" et "faces" :

with st.chat_message("assistant"):
    st.markdown(response)
    feedback = st.feedback("thumbs")
    if feedback is not None:
        st.toast(f"Feedback received: {'👍' if feedback == 1 else '👎'}")

Effacer le chat

Ajoutez un bouton pour réinitialiser la conversation :

def clear_chat():
    st.session_state.messages = []

st.button("Clear chat", on_click=clear_chat)

Compétences connexes

  • connecting-streamlit-to-snowflake: Requêtes de base de données et exemple de chat Cortex
  • optimizing-streamlit-performance: Stratégies de mise en cache pour les appels LLM

Références

Skills similaires