| name | langchain-rag |
| description | Build Retrieval Augmented Generation (RAG) systems with LangChain - includes embeddings, vector stores, retrievers, document loaders, and text splitting |
| language | python |
langchain-rag (Python)
Overview
Retrieval Augmented Generation (RAG) enhances LLM responses by fetching relevant context from external knowledge sources. Instead of relying solely on training data, RAG systems retrieve documents at query time and use them to ground responses.
Key Concepts:
- Document Loaders: Ingest data from files, web, databases
- Text Splitters: Break documents into chunks
- Embeddings: Convert text to vectors
- Vector Stores: Store and search embeddings
- Retrievers: Fetch relevant documents for queries
RAG Pipeline
- Index: Load → Split → Embed → Store
- Retrieve: Query → Embed → Search → Return docs
- Generate: Docs + Query → LLM → Response
Code Examples
Basic RAG Setup
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import InMemoryVectorStore
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.schema import Document
docs = [
Document(page_content="LangChain is a framework for building LLM applications.", metadata={}),
Document(page_content="RAG stands for Retrieval Augmented Generation.", metadata={}),
]
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
)
splits = splitter.split_documents(docs)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = InMemoryVectorStore.from_documents(splits, embeddings)
retriever = vectorstore.as_retriever(k=4)
model = ChatOpenAI(model="gpt-4.1")
query = "What is RAG?"
relevant_docs = retriever.invoke(query)
context = "\n\n".join([doc.page_content for doc in relevant_docs])
response = model.invoke([
{"role": "system", "content": f"Use the following context to answer questions:\n\n{context}"},
{"role": "user", "content": query},
])
print(response.content)
Loading Web Pages
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://docs.langchain.com/oss/python/langchain/agents")
docs = loader.load()
print(f"Loaded {len(docs)} documents")
Loading PDF Files
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("./document.pdf")
docs = loader.load()
Advanced Text Splitting
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", " ", ""],
)
splits = splitter.split_documents(docs)
Using Chroma (Persistent)
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
collection_name="my-docs",
persist_directory="./chroma_db",
)
vectorstore2 = Chroma(
collection_name="my-docs",
embedding_function=embeddings,
persist_directory="./chroma_db",
)
Advanced Retrieval
results = vectorstore.similarity_search_with_score(query, k=5)
for doc, score in results:
print(f"Score: {score}, Content: {doc.page_content}")
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={"fetch_k": 20, "lambda_mult": 0.5, "k": 5},
)
Metadata Filtering
from langchain.schema import Document
docs = [
Document(
page_content="Python programming guide",
metadata={"language": "python", "topic": "programming"}
),
Document(
page_content="JavaScript tutorial",
metadata={"language": "javascript", "topic": "programming"}
),
]
results = vectorstore.similarity_search(
"programming",
k=5,
filter={"language": "python"}
)
RAG with Agent
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search_docs(query: str) -> str:
"""Search documentation for relevant information."""
docs = retriever.invoke(query)
return "\n\n".join([d.page_content for d in docs])
agent = create_agent(
model="gpt-4.1",
tools=[search_docs],
)
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I create an agent?"}]
})
Using Faiss for Performance
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(splits, embeddings)
vectorstore.save_local("faiss_index")
vectorstore2 = FAISS.load_local("faiss_index", embeddings)
Customizing Embeddings
from langchain_openai import OpenAIEmbeddings
small_embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
large_embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
custom_embeddings = OpenAIEmbeddings(
model="text-embedding-3-large",
dimensions=1024
)
Boundaries
What You CAN Configure
✅ Chunk size/overlap: Control document splitting
✅ Embedding model: Choose quality vs cost
✅ Number of results: Top-k retrieval
✅ Metadata filters: Filter by document properties
✅ Search algorithms: Similarity, MMR, hybrid
What You CANNOT Configure
❌ Embedding dimensions (per model): Fixed by model
❌ Perfect retrieval: Semantic search has limits
❌ Real-time document updates: Re-indexing needed
Gotchas
1. Forgetting to Split Documents
vectorstore.add_documents(large_docs)
splits = splitter.split_documents(large_docs)
vectorstore.add_documents(splits)
2. Chunk Size Too Small/Large
splitter = RecursiveCharacterTextSplitter(chunk_size=50)
splitter = RecursiveCharacterTextSplitter(chunk_size=10000)
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
3. No Overlap
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=0,
)
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
4. Not Persisting Vector Store
vectorstore = InMemoryVectorStore.from_documents(docs, embeddings)
vectorstore = Chroma.from_documents(
documents=docs,
embedding=embeddings,
collection_name="prod-docs",
persist_directory="./chroma_db",
)
5. Mixing Embedding Models
vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings(model="text-embedding-3-small"))
retriever = vectorstore.as_retriever(embeddings=OpenAIEmbeddings(model="text-embedding-3-large"))
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(docs, embeddings)
retriever = vectorstore.as_retriever()
Links to Documentation