Skip to content
Automation
Agent

rag

Complete guide to Retrieval-Augmented Generation with LangChain.

From plugin
dr-claw
1k8 skills8 agents
Install
$ npx -y skills add OpenLAIR/dr-claw --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Complete guide to Retrieval-Augmented Generation with LangChain.

Agent definition

rag.md

LangChain RAG Guide

Complete guide to Retrieval-Augmented Generation with LangChain.

What is RAG?

**RAG (Retrieval-Augmented Generation)** combines: 1. **Retrieval**: Find relevant documents from knowledge base 2. **Generation**: LLM generates answer using retrieved context

**Benefits**:

  • Reduce hallucinations
  • Up-to-date information
  • Domain-specific knowledge
  • Source citations

RAG pipeline components

1. Document loading

from langchain_community.document_loaders import (
    WebBaseLoader,
    PyPDFLoader,
    TextLoader,
    DirectoryLoader,
    CSVLoader,
    UnstructuredMarkdownLoader
)

# Web pages
loader = WebBaseLoader("https://docs.python.org/3/tutorial/")
docs = loader.load()

# PDF files
loader = PyPDFLoader("paper.pdf")
docs = loader.load()

# Multiple PDFs
loader = DirectoryLoader("./papers/", glob="**/*.pdf", loader_cls=PyPDFLoader)
docs = loader.load()

# Text files
loader = TextLoader("data.txt")
docs = loader.load()

# CSV
loader = CSVLoader("data.csv")
docs = loader.load()

# Markdown
loader = UnstructuredMarkdownLoader("README.md")
docs = loader.load()

2. Text splitting

from langchain.text_splitter import (
    RecursiveCharacterTextSplitter,
    CharacterTextSplitter,
    TokenTextSplitter
)

# Recommended: Recursive (tries multiple separators)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,        # Characters per chunk
    chunk_overlap=200,      # Overlap between chunks
    length_function=len,
    separators=["\n\n", "\n", " ", ""]
)

splits = text_splitter.split_documents(docs)

# Token-based (for precise token limits)
text_splitter = TokenTextSplitter(
    chunk_size=512,         # Tokens per chunk
    chunk_overlap=50
)

# Character-based (simple)
text_splitter = CharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separator="\n\n"
)

**Chunk size recommendations**:

  • **Short answers**: 256-512 tokens
  • **General Q&A**: 512-1024 tokens (recommended)
  • **Long context**: 1024-2048 tokens
  • **Overlap**: 10-20% of chunk_size

3. Embeddings

from langchain_openai import OpenAIEmbeddings
from langchain_community.embeddings import (
    HuggingFaceEmbeddings,
    CohereEmbeddings
)

# OpenAI (fast, high quality)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# HuggingFace (free, local)
embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/all-mpnet-base-v2"
)

# Cohere
embeddings = CohereEmbeddings(model="embed-english-v3.0")

4. Vector stores

from langchain_chroma import Chroma
from langchain_community.vectorstores import FAISS
from langchain_pinecone import PineconeVectorStore

# Chroma (local, persistent)
vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

# FAISS (fast similarity search)
vectorstore = FAISS.from_documents(splits, embeddings)
vectorstore.save_local("./faiss_index")

# Pinecone (cloud, scalable)
vectorstore = PineconeVectorStore.from_documents(
    documents=splits,
    embedding=embeddings,
    index_name="my-index"
)

5. Retrieval

# Basic retriever (top-k similarity)
retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 4}  # Return top 4 documents
)

# MMR (Maximal Marginal Relevance) - diverse results
retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={
        "k": 4,
        "fetch_k": 20,      # Fetch 20, return diverse 4
        "lambda_mult": 0.5  # Diversity (0=diverse, 1=similar)
    }
)

# Similarity score threshold
retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={
        "score_threshold": 0.5  # Minimum similarity score
    }
)

# Query documents directly
docs = retriever.get_relevant_documents("What is Python?")

6. QA chain

from langchain.chains import RetrievalQA
from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-sonnet-4-5-20250929")

# Basic QA chain
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    return_source_documents=True
)

# Query
result = qa_chain({"query": "What are Python decorators?"})
print(result["result"])
print(f"Sources: {len(result['source_documents'])}")

Advanced RAG patterns

Conversational RAG

from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory

# Add memory
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True,
    output_key="answer"
)

# Conversational RAG chain
qa = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=retriever,
    memory=memory,
    return_source_documents=True
)

# Multi-turn conversation
result1 = qa({"question": "What is Python used for?"})
result2 = qa({"question": "Can you give examples?"})  # Remembers context
result3 = qa({"question": "What about web development?"})

Custom prompt template

from langchain.prompts import PromptTemplate

# Custom QA prompt
template = """Use the following pieces of context to answer the question.
If you don't know the answer, say so - don't make it up.
Always cite your sources using [Source N] notation.

Context: {context}

Question: {question}

Helpful Answer:"""

prompt = PromptTemplate(
    template=template,
    input_variables=["context", "question"]
)

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type_kwargs={"prompt": prompt}
)

Chain types

# 1. Stuff (default) - Put all docs in context
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type="stuff"  # Fast, works if docs fit in context
)

# 2. Map-reduce - Summarize each doc, then combine
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type="map_reduce"  # For
Read more
Ships withdr-claw

A Super AI Lab with massive AI Doctors as Assistants. Best IDE for Research via AI Power.

Get the whole plugin