Skip to main content

RAG Summarization Using LangChain, FAISS, and Hugging Face

Output

Import 1: pipeline

This imports the pipeline function from the Hugging Face Transformers library. A pipeline provides an easy way to use a pre-trained model. In your code, it is used for:
Flow:

Import 2: Document

Document is a LangChain object used to store text and metadata. Example:
Your article is converted into a Document object so that LangChain components can process it.

Import 3: PromptTemplate

PromptTemplate is used to create reusable prompts with variables. For example:
The placeholders:
are replaced with actual values later. Example:

Import 4: StrOutputParser

The language model returns an output that needs to be processed. StrOutputParser() converts the model’s response into a normal Python string. Example:
Flow:

Import 5: RecursiveCharacterTextSplitter

This is used to divide a large document into smaller pieces called chunks. RAG systems usually do not store one large document as a single piece. Instead:
RecursiveCharacterTextSplitter tries to split text intelligently using separators such as:
This helps preserve meaningful text structure.

Import 6: FAISS

FAISS is used as a vector store. After converting text into embeddings, FAISS stores those embeddings and performs similarity searches. Example:
When the user asks a question:
The question is also converted into an embedding. FAISS finds the chunks with the most similar meaning. Flow:

Import 7: HuggingFaceEmbeddings and HuggingFacePipeline

These classes connect Hugging Face models with LangChain.

HuggingFaceEmbeddings

Used to convert text into embeddings.

HuggingFacePipeline

Used to convert a Hugging Face text-generation pipeline into a LangChain-compatible LLM.

Step 1: Create a long article

This is your knowledge source. The article contains information about:
  • RAG
  • Chunking
  • Embeddings
  • FAISS
  • Retrieval
  • Language models
  • Hallucinations
In a real RAG application, this information could come from:
Here, you are manually storing the content in a Python string.

Step 2: Convert the article into a LangChain Document

LangChain works with Document objects. Your article:
is converted into:
The square brackets:
create a list. So the structure is:
This is useful because real applications may contain multiple documents. Example:

Step 3: Create a text splitter

This creates an object responsible for splitting the document.

chunk_size=300

Each chunk contains approximately 300 characters. Conceptually:

chunk_overlap=50

The last part of one chunk is repeated in the next chunk. Example:
The overlap helps prevent important context from being lost at chunk boundaries.

Step 4: Split the article into chunks

This takes the LangChain document:
and converts it into:
Each chunk is also a Document object. For example:

Step 5: Display the chunks

This loop displays every chunk.

enumerate(chunks, start=1)

enumerate() provides two values:
Example:
Using:
starts numbering from 1 instead of 0. Output:

chunk.page_content

Each chunk is a LangChain Document. The actual text is stored inside:

Step 6: Load the embedding model

This loads the embedding model:
The embedding model converts text into a numerical representation. Example:
becomes conceptually:
This numerical representation is called an embedding. Similar meanings produce embeddings that are closer together. Example:
These sentences have similar meanings, so their embeddings should be relatively close.

Step 7: Create the FAISS vector store

This step does two main things.

1. Convert chunks into embeddings

2. Store the embeddings in FAISS

FAISS can now efficiently search for similar vectors.

Step 8: Create a retriever

The retriever provides a simple interface for searching the vector store. The value:
means:
Flow:

Step 9: Get a summarization topic

This asks the user to enter a topic. Example:
Then:
contains:
This query will be used to find relevant chunks.

Step 10: Retrieve relevant chunks

The retriever receives the user’s query. Example:
The process is:
The result is stored in:
For example:

Step 11: Display retrieved chunks

This prints a heading. Then:
This displays the retrieved chunks. Example:
The rank represents the position in the retrieved results.

Step 12: Combine retrieved chunks into context

The retrieved chunks are currently separate documents. Example:
The .join() operation combines them into one string.
The \n\n adds two line breaks between chunks. The final combined result is stored in:
This context will be sent to the language model.

Step 13: Load a local Hugging Face language model

This creates a Hugging Face text-generation pipeline.

task="text-generation"

Tells the pipeline that the model should generate text.

model="distilgpt2"

Loads the DistilGPT-2 model.

max_new_tokens=150

Limits the generated response to approximately 150 new tokens.

do_sample=False

Disables random sampling. This makes generation more deterministic. Flow:

Step 14: Convert the Hugging Face pipeline into a LangChain LLM

The Hugging Face pipeline alone is not directly part of the LangChain chain structure. So this wraps it inside:
Now it can be connected using LangChain’s pipe operator:

Step 15: Create the summarization prompt

This creates a reusable prompt template. It contains two variables:
Later, this:
replaces the placeholders. For example:
This complete prompt is then sent to the language model.

Step 16: Create the output parser

This creates an output parser. Its purpose is to convert the model output into a clean string. Flow:
The result can then be printed easily.

Step 17: Build the summarization chain

This is called an LCEL chain, where the pipe operator | connects components together. The complete flow is:
Or:

Step 18: Generate the summary

The chain receives two inputs.
Example:
And:
Example:
The values replace:
inside the prompt. The complete process is:

Step 19: Display the final summary

This displays the generated output. Example:

Complete RAG Flow

Your entire application works like this:
This program demonstrates the core RAG pipeline:
One important note: retrieval part is a proper basic RAG workflow, but distilgpt2 is not specifically trained for instruction-following or summarization. The code can run, but the final summary may sometimes repeat the prompt or produce poor-quality output.