Niveau Intermédiaire — GenAI et RAG sur Azure
4 modules : modèles et déploiements Azure OpenAI, prompt engineering et paramètres, embeddings et recherche vectorielle, RAG avec AI Search.
Module 5 : Azure OpenAI — modèles, déploiements et quotas
5.1 Catalogue des modèles et cas d’usage
- GPT-4o / GPT-4o mini — modèles polyvalents texte + vision + audio, fenêtre de contexte large (128K) ; mini = coût réduit pour les tâches simples.
- Série o (o1, o3, o-mini) — modèles de raisonnement pas à pas pour mathématiques, code et logique complexe ; latence plus élevée.
- Embeddings (text-embedding-3-large/small, ada-002) — vectorisation pour la recherche sémantique ; 3072 dimensions pour 3-large, 1536 pour ada-002.
- DALL-E 3 — génération d’images depuis des descriptions ; Whisper — transcription et traduction audio ; TTS — synthèse vocale.
# Créer une ressource Azure OpenAI puis un déploiement (Azure CLI)
az cognitiveservices account create \
--name openai-horizon5 \
--resource-group rg-ai102 \
--kind OpenAI \
--sku S0 \
--location swedencentral
az cognitiveservices account deployment create \
--name openai-horizon5 \
--resource-group rg-ai102 \
--deployment-name gpt4o-prod \
--model-name gpt-4o \
--model-version "2024-11-20" \
--model-format OpenAI \
--sku-capacity 50 \
--sku-name "Standard"
Pourquoi c'est important : votre chatbot de support passe en production et reçoit une erreur 429 en pleine pointe. Personne n'avait regardé les quotas TPM et RPM, et le modèle GPT-4o premium tourne même pour des tâches triviales que GPT-4o mini traiterait pour une fraction du prix. L'examen AI-102 teste ce discernement d'architecte : choisir le bon modèle pour le bon besoin et le bon type de déploiement avant que la facture ou la latence ne vous réveille.
L'analogie qui aide : pensez à une flotte de véhicules. GPT-4o mini, c'est la citadine économe pour les trajets quotidiens. GPT-4o, c'est la berline confortable pour les longs courriers avec vision et audio. La série o, c'est le camion de chantier : puissante pour raisonner pas à pas, mais lente et coûteuse. Le déploiement Standard, c'est le taxi au compteur ; Provisioned (PTU), c'est le véhicule avec chauffeur réservé au mois ; Batch, c'est le fret de nuit à tarif réduit.
5.2 Types de déploiement : Standard, Provisioned, Batch, Global
- Standard (pay-as-you-go) — facturation au token, quotas TPM/RPM partagés, idéal pour démarrer.
- Provisioned (PTU) — débit réservé en unités PTU, latence stable, facturation horaire : production à charge prévisible.
- Batch — files de traitement asynchrone volumineuses à tarif réduit, latence non garantie.
- Global / DataZone — routage multi-régions pour absorber les pics ; contrainte de résidence des données à vérifier pour les charges sensibles.
Quotas à l’examen : TPM et RPM
Chaque déploiement est borné en tokens par minute (TPM) et requêtes par minute (RPM). Une erreur 429 signifie quota dépassé : réduire la charge, demander une augmentation de quota ou passer en Provisioned.
Démonstration pas à pas : déroulez une mise en production : 1. Vous créez la ressource --kind OpenAI --sku S0 en Suède centrale. 2. Vous créez le déploiement gpt4o-prod avec le modèle gpt-4o version 2024-11-20 et 50 unités de capacité. 3. Vos appels utilisent le nom de déploiement dans l'URL, pas le nom du modèle. 4. Sous charge, une 429 apparaît : vérifiez TPM et RPM dans les métriques, puis arbitrez entre réduire la charge, demander plus de quota ou basculer en Provisioned pour un débit garanti.
Pièges classiques : confondre le nom du modèle et le nom du déploiement dans l'URL d'appel ; mettre GPT-4o partout au lieu de router vers mini ou embeddings pour économiser ; ignorer TPM et RPM jusqu'à la 429 le jour du lancement ; choisir Global pour absorber les pics sans vérifier la contrainte de résidence des données ; croire que Batch garantit une faible latence alors qu'il s'agit d'asynchrone à tarif réduit.
À vous de jouer : votre application renvoie des erreurs 429 chaque midi sur le déploiement Standard. Vous avez une charge prévisible et une exigence de latence stable. Que décidez-vous ?
Voir la réponse
Passez en Provisioned (PTU) : débit réservé, latence stable et facturation horaire adaptée à une charge prévisible. En parallèle, routez les tâches simples vers GPT-4o mini et demandez une augmentation de quota si le pic persiste. Le Standard reste pertinent pour démarrer, pas pour absorber une pointe quotidienne garantie.
- Associer chaque besoin au bon modèle : raisonnement → série o, image → DALL-E, audio → Whisper, recherche → embeddings.
- Choisir le déploiement : Standard pour démarrer, Provisioned (PTU) pour débit garanti, Batch pour volumes asynchrones.
- Connaître
az cognitiveservices account deployment create et la notion de nom de déploiement (utilisé dans l’URL d’appel).
- Diagnostiquer une 429 : TPM/RPM dépassés, puis citer les trois remèdes (réduire, augmenter le quota, PTU).
Module 6 : Prompt engineering et paramètres d’inférence
6.1 Anatomie d’un prompt : système, utilisateur, assistant, outil
Un appel de conversation empile des messages typés. Le message system fixe durablement le rôle, le ton, les règles et le format ; les messages user portent la demande ; les messages assistant conservent l’historique ; les messages tool renvoient les résultats d’outils (recherche, fonctions). Techniques clés : instructions explicites, few-shot (exemples), chaîne de pensée (raisonnement intermédiaire, surtout série o), structuration (délimiteurs, sections) et contraintes de sortie (JSON, longueur, langue).
Exemple de prompt système pour un assistant SOC (extrait) :
Tu es un analyste SOC senior. Règles strictes :
1. Ne réponds qu'à partir des alertes fournies, sans inventer de fait.
2. Classe chaque alerte : Vrai positif, Faux positif, À investiguer.
3. Format : JSON avec les champs alerte_id, verdict, justification, action_recommandee.
4. Si une donnée manque, écris "donnée manquante" au lieu de supposer.
Exemple d'appel REST (chat completions) :
POST https://openai-horizon5.openai.azure.com/openai/deployments/gpt4o-prod/chat/completions?api-version=2024-10-21
{
"messages": [
{"role": "system", "content": "Tu es un analyste SOC senior..."},
{"role": "user", "content": "Classe ces 3 alertes : ..."}
],
"temperature": 0.2,
"max_tokens": 800
}
Pourquoi c'est important : le même modèle répond brillamment ou catastrophiquement selon le prompt système. Un assistant SOC sans règles strictes invente des verdicts, oublie le format JSON et casse le pipeline en aval. Avec un prompt qui impose rôle, règles, format et gestion des données manquantes, le taux d'hallucination chute sans changer de modèle. Le prompt engineering n'est pas du cosmétique : c'est le levier le moins cher pour fiabiliser une solution.
L'analogie qui aide : le message système, c'est le brief que vous donnez à un nouvel analyste le premier jour : son rôle, ses interdits, le modèle de rapport à remplir. Les messages utilisateur, ce sont les dossiers qu'on lui pose chaque matin. Sans brief, même brillant, il improvise. Avec un brief précis, délimiteurs, exemples few-shot et contrainte JSON, il devient prévisible et auditable.
6.2 Paramètres : temperature, top_p, max_tokens, penalties, seed
- temperature (0 à 2) — 0 = déterministe et factuel (extraction, classification) ; 0.7-1 = créatif (rédaction, idées).
- top_p (0 à 1) — échantillonnage nucleus : ne piocher que dans le top cumulé ; réglez temperature OU top_p, pas les deux.
- max_tokens — borne la réponse ; la fenêtre totale inclut le prompt (dépassement = troncature ou erreur).
- frequency_penalty / presence_penalty — pénalisent répétitions et redites pour diversifier le texte.
- seed + response_format JSON — reproductibilité et sorties structurées pour les pipelines.
À retenir — Recette examen
Extraction et classification : temperature 0 + JSON + seed. Rédaction créative : temperature 0.7-1. Ne modifiez jamais temperature et top_p simultanément.
Démonstration pas à pas : reprenez l'assistant SOC : 1. Le système impose « ne réponds qu'à partir des alertes fournies » et « donnée manquante au lieu de supposer ». 2. L'utilisateur envoie trois alertes à classer en Vrai positif, Faux positif ou À investiguer. 3. Vous fixez temperature: 0.2 pour rester factuel et max_tokens: 800 pour laisser la place au JSON. 4. Vous ajoutez response_format: JSON et un seed pour des sorties reproductibles. Si le prompt dépasse la fenêtre, vous tronquez l'historique, pas les règles système.
Pièges classiques : régler temperature et top_p en même temps au lieu d'en choisir un seul ; mettre temperature à 1 pour une extraction et s'étonner des variations ; oublier le rôle tool après un appel de fonction, donc perdre le résultat d'outil ; demander du JSON sans response_format ni seed, puis parser des réponses instables ; laisser max_tokens trop élevé avec un prompt déjà long et dépasser la fenêtre de contexte.
À vous de jouer : vous devez extraire des montants de factures en JSON stable, exécuté chaque nuit. Quels paramètres choisissez-vous ?
Voir la réponse
Temperature à 0, response_format JSON et seed fixé pour la reproductibilité. Top_p laissé par défaut, car on ne touche jamais aux deux en même temps. Max_tokens dimensionné pour le JSON attendu, en gardant de la marge dans la fenêtre pour le prompt.
- Écrire un prompt système complet : rôle, règles, format JSON, gestion des données manquantes.
- Attribuer chaque rôle (system, user, assistant, tool) dans un échange multi-tours avec appel de fonction.
- Choisir temperature 0 pour le factuel, élevée pour le créatif, et justifier le mode JSON + seed.
- Calculer la place du prompt dans la fenêtre de contexte : prompt long + max_tokens élevé = risque de dépassement.
Module 7 : Embeddings et recherche vectorielle
7.1 Ce que sont les embeddings et comment les produire
Un embedding est la représentation numérique dense d’un texte (vecteur de 1536 à 3072 flottants). Deux textes de sens proche ont des vecteurs proches, mesurés par similarité cosinus. On génère les embeddings une fois à l’ingestion (documents découpés) puis à chaque requête (question vectorisée), et on compare. Règle d’or : le modèle d’embedding de la requête doit être identique (même version, mêmes dimensions) à celui de l’index, sinon la comparaison n’a aucun sens.
# SDK Python : générer un embedding (extrait)
from openai import AzureOpenAI
client = AzureOpenAI(api_key="VOTRE_CLE",
api_version="2024-10-21",
azure_endpoint="https://openai-horizon5.openai.azure.com")
resp = client.embeddings.create(model="text-embedding-3-large",
input="Procédure de confinement d'un poste compromis")
print(len(resp.data[0].embedding)) # 3072 dimensions
print(resp.data[0].embedding[:5]) # début du vecteur
Pourquoi c'est important : une recherche par mots-clés ne trouve jamais « confinement d'un poste » quand l'utilisateur tape « isoler un PC compromis ». Les deux formulations ont le même sens mais aucun mot en commun. Les embeddings comblent ce fossé : ils comparent le sens, pas les lettres. Sans eux, votre RAG rate les meilleurs passages et le LLM répond à côté, même avec un excellent prompt.
L'analogie qui aide : imaginez une bibliothèque où chaque livre est rangé non par titre mais par idée, sous forme de point sur une immense carte. Deux livres proches sur la carte parlent de la même chose, même avec des titres différents. La similarité cosinus, c'est la règle qui mesure l'angle entre deux points : plus l'angle est petit, plus le sens est proche. Mais si vous changez de carte en cours de route (un autre modèle d'embedding), toutes les positions deviennent fausses.
7.2 Index vectoriels dans Azure AI Search
- Champ vectoriel — type
Collection(Edm.Single) avec dimensions déclarées (1536 ou 3072) et profil vectoriel (HNSW).
- HNSW (Hierarchical Navigable Small World) — algorithme de recherche approximative : compromis vitesse/précision réglé par
m, efConstruction, efSearch.
- Requêtes vectorielles — k plus proches voisins (kNN) avec
k et fields ; combinables au plein texte en recherche hybride.
Démonstration pas à pas : indexez la phrase « Procédure de confinement d'un poste compromis » : 1. Vous appelez text-embedding-3-large et obtenez un vecteur de 3072 nombres. 2. À l'ingestion, chaque chunk est vectorisé avec le même modèle et stocké dans un champ Collection(Edm.Single) avec son profil HNSW. 3. À la requête, la question est vectorisée avec le même modèle, puis la recherche kNN remonte les k plus proches voisins. 4. En hybride, ce score vectoriel fusionne avec le score BM25 plein texte avant le réordonnancement sémantique.
Pièges classiques : vectoriser l'index avec ada-002 (1536 dimensions) et les requêtes avec 3-large (3072), rendant toute comparaison absurde ; oublier de déclarer les dimensions et le profil HNSW dans le schéma ; croire que HNSW est exact alors qu'il s'agit d'approximatif réglé par m, efConstruction et efSearch ; se limiter au plein texte ou au seul vectoriel au lieu de viser l'hybride pour l'examen.
À vous de jouer : votre recherche vectorielle ne renvoie rien de pertinent depuis que vous avez changé de modèle d'embedding pour les requêtes. Que s'est-il passé ?
Voir la réponse
Vous avez rompu la règle d'or : requête et index doivent partager exactement le même modèle, la même version et les mêmes dimensions. Réindexez avec le nouveau modèle ou revenez à l'ancien pour les requêtes. Vérifiez aussi les dimensions déclarées : 1536 pour ada-002, 3072 pour text-embedding-3-large.
- Expliquer la similarité cosinus et pourquoi requêtes et documents doivent partager le même modèle d’embedding.
- Décrire un champ vectoriel : dimensions, profil HNSW, paramètres m/efConstruction/efSearch.
- Opposer recherche plein texte (BM25, mots-clés) et vectorielle (sens, kNN) avant d’annoncer l’hybride.
- Citer les dimensions : ada-002 = 1536, text-embedding-3-large = 3072 (réductibles via l’option de dimensions).
Module 8 : RAG avec Azure AI Search (chunking, index, retrieval)
8.1 Le pipeline RAG de bout en bout
Pourquoi c'est important : votre direction veut un chatbot qui répond sur vos 2 000 pages de documentation interne. Première idée : poser la question directement au LLM. Problème : le modèle ne connaît pas vos documents — il va inventer une réponse plausible mais fausse (c'est l'hallucination), avec vos logos dessus. Le RAG résout exactement ça : au lieu de croire le modèle sur parole, on lui fournit les bons passages de VOS documents au moment de la question, et on exige qu'il cite ses sources. Résultat : des réponses vérifiables, à jour sans réentraînement, et un chatbot qu'on ose mettre en production.
L'analogie qui aide : pensez à un étudiant en examen. Sans RAG, c'est un étudiant qui répond de mémoire les yeux fermés : brillant sur la culture générale, catastrophique sur vos procédures internes — il bluffe. Avec RAG, c'est le même étudiant mais avec le droit d'ouvrir le manuel : il cherche d'abord les bons paragraphes (récupération), les pose ouverts devant lui (augmentation), puis rédige en citant les pages (génération). Votre travail d'ingénieur, c'est de lui construire la meilleure « bibliothèque ouverte » possible : bien découpée, bien indexée.
Le RAG (Retrieval-Augmented Generation) ancre le LLM dans vos données sans réentraînement : ingestion (découpage/chunking, embeddings, indexation), récupération (requête hybride + semantic ranker, top-k passages), augmentation (passages injectés dans le prompt avec citations exigées), génération (réponse grounded). Chaque chunk stocke ses métadonnées (source, page, section) pour tracer les citations.
# Créer un service AI Search puis alimenter un index (Azure CLI)
az search service create \
--name search-horizon5 \
--resource-group rg-ai102 \
--sku Standard \
--location westeurope
# Stratégie de chunking recommandée (extrait de configuration)
# - Taille : 512 à 1024 tokens par chunk
# - Chevauchement (overlap) : 10 à 20 %
# - Découpe : par paragraphes/sections, jamais au milieu d'une phrase
# - Métadonnées : source, page, titre de section, date
Démonstration pas à pas : suivez une question réelle — « Quelle est la durée de conservation des logs pare-feu ? » :
1. Récupération : la question est convertie en vecteur ; la recherche hybride interroge l'index et remonte 3 chunks : un extrait de la politique de journalisation (page 12), un tableau des durées (page 13), un paragraphe sans rapport sur les sauvegardes.
2. Augmentation : le prompt final devient « En te basant UNIQUEMENT sur ces passages [collés ici], réponds et cite tes sources ».
3. Génération : le modèle répond « 90 jours (Politique de journalisation, p.12) » au lieu d'inventer « 1 an ».
Retenez la mécanique : la qualité de la réponse ne dépasse jamais la qualité de la récupération. Un RAG qui hallucine, c'est presque toujours un problème d'indexation, pas de modèle.
Pièges classiques : des chunks trop gros (le bon passage est noyé) ou trop petits (contexte perdu) — visez 512 à 1024 tokens avec chevauchement ; découper au milieu des phrases ou des tableaux ; oublier les métadonnées (impossible de citer ou filtrer par source) ; ne jamais évaluer (sans jeu de questions/réponses de référence, vous ne verrez pas la dégradation) ; exposer le chatbot sans Content Safety (injection de prompt via les documents).
À vous de jouer : votre RAG répond correctement mais ne cite jamais ses sources, et parfois il mélange deux documents. Quel est le premier réglage à vérifier ?
Voir la réponse
Le prompt d'augmentation : il doit exiger explicitement les citations (« cite la source et la page de chaque affirmation ») et interdire de répondre hors passages (« si l'information n'est pas dans les passages, dis-le »). Le mélange de documents, lui, se traite côté récupération : resserrer le top-k et vérifier que les métadonnées de source sont bien filtrées. Si vous avez pensé « prompt » avant « modèle », vous avez le bon réflexe d'ingénieur RAG.
8.2 Index, indexeurs et récupération
- Schéma d’index — champs texte (filtrables, triables, facettables), champs vectoriels, analyseurs linguistiques (fr.microsoft pour le français).
- Indexeurs + skillsets — ingestion automatique depuis Blob/Data Lake : découpage, OCR (Vision), enrichissement IA (entités, PII, embeddings) puis projection en index.
- Requête hybride + semantic ranker — fusion BM25 + vectoriel (reciprocal rank fusion), réordonnancement sémantique L2, réponses avec
@search.captions et extraits sémantiques.
- Option « On Your Data » — configuration no-code dans AI Studio reliant déploiement OpenAI + index Search avec grounding automatique.
À retenir — Anti-hallucination
Le prompt RAG doit exiger : répondre uniquement depuis les passages, citer chaque affirmation (source + page), et avouer « information introuvable » sinon. Sans ces trois règles, le grounding n’est pas garanti.
- Dessiner le pipeline : chunking → embeddings → index → requête hybride → ranker → prompt augmenté → réponse citée.
- Choisir chunk 512-1024 tokens avec overlap et justifier les métadonnées de citation.
- Décrire indexeurs, skillsets et projections pour une ingestion Blob avec OCR + embeddings.
- Expliquer la recherche hybride (BM25 + vectoriel + semantic ranker) et l’option On Your Data.
Prochaine étape
Entraînez-vous dans le Terminal Azure IA (commandes embed, chunk, create-index, search, prompt), puis attaquez le niveau Expert : safety, agents, évaluation et production.