Notes pratiques : J’ai appris RAG en développant un système de questions-réponses
Guide pratique pas à pas : J’ai appris RAG en développant un système de questions-réponses : contrats, vérifications et emplacements prévus pour du code à intégrer destinés aux équipes utilisant ce modèle.
Utilisez ceci comme une version révisée destinée aux opérateurs des idées présentées dans « J’ai appris RAG en créant un système de Q&A » : étapes claires, emplacements de code organisés et notes de récupération qui survivent au transfert de responsabilités. L’étape « Aperçu » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement exemplaire, un cas d’échec et la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût en tokens ou requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe de la démonstration aux environnements partagés.
Une brève note sur RAG
Pour une note rapide sur le terrain : définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu, sans avoir à deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
Comment le système est structuré
Pour définir comment le système fonctionne à chaque étape, il convient de préciser les entrées, le responsable de chaque étape ainsi que les critères d’achèvement avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu, sans avoir à deviner l’état caché. Documentez conjointement le parcours normal et les scénarios de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non traités font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Citez les passages qui justifient réellement la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
Construire le pipeline d’ingestion
Pour la phase de construction du pipeline d’ingestion, définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner un état caché. Préférez des unités petites et testables à des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un pipeline embrouillé. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
Téléchargement
Pendant l’étape de téléchargement, définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des vérifications de succès et refusez les terminaisons partielles silencieuses. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
{
"doc_id": "bsp-mpr-2023-q3",
"title": "Monetary Policy Report Q3 2023",
"period_label": "Q3 2023",
"publication_date": "2023-08-17",
"url": "https://www.bsp.gov.ph/..."
}
Analyse
Pour l’étape de parsing, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce du coût permet d’éviter des factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque dans l’indexation.
Chunking, embedding et upserting
Pour l’étape d’incorporation par chunking et de mise à jour, définissez les entrées, le responsable de l’étape ainsi que les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
def chunk_text_by_tokens(text, enc, chunk_size=512, overlap=64):
tokens = enc.encode(text)
stride = chunk_size - overlap
chunks = []
start = 0
while start < len(tokens):
window = tokens[start : start + chunk_size]
chunks.append(enc.decode(window))
if start + chunk_size >= len(tokens):
break
start += stride
return chunks
La couche de récupération et le problème de la récentéité
Pour la couche et l’étape de récupération, définissez les entrées, le responsable de l’étape ainsi que les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non traités font partie intégrante du produit, et non d’une mise en forme ultérieure. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
RECENCY_WEIGHT = 0.85
def combined_score(hit):
relevance = hit.score / max_score
recency = (pub_date - min_date).days / date_span_days # 0.0 to 1.0
return (1 - RECENCY_WEIGHT) * relevance + RECENCY_WEIGHT * recency
# scope to Q1 2023 only
retrieve_chunks(query, period_label_key="q1_2023")
# scope to a date range
retrieve_chunks(query, publication_date_from="2023-01-01", publication_date_to="2023-12-31")
La couche de génération
Pour l’étape de la couche de génération, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Citez les passages qui fondent réellement la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation. Pour l’étape de la couche de génération, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût en tokens ou requêtes à côté des résultats fonctionnels. Une visibilité précoce du coût évite les factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés.
Problèmes auxquels vous êtes réellement confrontés
Lorsque vous travaillez sur les problèmes auxquels vous êtes réellement confrontés, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les administrateurs peuvent auditer sans devoir lire l’ensemble du système. Mesurez le taux de rappel sur un ensemble fixe de questions avant d’ajuster les prompts. Un changement fréquent des prompts ne résout que rarement un système de récupération insuffisant.
Les modèles PDF génériques qui polluent les données
Lorsque vous travaillez sur l’étape de traitement des blocs polluants du PDF, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Mesurez le taux de rappel sur un ensemble fixe de questions avant d’ajuster les prompts. Un changement fréquent des prompts ne résout que rarement un système de récupération insuffisant.
def _clean_parsed_text(text):
text = text.replace("\x0c", "\n\n")
text = re.sub(r"Classification:\s*GENERAL\s*\n", "", text)
text = re.sub(r"Monetary Policy Report\s*[--][^\n]+\|\s*\d+\s*\n", "", text)
text = re.sub(r"\n{3,}", "\n\n", text)
return text.strip()
Suppression accidentelle des données collectées
Lors du traitement de l’étape d’effacement de la collection Accidental, notez d’abord les spécifications : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité et non un processus embrouillé. Mesurez le taux de rappel sur un ensemble de questions fixe avant d’ajuster les prompts. Un changement fréquent des prompts ne résout généralement pas un système de récupération insuffisant. Lors du traitement de l’étape d’effacement de la collection Accidental, notez d’abord les spécifications : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les surprises financières lorsque le système passe de l’environnement de démonstration à des environnements partagés.
def _should_recreate_qdrant_collection():
if _is_production_environment():
return False
explicit = os.environ.get("QDRANT_RECREATE_COLLECTION", "").lower()
if explicit in ("1", "true", "yes"):
return True
app_env = (os.environ.get("ENVIRONMENT") or "").lower()
return app_env in ("development", "dev", "local")
Blocs dupliqués après ré-ingestion
L’étape des blocs dupliqués après ré-ingestion fonctionne le mieux lorsqu’elle est considérée comme une mesure quantitative. Capturez un transcript idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Séparez la politique de segmentation des blocs de la politique de récupération. Modifier l’une ne doit pas obliger à réécrire l’autre lorsque les métriques de qualité évoluent.
client.delete(
collection_name=collection,
points_selector=models.Filter(must=[
models.FieldCondition(
key="source_file",
match=models.MatchValue(value=source_file)
)
]),
)
Latence au démarrage sur le plan gratuit
La latence de démarrage en mode froid fonctionne le mieux lorsqu’elle est considérée comme une valeur mesurable. Capturez un exemple réussi, un cas d’échec ainsi que la note de réversion avant d’élargir le périmètre. Documentez en même temps le parcours normal et celui de récupération. Les tentatives répétées, les contrôles humains et le traitement des messages non livrés font partie intégrante du produit, et non d’une étape de finition ultérieure. Séparez la politique de segmentation de la politique de récupération : modifier l’une ne doit pas obliger à réécrire l’autre lorsque les métriques de qualité évoluent.
Choix de la taille du chunk
La phase de sélection de la taille des blocs fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’erreur doit pointer vers une seule responsabilité et non vers un processus embrouillé. Séparez la politique de segmentation de la politique de récupération. Modifier l’une ne doit pas obliger à réécrire l’autre lorsque les métriques de qualité évoluent. La phase de sélection de la taille des blocs fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.
Que vous feriez différemment
Pour l’étape « What you’d do », définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Citez les passages qui servent réellement de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
Essayez-le
Pour l’étape « Essayez-le », définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez ensemble le parcours idéal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non traités font partie du produit, et non d’améliorations ultérieures. Citez les passages qui ont réellement servi de base à la réponse. Sans citations, les opérateurs ne peuvent pas distinguer une hallucination d’un manque d’indexation.
Liste de contrôle opérationnelle
Lorsque vous travaillez sur l’étape de la liste de contrôle opérationnelle, écrivez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste garantit que les modifications ultérieures du code restent transparentes.
Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des vérifications de succès et refusez les terminations partielles silencieuses.
Évaluez le taux de rappel sur un ensemble de questions fixe avant d’ajuster les prompts. Le changement fréquent des prompts ne résout que rarement un système de récupération inefficace.
Fixez les versions dépendantes et enregistrez le résumé de l’image utilisée pour la démonstration. La reproductibilité vaut mieux que les connaissances empiriques.
Enregistrez les temps d’exécution ainsi que le coût en tokens ou requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque l’on passe de la démonstration à des environnements partagés.
Évaluez le taux de rappel sur un ensemble de questions fixe avant d’ajuster les prompts. Le changement fréquent des prompts ne résout que rarement un système de récupération inefficace.
Au préalable de promouvoir l’ensemble, figez les versions, conservez une transcription exemplaire pour le parcours critique et confirmez les étapes de réversion. Les environnements partagés nécessitent des limites de fréquence, des vérifications d’attribution et un responsable clair pour la rotation des secrets. Préférez une fiabilité banale à des démonstrations brillantes mais ponctuelles.
Note de lot pour a30a0175d827 : ne pas inclure les clés du fournisseur dans le répertoire, fixer une limite pour les tokens par session, et stocker les transcriptions à côté des fichiers d’évaluation afin que les remplacements ultérieurs de modèles restent comparables.