Tous les guides
IntermédiaireÀ votre rythmeGuide gratuitSection 83/95

Développer le frontend (prototype fonctionnel)

Pratiquez les fondations du développement : programmation, web, API, données et usages de l’IA. Des sections et exercices pour construire vos premiers projets.

💡

Contenu gratuit, accessible sans compte. Les outils et modèles évoluent : consultez le dossier actuel pour vérifier leurs versions. Modèles et sources

Section 11.5.5 : Développer le frontend (prototype fonctionnel)

🎯 Objectif pédagogique

Construire le frontend complet de l'application avec Streamlit : interface de chat, sidebar de configuration, dashboard de métriques, et expérience utilisateur soignée. Vous serez capable de créer un prototype fonctionnel et professionnel.


Sprint 3 — L'interface qui fait la différence

Marc a son agent qui fonctionne en terminal. Maintenant il construit l'interface. Un bon frontend transforme un script Python en produit : première impression, UX, confiance utilisateur. C'est ce que les gens voient et jugent.

Interface complète — app.py

# app.py — Interface Streamlit professionnelle

import streamlit as st
from agent import CareerAgentRAG
from guardrails import Guardrails, PIIFilter
from config import SYSTEM_PROMPT, APP_CONFIG

# ═══ Configuration de la page ═══
st.set_page_config(
    page_title=APP_CONFIG["title"],
    page_icon="🤖",
    layout="centered",
    initial_sidebar_state="expanded"
)

# ═══ CSS custom ═══
st.markdown("""
<style>
    .stApp \{ background-color: #F5F3EF; \}
    .main-header \{ 
        text-align: center; 
        padding: 1rem 0;
        border-bottom: 2px solid #0891B2;
    \}
    .disclaimer \{
        background-color: #FEF3C7;
        border: 1px solid #F59E0B;
        border-radius: 8px;
        padding: 0.5rem 1rem;
        font-size: 0.85rem;
        margin-bottom: 1rem;
    \}
</style>
""", unsafe_allow_html=True)

# ═══ Header ═══
st.markdown('<div class="main-header">', unsafe_allow_html=True)
st.title("🤖 CareerBot Pro")
st.caption("Ton assistant IA pour la reconversion tech")
st.markdown('</div>', unsafe_allow_html=True)

# ═══ Disclaimer IA (éthique) ═══
st.markdown("""
<div class="disclaimer">
⚠️ <strong>Assistant IA</strong> — Les conseils fournis sont générés par intelligence artificielle 
et basés sur une base de connaissances. Ils ne remplacent pas l'avis d'un professionnel.
</div>
""", unsafe_allow_html=True)

# ═══ Sidebar ═══
with st.sidebar:
    st.header("⚙️ Configuration")
    
    model = st.selectbox("Modèle IA", ["gpt-4o-mini", "gpt-4o"], index=0)
    temperature = st.slider("Créativité", 0.0, 1.0, 0.7, 0.1)
    
    st.divider()
    st.header("👤 Ton profil")
    background = st.text_input("Expérience", "Finance, 8 ans")
    target = st.text_input("Poste visé", "Data Analyst")
    skills = st.text_input("Compétences", "Python, SQL, Excel")
    location = st.text_input("Localisation", "Paris")
    
    st.divider()
    
    # Boutons d'action rapide
    st.header("⚡ Actions rapides")
    col1, col2 = st.columns(2)
    
    quick_action = None
    with col1:
        if st.button("📝 Mon CV", use_container_width=True):
            quick_action = "Analyse mon profil et donne-moi des suggestions pour améliorer mon CV."
        if st.button("🎯 Entretien", use_container_width=True):
            quick_action = "Prépare-moi pour un entretien technique Data Analyst."
    with col2:
        if st.button("💰 Salaires", use_container_width=True):
            quick_action = "Quels salaires puis-je espérer en reconversion Data Analyst ?"
        if st.button("📚 Formation", use_container_width=True):
            quick_action = "Quelles formations recommandes-tu pour devenir Data Analyst ?"
    
    st.divider()
    
    # Stats de conversation
    st.header("📊 Statistiques")
    msg_count = len(st.session_state.get("messages", []))
    st.metric("Messages", msg_count)
    
    if st.button("🗑️ Nouvelle conversation", use_container_width=True):
        st.session_state.messages = []
        st.session_state.agent = None
        st.rerun()

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

