Chapitre 3 : Auto-interrogation et filtrage par métadonnées
Qu'est-ce que l'auto-interrogation ?
Le LLM extrait à la fois la requête sémantique et les filtres structurés à partir de l'entrée utilisateur :
Utilisateur : "Trouver les politiques RH de 2023"
Extrait :
- Requête sémantique : "politiques RH"
- Filtres : {department: "RH", year: 2023}
Mise en œuvre avec LangChain
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo
# Définir les attributs de métadonnées
metadata_field_info = [
AttributeInfo(
name="department",
description="Le département (RH, Ingénierie, Ventes)",
type="string"
),
AttributeInfo(
name="year",
description="Année de publication",
type="integer"
),
AttributeInfo(
name="document_type",
description="Type de document (politique, guide, mémo)",
type="string"
)
]
# Créer un récupérateur d'auto-interrogation
retriever = SelfQueryRetriever.from_llm(
llm=llm,
vectorstore=vectorstore,
document_contents="Documents internes de l'entreprise",
metadata_field_info=metadata_field_info
)
# Requête avec filtres en langage naturel
results = retriever.get_relevant_documents(
"Montrez-moi les directives d'ingénierie de 2024"
)
# Filtre automatiquement : department=Ingénierie, year=2024
Comparaisons prises en charge
| Opérateur | Exemple |
|---|---|
$eq | year == 2023 |
$ne | status != "brouillon" |
$gt | year > 2020 |
$gte | year >= 2020 |
$lt | year < 2024 |
$in | department in ["RH", "Juridique"] |
Meilleures pratiques
- Schéma de métadonnées clair - Attributs bien définis
- Bonnes descriptions - Aident le LLM à comprendre les champs
- Logique de secours - Gérer les échecs d'extraction
- Tester minutieusement - Divers modèles de requêtes
Combinaison des approches
# Multi-requête + Auto-interrogation
def advanced_retrieve(query, retriever):
# Générer des variations
queries = generate_variations(query)
# Auto-interroger chaque variation
all_results = []
for q in queries:
results = self_query_retriever.get_relevant_documents(q)
all_results.extend(results)
# Dédupliquer et classer
return rank_and_dedupe(all_results)