This repository is a record of my learning journey with LangChain, RAG, advanced RAG, and LangGraph.
The project is not just a code dump. It shows how I moved from simple LLM calls to embeddings, vector search, retrieval pipelines, tool usage, structured outputs, and graph-based orchestration.
The repo is split into three main parts:
- Root files: LangChain experiments, RAG pipelines, embeddings, prompt templates, tools, models, and vector store work
langgraph/: graph workflows, persistence, time travel, subgraphs, memory, and advanced RAG notebooks- assets/data: PDFs, text files, screenshots, and vector store folders used during experiments
This project includes work on:
- LLM model setup with OpenAI Azure and Hugging Face
- Prompt templates and message handling
- Embeddings and similarity search
- PDF loading and document extraction
- Text splitting and chunking
- Vector stores with Chroma
- Retriever strategies
- Contextual compression and multi-query retrieval
- Tool creation and tool calling
- Basic LangGraph workflows
- Conditional routing and branching
- Parallel execution
- Persistence and memory
- Time travel / state inspection
- Subgraphs
- Basic RAG and advanced RAG techniques like CRAG and Self-RAG
Current project documentation and learning overview.
Lists the main packages used in the project, including:
langchain-corelangchain-communitylangchain-huggingfacelanggraphchromadbpypdfbs4transformerstorch
Runs a Hugging Face chat model using Qwen/Qwen2.5-1.5B-Instruct through ChatHuggingFace and HuggingFacePipeline.
Creates the Hugging Face pipeline-backed chat model used by other scripts.
Uses Azure OpenAI with ChatOpenAI and a prompt template to test Azure-hosted chat completion.
Shows basic prompt template usage and message setup.
Demonstrates embeddings and similarity scoring with HuggingFaceEmbeddings and NumPy dot-product matching.
Loads PDF documents using PyPDFLoader and DirectoryLoader for document ingestion experiments.
Experiments with RecursiveCharacterTextSplitter on the resume PDF for chunking text into smaller pieces.
Creates and queries a Chroma vector store from embedded PDF chunks.
Uses retriever strategies such as:
as_retriever()- MMR search
- MultiQueryRetriever
- ContextualCompressionRetriever
LLMChainFilter
This is one of the main files for the RAG and advanced retrieval work.
Defines custom tools using @tool and StructuredTool for arithmetic operations.
Demonstrates tool calling with an LLM, including binding tools, invoking them, reading tool calls, and combining tool outputs with the model response.
Plain text data used in experimentation.
Resume PDFs used as the source document for PDF loading, splitting, embeddings, retrieval, and RAG testing.
Reference screenshot saved in the project.
Persisted Chroma vector store folders used during retrieval experiments.
Environment file for keys and local configuration.
Project and environment support folders.
I started by connecting to different model backends:
- Azure OpenAI chat models
- Hugging Face pipelines
This helped me understand how to switch between providers and how model configuration works.
I learned how to:
- Build prompt templates
- Pass variables into prompts
- Use messages for chat-style workflows
- Think about outputs in a structured way
I explored embeddings using HuggingFaceEmbeddings to understand how text is converted into vectors and how semantic similarity works.
I loaded PDFs and experimented with extracting content from documents so that unstructured files could become searchable knowledge sources.
I used text splitters to break large documents into smaller chunks for retrieval and vector indexing.
I stored embedded chunks in Chroma so the project could perform semantic search over document content.
I tested retrievers and learned how retrieval improves LLM answers by fetching relevant context before generation.
I expanded retrieval with:
- MMR to improve diversity
- MultiQueryRetriever to generate multiple search angles
- ContextualCompressionRetriever to reduce noise
- LLMChainFilter to keep only the most relevant results
This is where the project moves beyond basic RAG into advanced RAG.
I learned how to define tools, bind them to an LLM, inspect tool calls, and execute them.
The langgraph/ folder contains the workflow and memory side of the project.
sequentical_workflow.py— basic step-by-step graph executionparallel_workflow.py— branching into multiple nodes in parallelcondition_workflow.py— conditional routing based on state valuespersistance.py— graph persistence and checkpointing with memorytime_travelling.py— inspecting and resuming prior graph statesfault_tolerance.py— recovery and safer workflow behavior
notebook.ipynb— general LangGraph experimentationtools.ipynb— tool usage inside LangGraphRAG.ipynb— basic LangGraph + retrieval/RAG flowiterative_workflow.ipynb— repeated/looping graph executionsubgraph.ipynb— subgraph-based designsubgraph_type2.ipynb— alternate subgraph implementationcondition_jupiter.ipynb— conditional graph notebookpersistance.ipynb— persistence notebook versiontime_travelling.ipynb— time-travel and checkpoint explorationfault_tolerance.ipynb— fault-tolerance experiments
memory/short_term.ipynb— short-term memory handlingmemory/long_term.ipynb— long-term memory conceptsmemory/longterm_example.ipynb— long-term memory example workflow
advance_rag/CRAG.ipynb— Corrective RAG (CRAG)advance_rag/SelfRAG.ipynb— Self-RAGadvance_rag/correctiveRAG.png— visual reference for CRAGadvance_rag/SELF-RAG.png— Self-RAG reference imageadvance_rag/SELF-RAG-GRAPH.png— graph diagram for Self-RAGadvance_rag/data.txt— supporting data for the advanced RAG notebooksadvance_rag/vectorStore/— vector store used in advanced RAG work
From the LangGraph part of the project, I learned:
- How to define graph state with
TypedDict - How nodes pass and update state
- How
STARTandENDcontrol execution - How conditional edges work
- How to build parallel execution paths
- How to checkpoint and resume workflows
- How to inspect state history
- How to handle time-travel style debugging
- How subgraphs help structure larger systems
- How memory changes graph behavior over multiple turns
The project includes more than basic retrieval. It also touches advanced retrieval design such as:
- CRAG: correcting or refining retrieval before generation
- Self-RAG: the model evaluates or improves its own retrieval behavior
- Retriever compression
- Query expansion
- Relevance filtering
- Better context selection
- Vector-store backed search over document collections
These files show that the project is not only about loading documents, but about improving retrieval quality and answer quality.
By building this project, I learned:
- How LLM apps are assembled from smaller pieces
- How embeddings and vector databases support semantic search
- How RAG pipelines are built and improved
- How advanced retrieval techniques make answers more reliable
- How tools extend model capabilities
- How LangGraph adds workflow control, memory, and branching
- How to think in terms of systems instead of single prompts
This project reflects my progress from:
- Basic model testing
- Prompt engineering
- Embeddings and retrieval
- Basic RAG
- Advanced RAG
- Tools and function calling
- LangGraph orchestration
- Persistence, memory, and time travel
It shows practical experimentation and a real understanding of how modern LLM applications are built.
Possible next steps:
- Add a diagram for each LangGraph workflow
- Turn the scripts into cleaner modules
- Add README notes for each notebook
- Add tests for retriever and tool logic
- Create one end-to-end assistant that combines RAG, tools, and LangGraph
- Clean up duplicate or temporary vector store folders
This repository is my personal AI learning lab.
It contains:
- LangChain experiments
- RAG and advanced RAG implementations
- Tool calling examples
- Hugging Face and Azure model setup
- LangGraph workflows
- Memory, persistence, and branching examples
The project shows the full journey from simple prompts to advanced retrieval and graph-based AI systems.