Projet RAG à Muffin 🧁

Développement d'un Assistant Culinaire Spécialisé IA Générative Python

1. Contexte & Mission

L'objectif est de développer une application utilisant la technologie RAG (Retrieval-Augmented Generation) capable de recommander des recettes à partir d'une liste d'ingrédients fournie par l'utilisateur.

⚠️ La Contrainte Absolue : Le système doit être exclusivement dédié aux MUFFINS (sucrés ou salés).
Peu importe si l'utilisateur demande "une pizza" ou "des lasagnes", votre IA doit refuser poliment et ramener le sujet au muffin.

Spécificité "French Touch" 🇫🇷 : Le projet doit être réalisé entièrement en français (données, embeddings, génération).

2. Architecture technique indicative

3. Kit de démarrage indicatif (Python)

Voici un script de démarrage exemple pour les phases 1 et 2. Il simule des données et met en place la base vectorielle compatible avec le français.

import pandas as pd
import chromadb
from sentence_transformers import SentenceTransformer
import uuid

# --- CONFIGURATION FRANÇAISE 🇫🇷 ---
# Modèle multilingue indispensable pour bien comprendre le français
EMBEDDING_MODEL_NAME = "paraphrase-multilingual-MiniLM-L12-v2"
COLLECTION_NAME = "royaume_du_muffin"

def load_and_simulate_data():
    """ Simule un chargement de données (à remplacer par vos données) """
    data = [
        {"title": "Muffins tout chocolat", "ingredients": "farine, sucre, oeufs, chocolat noir, beurre", "type": "sucré"},
        {"title": "Lasagnes à la bolognaise", "ingredients": "pâtes, boeuf, tomate, fromage, oignon", "type": "plat"},
        {"title": "Muffins salés chèvre épinards", "ingredients": "farine, oeufs, chèvre, épinards, huile d'olive", "type": "salé"},
        {"title": "Salade César", "ingredients": "laitue, poulet, parmesan, croutons", "type": "entrée"},
        {"title": "Cupcakes vanille (façon muffin)", "ingredients": "farine, sucre, vanille, glaçage", "type": "sucré"}
    ]
    return pd.DataFrame(data)

def filter_only_muffins(df):
    """ FILTRE STRICT : On ne garde que les muffins ! """
    keywords = ["muffin", "cupcake", "moelleux"]
    # Filtre insensible à la casse
    mask = df['title'].str.contains('|'.join(keywords), case=False, na=False)
    return df[mask]

def create_embeddings_and_store(df):
    print("🤖 Chargement du modèle d'embedding multilingue...")
    model = SentenceTransformer(EMBEDDING_MODEL_NAME)

    # Concaténation Titre + Ingrédients pour la recherche
    documents = (df['title'] + " : " + df['ingredients']).tolist()
    metadatas = df.to_dict(orient='records')
    ids = [str(uuid.uuid4()) for _ in range(len(df))]

    print("⚡ Vectorisation en cours...")
    embeddings = model.encode(documents).tolist()

    # Stockage ChromaDB
    client = chromadb.Client() # En mémoire pour le test
    try: client.delete_collection(name=COLLECTION_NAME)
    except: pass

    collection = client.create_collection(name=COLLECTION_NAME)
    collection.add(documents=documents, embeddings=embeddings, metadatas=metadatas, ids=ids)

    print(f"✅ Indexation terminée ! {collection.count()} recettes stockées.")
    return collection

# --- TEST ---
if __name__ == "__main__":
    df = load_and_simulate_data()
    df_muffins = filter_only_muffins(df)
    db = create_embeddings_and_store(df_muffins)

    # Test de recherche en français
    query = "Je veux utiliser mes restes de fromage"
    model = SentenceTransformer(EMBEDDING_MODEL_NAME)
    results = db.query(query_embeddings=model.encode([query]).tolist(), n_results=1)
    print(f"\n🔎 Question: '{query}'")
    print(f"👉 Réponse RAG: {results['metadatas'][0][0]['title']}")

4. Le "System Prompt" (Phase Génération)

C'est ici que vous définissez la personnalité de l'IA. Voici un exemple de prompt que vous pourriez utiliser pour votre LLM (Mistral/OpenAI) :

TU ES "CHEF MUFFIN", UN ASSISTANT CULINAIRE OBSESSIONNEL MAIS SYMPATHIQUE.
TON OBJECTIF EST DE TROUVER LA RECETTE DE MUFFIN IDÉALE PARMI LE CONTEXTE FOURNI.

### TES DIRECTIVES (GUARDRAILS) :
1. OBSESSION : Tu ne cuisines QUE des muffins. Si on te demande des lasagnes ou une pizza, REFUSE poliment avec humour.
2. ANCRAGE : Utilise UNIQUEMENT les recettes fournies dans le bloc [CONTEXTE]. N'invente rien.
3. LANGUE : Réponds toujours en français courant et appétissant.

[CONTEXTE]
{context_str}
[QUESTION]
{query_str}

5. Critères d'Évaluation 🎓

Critère Poids Attendu
Qualité Data & Filtre 25% Le système est incapable de proposer autre chose qu'un muffin (Data cleaning robuste).
Pertinence RAG 30% La recherche sémantique fonctionne bien en français (bon choix d'embedding).
Code & Architecture 25% Code propre, modulaire, commenté. Usage de librairies standards.
Prompt Engineering 10% L'IA a une personnalité ("Persona") et refuse les hors-sujets (Lasagnes).
Démo (UI) 10% Interface fonctionnelle (Streamlit/Gradio).