if "agent" not in st.session_state or st.session_state.agent is None:
    user_profile = \{
        "background": background,
        "target": target,
        "skills": skills,
        "location": location
    \}
    st.session_state.agent = CareerAgentRAG(
        model=model,
        temperature=temperature,
        user_profile=user_profile
    )

# ═══ Message de bienvenue ═══
if not st.session_state.messages:
    welcome = f"""Bonjour ! 👋 Je suis **CareerBot Pro**, ton assistant de reconversion tech.

Je vois que tu as un background en **\{background\}** et tu vises **\{target\}**. Super choix !

Je peux t'aider avec :
- 📝 **Analyse de ton profil** et suggestions de CV
- 💼 **Analyse d'offres d'emploi** et compatibilité
- 📚 **Recommandations de formation**
- 🎯 **Préparation d'entretien**
- 📊 **Données marché** (salaires, tendances)

Comment puis-je t'aider aujourd'hui ?"""
    
    st.session_state.messages.append(\{"role": "assistant", "content": welcome\})

# ═══ Afficher l'historique ═══
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# ═══ Traitement des messages ═══
prompt = quick_action or st.chat_input("Pose ta question...")

if prompt:
    # Guardrails input
    is_valid, error_msg = Guardrails.check_input(prompt)
    
    if not is_valid:
        st.error(error_msg)
    else:
        # Filtrer les PII
        filtered_prompt = PIIFilter.filter_pii(prompt)
        
        # Afficher le message user
        st.session_state.messages.append(\{"role": "user", "content": prompt\})
        with st.chat_message("user"):
            st.markdown(prompt)
        
        # Générer la réponse
        with st.chat_message("assistant"):
            with st.spinner("Réflexion en cours..."):
                response = st.session_state.agent.chat(filtered_prompt)
                
                # Guardrails output
                response = Guardrails.check_output(response)
                
                st.markdown(response)
        
        st.session_state.messages.append(\{"role": "assistant", "content": response\})

Bonnes pratiques UX pour les chatbots

✅ À FAIRE :
- Message de bienvenue avec les capacités du bot
- Boutons d'action rapide (réduisent la friction)
- Streaming des réponses (retour visuel immédiat)
- Disclaimer IA visible
- Bouton "Nouvelle conversation" facile d'accès
- Feedback visuel pendant le chargement (spinner)

❌ À ÉVITER :
- Champ de saisie vide sans indication
- Pas de message d'erreur clair si le bot échoue
- Réponses trop longues (> 500 mots sans pagination)
- Pas de moyen de repartir à zéro
- Interface surchargée (trop de boutons, trop d'options)

Prototype ≠ Produit final

Ce frontend Streamlit est un prototype de qualité professionnelle — parfait pour montrer en entretien, présenter à un client, ou valider un concept. Pour un produit final à grande échelle, il faudrait migrer vers React/Next.js + FastAPI. Mais le prototype permet de valider l'idée AVANT d'investir dans la production.

🏋️ Exercice pratique (30 minutes)

  1. →Implémentez l'interface app.py complète ci-dessus
  2. →Personnalisez les couleurs, le titre, et le système prompt
  3. →Ajoutez 4 boutons d'action rapide pertinents pour votre cas d'usage
  4. →Testez l'interface dans le navigateur : 5 conversations de test
  5. →Prenez une capture d'écran pour votre portfolio
Vérification rapide

Pourquoi ajouter un message de bienvenue avec les capacités du chatbot ?

Vérification rapide

Quel est le rôle des 'boutons d'action rapide' dans l'interface ?

Apprendre l’IA, du premier prompt aux agents

15 guides gratuitsQuiz, schémas et ateliersSans compte

Votre progression

Cette progression est déclarative et conservée dans votre navigateur. L’attestation finale ne constitue pas un diplôme ni une évaluation indépendante.

Voir ma progression et mon attestation

Apprendre l’IA, du premier prompt aux agents

15 guides gratuitsQuiz, schémas et ateliersSans compte

Un cas pratique IA dans votre boîte mail

Méthodes, ressources et nouveaux exercices. Gratuit, avec désinscription à tout moment.