Get AI summaries of any video or article — Sign up free
Document Loaders in LangChain |  Generative AI using LangChain | Video 10 | CampusX thumbnail

Document Loaders in LangChain | Generative AI using LangChain | Video 10 | CampusX

CampusX·
5 min read

Based on CampusX's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Document loaders normalize data from many sources into standardized LangChain Document objects with page_content and metadata.

Briefing

LangChain’s document loaders are the glue that turns messy, source-specific data—PDFs, text files, web pages, CSVs—into a single standardized “Document” format that downstream RAG steps (chunking, embeddings, retrieval, and generation) can reliably use. The core idea is simple but foundational: data can live in many places and many formats, yet RAG pipelines need consistent inputs. Document loaders solve that by converting each source into LangChain Document objects containing (1) page/content text and (2) metadata such as source, timestamps, and provenance.

The walkthrough starts by reframing RAG as a practical fix for chatbots that lack the right knowledge. When a user asks about current events, personal emails, or internal company documentation—information not present in a model’s training data—RAG connects the LLM to an external knowledge base. At query time, the system retrieves relevant documents from that knowledge base and feeds them back to the LLM as context, producing more grounded answers. The video emphasizes why this matters: RAG can pull up-to-date information, improve privacy by avoiding direct uploads of sensitive documents, and handle large files by splitting them into manageable chunks.

From there, the focus narrows to the first of four common RAG components: document loaders. The presenter argues that most RAG architectures ultimately rely on a small set of building blocks—document loaders, text splitters, vector databases, and retrievers—and that learning loaders first makes the rest easier. Instead of attempting to teach every loader, the session highlights four high-usage loaders: TextLoader, PyPDFLoader, WebBaseLoader, and CSVLoader.

TextLoader is positioned as the simplest option for plain text inputs like logs, code snippets, or transcripts. It loads a text file into a list of Document objects. Even in this “simple” case, the output is standardized: each Document includes page_content and metadata. The code flow demonstrates how page_content can be passed into an LLM chain for tasks like summarization.

PyPDFLoader is then used to load PDFs page-by-page. For a 23-page curriculum PDF, the loader produces 23 Document objects, each with its own page_content and metadata including page number and source details. The video also cautions that PyPDFLoader works best for mostly text-based PDFs; scanned or complex layout PDFs may require other loaders such as PDFPlumberLoader, UnstructuredPDFLoader, AmazonTextractPDFLoader, or PyMuPDFLoader.

Next comes DirectoryLoader, which batches loading across many files in a folder. It explains why this can be slow and memory-heavy when using eager loading: loading hundreds of PDFs at once can overwhelm RAM. To address that, the session contrasts eager loading (load everything into memory and return a list) with lazy loading (return a generator that fetches one document at a time on demand). Lazy loading enables streaming-style processing and reduces memory pressure.

Finally, WebBaseLoader extracts text from web pages by fetching HTML and using BeautifulSoup to strip tags into usable text. It works best for relatively static pages and returns one Document per URL (or one per URL when given a list). CSVLoader handles tabular data by creating one Document per row, embedding column values into page_content and attaching row/source metadata. The session closes by noting that LangChain also supports creating custom document loaders when a needed source type isn’t available, by implementing load and lazy load behavior in a subclass.

Cornell Notes

LangChain document loaders convert data from many sources (PDFs, text files, web pages, CSVs) into a standardized set of Document objects. Each Document includes page_content plus metadata (like source, timestamps, and page/row identifiers), which makes it usable for downstream RAG steps such as chunking, embeddings, retrieval, and generation. The video highlights four common loaders: TextLoader (plain text), PyPDFLoader (page-by-page PDFs), WebBaseLoader (static web pages via HTML parsing), and CSVLoader (one Document per CSV row). For loading many files, DirectoryLoader supports eager loading (everything in memory) and lazy loading (generator-style, one document at a time), which helps avoid RAM issues. When no loader fits a data source, LangChain allows custom loader implementations.

Why do RAG pipelines need document loaders instead of sending raw files directly to an LLM?

