> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview of Chains

> Explains LangChain chain patterns, comparing 'stuff' and retrieval RAG workflows for combining documents, summarization, and choosing combine strategies like map_reduce and refine.

In this lesson we cover how to implement and choose between common chain patterns in LangChain for working with multiple documents and retrieval-augmented generation (RAG) workflows.

We focus on two built-in chain constructs:

* The "stuff" chain
* The "retrieval" chain

These building blocks are central when you need to combine multiple documents, summarize content, or answer questions over large collections.

<Callout icon="lightbulb" color="#1CB2FE">
  In this article, "stuff" refers to the approach that formats and injects multiple documents directly into a single prompt, while "retrieval" refers to the pattern that first fetches relevant chunks from a retriever (e.g., a vector store) before combining them for the LLM.
</Callout>

## What is a chain in LangChain?

A chain in LangChain is a pipeline that orchestrates one or more steps (prompts, LLM calls, retrievers, combiners) to produce a final output. Chains make it easier to standardize how you prepare context, call an LLM, and post-process results for tasks like summarization, extraction, and QA.

## 1) Stuff chain (combine by concatenation)

The StuffDocumentsChain (often called the "stuff" combiner) concatenates a list of documents, formats them into a single prompt, and sends that prompt to the LLM in a single call.

When to use:

* The combined size of all documents fits within the LLM’s context window.
* You prefer a straightforward, deterministic single-pass approach (e.g., summarization, extraction).

Advantages:

* Simple and fast: one LLM call with all context.
* Deterministic: model sees all provided content at once, which can help for faithful summarization or extraction.

Limitations:

* Not viable if the total tokens exceed the model's context window.
* Inefficient if many documents are irrelevant to the query.

Example usage:

```python theme={null}
from langchain.chains.combine_documents.stuff import StuffDocumentsChain

# llm: an instantiated LLM
# prompt: your PromptTemplate or prompt string
stuff_chain = StuffDocumentsChain(llm=llm, prompt=prompt)

# documents: a list of langchain.schema.Document objects
result = stuff_chain.run(documents)
print(result)
```

Tips:

* Pre-filter documents if you cannot guarantee they will always fit.
* Use concise prompts and templates to reduce token usage.

## 2) Retrieval chain (RAG-style)

When your document collection is too large for a single prompt, use a retrieval-style chain. This pattern fetches relevant chunks from a retriever (vector DBs like FAISS, Chroma, Milvus, Pinecone, etc.), then combines the retrieved chunks into a prompt using a combiner (e.g., "stuff", "map\_reduce", "refine") before calling the LLM.

This is the common Retrieval-Augmented Generation (RAG) flow: retrieve → combine → generate.

When to use:

* Your corpus is large or contains long documents.
* You need better precision by narrowing context to the most relevant chunks.

Advantages:

* Scales to very large document collections.
* Focuses the LLM on relevant context, improving answer quality and reducing cost.
* Allows indexing, caching, and faster repeated queries.

Limitations:

* Requires an index and retriever infrastructure.
* Adds retrieval latency and tuning complexity (chunk size, embedding model, similarity metrics).

Typical pattern with LangChain’s RetrievalQA helper:

```python theme={null}
from langchain.chains import RetrievalQA

# llm: your LLM instance
# retriever: retriever from a vector store (e.g., faiss_retriever)
retrieval_qa = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",   # or "map_reduce", "refine" depending on your combine strategy
    retriever=retriever
)

answer = retrieval_qa.run("What is the summary of topic X?")
print(answer)
```

Additional notes:

* The `chain_type` selects the combiner strategy used after retrieval.
* For extremely long collections, `map_reduce` first summarizes chunks (map) then combines summaries (reduce).
* `refine` iteratively improves an initial answer using additional context.

## Compare chains: quick reference

| Chain Type              | Best for                                                | Key advantages                                     | Example usage                                               |
| ----------------------- | ------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------- |
| `stuff`                 | Small collections or when all context fits in the model | Simple, single LLM call, deterministic             | `StuffDocumentsChain(llm=llm, prompt=prompt)`               |
| `retrieval` (RAG)       | Large collections, many documents, or long docs         | Scales, focuses on relevant chunks, more efficient | `RetrievalQA.from_chain_type(llm=llm, retriever=retriever)` |
| `map_reduce` (combiner) | Very large inputs where summarization per chunk helps   | Summarizes chunks first, reduces prompt size       | Use as `chain_type="map_reduce"` in RetrievalQA             |
| `refine` (combiner)     | When iterative improvement yields better quality        | Improves answers stepwise with more context        | Use as `chain_type="refine"` in RetrievalQA                 |

## Choosing the right combine strategy

Selecting a combiner depends on:

* Context window size of your LLM (e.g., 8k, 32k tokens).
* Document size and number of documents.
* Desired latency vs. quality trade-offs.

Guidelines:

* If total tokens \<\< context window: prefer `stuff` for simplicity.
* If documents are many or long: use a retrieval chain with `map_reduce` or `refine`.
* If you need higher accuracy and can afford extra calls, prefer `refine`.
* If you need the fastest throughput and context fits: `stuff` is usually best.

<Callout icon="lightbulb" color="#1CB2FE">
  Choosing the right combiner (e.g., `stuff`, `map_reduce`, `refine`) affects quality and cost: `stuff` is fast and simple, `map_reduce` reduces token usage by summarizing pieces first, and `refine` iteratively improves an answer and can yield higher-quality responses.
</Callout>

## Example end-to-end flow (retrieval + stuff)

1. Index documents into a vector store (FAISS, Chroma, etc.) with embeddings.
2. Create a retriever from the vector store.
3. Instantiate a RetrievalQA chain using `chain_type="stuff"` (or a different combiner).
4. Run queries to retrieve relevant chunks and generate answers.

Minimal skeleton:

```python theme={null}
# 1. Indexing (pseudo)
# embeddings = embed_model.embed_documents(doc_texts)
# 2. Create retriever
retriever = vector_store.as_retriever(search_k=10)

# 3. Create RetrievalQA chain
from langchain.chains import RetrievalQA
retrieval_qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever)

# 4. Run a query
answer = retrieval_qa.run("Explain the main points about X.")
print(answer)
```

## Practical tips for production

* Monitor token usage and costs when using `stuff` on many documents.
* Tune chunk size and overlap at indexing time to balance retrieval relevance and context length.
* Cache frequent retrieval results or answers to reduce repeated costs.
* Test different combiner strategies on a validation set to pick the best trade-off of cost and quality.

## Summary

* Stuff chain: concatenates documents into a single prompt and works well when everything fits in the LLM context window.
* Retrieval chain: retrieves relevant chunks from a vector store and then combines them (often via `stuff`, `map_reduce`, or `refine`) before calling the LLM; it scales to large document collections.
* Choose between them based on corpus size, LLM context limits, latency, and quality needs.

## Links and references

* [LangChain documentation](https://langchain.readthedocs.io/)
* FAISS: [https://github.com/facebookresearch/faiss](https://github.com/facebookresearch/faiss)
* Chroma: [https://www.trychroma.com/](https://www.trychroma.com/)
* Overview on RAG patterns: [https://arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/langchain/module/a4d85af7-bfc2-40d7-89fc-f537792272ff/lesson/83ce2c7c-a5ea-428f-8fec-a33a56c9d69e" />
</CardGroup>
