Welcome to the fifth and final lesson of our module on long-term memory for AI agents. In our last session, you successfully set up a Qdrant vector database in the cloud and mastered the fundamental CRUD operations to manage its contents. You've essentially built the "library" for our agent; now it's time to teach the agent how to read the books.
Today's objective is to implement a Retrieval-Augmented Generation (RAG) pattern by integrating a vector store as a retrieval tool in an agent. We will connect the Qdrant database you prepared to a LangChain agent, enabling it to query its long-term memory to answer questions with information it wasn't originally trained on. This lesson marks a pivotal moment where we combine memory and action into a single, cohesive system.
From Hallucination to Grounding: The RAG Pattern
A standalone Large Language Model, powerful as it is, has two major limitations: its knowledge is frozen at the time of training, and it has no access to your private, real-time data. This can lead to outdated answers or "hallucinations" when asked about specific or recent information.
Retrieval-Augmented Generation (RAG) is a powerful pattern that solves this by grounding the LLM in external knowledge. Instead of just asking the model a question, the RAG process works in three steps:
- Retrieve: Before answering, the system retrieves relevant documents from a knowledge source (like our Qdrant database).
- Augment: The retrieved documents are added as context to the original user prompt.
- Generate: The LLM receives the augmented prompt (original question + retrieved context) and generates an answer based on the provided information.
This turns the vector database from a passive data store into an active tool the agent can use to find facts and inform its responses.
{"type":"image","url":"https://qdrant.tech/articles_data/agentic-rag/ai-agent.png","caption":"This diagram illustrates how an AI Agent can use RAG as one of its tools. When a user asks a query, the agent can decide to invoke the RAG system, which retrieves context from a vector database to help the LLM generate a factually grounded response.","isV2":true,"blockId":"748ed538-4a36-4fa7-9c7e-856c45deacf3","lessonId":"b7b5fc9f-ce63-4798-b52a-b10c1e5c4f90"}
The following reading provides a high-level overview of this "Agentic RAG" concept, framing RAG as a versatile tool within a larger agent toolkit.
{"type":"reading","par_intro":"This article introduces the concept of \"Agentic RAG,\" which moves beyond a simple linear pipeline to a more dynamic system where an AI agent intelligently decides when and how to use retrieval as a tool.","par_directions":"Please read the introduction, the \"What We'll Build\" section, and the \"Workflow\" table. Focus on the distinction between <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"0b9fc4e2\" data-range-start=\"Traditional Retrieval-Augmented Generation\" data-range-end=\"diverse types of information\">traditional RAG</span> and <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"fccc1b79\" data-range-start=\"Agentic RAG takes things\" data-range-end=\"more versatile toolkit\">Agentic RAG</span>. The workflow table provides a clear, step-by-step breakdown of how the agent processes a query and utilizes its tools.","learning_duration":"5 minutes","url":"https://qdrant.tech/documentation/tutorials-build-essentials/agentic-rag-langgraph/","title":"Agentic RAG with LangGraph - Qdrant","isV2":true,"blockId":"a0f6318f-c9d8-4e49-9a4c-cd454347f730","lessonId":"b7b5fc9f-ce63-4798-b52a-b10c1e5c4f90"}
Building a RAG Agent with LangChain
As you've seen, LangChain provides powerful abstractions that simplify building complex agentic systems. For RAG, it offers a clear pathway to connect your data, retriever, and agent.
The entire process is well-documented in the official LangChain documentation. This will be our main guide for the implementation.
{"type":"reading","par_intro":"This tutorial is a comprehensive guide to building a RAG application using LangChain. It covers everything from indexing data to creating the agent.","par_directions":"First, read the <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"38366b50\" data-range-start=\"Overview\" data-range-end=\"retrieval and generation\">initial sections</span> to understand the two main phases: **Indexing** and **Retrieval/Generation**.\n\nNext, skim through the <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"778afd37\" data-range-start=\"1. Indexing\" data-range-end=\"query-able vector store\">Indexing section</span>. You don't need to execute the code for loading from a web page, but pay attention to the three steps: **Load, Split, and Store**. This is the standard pipeline for preparing data for a vector database.\n\nFinally, focus your attention on the section titled <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"e9495026\" data-range-start=\"RAG agents\" data-range-end=\"retrieves information\">**RAG agents**</span>. This is the core of our lesson. It demonstrates exactly how to:\n1. Wrap a vector store in a `tool`.\n2. Provide this tool to a `create_agent` function.\n3. Invoke the agent and observe its reasoning process.","learning_duration":"20 minutes","url":"https://docs.langchain.com/oss/python/langchain/rag","title":"Build a RAG agent with LangChain","isV2":true,"blockId":"7b6a18a2-222e-40b0-9a87-1abdfa4e6652","lessonId":"b7b5fc9f-ce63-4798-b52a-b10c1e5c4f90"}
Now, let's put these concepts into practice. The following video provides a hands-on demonstration that mirrors the LangChain documentation, making it easier to see all the pieces working together.
{"type":"video","title":"LangChain Full Crash Course - AI Agents in Python","learning_duration":515,"video_id":"J7j5tCB_y4w","par_intro":"This segment from the \"LangChain Full Crash Course\" by NeuralNine provides a practical walkthrough of building a RAG agent. It covers setting up embeddings, creating a vector store, converting it into a retriever tool, and integrating it with an agent.","par_directions":"Please watch from <span data-type=\"resource_video_timerange\" data-resource-subitem-id=\"ebbfa87b\" data-range-start=\"1769\" data-range-end=\"2284\">the beginning of the RAG example</span>. The instructor will guide you through:\n1. **Setting up the components** (`OpenAIEmbeddings`, `FAISS` vector store). We'll be using Qdrant, but the concept is identical.\n2. **Populating the vector store** with text data.\n3. **Turning the vector store into a retriever** using `.as_retriever()`.\n4. **Creating a `retriever_tool`** with a name and description.\n5. **Building and invoking the agent** with the new tool.","video_duration":3199,"isV2":true,"blockId":"8f79829e-a640-4423-accd-8528fd544de2","lessonId":"b7b5fc9f-ce63-4798-b52a-b10c1e5c4f90"}
{
"type": "exercise",
"id": "3b04f917-8e9b-4093-bf2a-cfbddf5b3e6c"
}
Hands-On: Building an E-commerce Product Assistant
Let's synthesize what you've learned into a complete, runnable example tailored to your interest in e-commerce. We will build an agent that can answer questions about a small product catalog.
Prerequisites:
Make sure you have the necessary libraries installed. You should have qdrant-client from the last lesson. You will also need langchain and its OpenAI integration.
pip install langchain langchain-openai qdrant-client python-dotenv
Your .env file should contain your OPENAI_API_KEY, QDRANT_URL, and QDRANT_API_KEY.
Step 1: Setup and Data Indexing
First, we'll define our product data and index it into a new Qdrant collection. LangChain's QdrantVectorStore.from_texts method handles embedding and upserting in a single step.
import os
from dotenv import load_dotenv
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_qdrant import Qdrant
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from langchain.tools.retriever import create_retriever_tool
# Load environment variables
load_dotenv()
# 1. Initialize Embeddings and LLM
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
llm = ChatOpenAI(model="gpt-4o-mini")
# 2. Define Product Data and Collection Name
collection_name = "ecommerce_products"
product_docs = [
"Product: 'SmartHome Hub', Price: $129.99, Description: A central device to control all your smart home gadgets, from lights to thermostats. Supports Zigbee, Z-Wave, and Wi-Fi. Features voice control via Alexa and Google Assistant.",
"Product: 'Quantum-LED Smart TV', Price: $899.99, Description: A 65-inch 4K UHD Smart TV with Quantum-LED technology for vibrant colors. Comes with built-in streaming apps like Netflix, Hulu, and Disney+. Has 4 HDMI ports and supports Dolby Atmos audio.",
"Product: 'Ergo-Pro Office Chair', Price: $349.99, Description: An ergonomic office chair with adjustable lumbar support, armrests, and seat height. Made with breathable mesh to keep you cool. Supports up to 300 lbs.",
"Product: 'Noise-Canceling Wireless Headphones', Price: $249.99, Description: Over-ear wireless headphones with active noise cancellation (ANC). Features 30-hour battery life, a built-in microphone for calls, and connects via Bluetooth 5.2.",
]
# 3. Index data into Qdrant
# This will create embeddings and store them in the specified collection.
# If the collection already exists, it will add the documents.
# For a fresh start, you can delete the collection in the Qdrant UI.
qdrant_vector_store = Qdrant.from_texts(
product_docs,
embeddings,
url=os.getenv("QDRANT_URL"),
api_key=os.getenv("QDRANT_API_KEY"),
collection_name=collection_name,
)
print(f"Successfully indexed {len(product_docs)} documents into collection '{collection_name}'.")
Step 2: Create the Retrieval Tool
Now, we'll create the retriever and wrap it in a tool. The description is crucial—it's how the agent determines that this tool is the right one to use for product-related questions.
# 4. Create a retriever from the vector store
retriever = qdrant_vector_store.as_retriever()
# 5. Create the retriever tool
# The description tells the agent when to use this tool.
retrieval_tool = create_retriever_tool(
retriever,
"product_catalog_search",
"Searches and returns information about products from the e-commerce catalog. Use it for any questions about product features, pricing, or specifications."
)
tools = [retrieval_tool]
Step 3: Create and Run the Agent
Finally, we assemble the agent with its new tool and a prompt that encourages it to be a helpful assistant. We use AgentExecutor to run the agent's reasoning loop.
# 6. Create the agent prompt
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant for an e-commerce store. Answer the user's questions based on the product information provided by the search tool."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
# 7. Create the agent
agent = create_tool_calling_agent(llm, tools, prompt)
# 8. Create the Agent Executor to run the agent
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 9. Invoke the agent with a question
question = "How much does the Smart TV cost and does it have Netflix?"
response = agent_executor.invoke({"input": question})
print("\n--- Final Answer ---")
print(response["output"])
When you run this full script, pay close attention to the verbose=True output. It will show you the agent's "thoughts":
- It receives your question.
- It reasons that it needs to find product information.
- It decides to call the
product_catalog_searchtool. - It shows the documents retrieved from Qdrant.
- It uses those documents to generate the final, accurate answer.
{
"type": "exercise",
"id": "474bcdbe-6222-4f51-b6b8-aaff7968c921"
}
Conclusion
Congratulations! You have successfully built a complete Retrieval-Augmented Generation system. By integrating the Qdrant vector store as a tool, you've given your agent a reliable, external memory, allowing it to answer specific questions with grounded, factual information.
Here are the key takeaways from today's lesson:
- RAG grounds LLMs by providing relevant external context within the prompt, preventing hallucinations and enabling access to private data.
- In LangChain, the core components for RAG are the
VectorStore, theRetriever, and theTool. - The
create_retriever_toolfunction is a convenient way to make your knowledge base available to an agent. - The tool's description is critical for the agent's reasoning process, as it dictates when the tool will be selected and used.
In this lesson, we loaded a small, static list of documents. In a real-world e-commerce scenario, you would have thousands of products, and the data might be messy. Our next and final lesson in this module, "Design a chunking strategy and metadata schema for indexing an e-commerce product catalog," will address this. We will explore strategies for breaking down large documents into effective, searchable chunks and how to use metadata to enable powerful, filtered searches.
Can't find a good explanation? Sign up and we'll make it for you