Four self-contained Jupyter notebooks, each implementing a different way of making a Retrieval-Augmented Generation (RAG) pipeline "agentic" — able to decide, check itself, correct its own mistakes, or defer to a person, instead of blindly retrieving once and answering.
| Notebook | Pattern | What makes it agentic |
|---|---|---|
1_Agentic_RAG.ipynb (free demo) | Agentic RAG | An LLM agent decides whether to retrieve at all, and which of two knowledge bases to search, using tool calling. |
2_Corrective_RAG.ipynb | Corrective RAG (CRAG) | Always retrieves first, then grades what it got — and automatically falls back to a live web search if the local documents aren't good enough. |
3_Adaptive_RAG.ipynb | Adaptive RAG | Routes each question to a vectorstore or the web before retrieving, then grades both the documents and the final answer (hallucination + relevance checks) before returning it. |
4_Human_in_the_Loop_RAG.ipynb | Human-in-the-Loop RAG | Takes the same retrieve/grade/generate machinery and replaces the automatic loop-decisions with a person: the graph pauses after retrieval and after generation, shows the LLM's grades as advisory suggestions only, and waits for a human to approve, request a revision, or send it back. |
Each notebook is fully commented with markdown cells explaining what every step does and why — you don't need to already know LangGraph to follow along.
This is the free demo notebook (
1_Agentic_RAG.ipynb). The full series — including Corrective RAG, Adaptive RAG, and Human-in-the-Loop RAG — is available here: Agentic RAG — Four Working Patterns with LangGraph
They sit on a spectrum of how much a RAG pipeline second-guesses itself — and who gets the final say:
interrupt / Command(resume=...) pattern with a MemorySaver checkpointer.Understanding all four, and where each one is worth the extra complexity, is more useful than knowing just one.
pip + venv with one tool and one lockfile.Pick whichever matches your setup — you only need one of these.
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Already have Python + pip and prefer not to run an install script:
pip install uv
Other options (Homebrew, pipx, winget, cargo, standalone downloads) are listed
in the official install docs.
Check it worked:
uv --version
From the project folder:
# Creates a .venv and installs every dependency from pyproject.toml,
# pinned exactly via uv.lock, in one step.
uv sync
# Register the environment as a Jupyter kernel.
uv run python -m ipykernel install --user --name agentic-rag
Copy the env template and add your API keys:
macOS / Linux:
cp .env.example .env
Windows (Command Prompt):
copy .env.example .env
Windows (PowerShell):
Copy-Item .env.example .env
Open .env and fill in GROQ_API_KEY and TAVILY_API_KEY.
File > Open Folder...)..ipynb files..venv (Python 3.11) —
pick the one whose path points at this project's .venv).That's the whole setup — no manually creating a virtualenv, no separate pip install -r requirements.txt step, and uv.lock means everyone who runs uv sync gets the exact
same dependency versions you tested with.
Kernel is selected per notebook, not per project. VS Code remembers a separate kernel choice for each
.ipynbfile, so it's easy to open a second notebook and have it silently fall back to your global Python install instead of this project's.venv— especially if the.venvkernel hasn't been used in that notebook before. If one notebook runs fine but another throws import errors for packages this project clearly installs (e.g.chromadb,langchain_chroma), that's the first thing to check: open the kernel picker for the failing notebook and confirm the path points into this project's.venv, notAppData\Local\Programs\Python\...or any other system/global install.
1_Agentic_RAG.ipynb scrapes the LangGraph and LangChain documentation into two
separate Chroma vector stores, wraps each as a retriever tool, and gives both tools to a
tool-calling agent. The agent decides per question whether to call a tool, which one,
and whether the retrieved documents are good enough to answer from or need a rewritten
query.
2_Corrective_RAG.ipynb indexes a small set of blog posts on AI agents into one
vector store. Every question always retrieves from it; a grading step then checks each
retrieved chunk for relevance. If nothing relevant comes back, the question is rewritten
for web search and Tavily fills the gap before the answer is generated.
3_Adaptive_RAG.ipynb builds on the same idea but adds a router at the very start
(should this question go to the vectorstore or straight to the web?) and two more graders
at the very end, checking that the generated answer is actually grounded in the
retrieved documents and actually answers the question — looping back to retry if either
check fails.
4_Human_in_the_Loop_RAG.ipynb takes the retrieve/grade/generate/self-check
machinery from the Adaptive RAG notebook and puts a person in charge of the two
decisions that used to be automatic:
Mechanically, this runs on LangGraph's current recommended HITL pattern: interrupt(payload)
called inside a node pauses the graph and surfaces payload to whoever is running it;
resuming happens with graph.stream(Command(resume=...), config), and a MemorySaver
checkpointer persists the graph's state while it's paused. All branching still goes
through plain add_conditional_edges rather than Command(goto=...), so every routing
decision lives in one place. This notebook only needs GROQ_API_KEY — it doesn't call
Tavily.
sentence-transformers (BAAI/bge-m3) — no embedding API
key needed.chroma/ is gitignored).1_Agentic_RAG.ipynb is a free demo — use it, share it, redistribute it. The other
three notebooks are a paid, personal-use resource — see LICENSE.md. In short: use
them, learn from them, build on them, but don't resell or redistribute the notebooks
themselves.
Get the full bundle here: Agentic RAG — Four Working Patterns with LangGraph
17 commits
Jupyter Notebook
100.0%
Four self-contained Jupyter notebooks, each implementing a different way of making a Retrieval-Augmented Generation (RAG) pipeline "agentic" — able to decide, check itself, correct its own mistakes, or defer to a person, instead of blindly retrieving once and answering.
| Notebook | Pattern | What makes it agentic |
|---|---|---|
1_Agentic_RAG.ipynb (free demo) | Agentic RAG | An LLM agent decides whether to retrieve at all, and which of two knowledge bases to search, using tool calling. |
2_Corrective_RAG.ipynb | Corrective RAG (CRAG) | Always retrieves first, then grades what it got — and automatically falls back to a live web search if the local documents aren't good enough. |
3_Adaptive_RAG.ipynb | Adaptive RAG | Routes each question to a vectorstore or the web before retrieving, then grades both the documents and the final answer (hallucination + relevance checks) before returning it. |
4_Human_in_the_Loop_RAG.ipynb | Human-in-the-Loop RAG | Takes the same retrieve/grade/generate machinery and replaces the automatic loop-decisions with a person: the graph pauses after retrieval and after generation, shows the LLM's grades as advisory suggestions only, and waits for a human to approve, request a revision, or send it back. |
Each notebook is fully commented with markdown cells explaining what every step does and why — you don't need to already know LangGraph to follow along.
This is the free demo notebook (
1_Agentic_RAG.ipynb). The full series — including Corrective RAG, Adaptive RAG, and Human-in-the-Loop RAG — is available here: Agentic RAG — Four Working Patterns with LangGraph
They sit on a spectrum of how much a RAG pipeline second-guesses itself — and who gets the final say:
interrupt / Command(resume=...) pattern with a MemorySaver checkpointer.Understanding all four, and where each one is worth the extra complexity, is more useful than knowing just one.
pip + venv with one tool and one lockfile.Pick whichever matches your setup — you only need one of these.
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Already have Python + pip and prefer not to run an install script:
pip install uv
Other options (Homebrew, pipx, winget, cargo, standalone downloads) are listed
in the official install docs.
Check it worked:
uv --version
From the project folder:
# Creates a .venv and installs every dependency from pyproject.toml,
# pinned exactly via uv.lock, in one step.
uv sync
# Register the environment as a Jupyter kernel.
uv run python -m ipykernel install --user --name agentic-rag
Copy the env template and add your API keys:
macOS / Linux:
cp .env.example .env
Windows (Command Prompt):
copy .env.example .env
Windows (PowerShell):
Copy-Item .env.example .env
Open .env and fill in GROQ_API_KEY and TAVILY_API_KEY.
File > Open Folder...)..ipynb files..venv (Python 3.11) —
pick the one whose path points at this project's .venv).That's the whole setup — no manually creating a virtualenv, no separate pip install -r requirements.txt step, and uv.lock means everyone who runs uv sync gets the exact
same dependency versions you tested with.
Kernel is selected per notebook, not per project. VS Code remembers a separate kernel choice for each
.ipynbfile, so it's easy to open a second notebook and have it silently fall back to your global Python install instead of this project's.venv— especially if the.venvkernel hasn't been used in that notebook before. If one notebook runs fine but another throws import errors for packages this project clearly installs (e.g.chromadb,langchain_chroma), that's the first thing to check: open the kernel picker for the failing notebook and confirm the path points into this project's.venv, notAppData\Local\Programs\Python\...or any other system/global install.
1_Agentic_RAG.ipynb scrapes the LangGraph and LangChain documentation into two
separate Chroma vector stores, wraps each as a retriever tool, and gives both tools to a
tool-calling agent. The agent decides per question whether to call a tool, which one,
and whether the retrieved documents are good enough to answer from or need a rewritten
query.
2_Corrective_RAG.ipynb indexes a small set of blog posts on AI agents into one
vector store. Every question always retrieves from it; a grading step then checks each
retrieved chunk for relevance. If nothing relevant comes back, the question is rewritten
for web search and Tavily fills the gap before the answer is generated.
3_Adaptive_RAG.ipynb builds on the same idea but adds a router at the very start
(should this question go to the vectorstore or straight to the web?) and two more graders
at the very end, checking that the generated answer is actually grounded in the
retrieved documents and actually answers the question — looping back to retry if either
check fails.
4_Human_in_the_Loop_RAG.ipynb takes the retrieve/grade/generate/self-check
machinery from the Adaptive RAG notebook and puts a person in charge of the two
decisions that used to be automatic:
Mechanically, this runs on LangGraph's current recommended HITL pattern: interrupt(payload)
called inside a node pauses the graph and surfaces payload to whoever is running it;
resuming happens with graph.stream(Command(resume=...), config), and a MemorySaver
checkpointer persists the graph's state while it's paused. All branching still goes
through plain add_conditional_edges rather than Command(goto=...), so every routing
decision lives in one place. This notebook only needs GROQ_API_KEY — it doesn't call
Tavily.
sentence-transformers (BAAI/bge-m3) — no embedding API
key needed.chroma/ is gitignored).1_Agentic_RAG.ipynb is a free demo — use it, share it, redistribute it. The other
three notebooks are a paid, personal-use resource — see LICENSE.md. In short: use
them, learn from them, build on them, but don't resell or redistribute the notebooks
themselves.
Get the full bundle here: Agentic RAG — Four Working Patterns with LangGraph
17 commits
Jupyter Notebook
100.0%