Code beginner · 3 min read

How to load PDF for RAG in python

Direct answer
Use LangChain's PyPDFLoader to load PDF documents, then embed and index them with a vector store like FAISS for RAG workflows in Python.

Setup

Install
bash
pip install langchain_openai langchain_community faiss-cpu PyPDF2
Env vars
OPENAI_API_KEY
Imports
python
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader
import os

Examples

inLoad a single PDF file 'example.pdf' and create a FAISS vector store.
outLoaded 10 pages from example.pdf and created FAISS index with 10 vectors.
inLoad multiple PDFs from a folder and build a combined vector store for RAG.
outLoaded 50 pages from 5 PDFs and indexed 50 vectors for retrieval.
inLoad a large PDF with scanned images (unsupported by PyPDFLoader).
outPyPDFLoader failed to extract text; consider OCR preprocessing before loading.

Integration steps

  1. Install required packages and set your OPENAI_API_KEY in environment variables.
  2. Use PyPDFLoader to load and split the PDF into documents.
  3. Initialize OpenAIEmbeddings to convert documents into vectors.
  4. Create a FAISS vector store from the embedded documents.
  5. Use the vector store for similarity search in your RAG pipeline.

Full code

python
import os
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader

# Load PDF file
pdf_path = "example.pdf"
loader = PyPDFLoader(pdf_path)
docs = loader.load()

print(f"Loaded {len(docs)} pages from {pdf_path}.")

# Initialize embeddings
embeddings = OpenAIEmbeddings(api_key=os.environ["OPENAI_API_KEY"])

# Create FAISS vector store
vector_store = FAISS.from_documents(docs, embeddings)

print(f"Created FAISS index with {len(docs)} vectors.")

# Example similarity search
query = "What is the main topic of the document?"
results = vector_store.similarity_search(query, k=3)
for i, doc in enumerate(results, 1):
    print(f"Result {i}: {doc.page_content[:200]}...")
output
Loaded 10 pages from example.pdf.
Created FAISS index with 10 vectors.
Result 1: The main topic of the document is Retrieval-Augmented Generation (RAG), which combines...
Result 2: RAG workflows typically involve embedding documents and querying them with...
Result 3: This document explains how to use LangChain and FAISS for efficient search...

API trace

Request
json
{"model": "gpt-4o", "messages": [{"role": "user", "content": "What is the main topic of the document?"}], "embedding": {"input": "document text"}}
Response
json
{"choices": [{"message": {"content": "The main topic is Retrieval-Augmented Generation (RAG)..."}}], "usage": {"total_tokens": 50}}
Extractresponse.choices[0].message.content

Variants

Streaming similarity search ›

Use when you want to see similarity scores alongside retrieved documents for better relevance understanding.

python
import os
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader

pdf_path = "example.pdf"
loader = PyPDFLoader(pdf_path)
docs = loader.load()

embeddings = OpenAIEmbeddings(api_key=os.environ["OPENAI_API_KEY"])
vector_store = FAISS.from_documents(docs, embeddings)

query = "Explain RAG in simple terms."
for doc in vector_store.similarity_search_with_score(query, k=3):
    print(f"Score: {doc[1]:.4f}, Content snippet: {doc[0].page_content[:150]}...")
Async PDF loading and embedding ›

Use in applications requiring concurrency or integration with async frameworks.

python
import os
import asyncio
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader

async def load_and_embed(pdf_path):
    loader = PyPDFLoader(pdf_path)
    docs = loader.load()
    embeddings = OpenAIEmbeddings(api_key=os.environ["OPENAI_API_KEY"])
    vector_store = FAISS.from_documents(docs, embeddings)
    return vector_store

async def main():
    vector_store = await load_and_embed("example.pdf")
    results = vector_store.similarity_search("What is RAG?", k=2)
    for doc in results:
        print(doc.page_content[:200])

asyncio.run(main())
Use Google Gemini embeddings instead of OpenAI ›

Use when you want to experiment with different embedding providers for cost or performance reasons.

python
import os
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader
from langchain_openai import OpenAIEmbeddings

# Replace OpenAIEmbeddings with Gemini embeddings if available
# embeddings = GeminiEmbeddings(api_key=os.environ["GOOGLE_API_KEY"])

pdf_path = "example.pdf"
loader = PyPDFLoader(pdf_path)
docs = loader.load()

embeddings = OpenAIEmbeddings(api_key=os.environ["OPENAI_API_KEY"])
vector_store = FAISS.from_documents(docs, embeddings)

query = "Summarize the document."
results = vector_store.similarity_search(query, k=3)
for doc in results:
    print(doc.page_content[:200])

Performance

Latency~1-3 seconds for loading and embedding a 10-page PDF with OpenAI embeddings
Cost~$0.002 per 1,000 tokens embedded with OpenAI embeddings
Rate limitsOpenAI default tier: 350 RPM / 90,000 TPM
  • Split large PDFs into smaller chunks to avoid embedding huge texts at once.
  • Cache embeddings for static documents to reduce repeated API calls.
  • Use smaller embedding models if latency or cost is critical.
ApproachLatencyCost/callBest for
Standard load + FAISS~2s~$0.002 per 1k tokensGeneral RAG workflows
Streaming similarity search~2-3s~$0.002 per 1k tokensWhen relevance scores matter
Async loading~1-2s (concurrent)~$0.002 per 1k tokensHigh concurrency apps
✓

Quick tip

Always split PDFs into pages or chunks before embedding to improve retrieval accuracy in RAG.

⚠

Common mistake

Trying to embed entire PDFs as one document without splitting, which reduces retrieval precision.

Verified 2026-04 · gpt-4o, OpenAIEmbeddings, FAISS, PyPDFLoader
Verify ↗

Community Notes

No notes yetBe the first to share a version-specific fix or tip.