TechLead
Lección 10 de 18
5 min de lectura
LangChain

Cargadores de Documentos y Divisores de Texto

Carga datos desde PDFs, páginas web, CSVs y más, luego divídelos en fragmentos óptimos para RAG

Cargadores de Documentos

Los Document Loaders son componentes de LangChain que cargan datos de diversas fuentes y los convierten en objetos Document. Cada Document tiene pageContent (el texto) y metadata (información de fuente, números de página, etc.).

📁 Fuentes Soportadas

📄 Archivos

PDF, TXT, CSV, JSON, Markdown, DOCX

🌐 Web

Páginas web, sitemaps, repos de GitHub

🗄️ Bases de Datos

Notion, Confluence, Google Docs

Cargando PDFs

npm install pdf-parse
import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf";

// Cargar PDF completo
const loader = new PDFLoader("./docs/reporte.pdf");
const docs = await loader.load();

// Cargar con un documento por página
const loaderPorPagina = new PDFLoader("./docs/reporte.pdf", {
  splitPages: true,
});
const paginas = await loaderPorPagina.load();
console.log(paginas[0].metadata);
// { source: "./docs/reporte.pdf", pdf: { ... }, loc: { pageNumber: 1 } }

Cargando Páginas Web

import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";

const loader = new CheerioWebBaseLoader(
  "https://www.frontendtechlead.com/learn-langchain"
);
const docs = await loader.load();
console.log(docs[0].pageContent.slice(0, 200));

Cargando CSVs

import { CSVLoader } from "@langchain/community/document_loaders/fs/csv";

// Cada fila se convierte en un documento
const loader = new CSVLoader("./data/productos.csv");
const docs = await loader.load();

console.log(docs[0].pageContent);
// "nombre: Widget A\nprecio: 29.99\ncategoría: Herramientas"

Cargador de Directorios

import { DirectoryLoader } from "langchain/document_loaders/fs/directory";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { JSONLoader } from "langchain/document_loaders/fs/json";
import { CSVLoader } from "@langchain/community/document_loaders/fs/csv";

const loader = new DirectoryLoader("./docs", {
  ".txt": (path) => new TextLoader(path),
  ".json": (path) => new JSONLoader(path),
  ".csv": (path) => new CSVLoader(path),
});

const docs = await loader.load();
console.log(`Cargados ${docs.length} documentos`);

Divisores de Texto

Después de cargar documentos, necesitas dividirlos en fragmentos más pequeños por dos razones:

  • Los LLMs tienen límites de ventana de contexto — no puedes pasar libros enteros
  • Los fragmentos más pequeños mejoran la precisión de recuperación

RecursiveCharacterTextSplitter (Recomendado)

import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";

const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,     // Máximo de caracteres por fragmento
  chunkOverlap: 200,   // Solapamiento entre fragmentos para contexto
  separators: ["\n\n", "\n", ". ", " ", ""],
});

const text = "El contenido de tu documento largo aquí...";
const chunks = await splitter.createDocuments([text]);
console.log(`Dividido en ${chunks.length} fragmentos`);

Pipeline Completo: Cargar → Dividir → Almacenar

import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";

// 1. Cargar
const loader = new PDFLoader("./docs/manual.pdf", { splitPages: true });
const rawDocs = await loader.load();

// 2. Dividir
const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,
  chunkOverlap: 200,
});
const splitDocs = await splitter.splitDocuments(rawDocs);

// 3. Almacenar en base de datos vectorial
const vectorStore = await MemoryVectorStore.fromDocuments(
  splitDocs,
  new OpenAIEmbeddings()
);

// 4. ¡Buscar!
const results = await vectorStore.similaritySearch(
  "¿Cómo configuro los ajustes?", 3
);

📏 Guía de Tamaño de Fragmentos

  • Fragmentos pequeños (200-500): Mejor precisión, más resultados necesarios
  • Fragmentos medianos (500-1000): Mejor balance para la mayoría de apps RAG
  • Fragmentos grandes (1000-2000): Más contexto por resultado
  • Solapamiento (10-20%): Previene pérdida de contexto en los límites

💡 Puntos Clave

  • • Los cargadores de documentos convierten archivos, páginas web y APIs en Documents de LangChain
  • • Siempre divide documentos grandes antes de almacenarlos en una base de datos vectorial
  • • RecursiveCharacterTextSplitter es la mejor opción por defecto
  • • Usa solapamiento de fragmentos para no perder contexto en los límites
  • • El pipeline siempre es: Cargar → Dividir → Embeddings → Almacenar → Recuperar

Continuar aprendiendo