RAG needs consistent inputs for chunking, embeddings, retrieval, and generation. Data can come from PDFs, text files, databases, or web pages, each with different formats. Document loaders normalize that variety by converting source-specific data into LangChain Document objects with two core fields: page_content (the extracted text) and metadata (provenance like source and timestamps). That standardized structure lets later components operate uniformly across sources.

What exactly does a LangChain Document contain, and how does that affect downstream steps?

Each loader returns a list of Document objects. Every Document includes (1) page_content, which holds the extracted content (e.g., text from a file, a PDF page’s text, a web page’s cleaned text, or a CSV row’s values) and (2) metadata, which stores context such as source, creation/modification details, and identifiers like page number or row information. Downstream steps can use page_content for embeddings and retrieval, while metadata supports filtering, traceability, and debugging.

How does PyPDFLoader differ from TextLoader in output granularity?

TextLoader typically produces a small number of Document objects for a text file (often one Document). PyPDFLoader operates page-by-page: a 23-page PDF yields 23 Document objects, each representing one page’s content. Metadata includes page-level details such as page number and total pages, enabling precise retrieval and citation-like behavior.

When should DirectoryLoader use eager loading vs lazy loading?

Eager loading uses loader.load(), which loads all documents into memory at once and returns a list. This is practical for a small number of documents. Lazy loading uses loader.lazy_load(), which returns a generator and fetches one document at a time on demand. This is crucial when dealing with many files/pages because loading everything into RAM can be slow or impossible; lazy loading supports streaming-style processing with lower memory usage.

How do WebBaseLoader and CSVLoader map external data into Document objects?

WebBaseLoader fetches a web page’s HTML and uses BeautifulSoup to extract textual content, returning one Document per URL (or one per URL when multiple URLs are provided). CSVLoader reads a CSV file and creates one Document per row; each Document’s page_content includes the row’s column-value pairs, while metadata includes row/source context. This row/page mapping makes retrieval granular and queryable.

What’s the fallback when a needed data source doesn’t have a built-in loader?

LangChain supports custom document loaders. The approach is to create a class that inherits from the base loader class and implement load and/or lazy load methods with custom extraction logic. This lets teams integrate proprietary formats or uncommon sources into the same Document + metadata standard used by RAG pipelines.

Review Questions

  1. How does the Document object’s page_content and metadata enable consistent RAG behavior across PDFs, web pages, and CSVs?
  2. Describe the practical difference between load() and lazy_load() in DirectoryLoader, and explain why lazy loading matters for large document sets.
  3. Give one example of when PyPDFLoader might underperform and name alternative loaders mentioned for those cases.

Key Points

  1. 1

    Document loaders normalize data from many sources into standardized LangChain Document objects with page_content and metadata.

  2. 2

    RAG addresses cases where an LLM lacks the needed knowledge by retrieving relevant documents from an external knowledge base and using them as context.

  3. 3

    PyPDFLoader converts PDFs into one Document per page, making page-level retrieval and metadata tracking straightforward.

  4. 4

    DirectoryLoader can batch-load many files, but eager loading can be slow and memory-intensive at scale.

  5. 5

    Lazy loading returns a generator that fetches documents on demand, reducing RAM pressure and enabling streaming-style processing.

  6. 6

    WebBaseLoader extracts text from relatively static web pages by parsing HTML with BeautifulSoup.

  7. 7

    CSVLoader creates one Document per CSV row, embedding column values into page_content for row-level querying.

Highlights

Document loaders turn heterogeneous inputs into a uniform Document schema—page_content plus metadata—so chunking and retrieval work the same way across sources.
PyPDFLoader’s page-by-page behavior means a 23-page PDF becomes 23 Document objects, each with page-specific metadata.
Eager loading loads everything into memory and returns a list; lazy loading returns a generator and fetches one document at a time to avoid RAM bottlenecks.
WebBaseLoader is best for static HTML-heavy pages; highly JavaScript-driven sites may require a different approach like Selenium URL loading.
CSVLoader’s one-row-per-Document design makes it easy to ask questions about specific fields and values.

Topics

  • RAG
  • Document Loaders
  • PyPDFLoader
  • WebBaseLoader
  • CSVLoader