topics = [
("python", "Python", "langage interprété, typage dynamique et écosystème de bibliothèques", "pip, environnements virtuels et tests pytest"),
("docker", "Docker", "conteneurs isolés construits à partir d'images reproductibles", "Dockerfile, volumes et réseaux de conteneurs"),
("git", "Git", "contrôle de version distribué fondé sur des commits", "branches, fusion et résolution de conflits"),
("kubernetes", "Kubernetes", "orchestration de conteneurs déclarative", "pods, deployments, services et autoscaling"),
("rest", "API REST", "interface HTTP organisée autour de ressources", "verbes HTTP, codes de statut et JSON"),
("sql", "SQL", "langage déclaratif pour les bases relationnelles", "jointures, index, transactions et contraintes"),
("nosql", "NoSQL", "famille de bases non relationnelles adaptées à certains accès", "documents, clés-valeurs, cohérence et partitionnement"),
("ml", "apprentissage automatique", "modèles ajustés à partir de données", "entraînement, validation, test et généralisation"),
("overfit", "surapprentissage", "écart entre performance d'entraînement et de validation", "régularisation, early stopping et augmentation de données"),
("transformer", "transformer", "architecture neuronale fondée sur l'attention", "requêtes, clés, valeurs et connexions résiduelles"),
("embedding", "embedding", "vecteur dense représentant un objet par sa proximité sémantique", "similarité cosinus, index vectoriel et retrieval"),
("rag", "RAG", "génération augmentée par des documents récupérés", "chunking, recherche, citations et grounding"),
("qdrant", "Qdrant", "base vectorielle dédiée à la recherche de voisins", "collections, payloads, HNSW et filtres"),
("lora", "LoRA", "adaptation bas-rang de matrices de poids gelées", "rang, facteur alpha, fusion et faible coût mémoire"),
("quant", "quantification", "réduction de précision numérique des poids", "formats 8 bits ou 4 bits, mémoire et erreur d'approximation"),
("dpo", "DPO", "optimisation directe de préférences sans modèle de récompense séparé", "paires choisi-rejeté et politique de référence"),
("grpo", "GRPO", "optimisation de politique par groupes de complétions", "récompenses vérifiables, avantage relatif et raisonnement"),
("observability", "observabilité", "compréhension d'un système par ses signaux", "logs, métriques, traces et corrélation"),
("testing", "tests logiciels", "vérification automatisée de comportements attendus", "tests unitaires, intégration, propriétés et non-régression"),
("security", "sécurité des secrets", "protection des clés et jetons d'accès", "variables d'environnement, rotation et moindre privilège"),
]
documents = []
for key, title, definition, practice in topics:
variants = [
f"{title} — définition. {title} désigne {definition}.",
f"{title} — pratique. On le reconnaît notamment par {practice}.",
f"{title} — décision. Le choix dépend du besoin ; il faut mesurer les compromis liés à {definition} et à {practice}.",
]
for variant, text in enumerate(variants):
documents.append({"id": f"{key}-{variant}", "topic": key, "text": text})
question_by_topic = {
"python": "Quel langage utilise pip et pytest ?",
"docker": "À quoi servent un Dockerfile et les volumes ?",
"git": "Comment suivre des versions avec des branches et des commits ?",
"kubernetes": "Quel orchestrateur manipule des pods et des deployments ?",
"rest": "Pourquoi une API emploie-t-elle des verbes HTTP et des codes de statut ?",
"sql": "Quel langage permet jointures et transactions relationnelles ?",
"nosql": "Quand choisir une base documentaire ou clé-valeur ?",
"ml": "Comment séparer entraînement, validation et test ?",
"overfit": "Comment reconnaître et limiter le surapprentissage ?",
"transformer": "Quelle architecture repose sur requêtes, clés et valeurs ?",
"embedding": "Quel vecteur sert à mesurer une proximité sémantique ?",
"rag": "Comment ancrer une génération dans des documents récupérés ?",
"qdrant": "Quelle base vectorielle utilise collections et HNSW ?",
"lora": "Comment adapter un modèle avec des matrices de faible rang ?",
"quant": "Comment réduire la mémoire des poids avec quatre ou huit bits ?",
"dpo": "Quelle méthode apprend directement avec des paires choisi-rejeté ?",
"grpo": "Quelle méthode compare des groupes de complétions avec des récompenses ?",
"observability": "Quels signaux combinent logs, métriques et traces ?",
"testing": "Comment automatiser la non-régression d'un logiciel ?",
"security": "Comment stocker et faire tourner une clé d'API sans la committer ?",
}
queries = []
for topic, question in question_by_topic.items():
relevant = {doc["id"] for doc in documents if doc["topic"] == topic}
queries.append({"id": f"q-{topic}", "question": question, "relevant": relevant, "in_corpus": True})
for index, question in enumerate([
"Comment tailler un bonsaï au printemps ?",
"Quelle est la recette traditionnelle du kouign-amann ?",
"Comment entretenir un violoncelle ancien ?",
"Quels oiseaux migrent à travers la Camargue ?",
]):
queries.append({"id": f"q-out-{index}", "question": question, "relevant": set(), "in_corpus": False})
print(f"Corpus : {len(documents)} documents | thèmes : {len(topics)}")
print(f"Gold QA : {len(queries)} questions ({sum(q['in_corpus'] for q in queries)} in-corpus, {sum(not q['in_corpus'] for q in queries)} hors corpus)")
print("Exemple :", documents[0])