Carga y división de documentos de LangChain
En artículos anteriores ingresábamos texto manualmente, pero en proyectos reales, los documentos pueden provenir de PDF, páginas web, archivos Markdown, etc.
Esta sección explica cómo usar Document Loader para cargar varios tipos de documentos y cómo usar Text Splitter para dividir los documentos en fragmentos pequeños adecuados para la recuperación.
Document Loader——Cargar documentos
LangChain ofrece decenas de cargadores de documentos que cubren formatos de archivo comunes:
| Loader | Origen | Paquete de instalación |
|---|---|---|
| TextLoader | Archivo .txt | langchain (integrado) |
| PyPDFLoader | Archivo PDF | langchain-community + pypdf |
| WebBaseLoader | URL web | langchain-community + beautifulsoup4 |
| CSVLoader | Archivo CSV | langchain-community |
| UnstructuredMarkdownLoader | Archivo Markdown | langchain-community + unstructured |
Ejemplo
from langchain_community.document_loaders import TextLoader
loader = TextLoader("knowledge.txt", encoding="utf-8")
docs = loader.load()
print(f"Se cargaron {len(docs)} documentos")
print(f"Vista previa del contenido: {docs)
# Cargar página 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"\n"Contenido web: {docs)
Text Splitter——División de documentos
Los documentos suelen ser demasiado largos; es necesario dividirlos en fragmentos pequeños (chunks) para una recuperación eficaz. La estrategia de división afecta directamente el resultado de RAG:
Ejemplo
# Crear el divisor
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # Máximo 500 caracteres por fragmento
chunk_overlap=50, # Superposición de 50 caracteres entre fragmentos
separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""],
# Dividir primero por párrafos, luego por oraciones y finalmente por caracteres
)
# Documento de ejemplo
long_text = """Tutorial para novatos (EJEMPLO) es una plataforma gratuita de aprendizaje de programación.
La plataforma ofrece completos tutoriales de lenguajes de programación, incluyendo, entre otros:
- Tutorial de Python: desde sintaxis básica hasta análisis de datos
- Tutorial de Java: desde programación orientada a objetos hasta el framework Spring
- Tutorial de front-end: HTML, CSS, JavaScript y sus frameworks
Todos los tutoriales incluyen ejemplos de código detallados y un entorno de ejecución en línea.
Los estudiantes pueden dominar rápidamente habilidades de programación aprendiendo y practicando simultáneamente."""
# Dividir documento
chunks = text_splitter.split_text(long_text)
print(f"Longitud del texto original: {len(long_text)} caracteres")
print(f"Después de dividir: {len(chunks)} fragmentos"\n")
for i, chunk in enumerate(chunks):
print(f"--- Fragmento {i+1} ({len(chunk)} caracteres) ---")
print(chunk)
print()
Resultado de ejecución:
Longitud original: 153 字 Fragmentos tras dividir: 3 块 --- 块 1 (54 字) --- Ejemplo es una plataforma gratuita de aprendizaje de programación. 平台提供了丰富的编程语言教程,包括但不限于: --- 块 2 (49 字) --- - Python 教程:从基础语法到数据分析 - Java 教程:面向对象编程到 Spring 框架 --- 块 3 (50 字) --- - 前端教程:HTML、CSS、JavaScript 及其框架 所有教程都配有详细的代码示例和在线运行环境。
chunk_overlap es muy importante. Si no hay superposición entre fragmentos, una oración completa puede cortarse por la mitad, provocando la omisión de información clave durante la recuperación. Una superposición de 50-100 caracteres es una configuración común.
Guía de configuración de parámetros de división
| Escenario | chunk_size | chunk_overlap | Razón |
|---|---|---|---|
| Preguntas frecuentes (FAQ) | 200~500 | 20~50 | Los pares de preguntas y respuestas son cortos, bastan fragmentos pequeños |
| Documentación técnica | 500~1000 | 50~100 | El contenido técnico requiere más contexto |
| Artículos largos/trabajos académicos | 1000~2000 | 100~200 | Es necesario preservar la integridad de los párrafos |
| Base de código | 500~1500 | 0~50 | Funciones/clases como límites naturales |
Proceso completo: Carga → División → Vectorización
Ejemplo
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
# from langchain_community.document_loaders import TextLoader
# Proceso 1: Carga
# loader = TextLoader("ejemplo_knowledge.txt", encoding="utf-8")
# docs = loader.load()
# Para la demostración, se utiliza texto de ejemplo directamente
docs = [
"Tutorial para novatos (EJEMPLO) es un sitio web gratuito de aprendizaje de programación.",
"El sitio ofrece tutoriales de varios lenguajes de programación como Python, Java, HTML, etc.",
"El tutorial básico de Python3 tiene 30 capítulos, adecuado para principiantes sin conocimientos previos.",
"El tutorial básico de HTML tiene 25 capítulos, incluye formularios, multimedia, etc.",
"Todos los tutoriales básicos de Tutorial para novatos son gratuitos.",
]
# Proceso 2: División
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
)
chunks = text_splitter.create_documents(docs)
# Proceso 3: Almacenamiento vectorial
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./ejemplo_db",
)
print(f"Índice creado: {len(chunks)} fragmentos de documentos")
# Proceso 4: Recuperación
results = vector_store.similarity_search("¿Cuántos capítulos tiene el tutorial de Python?", k=2)
for doc in results:
print(f"Resultado de la recuperación: {doc.page_content}")
Resultado de ejecución:
Índice creado:5 个文档块 Resultado de búsqueda: Python3 基础教程共 30 章,适合零基础入门学习。 Resultado de búsqueda: Ejemplo es un sitio web gratuito de aprendizaje de programación.Otras extensiones