LangChain : chargement et découpage de documents
Dans les articles précédents, nous saisissions manuellement le texte, mais dans des projets réels, les documents peuvent provenir de PDF, de pages web, de fichiers Markdown, etc.
Cette section présente comment utiliser Document Loader pour charger différents types de documents, et comment utiliser Text Splitter pour découper les documents en petits morceaux adaptés à la récupération.
Document Loader — Chargement de documents
LangChain fournit des dizaines de chargeurs de documents, couvrant les formats de fichiers courants :
| Loader | Source | Paquet d'installation |
|---|---|---|
| TextLoader | fichiers .txt | langchain (intégré) |
| PyPDFLoader | fichiers PDF | langchain-community + pypdf |
| WebBaseLoader | URL de la page Web | langchain-community + beautifulsoup4 |
| CSVLoader | Fichiers CSV | langchain-community |
| UnstructuredMarkdownLoader | Fichiers Markdown | langchain-community + unstructured |
Exemple
from langchain_community.document_loaders import TextLoader
loader = TextLoader("knowledge.txt", encoding="utf-8")
docs = loader.load()
print(f"{len(docs)} documents chargés")
print(f"Aperçu du contenu : {docs)
# Charger une page web
# pip install langchain-community beautifulsoup4
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://www.example.com/python/python-tutorial.html")
docs = loader.load()
print(f"\nContenu de la page web : {docs)
Découpeur de texte—Fractionnement de document
Les documents sont généralement trop longs et doivent être divisés en petits morceaux pour une récupération efficace. La stratégie de découpage affecte directement les performances du RAG :
Exemple
# Créer un découpeur
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # Maximum de 500 caractères par segment
chunk_overlap=50, # Chevauchement de 50 caractères entre les segments
separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""],
# Découper d'abord par paragraphe, puis par phrase, et enfin par caractère
)
# Document d'exemple
long_text = """Tutoriel d'exemple (EXAMPLE) est une plateforme gratuite d'apprentissage de la programmation.
La plateforme propose de riches tutoriels sur les langages de programmation, incluant, sans s'y limiter :
- Tutoriel Python : de la syntaxe de base à l'analyse de données
- Tutoriel Java : de la programmation orientée objet au framework Spring
- Tutoriel front-end : HTML, CSS, JavaScript et leurs frameworks
Tous les tutoriels sont accompagnés d'exemples de code détaillés et d'un environnement d'exécution en ligne.
Les apprenants peuvent rapidement maîtriser les compétences en programmation en apprenant tout en pratiquant."""
# Découper le document
chunks = text_splitter.split_text(long_text)
print(f"Longueur originale : {len(long_text)} caractères")
print(f"Après découpage : {len(chunks)} segments"\n")
for i, chunk in enumerate(chunks):
print(f"--- Segment {i+1} ({len(chunk)} caractères) ---")
print(chunk)
print()
Résultat de l'exécution:
Original length: 153 字 Chunks after split: 3 块 --- 块 1 (54 字) --- Example is a free programming learning platform. 平台提供了丰富的编程语言教程,包括但不限于: --- 块 2 (49 字) --- - Python 教程:从基础语法到数据分析 - Java 教程:面向对象编程到 Spring 框架 --- 块 3 (50 字) --- - 前端教程:HTML、CSS、JavaScript 及其框架 所有教程都配有详细的代码示例和在线运行环境。
chunk_overlap est très important. S'il n'y a pas de chevauchement entre les segments, une phrase complète peut être coupée en deux, ce qui peut entraîner la perte d'informations clés lors de la récupération. Un chevauchement de 50-100 caractères est un paramètre courant.
Guide des paramètres de découpage
| Scénario | chunk_size | chunk_overlap | Raison |
|---|---|---|---|
| FAQ Q&R | 200~500 | 20~50 | Les paires Q&R sont courtes, de petits segments suffisent |
| Documentation technique | 500~1000 | 50~100 | Le contenu technique nécessite plus de contexte |
| Articles longs/articles scientifiques | 1000~2000 | 100~200 | Nécessité de préserver la complétude des paragraphes |
| Dépôt de code | 500~1500 | 0~50 | Fonctions/classes comme limites naturelles |
Flux complet : Charger → Diviser → Vectoriser
Exemple
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
# from langchain_community.document_loaders import TextLoader
# Étape 1 : Charger
# loader = TextLoader("example_knowledge.txt", encoding="utf-8")
# docs = loader.load()
# Pour la démonstration, utilisez directement le texte d'exemple
docs = [
"Example Tutorial (EXAMPLE) est un site web gratuit d'apprentissage de la programmation.",
"Le site Web propose des tutoriels pour plusieurs langages de programmation tels que Python, Java et HTML.",
"Le tutoriel de base Python3 comporte 30 chapitres, adapté aux débutants n'ayant aucune base.",
"Le tutoriel de base HTML comporte 25 chapitres, incluant les formulaires, le multimédia, et plus encore.",
"Tous les tutoriels de base sur Example sont gratuits.",
]
# Étape 2 : Découpage
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
)
chunks = text_splitter.create_documents(docs)
# Étape 3 : Vectoriser et stocker
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./example_db",
)
print(f"Index construit : {len(chunks)} segments de document")
# Étape 4 : Récupération
results = vector_store.similarity_search("Combien de chapitres le tutoriel Python a-t-il ?", k=2)
for doc in results:
print(f"Résultat de recherche : {doc.page_content}")
Résultat de l'exécution:
Index built:5 个文档块 Search result: Python3 基础教程共 30 章,适合零基础入门学习。 Search result: Example is a free programming learning website.Autres extensions