RAG With LangChain: Build and Check a Source-Based Workflow

LangChain provides the components to build a retrieval-augmented generation pipeline in Python. Here is a minimal working workflow, how to verify your sources, and how to keep the project decisions that sit alongside it.

Updated 4 min read

LangChain is a Python (and JavaScript) library that provides the building blocks for retrieval-augmented generation: document loaders, text splitters, embedding wrappers, vector store connectors, and retrieval chains. You assemble these components into a pipeline that loads your documents, indexes them, and retrieves relevant passages at query time.

A RAG pipeline answers questions from your documents. What it does not supply is the explicit project context that sits around those documents: the decisions about which sources to trust, the tasks that are open, and the follow-up work the last query created. fenbs keeps that record alongside the indexed material, so the team knows what the system is built on and what still needs doing.

What you need

  • Python 3.9 or later.
  • LangChain and its community packages: pip install langchain langchain-community langchain-openai.
  • An OpenAI API key for the embedding model and the LLM, or an alternative provider.
  • Chroma for local vector storage in this example: pip install chromadb.
  • One or more source documents to index.

Load and split your documents

The first step is getting your documents into LangChain's document format and splitting them into chunks. Chunks of 500-1,000 characters with some overlap work well as a starting point:

Load and split documents
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

loader = DirectoryLoader("./docs", glob="**/*.md", loader_cls=TextLoader)
documents = loader.load()

splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=100,
)
chunks = splitter.split_documents(documents)

LangChain includes loaders for PDFs, CSVs, web pages, and many other formats in the langchain-community package. Each loaded document carries metadata — filename, source URL, page number — that will be available when a chunk is retrieved. Keep that metadata; it is how you verify sources.

Create embeddings and store them

Embed the chunks and store them in a local Chroma vector store:

Embed and store chunks
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db",
)
vectorstore.persist()

The persist directory saves the index to disk so you do not have to re-embed on every run. Use the same embedding model every time you add documents or query the store — mixing models in the same vector space produces poor retrieval results.

Build the retrieval chain

With the index in place, build a retrieval chain that retrieves relevant chunks and passes them to the model:

Build and run a retrieval chain
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
    return_source_documents=True,
)

result = qa_chain.invoke({"query": "What does the refund policy say?"})
print(result["result"])
for doc in result["source_documents"]:
    print(doc.metadata["source"])

Setting return_source_documents=True gives you the actual chunks the answer was based on. Print the source metadata from each to see which documents contributed. The LangChain documentation at python.langchain.com (opens in a new tab) covers the full range of chain types and retriever options.

Verify your sources

Source verification is the step that most implementations skip. Retrieving source documents is not enough — you need to confirm that the retrieved text actually supports the answer, not just that it was deemed relevant by similarity score. For high-stakes uses (legal, medical, financial), a human should review the sources before an answer is shared externally.

Build a habit of checking a sample of answers against their sources. When you find a case where the answer is confidently wrong or where the retrieved chunk does not contain the information needed, that is a signal to adjust chunk size, retrieval depth, or the prompt template. Record these findings as lessons so future changes to the pipeline are informed by what failed.

One useful test is to ask the pipeline a question whose answer you already know, then check that the retrieved chunks actually contain the answer. If the correct chunk is not in the top four results, the retrieval settings need tuning. Adjust chunk size, overlap, or the number of results fetched, then test again. Keep the test questions in a file alongside the pipeline code so you can rerun them after any change.

Common issues and how to fix them

  • **Wrong model at query time**: if you indexed with text-embedding-3-small but query with text-embedding-ada-002, results will be poor. The embedding model must match in both directions.
  • **Chunks that lose context**: a paragraph that says "it was approved on Tuesday" makes no sense without knowing what "it" refers to. Increase chunk overlap or add a brief summary at the start of each chunk.
  • **Outdated index**: if your source documents change frequently, rebuild or update the index on a schedule. A stale index retrieves outdated passages confidently.
  • **Top-k too small**: if the relevant chunk is often in position 5-8 but you only fetch 4 results, raise the k parameter and check whether the answer quality improves.
How fenbs helps

Track your indexed sources and open follow-up tasks

fenbs Links and listings keep every source document, dataset, and external reference in one place with status and notes. When a source turns out to be stale or unreliable, record that as a Lesson. When a gap in the index creates a follow-up task, add it to the board. Create a free account and connect your AI from Integrations.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for the RAG application. Write the key decisions: which sources are authoritative, which model to use for embeddings, and any constraints on the answers the pipeline can give.
  2. Add the source documents as Links in fenbs — the document name, its source URL or path, and its current status (authoritative, draft, deprecated).
  3. Connect your AI app to fenbs over MCP from Integrations so it can read the source list and project decisions at the start of a session.
  4. When source verification finds a bad answer, open a task in fenbs to investigate and fix it. Note what the query was, what the answer was, and what the correct answer should have been.
  5. Record lessons — wrong chunk sizes, retrieval failures, sources that needed updating — as Lessons in fenbs so they inform the next pipeline iteration.

The what is RAG article explains the full RAG pipeline from first principles. The agent memory vs RAG article covers how retrieval fits into a broader memory architecture.

Questions people ask.

What LangChain packages do I need for RAG?

At minimum: langchain, langchain-community (for document loaders and vector store connectors), and a provider package like langchain-openai. You also need a vector store library such as chromadb for local development. Install them with pip.

How do I choose the right chunk size for LangChain RAG?

Start with 500-1,000 characters and 10-15% overlap. Smaller chunks retrieve more precisely but may lose context; larger chunks include more context but may contain irrelevant material. Test with representative queries and check whether the retrieved chunks actually contain the answer.

How do I verify that LangChain RAG answers are based on the right sources?

Set return_source_documents=True on your retrieval chain and print the source metadata from each returned document. Read the retrieved chunks and confirm that the answer can be found in them. For high-stakes uses, have a person review a sample of answers against their sources.

Can I use LangChain RAG with models other than OpenAI?

Yes. LangChain supports many model providers through its community packages, including Anthropic, Google, Mistral, and local models through Ollama. Swap the ChatOpenAI and OpenAIEmbeddings classes for your provider's equivalents.

More in Agent harness (for developers)

All Agent harness (for developers) articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.