{"id":150313,"date":"2025-03-22T19:51:53","date_gmt":"2025-03-22T19:51:53","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/guide-to-adaptive-rag-systems-with-langgraph\/"},"modified":"2025-03-22T19:51:53","modified_gmt":"2025-03-22T19:51:53","slug":"guide-to-adaptive-rag-systems-with-langgraph","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=150313","title":{"rendered":"Guide to Adaptive RAG Systems with LangGraph"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div id=\"article-start\">\n<p><a href=\"https:\/\/www.analyticsvidhya.com\/blog\/2023\/03\/an-introduction-to-large-language-models-llms\/\" target=\"_blank\" rel=\"noreferrer noopener\">Large language models<\/a> answer questions using the knowledge they learned during training. This fixed knowledge base limits them. They can\u2019t give you current or highly specific information. <a href=\"https:\/\/www.analyticsvidhya.com\/blog\/2023\/09\/retrieval-augmented-generation-rag-in-ai\/\" target=\"_blank\" rel=\"noreferrer noopener\">Retrieval-Augmented Generation<\/a> (RAG) helps by letting LLMs pull in external data, but even RAG needs help with complex questions. Adaptive RAG offers a solution. It picks the best approach for answering a question. This could be a direct answer from the LLM, a single data lookup, or multiple data lookups or even a web search. A classifier looks at the question\u2019s complexity and decides the best method. <\/p>\n<p>Here are the three answering strategies Adaptive RAG uses:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Straight forward Response:<\/strong> For easy questions, the LLM uses its own stored knowledge. This gives fast answers without needing to look up external information.<\/li>\n<li><strong>Single-step Approach:<\/strong> For questions that are a bit harder, the system gets information from one external source. This keeps the answer quick but also well-informed.<\/li>\n<li><strong>Multi-step Approach:<\/strong> For the most complex questions, the system looks at several sources. This builds a detailed and complete answer.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\" id=\"h-why-adaptive-rag-works-so-well\">Why Adaptive-RAG Works So Well?<\/h2>\n<p>Adaptive-RAG is flexible. It handles each question efficiently, using only the resources needed. This saves computing power and makes users happier because they get precise answers quickly.\u00a0 Adaptive-RAG also updates itself based on question complexity. Because it adapts, it reduces the chance of old or too-general answers. It gives current, specific and reliable answers.<\/p>\n<p><strong>Improving Accuracy<\/strong><\/p>\n<p>Adaptive-RAG is very accurate. It understands the complexity of each question and adapts. By matching the retrieval method to the question, Adaptive-RAG makes sure answers are relevant. It also uses the newest available information. This adaptability greatly reduces the chance of getting old or generic answers. Adaptive-RAG sets a new standard for accurate automated question answering.<\/p>\n<figure class=\"wp-block-image aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1407\" height=\"606\" src=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/image-105-1.webp\" alt=\"QA performance (F1) and efficiency (Time\/Query)&#10;for different retrieval-augmented generation approaches.\" class=\"wp-image-227606\" srcset=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/image-105-1.webp 1407w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/image-105-1-300x129.webp 300w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/image-105-1-768x331.webp 768w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/image-105-1-150x65.webp 150w\" sizes=\"(max-width: 1407px) 100vw, 1407px\"\/><figcaption class=\"wp-element-caption\">Source: <a href=\"https:\/\/arxiv.org\/pdf\/2403.14403.pdf\" target=\"_blank\" rel=\"nofollow noopener\">click here<\/a><\/figcaption><\/figure>\n<p>The image from the research paper compares different RAG approaches. Adaptive RAG excels in both speed and performance.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-what-is-adaptive-rag\">What is Adaptive RAG?<\/h2>\n<p><strong>Adaptive Retrieval-Augmented Generation (Adaptive RAG)<\/strong> is a RAG architecture designed to improve how large language models (LLMs) handle queries. It adjusts the strategy for answering questions based on their complexity.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-the-key-idea-of-adaptive-rag\">The Key Idea of Adaptive RAG<\/h3>\n<p>Adaptive RAG selects the best approach for answering a query, whether it\u2019s simple or complex. A classifier evaluates the query and decides whether to use a straightforward method, a single-step retrieval, or a multi-step process.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-comparison-with-other-approaches\">Comparison with other approaches<\/h3>\n<p>As shown in the above image, here\u2019s the comparison of adaptive RAG with a single-step, multi-step approach.<\/p>\n<h4 class=\"wp-block-heading\" id=\"h-1-single-step-approach\">1. Single-Step Approach<\/h4>\n<ol class=\"wp-block-list\"\/>\n<p>This method retrieves information in one go and pass it to the LLm to generate an answer directly. Although it works well for simple questions like \u201cWhat is Agentic RAG?\u201d, it struggles with complex queries. For instance \u201cWhat is the use of Agentic RAG in the healthcare sector?\u201d due to lack of reasoning on the retrieved information.<\/p>\n<h4 class=\"wp-block-heading\" id=\"h-2-multi-step-approach\">2. Multi-Step Approach<\/h4>\n<ol start=\"2\" class=\"wp-block-list\"\/>\n<p>This method processes all queries through multiple retrieval steps, refining answers iteratively. While effective for complex queries, it can waste resources on simple questions. For instance, repeatedly processing \u201cWhat is Agentic RAG?\u201d is inefficient.<\/p>\n<h4 class=\"wp-block-heading\" id=\"h-3-adaptive-approach\">3. Adaptive Approach<\/h4>\n<ol start=\"3\" class=\"wp-block-list\"\/>\n<p>A classifier determines the complexity of the query and selects the appropriate strategy:\u00a0<\/p>\n<ul class=\"wp-block-list\">\n<li>Straightforward Query: Generates an answer without retrieval (e.g., \u201cWhat is the capital of India?\u201d).\u00a0<\/li>\n<li>Simple Query: Uses a single-step retrieval.\u00a0<\/li>\n<li>Complex Query: Employs multi-step retrieval for detailed reasoning.\u00a0<\/li>\n<li>Advantages: This method reduces unnecessary processing for simple queries while ensuring accuracy for complex ones.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Adaptive RAG Framework<\/h2>\n<ul class=\"wp-block-list\">\n<li><strong>Classifier Role<\/strong>: A smaller language model predicts the complexity of the query. It learns from past outcomes and patterns in the data.\u00a0<\/li>\n<li><strong>Dynamic Strategy Selection<\/strong>: The framework conserves resources for simple queries and ensures thorough reasoning for complex ones.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">RAG System Architecture Flow from LangGraph<\/h2>\n<p>Here\u2019s another example of an adaptive RAG System architecture flow from LangGraph:<\/p>\n<p>Adaptive RAG System Architecture Flow:<\/p>\n<h3 class=\"wp-block-heading\">1. Query Analysis<\/h3>\n<p>The process begins with analyzing the user query to determine the most appropriate pathway for retrieving and generating the answer.<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>\u00a0Route Determination<\/strong>\n<ul class=\"wp-block-list\">\n<li>The query is classified into categories based on its relevance to the existing index (database or vector store).<\/li>\n<li><strong>Related to Index:<\/strong> If the query is aligned with the indexed content, it is routed to the RAG module for retrieval and generation.<\/li>\n<li><strong>Unrelated to Index:<\/strong> If the query is outside the scope of the index, it is routed for a <strong>web search<\/strong> or another external knowledge source.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Optional Routes:<\/strong> Additional pathways can be added for more specialized scenarios, such as domain-specific tools or external APIs.<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">2. RAG + Self-Reflection<\/h3>\n<p>If the query is routed through the <strong>RAG module<\/strong>, it undergoes an iterative, self-reflective process to ensure high-quality and accurate responses.<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Retrieve Node<\/strong>\n<ul class=\"wp-block-list\">\n<li>Retrieves documents from the indexed database based on the query.<\/li>\n<li>These documents are passed to the next stage for evaluation.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Grade Node<\/strong>\n<ul class=\"wp-block-list\">\n<li>Assesses the relevance of the retrieved documents.<\/li>\n<li>Decision Point:\n<ul class=\"wp-block-list\">\n<li>If documents are relevant: Proceed to generate an answer.<\/li>\n<li>If documents are irrelevant: The query is rewritten for better retrieval and the process loops back to the retrieve node.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong>Generate Node<\/strong>\n<ul class=\"wp-block-list\">\n<li>Generates a response based on the relevant documents.<\/li>\n<li>The generated response is evaluated further to ensure accuracy and relevance.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Self-Reflection Steps<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Does it answer the question?<\/strong>\n<ul class=\"wp-block-list\">\n<li>If yes: The process ends, and the answer is returned to the user.<\/li>\n<li>If no: The query undergoes another iteration, potentially with additional refinements.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Hallucinations Check<\/strong>\n<ul class=\"wp-block-list\">\n<li>If hallucinations are detected (inaccuracies or made-up facts): The query is rewritten, or additional retrieval is triggered for correction.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong>Re-write Question Node<\/strong>\n<ul class=\"wp-block-list\">\n<li>Refines the query for better retrieval results and loops it back into the process.<\/li>\n<li>This ensures that the model adapts dynamically to handle edge cases or incomplete data.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">3. Web Search for Unrelated Queries<\/h3>\n<p>If the query is deemed unrelated to the indexed knowledge base during the Query Analysis stage:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Generate Node with Web Search:<\/strong> The system directly performs a web search and uses the retrieved data to generate a response.<\/li>\n<li><strong>Answer with Web Search:<\/strong> The generated response is delivered directly to the user.<\/li>\n<\/ul>\n<p>In summary, Adaptive RAG is a smart framework that enhances response quality and efficiency by adapting to the complexity of queries. Now let\u2019s build a RAG application using the Adaptive-RAG strategy. Our application sends user questions to the best data source. Here\u2019s the setup:<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-implementation-steps\">Implementation Steps<\/h2>\n<p>Here\u2019s a breakdown of how we build the application using the LangGraph framework:<\/p>\n<ol class=\"wp-block-list\">\n<li><strong>Indexing Documents:<\/strong> We start by indexing documents with ChromaDB, a vector database in LangChain. This lets us quickly find relevant documents for a user\u2019s question.<\/li>\n<li><strong>Routing:<\/strong> The key part of our application is sending each question to the right place. This could be our web search or our internal vector database.<\/li>\n<li><strong>Retrieval Grader:<\/strong> We use a retrieval grader to check if the retrieved documents are relevant. It gives a simple \u201cyes\u201d or \u201cno\u201d score.<\/li>\n<li><strong>Generation:<\/strong> To create answers, we combine the prompt, the language model (LLM), and the data from the vector database or web search. This builds a clear and relevant response.<\/li>\n<li><strong>Hallucination Grader:<\/strong> To make sure the information is correct, a hallucination grader checks if the answer is based on facts. It also gives a \u201cyes\u201d or \u201cno\u201d score.<\/li>\n<li><strong>Answer Grader:<\/strong> An answer grader checks if the response fully answers the user\u2019s question.<\/li>\n<li><strong>Question Rewriter:<\/strong> This part improves the question. It rewrites the question to make it work better with the vector database.<\/li>\n<li><strong>Web Search:<\/strong> The system finds relevant information online with the paraphrased question.<\/li>\n<li><strong>Graph Representation using LangGraph:<\/strong> Finally, we use LangGraph to show how the application works. We define nodes and build a graph that shows the whole process.<\/li>\n<\/ol>\n<h2 class=\"wp-block-heading\" id=\"h-building-an-adaptive-rag-system-with-self-reflection\">Building an Adaptive RAG System with Self-Reflection<\/h2>\n<p>We will be implementing the Adaptive RAG System we have discussed so far using<a href=\"https:\/\/langchain-ai.github.io\/langgraph\/\" target=\"_blank\" rel=\"nofollow noopener\"> LangGraph<\/a>. We will be loading some of our blog contents using PyPDFLoader into our vector database, the<a href=\"https:\/\/www.trychroma.com\/\" target=\"_blank\" rel=\"nofollow noopener\"> ChromaDB<\/a> vector database. and also using the<a href=\"https:\/\/tavily.com\/#api\" target=\"_blank\" rel=\"nofollow noopener\"> Tavily Search tool<\/a> for web search. Connections to LLMs and prompting will be made with<a href=\"https:\/\/www.langchain.com\/\" target=\"_blank\" rel=\"nofollow noopener\"> LangChain<\/a>, and the agent will be built using LangGraph. For our LLM, we will be using<a href=\"https:\/\/openai.com\/index\/hello-gpt-4o\/\" target=\"_blank\" rel=\"nofollow noopener\"> ChatGPT GPT-4o<\/a>, which is a powerful LLM that has native support for tool calling. Although, we can use any other LLM, it is advisable to use LLM finetuned for tool calling.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-workflow-of-adaptive-rag\">Workflow of Adaptive RAG<\/h3>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"1119\" src=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG.webp\" alt=\"Workflow of Adaptive RAG\" class=\"wp-image-227514\" style=\"width:430px;height:auto\" srcset=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG.webp 839w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG-225x300.webp 225w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG-768x1024.webp 768w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG-640x853.webp 640w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-of-Adaptive-RAG-150x200.webp 150w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\"\/><figcaption class=\"wp-element-caption\">Source: Author<\/figcaption><\/figure>\n<\/div>\n<p>This image explains the workflow of the adaptive rag system.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-install-openai-chromadb-langgraph-and-langchain-dependencies\">Install OpenAI, ChromaDB, LangGraph and LangChain Dependencies<\/h3>\n<pre class=\"wp-block-code\"><code>!pip install -U langchain_community tiktoken langchain-openai langchainhub langchain_chroma langchain langgraph\u00a0 tavily-python pypdf<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-set-up-openai-and-tavily-api\">Set up OpenAI and Tavily API<\/h4>\n<pre class=\"wp-block-code\"><code>from getpass import getpass<p>OPENAI_KEY = getpass('Enter Open AI API Key: ')<\/p><p>TAVILY_API_KEY = getpass('Enter Tavily Search API Key: ')<\/p><\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-setting-up-environment-variables\">Setting up environment variables<\/h4>\n<pre class=\"wp-block-code\"><code>import os\nos.environ['OPENAI_API_KEY'] = OPENAI_KEY\nos.environ['TAVILY_API_KEY'] = TAVILY_API_KEY<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-set-up-openai-embeddings\">Set up OpenAI embeddings<\/h4>\n<pre class=\"wp-block-code\"><code>from langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain_community.document_loaders import WebBaseLoader\nfrom langchain_community.vectorstores import Chroma\nfrom langchain_openai import OpenAIEmbeddings\nopenai_embed_model = OpenAIEmbeddings(model=\"text-embedding-3-small\")<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-load-knowledge-base\">Load Knowledge Base<\/h4>\n<p>We have downloaded the blogs PDFs and made the pdfs documents available in a folder named \u201cpdf\u201d on Google Drive, you can download it from here.<\/p>\n<p><a href=\"https:\/\/drive.google.com\/drive\/folders\/1zp8TdYKde09z5jZ55xD6RRgdVa25KHul?usp=drive_link\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Google drive link.<\/a><\/p>\n<p>Now upload the \u201cpdf\u201d folder in the colab.<\/p>\n<p>After loading the pdfs, docs_list contains the documents loaded from the PDFs in the directory<\/p>\n<pre class=\"wp-block-code\"><code>from langchain_community.document_loaders import DirectoryLoader\nfrom langchain_community.document_loaders import PyPDFLoader\n\n\npdf_directory = \"\/content\/pdf\"\n\n\n# Create a DirectoryLoader with PyPDFLoader as the loader\nloader = DirectoryLoader(pdf_directory, glob=\"**\/*.pdf\", loader_cls=PyPDFLoader)\n\n\ndocs_list = loader.load()\n\n\n# Now, docs_list contains the documents loaded from the PDFs in the directory\nprint(f\"Loaded {len(docs_list)} documents.\")\n\n\n# Example: Print the first few pages of the first document (if it has pages)\nif docs_list:\n   first_doc = docs_list[0]\n   if hasattr(first_doc, 'page_content'):\n       print(first_doc.page_content[:500])  # Print the first 500 characters of the first page<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">Loaded 60 documents.\n\n5 Types of AI Agents that you Must Know About\n\nIntroduction\n\nWhat if machines could make their own decisions, solve problems, and adapt to new\n situations just like wedo? This would potentially lead to a world where artificial\n intelligence becomes not just a tool but acollaborator. That\u2019s exactly what AI\n agents aim to achieve! These smart systems are designed tounderstand their \nsurroundings, process information, and act independently to accomplish specific\n tasks.<\/pre>\n<p>Let\u2019s think about your daily life\u2014w<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-performing-the-chunking-using-recursivecharactertextsplitter\">Performing the Chunking using RecursiveCharacterTextSplitter<\/h3>\n<pre class=\"wp-block-code\"><code>splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=300)\nchunked_docs = splitter.split_documents(docs_list)\nchunked_docs[67].page_content<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-0\">Output<\/h4>\n<pre class=\"wp-block-preformatted\"># Instantiate tools docs_tool = <br\/>DirectoryReadTool(directory='\/home\/xy\/VS_Code\/Ques_Ans_Gen\/blog-posts')\\nfile_tool = <br\/>FileReadTool() search_tool = SerperDevTool() web_rag_tool = <br\/>WebsiteSearchTool()\\nExplanations\\ndocs_tool: Reads files from the specified <br\/>directory(\/home\/badrinarayan\/VS_Code\/Ques_Ans_Gen\/blog-posts). This could be used<br\/>for reading past blogposts to help in writing new ones.\\nfile_tool: Reads<br\/>individual files, which could come in handy for retrieving research materials or<br\/>drafts.\\nsearch_tool: Performs web searches using the Serper API to gather data on<br\/>market trends in AI.\\nweb_rag_tool: Searches for specific website content to assist<br\/>in research.\\n# Create agents researcher = Agent( role=\"Market Research Analyst\"<br\/>, goal=\"Provide 2024 market analysis of the\\nAI industry\", backstory='An expert<br\/>analyst with a keen eye for market trends.', tools=[search_tool,\\nweb_rag_tool], <br\/>verbose=True )\\nExplanations\\nResearcher: This agent conducts market research. It <br\/>uses the search_too<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-creating-a-vector-store-using-chroma\">Creating a Vector Store using Chroma<\/h3>\n<p>Storing vectors in Chroma DB using hnsw index for a better retrieval.<\/p>\n<pre class=\"wp-block-code\"><code>from langchain_chroma import Chroma\nchroma_db = Chroma.from_documents(documents=chunked_docs,\n                                 collection_name=\"rag_db\",\n                                 embedding=openai_embed_model,\n# need to set the distance function to cosine else it uses Euclidean by default\n# check https:\/\/docs.trychroma.com\/guides#changing-the-distance-function\n                                 collection_metadata={\"hnsw:space\": \"cosine\"},\n                                 persist_directory=\".\/rag_db\")<\/code><\/pre>\n<p>Here we set up a similarity_threshold_retriever that extracts the best chunks using a threshold value for similarity between user query and chunks.<\/p>\n<pre class=\"wp-block-code\"><code>similarity_threshold_retriever = chroma_db.as_retriever(search_type=\"similarity_score_threshold\",\n                      search_kwargs={\"k\": 3,\n                      \"score_threshold\": 0.3})<\/code><\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-lets-test-our-retriever-nbsp\">Lets Test our Retriever\u00a0<\/h3>\n<pre class=\"wp-block-code\"><code>query = \"what is AI agents?\"\ntop3_docs = similarity_threshold_retriever.invoke(query)\ntop3_docs<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-1\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">[Document(id='f808a58f-69b9-4442-86b4-fdf3247bdffa', metadata={'creationdate':\n '2025-03-06T11:05:04+00:00', 'creator': 'Chromium', 'moddate': '2025-03-\n06T11:05:04+00:00', 'page': 0, 'page_label': '1', 'producer': 'Skia\/PDF m83',\n 'source': '\/content\/pdf\/Understanding LangChain Agent Framework.pdf', \n'total_pages': 9}, page_content=\"AI Agent Terms\\nHere\u2019s the list of AI Agent\n terms:\\n1. AI Agent\\nAn AI agent is a type of digital assistant or robot that\n perceives its environment, processes it, and performsactions to accomplish\n particular goals. An example is a self-driving vehicle that has cameras and\n sensorsto drive on the road. It is an AI that is working to keep you safe in real\n time.\\n2. Autonomous Agent\\nAn autonomous agent is an AI that operates on its own\n and does not require human supervision. Anexample would be a package delivery drone \nthat decides on a specific route, avoids obstacles, and makesthe delivery without \nany help.\\nA I\u00a0 A G E N T S\\nA R T I F I C I A L\u00a0 I N T E L L I G E N C E\\nB E G I N\n N E R\"),\n\nDocument(id='eef333a4-e2b4-4876-924a-e02ab77052a9', metadata={'creationdate': '2025-\n03-06T11:05:04+00:00', 'creator': 'Chromium', 'moddate': '2025-03-\n06T11:05:04+00:00', 'page': 0, 'page_label': '1', 'producer': 'Skia\/PDF m83', \n'source': '\/content\/pdf\/Understanding LangChain Agent Framework.pdf', 'total_pages':\n 9}, page_content=\"AI Agent Terms\\nHere\u2019s the list of AI Agent terms:\\n1. AI\n Agent\\nAn AI agent is a type of digital assistant or robot that perceives its\n environment, processes it, and performsactions to accomplish particular goals. An\n example is a self-driving vehicle that has cameras and sensorsto drive on the road.\n It is an AI that is working to keep you safe in real time.\\n2. Autonomous Agent\\nAn\n autonomous agent is an AI that operates on its own and does not require human\n supervision. Anexample would be a package delivery drone that decides on a specific\n route, avoids obstacles, and makesthe delivery without any help.\\nA I\u00a0 A G E N T\n S\\nA R T I F I C I A L\u00a0 I N T E L L I G E N C E\\nB E G I N N E R\"),\n\n\nDocument(id='2a9a3be4-2a61-4bed-8e46-804f34dc624c', metadata={'creationdate': '2024-\n07-10T10:50:06+00:00', 'creator': 'Chromium', 'moddate': '2024-07-\n\n10T10:50:06+00:00', 'page': 1, 'page_label': '2', 'producer': 'Skia\/PDF m83',\n 'source': '\/content\/pdf\/Build a Customized AI Agent Without Code Using \nRelevance.ai.pdf', 'total_pages': 11}, page_content=\"Frequently Asked\n Questions\\nUnderstanding AI Agents\\nAI agents are self-governing creatures that\n employ sensors to keep an eye on their environment, processinformation, and \naccomplish predefined goals. They can be anything from basic bots to \nsophisticatedsystems that can adjust and learn over time. Typical instances include\n recommendation engines likeNetflix and Amazon\u2019s, chatbots like Siri and Alexa, and\n self-driving cars from Tesla and Waymo.\\nAlso essential in a number of sectors are these agents: UiPath and Blue Prism are examples of roboticprocess automation (RPA)\n programs that automate repetitive processes. DeepMind and IBM Watson Healthare \nexamples of healthcare diagnostics systems that help diagnose diseases and recommend\n treatments.In their domains, AI agents greatly improve productivity, precision, and\n customisation.\\nWhy AI Agents are Important?\\nThese agents play a critical role in\n improving our daily lives and accomplishing particular objectives.\\nAI agents are\n significant because they can:\\nlowering the amount of human labor required to \ncomplete routine operations, resulting in increasedproduction and\n efficiency.\\nanalyzing enormous volumes of data to offer conclusions and suggestions that support decision-making.\\nutilizing chatbots and virtual assistants\n to provide individualized interactions and assistance.\\nenabling complex \napplications in industries like as banking, transportation, and healthcare.\\nIn\n essence, AI agents are pivotal in driving the next wave of technological\n advancements, making systemssmarter and more responsive to user\n needs.\\nApplications and Use Cases of AI Agents\\nAI agents have a wide range of\n applications across various industries. Here are some notable use cases:\\nCustomer\n Service: AI agents in the form of chatbots and virtual assistants handle customer\n inquiries,resolve issues, and provide personalized support. They can operate 24\/7,\n offering consistent andefficient service.\")]<\/pre>\n<pre class=\"wp-block-code\"><code>query = \"what is the capital of USA?\"\ntop3_docs = similarity_threshold_retriever.invoke(query)\ntop3_docs<\/code><\/pre>\n<p>Let\u2019s now try a question that is out of context, such that no context documents related to the question are there in the vector database.<\/p>\n<h4 class=\"wp-block-heading\" id=\"h-output-2\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">[]<\/pre>\n<p>We can see that our RAG system is working well.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-creating-router\">Creating Router<\/h3>\n<p>It will route the user query based on the nature of the query to Web Search or Vector Store<\/p>\n<pre class=\"wp-block-code\"><code>from typing import Literal\nfrom langchain_core.prompts import ChatPromptTemplate\nfrom langchain_core.pydantic_v1 import BaseModel, Field\nfrom langchain_openai import ChatOpenAI\n\n\n# Data model\nclass RouteQuery(BaseModel):\n   \"\"\"Route a user query to the most relevant datasource.\"\"\"\n   datasource: Literal[\"vectorstore\", \"web_search\"] = Field(\n       description=\"Given a user question choose to route it to web search or a vectorstore.\",\n   )\n# LLM with function call\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\nstructured_llm_router = llm.with_structured_output(RouteQuery)\n# Prompt\nsystem = \"\"\"You are an expert at routing a user question to a vectorstore or web search.\nThe vectorstore contains documents related to AI agents, Agentic Patterns and Types of AI agents.\nUse the vectorstore for questions on these topics. Otherwise, use web-search.\"\"\"\nroute_prompt = ChatPromptTemplate.from_messages(\n   [\n       (\"system\", system),\n       (\"human\", \"{question}\"),\n   ]\n)\nquestion_router = route_prompt | structured_llm_router\nprint(question_router.invoke({\"question\": \"Who won the IPL 2024?\"}))\nprint(question_router.invoke({\"question\": \"What are the types of AI agents?\"}))<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-3\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">datasource=\"web_search\"<p>datasource=\"vectorstore\"<\/p><\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-retriever-grader\">Retriever Grader<\/h3>\n<p>It indicates whether the query is relevant to retrieved documents or not by simple \u201cyes\u201d or \u201cno\u201d output.<\/p>\n<pre class=\"wp-block-code\"><code># Data model\nclass GradeDocuments(BaseModel):\n   \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n\n\n   binary_score: str = Field(\n       description=\"Documents are relevant to the question, 'yes' or 'no'\"\n   )\n\n# LLM with function call\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(GradeDocuments)\n\n\n# Prompt\nsystem = \"\"\"You are a grader assessing the relevance of a retrieved document to a user question. \\n\n   If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\n   It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n   Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\ngrade_prompt = ChatPromptTemplate.from_messages(\n   [\n       (\"system\", system),\n       (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n   ]\n)\n\n\nretrieval_grader = grade_prompt | structured_llm_grader\nquestion = \"agentic patterns\"\ndocs = similarity_threshold_retriever.invoke(question)\ndoc_txt = docs[1].page_content\nprint(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt})<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-4\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">binary_score=\"yes\"<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-generation-node\">Generation Node<\/h3>\n<p>This piece of code is fetching rag prompt from Langchain hub and then generating answer using LLM<\/p>\n<pre class=\"wp-block-code\"><code>from langchain import hub\nfrom langchain_core.output_parsers import StrOutputParser\n\n\n# Prompt\nprompt = hub.pull(\"rlm\/rag-prompt\")\n\n\n# LLM\nllm = ChatOpenAI(model_name=\"gpt-4o\", temperature=0)\n\n# Post-processing\ndef format_docs(docs):\n   return \"\\n\\n\".join(doc.page_content for doc in docs)\n\n# Chain\nrag_chain = prompt | llm | StrOutputParser()\n\n# Run\ngeneration = rag_chain.invoke({\"context\": docs, \"question\": question})\nprint(generation)<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-5\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">Agentic patterns in AI design refer to strategies that enhance AI systems' autonomy<br\/>and effectiveness. The key agentic design patterns include the Reflection Pattern,<br\/>which focuses on self-evaluation and refinement of outputs, Tool Use, Planning, and<br\/>Multi-Agent Collaboration. These patterns enable AI models to perform complex tasks<br\/>by encouraging self-evaluation, tool integration, strategic thinking, and collaboration.<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-hallucination-grader\">Hallucination Grader<\/h3>\n<p>Here we are checking if the generated answer contains hallucination or not which is a self reflection step:<\/p>\n<pre class=\"wp-block-code\"><code># Data model\nclass GradeHallucinations(BaseModel):\n   \"\"\"Binary score for hallucination present in generated answer.\"\"\"\n\n\n   binary_score: str = Field(\n       description=\"Answer is grounded in the facts, 'yes' or 'no'\"\n   )\n\n# LLM with function call\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(GradeHallucinations)\n\n\n# Prompt\nsystem = \"\"\"You are a grader assessing whether an LLM generation is grounded in \/ supported by a set of retrieved facts. \\n\n    Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in \/ supported by the set of facts.\"\"\"\nhallucination_prompt = ChatPromptTemplate.from_messages(\n   [\n       (\"system\", system),\n       (\"human\", \"Set of facts: \\n\\n {documents} \\n\\n LLM generation: {generation}\"),\n   ]\n)\n\n\nhallucination_grader = hallucination_prompt | structured_llm_grader\nhallucination_grader.invoke({\"documents\": docs, \"generation\": generation})<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-6\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">GradeHallucinations(binary_score=\"yes\")<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-answer-grader\">Answer Grader<\/h3>\n<p>It denotes whether the provided answer is legit or not according to the question asked<\/p>\n<pre class=\"wp-block-code\"><code># Data model\nclass GradeAnswer(BaseModel):\n   \"\"\"Binary score to assess answer addresses question.\"\"\"\n\n\n   binary_score: str = Field(\n       description=\"Answer addresses the question, 'yes' or 'no'\"\n   )\n\n\n# LLM with function call\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(GradeAnswer)\n\n\n# Prompt\nsystem = \"\"\"You are a grader assessing whether an answer addresses \/ resolves a question \\n\n    Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.\"\"\"\nanswer_prompt = ChatPromptTemplate.from_messages(\n   [\n       (\"system\", system),\n       (\"human\", \"User question: \\n\\n {question} \\n\\n LLM generation: {generation}\"),\n   ]\n)\n\n\nanswer_grader = answer_prompt | structured_llm_grader\nanswer_grader.invoke({\"question\": question, \"generation\": generation})<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-7\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">GradeAnswer(binary_score=\"no\")<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-question-re-writer\">Question Re-Writer<\/h3>\n<p>It rewrites the question which contains more semantic information which is used if the answer grader tags the answer as not relevant.<\/p>\n<pre class=\"wp-block-code\"><code># LLM\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n\n\n# Prompt\nsystem = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n\n    for vectorstore retrieval. Look at the input and try to reason about the underlying semantic intent \/ meaning.\"\"\"\nre_write_prompt = ChatPromptTemplate.from_messages(\n   [\n       (\"system\", system),\n       (\n           \"human\",\n           \"Here is the initial question: \\n\\n {question} \\n Formulate an improved question.\",\n       ),\n   ]\n)\n\n\nquestion_rewriter = re_write_prompt | llm | StrOutputParser()\nquestion_rewriter.invoke({\"question\": question})<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-8\">Output<\/h4>\n<pre class=\"wp-block-preformatted\">\u2018What are agentic patterns and how do they influence behavior or decision-making?\u2019<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-defining-search-tool\">Defining Search Tool<\/h3>\n<p>Here Tavily search tool is defined which will be used to search the web<\/p>\n<pre class=\"wp-block-code\"><code>from langchain_community.tools.tavily_search import TavilySearchResults\n\nweb_search_tool = TavilySearchResults(k=3)<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-constructing-the-graph-using-langgraph\">Constructing the Graph using LangGraph<\/h4>\n<p>Capturing the flow in as a graph.<\/p>\n<h4 class=\"wp-block-heading\" id=\"h-defining-the-graphstate\">Defining the GraphState<\/h4>\n<ul class=\"wp-block-list\">\n<li><strong>question: <\/strong>query of the user<\/li>\n<li><strong>generation:<\/strong> LLM generated answer<\/li>\n<li><strong>documents:<\/strong> list of retrieved documents<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>from typing import List\nfrom typing_extensions import TypedDict\n\nclass GraphState(TypedDict):\n   \"\"\"\n   Represents the state of our graph.\n\n\n   Attributes:\n       question: question\n       generation: LLM generation\n       documents: list of documents\n   \"\"\"\n\n\n   question: str\n   generation: str\n   documents: List[str]<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-creating-functions-for-the-graphs-node\">Creating functions for the graphs node.<\/h4>\n<ul class=\"wp-block-list\">\n<li>retrieve: Adds the retrieved documents to the graph state<\/li>\n<li>generate: Adds the generated answer to the graph state<\/li>\n<li>grade_documents: It updates the document key with only relevant documents<\/li>\n<li>transform_query: Rephrases the query which capture more semantic meaning<\/li>\n<li>web_search: It searches the web for the updated answer and updates the document key accordingly<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>from langchain.schema import Document\ndef retrieve(state):\n   \"\"\"\n   Retrieve documents\n   Args:\n       state (dict): The current graph state\n\n\n   Returns:\n       state (dict): New key added to state, documents, that contains retrieved documents\n   \"\"\"\n   print(\"---RETRIEVE---\")\n   question = state[\"question\"]\n\n\n   # Retrieval\n   documents = similarity_threshold_retriever.invoke(question)\n   return {\"documents\": documents, \"question\": question}\n\n\ndef generate(state):\n   \"\"\"\n   Generate answer\n\n\n   Args:\n       state (dict): The current graph state\n\n   Returns:\n       state (dict): New key added to state, generation, that contains LLM generation\n   \"\"\"\n   print(\"---GENERATE---\")\n   question = state[\"question\"]\n   documents = state[\"documents\"]\n\n\n   # RAG generation\n   generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n   return {\"documents\": documents, \"question\": question, \"generation\": generation}\n\ndef grade_documents(state):\n   \"\"\"\n   Determines whether the retrieved documents are relevant to the question.\n\n\n   Args:\n       state (dict): The current graph state\n\n\n   Returns:\n       state (dict): Updates documents key with only filtered relevant documents\n   \"\"\"\n\n\n   print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n   question = state[\"question\"]\n   documents = state[\"documents\"]\n\n\n   # Score each doc\n   filtered_docs = []\n   for d in documents:\n       score = retrieval_grader.invoke(\n           {\"question\": question, \"document\": d.page_content}\n       )\n       grade = score.binary_score\n       if grade == \"yes\":\n           print(\"---GRADE: DOCUMENT RELEVANT---\")\n           filtered_docs.append(d)\n       else:\n           print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n           continue\n   return {\"documents\": filtered_docs, \"question\": question}\n\ndef transform_query(state):\n   \"\"\"\n   Transform the query to produce a better question.\n\n\n   Args:\n       state (dict): The current graph state\n\n   Returns:\n       state (dict): Updates question key with a re-phrased question\n   \"\"\"\n\n\n   print(\"---TRANSFORM QUERY---\")\n   question = state[\"question\"]\n   documents = state[\"documents\"]\n\n\n   # Re-write question\n   better_question = question_rewriter.invoke({\"question\": question})\n   return {\"documents\": documents, \"question\": better_question}\n\n\ndef web_search(state):\n   \"\"\"\n   Web search based on the re-phrased question.\n\n   Args:\n       state (dict): The current graph state\n\n\n   Returns:\n       state (dict): Updates documents key with appended web results\n   \"\"\"\n   print(\"---WEB SEARCH---\")\n   question = state[\"question\"]\n\n   # Web search\n   docs = web_search_tool.invoke({\"query\": question})\n   web_results = \"\\n\".join([d[\"content\"] for d in docs])\n   web_results = Document(page_content=web_results)\n\n\n   return {\"documents\": web_results, \"question\": question}<\/code><\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-creating-edges-functions\">Creating Edges Functions<\/h3>\n<ul class=\"wp-block-list\">\n<li>route_question: It directs the question to RAG or web search<\/li>\n<li>decide_to_generate: It denotes whether to generate the answer or rephrase it<\/li>\n<li>grade_generation_v_documents_and_question: It determines whether the generated answer is relevant to the question<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>\ndef route_question(state):\n   \"\"\"\n   Route question to web search or RAG.\n\n\n   Args:\n       state (dict): The current graph state\n\n\n   Returns:\n       str: Next node to call\n   \"\"\"\n\n\n   print(\"---ROUTE QUESTION---\")\n   question = state[\"question\"]\n   source = question_router.invoke({\"question\": question})\n   if source.datasource == \"web_search\":\n       print(\"---ROUTE QUESTION TO WEB SEARCH---\")\n       return \"web_search\"\n   elif source.datasource == \"vectorstore\":\n       print(\"---ROUTE QUESTION TO RAG---\")\n       return \"vectorstore\"\n\n\ndef decide_to_generate(state):\n   \"\"\"\n   Determines whether to generate an answer, or re-generate a question.\n\n   Args:\n       state (dict): The current graph state\n\n   Returns:\n       str: Binary decision for next node to call\n   \"\"\"\n\n\n   print(\"---ASSESS GRADED DOCUMENTS---\")\n   state[\"question\"]\n   filtered_documents = state[\"documents\"]\n\n\n   if not filtered_documents:\n       # All documents have been filtered check_relevance\n       # We will re-generate a new query\n       print(\n           \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n       )\n       return \"transform_query\"\n   else:\n       # We have relevant documents, so generate answer\n       print(\"---DECISION: GENERATE---\")\n       return \"generate\"\n\n\ndef grade_generation_v_documents_and_question(state):\n   \"\"\"\n   Determines whether the generation is grounded in the document and answers question.\n\n\n   Args:\n       state (dict): The current graph state\n\n\n   Returns:\n       str: Decision for next node to call\n   \"\"\"\n\n\n   print(\"---CHECK HALLUCINATIONS---\")\n   question = state[\"question\"]\n   documents = state[\"documents\"]\n   generation = state[\"generation\"]\n\n\n   score = hallucination_grader.invoke(\n       {\"documents\": documents, \"generation\": generation}\n   )\n   grade = score.binary_score\n\n\n   # Check hallucination\n   if grade == \"yes\":\n       print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n       # Check question-answering\n       print(\"---GRADE GENERATION vs QUESTION---\")\n       score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n       grade = score.binary_score\n       if grade == \"yes\":\n           print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n           return \"useful\"\n       else:\n           print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n           return \"not useful\"\n   else:\n       pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n       return \"not supported\"\n<\/code><\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-defining-the-graph-architecture\">Defining the Graph Architecture<\/h3>\n<p>We will look into the workflow Flow Description below:<\/p>\n<p>Initial Routing:<\/p>\n<ul class=\"wp-block-list\">\n<li>The workflow begins at the START node.<\/li>\n<li>The route_question function determines whether to proceed with a web_search or a retrieve operation based on the incoming question.<\/li>\n<\/ul>\n<p>Data Acquisition and Processing:<\/p>\n<ul class=\"wp-block-list\">\n<li>If web_search is chosen, the system performs a web search and then moves to the generate node.<\/li>\n<li>If retrieve is chosen, the system retrieves relevant documents from a vector store, which are then passed to the grade_documents node.<\/li>\n<li>The grade_documents node then determines if the flow should go to transform_query or to generate.<\/li>\n<li>If the flow goes to transform_query, then the query is transformed, and sent to the retrieve node.<\/li>\n<\/ul>\n<p>Content Generation and Evaluation:<\/p>\n<ul class=\"wp-block-list\">\n<li>The generate node creates a response based on the information gathered.<\/li>\n<li>The grade_generation_v_documents_and_question function assesses the generated content.<\/li>\n<\/ul>\n<p>Decision and Termination:<\/p>\n<ul class=\"wp-block-list\">\n<li>If the generated content is deemed useful, the workflow reaches the END node, concluding the process.<\/li>\n<li>If the generated content is deemed not useful, the workflow goes to transform_query node.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>from langgraph.graph import END, StateGraph, START\n\n\nworkflow = StateGraph(GraphState)\n\n\n# Define the nodes\nworkflow.add_node(\"web_search\", web_search)  # web search\nworkflow.add_node(\"retrieve\", retrieve)  # retrieve\nworkflow.add_node(\"grade_documents\", grade_documents)  # grade documents\nworkflow.add_node(\"generate\", generate)  # generatae\nworkflow.add_node(\"transform_query\", transform_query)  # transform_query\n\n\n# Build graph\nworkflow.add_conditional_edges(\n   START,\n   route_question,\n   {\n       \"web_search\": \"web_search\",\n       \"vectorstore\": \"retrieve\",\n   },\n)\nworkflow.add_edge(\"web_search\", \"generate\")\nworkflow.add_edge(\"retrieve\", \"grade_documents\")\nworkflow.add_conditional_edges(\n   \"grade_documents\",\n   decide_to_generate,\n   {\n       \"transform_query\": \"transform_query\",\n       \"generate\": \"generate\",\n   },\n)\nworkflow.add_edge(\"transform_query\", \"retrieve\")\nworkflow.add_conditional_edges(\n   \"generate\",\n   grade_generation_v_documents_and_question,\n   {\n       # \"not supported\": \"generate\",\n       \"useful\": END,\n       \"not useful\": \"transform_query\",\n   },\n)\n\n\n# Compile\napp = workflow.compile()<\/code><\/pre>\n<h4 class=\"wp-block-heading\">Workflow Graph<\/h4>\n<p>Printing the workflow graph using draw_mermaid\u00a0:<\/p>\n<pre class=\"wp-block-code\"><code>from IPython.display import Image, display, Markdown\ndisplay(Image(app.get_graph().draw_mermaid_png()))<\/code><\/pre>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"485\" height=\"570\" src=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-Graph.webp\" alt=\"Workflow Graph\" class=\"wp-image-227530\" style=\"width:376px;height:auto\" srcset=\"https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-Graph.webp 485w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-Graph-255x300.webp 255w, https:\/\/cdn.analyticsvidhya.com\/wp-content\/uploads\/2025\/03\/Workflow-Graph-150x176.webp 150w\" sizes=\"auto, (max-width: 485px) 100vw, 485px\"\/><\/figure>\n<\/div>\n<p>This image depicts the workflow of Adaptive RAG<\/p>\n<h3 class=\"wp-block-heading\">Testing the Agent<\/h3>\n<pre class=\"wp-block-code\"><code>from pprint import pprint\n\n\n# Run\ninputs = {\n   \"question\": \"What are the types of Agentic Patterns?\"\n}\nfor output in app.stream(inputs):\n   for key, value in output.items():\n       # Node\n       pprint(f\"Node '{key}':\")\n       # Optional: print full state at each node\n       # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n   pprint(\"\\n---\\n\")\n\n\n# Final generation\npprint(value[\"generation\"])<\/code><\/pre>\n<h4 class=\"wp-block-heading\" id=\"h-output-9\">Output<\/h4>\n<pre class=\"wp-block-code\"><code>---ROUTE QUESTION---\n---ROUTE QUESTION TO RAG---\n---RETRIEVE---\n\"Node 'retrieve':\"\n'\\n---\\n'\n---CHECK DOCUMENT RELEVANCE TO QUESTION---\n---GRADE: DOCUMENT RELEVANT---\n---GRADE: DOCUMENT RELEVANT---\n---GRADE: DOCUMENT RELEVANT---\n---ASSESS GRADED DOCUMENTS---\n---DECISION: GENERATE---\n\"Node 'grade_documents':\"\n'\\n---\\n'\n---GENERATE---\n---CHECK HALLUCINATIONS---\n---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\n---GRADE GENERATION vs QUESTION---\n---DECISION: GENERATION ADDRESSES QUESTION---\n\"Node 'generate':\"\n'\\n---\\n'\n('The types of Agentic Patterns are Reflection, Tool Use, Planning, and '\n 'Multi-Agent Collaboration.')<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>from pprint import pprint\n\n\n# Run\ninputs = {\n   \"question\": \"What player at the IPL 2024 hit maximum sixes?\"\n}\nfor output in app.stream(inputs):\n   for key, value in output.items():\n       # Node\n       pprint(f\"Node '{key}':\")\n       # Optional: print full state at each node\n       # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n   pprint(\"\\n---\\n\")\n\n\n# Final generation\npprint(value[\"generation\"])<\/code><\/pre>\n<p>Output:<\/p>\n<pre class=\"wp-block-code\"><code>---ROUTE QUESTION---\n---ROUTE QUESTION TO WEB SEARCH---\n---WEB SEARCH---\n\"Node 'web_search':\"\n'\\n---\\n'\n---GENERATE---\n---CHECK HALLUCINATIONS---\n---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\n---GRADE GENERATION vs QUESTION---\n---DECISION: GENERATION ADDRESSES QUESTION---\n\"Node 'generate':\"\n'\\n---\\n'\n('Abhishek Sharma from Sunrisers Hyderabad hit the maximum sixes in IPL 2024, '\n 'with a total of 42 sixes.')<\/code><\/pre>\n<p>Hence, we can see that our Adaptive RAG is working very well utilizing its self reflection capabilities to reason about the relevancy of output generated by LLM, Also utilizing the web search tool when retrieved documents are not that good.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n<p>Adaptive RAG Systems with LangGraph is an important advancement in creating intelligent question-answering systems. It selects the best retrieval method based on how complex a question is, which helps improve both speed and accuracy. This method overcomes the limitations found in traditional language models and basic retrieval-augmented generation systems. It provides users with relevant, current, and trustworthy information.<\/p>\n<p>The examples and code resources available show how to implement Adaptive RAG Systems with LangGraph. This makes it easier to develop more effective and user-friendly AI applications. As AI technology progresses, methods like Adaptive RAG will be essential for building systems that can understand and respond to human questions more effectively.<\/p>\n<div class=\"border-top py-3 author-info my-4\">\n<div class=\"author-card d-flex align-items-center\">\n<div class=\"flex-shrink-0 overflow-hidden\">\n                                    <a href=\"https:\/\/www.analyticsvidhya.com\/blog\/author\/harsh9480979\/\" class=\"text-decoration-none active-avatar\"><br \/>\n                                                                       <img decoding=\"async\" src=\"https:\/\/av-eks-lekhak.s3.amazonaws.com\/media\/lekhak-profile-images\/converted_image_0fBqNLi.webp\" width=\"48\" height=\"48\" alt=\"Harsh Mishra\" loading=\"lazy\" class=\"rounded-circle\"\/><\/p>\n<p>                                <\/a>\n                                <\/div>\n<\/p><\/div>\n<p>Harsh Mishra is an AI\/ML Engineer who spends more time talking to Large Language Models than actual humans. Passionate about GenAI, NLP, and making machines smarter (so they don\u2019t replace him just yet). When not optimizing models, he\u2019s probably optimizing his coffee intake. \ud83d\ude80\u2615<\/p>\n<\/p><\/div>\n<\/p><\/div>\n<p><h4 class=\"fs-24 text-dark\">Login to continue reading and enjoy expert-curated content.<\/h4>\n<p>                        <button class=\"btn btn-primary mx-auto d-table\" data-bs-toggle=\"modal\" data-bs-target=\"#loginModal\" id=\"readMoreBtn\">Keep Reading for Free<\/button>\n                    <\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Large language models answer questions using the knowledge they learned during training. This fixed knowledge base limits them. They can\u2019t give you current or highly specific information. Retrieval-Augmented Generation (RAG) helps by letting LLMs pull in external data, but even RAG needs help with complex questions. Adaptive RAG offers a solution. It picks the best [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":150314,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[17108,2059,31128,32726,11355],"dealstore":[],"offerexpiration":[],"class_list":["post-150313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-adaptive","tag-guide","tag-langgraph","tag-rag","tag-systems"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Guide to Adaptive RAG Systems with LangGraph - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=150313\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Guide to Adaptive RAG Systems with LangGraph - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"Large language models answer questions using the knowledge they learned during training. This fixed knowledge base limits them. They can\u2019t give you current or highly specific information. Retrieval-Augmented Generation (RAG) helps by letting LLMs pull in external data, but even RAG needs help with complex questions. Adaptive RAG offers a solution. It picks the best [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=150313\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-22T19:51:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"872\" \/>\n\t<meta property=\"og:image:height\" content=\"473\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"26 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=150313#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Guide to Adaptive RAG Systems with LangGraph\",\"datePublished\":\"2025-03-22T19:51:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313\"},\"wordCount\":2249,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp\",\"keywords\":[\"Adaptive\",\"Guide\",\"LangGraph\",\"RAG\",\"Systems\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=150313#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=150313\",\"url\":\"https:\/\/fivemor.com\/?p=150313\",\"name\":\"Guide to Adaptive RAG Systems with LangGraph - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp\",\"datePublished\":\"2025-03-22T19:51:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=150313#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=150313\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=150313#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp\",\"width\":872,\"height\":473},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=150313#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Guide to Adaptive RAG Systems with LangGraph\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Guide to Adaptive RAG Systems with LangGraph - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=150313","og_locale":"en_US","og_type":"article","og_title":"Guide to Adaptive RAG Systems with LangGraph - Som2ny Network","og_description":"Large language models answer questions using the knowledge they learned during training. This fixed knowledge base limits them. They can\u2019t give you current or highly specific information. Retrieval-Augmented Generation (RAG) helps by letting LLMs pull in external data, but even RAG needs help with complex questions. Adaptive RAG offers a solution. It picks the best [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=150313","og_site_name":"Som2ny Network","article_published_time":"2025-03-22T19:51:53+00:00","og_image":[{"width":872,"height":473,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp","type":"image\/webp"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"26 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=150313#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=150313"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Guide to Adaptive RAG Systems with LangGraph","datePublished":"2025-03-22T19:51:53+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=150313"},"wordCount":2249,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=150313#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp","keywords":["Adaptive","Guide","LangGraph","RAG","Systems"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=150313#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=150313","url":"https:\/\/fivemor.com\/?p=150313","name":"Guide to Adaptive RAG Systems with LangGraph - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=150313#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=150313#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp","datePublished":"2025-03-22T19:51:53+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=150313#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=150313"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=150313#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/A-Comprehensive-Guide-to-Adaptive-RAG-Systems-with-LangGraph-and-Coding-Hands-on-.webp.webp","width":872,"height":473},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=150313#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Guide to Adaptive RAG Systems with LangGraph"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/150313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=150313"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/150313\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/150314"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=150313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=150313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=150313"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=150313"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=150313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}