Contrats : découpage par structure et métadonnées
Construire un RAG sur des contrats qui découpe par articles et clauses, filtre par type, partie et date, répond aux questions comparatives par un tableau cité et produit un récapitulatif des contrats en sortie structurée.
Un contrat n'est pas un texte comme les autres : il est structuré (articles, clauses numérotées), il a une identité (référence, type, parties, date de signature) et les questions qu'on lui pose sont souvent comparatives (« quels préavis dans nos contrats de prestation ? »). Un RAG qui découpe tous les 500 caractères et ignore cette identité se trompe de contrat ou coupe une clause en deux.
Ce lab travaille sur 5 contrats fictifs d'Atelier Nova (location d'entrepôt, maintenance logicielle, nettoyage, licence, accord de confidentialité).
Ce que vous allez construire
flowchart LR
T["contrats/*.txt"] --> P["parse_contract : en-tête + articles + clauses"]
P --> M[("SQLite : contrats (type, parties, date)")]
P --> CS["chunk_structure : 1 morceau par article"]
CS --> E["embeddings + titre du contrat"]
E --> CH[("SQLite : chunks")]
Q["Question"] --> F["extraire_filtres (sortie structurée)"]
F --> S["search : WHERE type/partie/date puis cosinus"]
CH --> S
M --> S
S --> G["Gemini : réponse ou tableau cité [CT-... art. N]"]
M --> R["tableau : récapitulatif de tous les contrats"]
Pour qui ?
- Vous avez fait les labs 1 et 2, ou vous avez déjà écrit un RAG simple.
- Vous travaillez sur des documents structurés (contrats, politiques, normes, cahiers des charges).
Prérequis
- Python 3.10+, une clé d'API Gemini dans
.env(voir .env.example). pip install -r requirements.txt(requirements.txt) : google-genai, numpy, pydantic.
Programme
| Module | Leçon | Ce que vous faites | Fichiers |
|---|---|---|---|
| 1. Le cas d'usage | Contrats et architecture | structure d'un contrat, questions types, corpus fictif | make_contracts.py |
| 2. Construire | Découper par structure | parseur, articles et clauses, comparaison avec un découpage par taille | contrats_rag.py |
| 2. Construire | Filtres, comparaisons et tableau | self-query, filtres SQL, un résultat par contrat, métadonnées dans le contexte, récapitulatif | contrats_rag.py |
| 3. Évaluer | Évaluer et exploiter | tests sans clé, rappel taille vs structure, filtres corrects, fidélité, refus | eval.py, golden.json, test_contrats.py |
En local ou sur GCP ?
| Ce lab | Sur Google Cloud | |
|---|---|---|
| Contrats | fichiers texte | PDF dans Cloud Storage, extraits par Document AI |
| Métadonnées et filtres | colonnes SQLite + WHERE | métadonnées de Vertex AI Search ou filtres de Vector Search |
| Tableau récapitulatif | sortie structurée Gemini | idem, résultat écrit dans BigQuery |
Code complet : contrats_rag.py, eval.py, test_contrats.py, make_contracts.py.
Ressources
- example.env.example1 KB
- pycontrats_rag.py13 KBVoir
- pyeval.py3 KBVoir
- jsongolden.json2 KBVoir
- pymake_contracts.py8 KBVoir
- txtrequirements.txt1 KBVoir
- pytest_contrats.py4 KBVoir
Références
- Embeddings avec l'API Geminiai.google.dev
- Sortie structurée (JSON) avec l'API Geminiai.google.dev — response_schema avec un modèle pydantic : utilisé pour les filtres et le tableau
- sqlite3 : module de la bibliothèque standard Pythondocs.python.org
- Lost in the Middle: How Language Models Use Long Contexts (Liu et al., 2023)arxiv.org — Pourquoi envoyer des morceaux ciblés plutôt que des contrats entiers
- Ragas: Automated Evaluation of Retrieval Augmented Generationarxiv.org
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (Lewis et al., 2020)arxiv.org