Skip to content

Repository files navigation

🤖 Agentic AI Learning

Building Practical AI Agents, RAG Pipelines & Multi-Agent Workflows

Live Demo — TripMate AI   Deployed on Netlify

🌐 Try the deployed app: https://tripmates-ai.netlify.app/

Python LangChain LangGraph FastAPI Groq MCP Docker License

A hands-on learning repository documenting my journey through Agentic AI — from foundational state management and graph-based workflows to a fully deployed multi-agent travel planning system with a Supervisor, MCP integrations, Guardrails, and Human-in-the-Loop approval.


📚 Table of Contents


🌟 Overview

This repository is a structured, implementation-first learning journey through Agentic AI engineering. Every file here represents a concept learned and then immediately built — not just read about.

The progression moves from understanding how LangGraph state works, through increasingly complex graph topologies (sequential, parallel, conditional, iterative), all the way to a production-style multi-agent system that orchestrates five specialist AI agents, integrates three external MCP servers, enforces input guardrails, and requires human approval before finalizing a travel plan.

The goal is simple: learn by building real things, understand why each pattern exists, and develop the intuition to design agentic systems from scratch.


🎯 What This Repository Covers

Agent & Graph Fundamentals

  • State definition using TypedDict, Pydantic, dataclasses, and MessagesState
  • Graph nodes, edges, and the START/END lifecycle
  • Sequential execution pipelines
  • Parallel branch execution with custom reducers
  • Conditional routing based on state
  • Iterative loops with tool calling and exit conditions

RAG (Retrieval-Augmented Generation)

  • PDF document loading and chunking
  • HuggingFace sentence-transformer embeddings
  • FAISS vector store retrieval
  • Query classification and conditional RAG routing
  • Context-aware response generation

Advanced Agent Patterns

  • Human-in-the-Loop with interrupt() and Command(resume=...)
  • In-memory checkpointing with MemorySaver
  • Persistent checkpointing with PostgreSQL
  • Multi-agent orchestration with a Supervisor
  • Input guardrails using LLM-based validation
  • MCP (Model Context Protocol) server and client integration
  • Dynamic agent selection based on query intent

🚀 Projects & Implementations

🧠 State Management

File: states.py

Explores the four main approaches to defining state in LangGraph:

  1. TypedDict — the most common approach, simple key-value state
  2. Pydantic BaseModel — adds runtime type validation and field validators
  3. Python dataclass — standard dataclass with default factories
  4. MessagesState — LangGraph's built-in state that includes the add_messages reducer, extended with custom fields
from langgraph.graph import MessagesState

class State(MessagesState):
    user_name: str
    language: str

This file is the conceptual foundation for everything else in the repository.


➡️ Sequential Workflow

File: sequential_base.py

A three-stage content pipeline that demonstrates how to chain nodes in a strict linear order.

What it does: Takes raw text input → cleans grammar and tone (Editor) → transforms it into a YouTube-style video script (Scriptwriter) → converts the script into natural Hinglish for the Indian market (Translator).

Graph topology:

START → editor → scriptwriter → translator → END

Key concepts demonstrated:

  • Defining a pipeline state with typed fields
  • Writing focused single-responsibility nodes
  • Connecting nodes with add_edge for strict sequential execution
  • Using llama-3.3-70b-versatile via Groq for each stage

⚡ Parallel Reducers

File: parallel_reducers.py

A content safety analyzer that runs three independent analysis branches simultaneously and merges their results into a single state field using a custom reducer.

What it does: Takes a text sample and simultaneously scores it for:

  • Toxicity and hate speech
  • Copyright and originality risk
  • Regional and cultural sensitivity

Graph topology:

START → toxicity_node  ─┐
START → copyright_check ─┼→ END
START → culture_node   ─┘

Key concept — custom reducer:

def merge_score_dicts(existing: dict, new_update: dict) -> dict:
    if existing is None:
        return new_update
    return {**existing, **new_update}

class AnalyzerState(TypedDict):
    raw_text: str
    safety_scores: Annotated[dict[str, int], merge_score_dicts]

Each parallel branch writes to the same safety_scores key. The reducer merges all three sub-dictionaries into one without overwriting.


🔁 Iterative Tool Workflow

File: iterative_tools.py

A LinkedIn post generator that loops between a writer agent and a reviewer agent until the post is approved or the maximum attempt limit is reached.

What it does:

  1. Writer drafts a LinkedIn post (optionally using Tavily web search for fresh data)
  2. Reviewer scores the draft against strict criteria
  3. If rejected, the writer rewrites with the feedback
  4. Loop continues until approved or 3 attempts are exhausted

Graph topology:

START → writer → [tools if needed] → extract_draft → reviewer
                                                         ↓
                                              approved? → END
                                              rejected? → writer (loop)

Key concepts demonstrated:

  • Conditional edges for tool-call detection (should_use_tool)
  • Conditional edges for loop control (should_stop_looping)
  • ToolNode for automatic tool execution
  • bind_tools to give the LLM access to Tavily search
  • Two different LLMs in one graph: GPT-4o-mini (writer) + LLaMA 3.3 (reviewer)

👤 Human-in-the-Loop

File: humanintheloop.py

The same LinkedIn post generator as iterative_tools.py, but the automated reviewer is replaced by a real human. The graph pauses mid-execution and waits for human input before continuing.

What it does:

  1. Writer drafts a LinkedIn post
  2. Graph pauses and presents the draft to the human
  3. Human types approved or provides revision feedback
  4. Graph resumes from the exact pause point
  5. If feedback was given, writer rewrites; if approved, workflow ends

Key concepts demonstrated:

  • interrupt() to pause graph execution and surface data to the caller
  • Command(resume=...) to inject human input and resume
  • MemorySaver checkpointer to persist state across the pause
  • Thread-based session management with configurable: {thread_id: ...}
human_response = interrupt({
    "draft": state["draft"],
    "instruction": "Type 'approved' to accept, or type your feedback."
})

🔀 Conditional RAG

File: conditional_RAG.py

A college student assistant that classifies each query and routes it to the appropriate knowledge source before generating a response.

What it does: A student asks a question. The system classifies it as academic, fee, or general, then:

  • academic → retrieves from academics_handbook.pdf via FAISS
  • fee → retrieves from fee_structure.pdf via FAISS
  • general → answers directly from the LLM without retrieval

Graph topology:

START → classifier → route_query()
                         ↓
              academic_rag / fee_rag / general
                         ↓
                      response → END

RAG pipeline:

  • PDF loading with PyPDFLoader
  • Chunking with RecursiveCharacterTextSplitter (800 chars, 100 overlap)
  • Embeddings: sentence-transformers/all-MiniLM-L6-v2 via HuggingFace
  • Vector store: FAISS (top-4 retrieval)
  • LLM: llama-3.3-70b-versatile via Groq

🎓 College Assistant UI

File: app.py

A Streamlit web application wrapping the same conditional RAG graph from conditional_RAG.py with a proper chat interface.

Features:

  • Programme selection sidebar (BCA, BBA, B.Com H)
  • Persistent multi-turn chat history
  • Query-type badges (ACADEMIC / FEE / GENERAL) on each response
  • Cached resource loading so the vector stores are built only once
  • Clear chat button

Run it:

streamlit run app.py

✈️ TripMate AI — Multi-Agent Travel Planner

Directory: Multi-Agent-System-using-LangGraph-MCP-Supervisor-Guardrails-HITL-main/

The most complete project in this repository. TripMate AI is a full-stack multi-agent travel planning application built with FastAPI, LangGraph, and three MCP server integrations.

What it does: A user describes a trip in natural language. The system validates the request, dynamically selects the right specialist agents, gathers live flight/hotel/weather/budget data, drafts an itinerary, pauses for human review, and then generates a polished final travel plan.

Agent Architecture

User Request (HTTP POST /api/travel)
        ↓
  Supervisor Agent
  ├── Input Guardrail (LLM-based validation)
  ├── Agent selection (dynamic, based on query)
  └── Trip constraint extraction
        ↓
  [Selected Specialist Agents — run in order]
  ├── Flight Agent   → AviationStack MCP (airports, airlines)
  ├── Hotel Agent    → Tavily MCP (live web search)
  ├── Weather Agent  → Custom Weather MCP (OpenWeatherMap)
  └── Budget Agent   → LLM analysis of all gathered data
        ↓
  Itinerary Agent (synthesizes all results into a draft)
        ↓
  Human Approval (graph pauses — HITL via interrupt())
  ├── Approved → Final Agent polishes and returns plan
  └── Rejected → Final Agent applies feedback and revises
        ↓
  Final Response (HTTP POST /api/travel/approve)

Specialist Agents

Agent Data Source Responsibility
flight_agent AviationStack MCP (list_airports, list_airlines) Airports, airlines, routes, airfare estimates
hotel_agent Tavily MCP (tavily_search) Live hotel and accommodation search
weather_agent Custom Weather MCP (get_current_weather, get_forecast) Current weather + 5-entry forecast
budget_agent LLM synthesis of all above Cost categories, risk areas, money-saving tips
itinerary_agent All specialist results Draft day-by-day travel plan

MCP Servers

Three MCP servers are connected via langchain-mcp-adapters:

  • Tavily MCPstreamable_http transport to mcp.tavily.com
  • AviationStack MCPstdio transport via uvx aviationstack-mcp
  • Custom Weather MCPstdio transport, runs custom_weather_mcp_server.py as a subprocess using OpenWeatherMap API

Guardrail

The Supervisor runs an LLM-based input guardrail before any agent is invoked. It returns a JSON verdict (allowed: true/false) and blocks requests unrelated to travel planning. On parser failure, it fails open to preserve the travel workflow.

Persistence

State is persisted across the HITL pause using PostgreSQL via langgraph-checkpoint-postgres. Each conversation is identified by a thread_id, allowing the /api/travel/approve endpoint to resume the exact paused graph state.

Frontend

A vanilla HTML/CSS/JavaScript single-page app served by FastAPI via Jinja2 templates:

  • Travel request input with quick-prompt buttons
  • Supervisor workflow panel showing selected agents and guardrail status
  • Draft itinerary display with Markdown rendering
  • Human approval panel with feedback textarea
  • Copy to clipboard and PDF download (html2pdf.js)

📊 Concept Matrix

Concept Implementation Key Technology What It Demonstrates
State Definition states.py TypedDict, Pydantic, MessagesState Four approaches to LangGraph state
Sequential Workflow sequential_base.py LangGraph, Groq Linear node chaining, pipeline design
Parallel Execution parallel_reducers.py LangGraph, Annotated reducers Fan-out branches, state merging
Iterative Loop iterative_tools.py LangGraph, ToolNode, Tavily Conditional loops, tool calling, multi-LLM
Human-in-the-Loop humanintheloop.py interrupt(), MemorySaver Graph pause/resume, human feedback injection
Conditional RAG conditional_RAG.py FAISS, HuggingFace, LangGraph Query routing, PDF retrieval, context-aware generation
RAG Web UI app.py Streamlit, LangGraph Wrapping a graph in a chat interface
Supervisor Pattern backend.py LangGraph, Groq Dynamic agent selection, guardrails
MCP Integration mcp_client.py MCP, langchain-mcp-adapters Multi-server MCP client, tool invocation
Custom MCP Server custom_weather_mcp_server.py FastMCP, OpenWeatherMap Building and exposing MCP tools
PostgreSQL Checkpointing backend.py langgraph-checkpoint-postgres Persistent state across HTTP requests
Full-Stack Agent App TripMate AI FastAPI, LangGraph, HTML/JS End-to-end agentic application

🏗️ Architecture

Core LangGraph Workflow Pattern

flowchart TD
    A[User Input] --> B[State Initialization]
    B --> C[Graph Entry Node]
    C --> D{Conditional Router}
    D -->|Path A| E[Node A]
    D -->|Path B| F[Node B]
    D -->|Path C| G[Node C]
    E --> H[Merge / Next Node]
    F --> H
    G --> H
    H --> I{Loop or End?}
    I -->|Loop| C
    I -->|End| J[Final Output]
Loading

TripMate AI Multi-Agent Flow

flowchart TD
    U[User Travel Request] --> S[Supervisor Agent]
    S --> GR{Guardrail Check}
    GR -->|Blocked| GB[Guardrail Blocked Response]
    GR -->|Allowed| AG[Dynamic Agent Selection]
    AG --> FA[Flight Agent - AviationStack MCP]
    AG --> HA[Hotel Agent - Tavily MCP]
    AG --> WA[Weather Agent - Custom MCP]
    FA --> BA[Budget Agent]
    HA --> BA
    WA --> BA
    BA --> IA[Itinerary Agent - Draft]
    IA --> HI[Human Approval - interrupt]
    HI -->|Approved| FIN[Final Agent - Polish]
    HI -->|Rejected + Feedback| FIN
    FIN --> R[Final Travel Plan]
Loading

Conditional RAG Flow

flowchart TD
    Q[Student Query] --> CL[Classifier Node]
    CL --> RT{Route Query}
    RT -->|academic| AR[Academic RAG - FAISS]
    RT -->|fee| FR[Fee RAG - FAISS]
    RT -->|general| GN[General Node - No Retrieval]
    AR --> RS[Response Node]
    FR --> RS
    GN --> RS
    RS --> ANS[Answer]
Loading

🛠️ Technology Stack

AI / Agent Framework

  • LangGraph 1.2.2 — graph-based agent orchestration, state management, HITL
  • LangChain 1.3.2 — LLM abstraction, document loaders, text splitters
  • langchain-groq 1.1.3 — Groq LLM integration
  • langchain-mcp-adapters 0.3.0 — MCP server connections
  • MCP 1.28.1 — Model Context Protocol, FastMCP server

LLMs

  • LLaMA 3.3 70B Versatile (via Groq) — primary LLM across all projects
  • GPT-4o-mini (via OpenAI) — writer LLM in iterative and HITL workflows

RAG / Embeddings

  • sentence-transformersall-MiniLM-L6-v2 embeddings
  • FAISS (faiss-cpu) — local vector store
  • PyPDF — PDF document loading
  • langchain-text-splitters — recursive character chunking

Backend

  • FastAPI 0.136.3 — REST API for TripMate AI
  • Uvicorn 0.48.0 — ASGI server
  • Jinja2 3.1.6 — HTML templating
  • psycopg 3.3.4 — PostgreSQL driver
  • langgraph-checkpoint-postgres 3.1.0 — persistent graph checkpointing

Frontend (TripMate AI)

  • Vanilla HTML, CSS, JavaScript
  • marked.js — Markdown rendering
  • html2pdf.js — PDF export

External APIs

  • Groq API — LLM inference
  • Tavily API — web search (via MCP and direct)
  • AviationStack API — airport and airline data (via MCP)
  • OpenWeatherMap API — current weather and forecast (via custom MCP server)

Infrastructure

  • Docker — containerized deployment for TripMate AI
  • PostgreSQL — persistent checkpoint storage
  • Streamlit — web UI for College Assistant

📁 Project Structure

Agentic-AI-Learning/
│
├── states.py                    # LangGraph state definition patterns
├── sequential_base.py           # Sequential 3-stage content pipeline
├── parallel_reducers.py         # Parallel content safety analyzer
├── iterative_tools.py           # Iterative LinkedIn post generator (auto-review)
├── humanintheloop.py            # LinkedIn post generator with human review
├── conditional_RAG.py           # Conditional RAG college assistant (CLI)
├── app.py                       # Streamlit UI for the college assistant
│
├── academics_handbook.pdf       # RAG knowledge source — academic rules
├── fee_structure.pdf            # RAG knowledge source — fee information
│
├── requirements.txt             # Root-level Python dependencies
│
└── Multi-Agent-System-using-LangGraph-MCP-Supervisor-Guardrails-HITL-main/
    │
    ├── app.py                   # FastAPI application, API endpoints
    ├── backend.py               # LangGraph multi-agent graph, all agent logic
    ├── mcp_client.py            # MCP client — Tavily, AviationStack, Weather
    ├── custom_weather_mcp_server.py  # Custom FastMCP weather server
    │
    ├── templates/
    │   └── index.html           # Single-page frontend UI
    ├── static/
    │   ├── script.js            # Frontend logic, API calls, approval flow
    │   └── style.css            # UI styling
    │
    ├── requirements.txt         # TripMate-specific dependencies
    ├── Dockerfile               # Docker image for TripMate AI
    ├── .dockerignore
    └── .gitignore

⚡ Getting Started

Prerequisites

  • Python 3.10 or higher
  • Git
  • A Groq API key (free tier available at console.groq.com)
  • For iterative_tools.py and humanintheloop.py: an OpenAI API key
  • For conditional_RAG.py and app.py: no external API keys (uses local FAISS + HuggingFace)
  • For TripMate AI: Groq, Tavily, AviationStack, OpenWeatherMap API keys + a PostgreSQL database URL
  • For TripMate AI MCP AviationStack: uv installed (pip install uv)
  • Docker (optional, for containerized TripMate deployment)

Installation

git clone https://github.com/SadiqCodex/Agentic-AI-Learning.git
cd Agentic-AI-Learning

Create and activate a virtual environment:

Windows:

python -m venv .venv
.venv\Scripts\activate

Linux / macOS:

python -m venv .venv
source .venv/bin/activate

Install root dependencies:

pip install -r requirements.txt

For TripMate AI, install its own dependencies:

cd Multi-Agent-System-using-LangGraph-MCP-Supervisor-Guardrails-HITL-main
pip install -r requirements.txt

⚙️ Configuration

Root-level projects (.env in repo root)

GROQ_API_KEY=your_groq_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
TAVILY_API_KEY=your_tavily_api_key_here

OPENAI_API_KEY is required only for iterative_tools.py and humanintheloop.py. TAVILY_API_KEY is required only for iterative_tools.py. GROQ_API_KEY is required for all other root-level scripts.

TripMate AI (.env inside the TripMate directory)

GROQ_API_KEY=your_groq_api_key_here
TAVILY_API_KEY=your_tavily_api_key_here
AVIATION_STACK_API_KEY=your_aviationstack_api_key_here
OPENWEATHER_API_KEY=your_openweathermap_api_key_here
DATABASE_URL=postgresql://user:password@host:port/dbname

DATABASE_URL must point to a PostgreSQL instance. The checkpointer will create its own tables automatically on first run.


▶️ Running the Projects

State Management (reference file)

python states.py

Sequential Workflow

python sequential_base.py

Parallel Reducers

python parallel_reducers.py

Iterative Tool Workflow

python iterative_tools.py

Human-in-the-Loop

python humanintheloop.py

Conditional RAG (CLI)

python conditional_RAG.py

College Assistant (Streamlit UI)

streamlit run app.py

TripMate AI (FastAPI)

From inside the TripMate directory:

cd Multi-Agent-System-using-LangGraph-MCP-Supervisor-Guardrails-HITL-main
python app.py

Or with uvicorn directly:

uvicorn app:app --reload --host 127.0.0.1 --port 8000

Then open http://127.0.0.1:8000 in your browser.

TripMate AI (Docker)

cd Multi-Agent-System-using-LangGraph-MCP-Supervisor-Guardrails-HITL-main
docker build -t tripmate-ai .
docker run -p 8000:8000 --env-file .env tripmate-ai

🔌 API Reference — TripMate AI

POST /api/travel

Start a new travel planning session.

Request:

{
  "message": "Plan a 7-day Japan trip from Dhaka under 2 lakhs",
  "thread_id": null
}

Response (requires approval):

{
  "success": true,
  "thread_id": "user_abc123",
  "answer": "...",
  "requires_approval": true,
  "approval_request": "Please review the draft itinerary...",
  "itinerary": "...",
  "flight_results": "...",
  "hotel_results": "...",
  "weather_results": "...",
  "budget_results": "...",
  "selected_agents": ["flight_agent", "hotel_agent", "weather_agent", "budget_agent", "itinerary_agent"],
  "supervisor_reasoning": "...",
  "guardrail_allowed": true
}

POST /api/travel/approve

Resume the paused graph after human review.

Request:

{
  "thread_id": "user_abc123",
  "approved": true,
  "feedback": ""
}

Request (revision):

{
  "thread_id": "user_abc123",
  "approved": false,
  "feedback": "Reduce hotel costs and add one free day for exploration"
}

Response:

{
  "success": true,
  "thread_id": "user_abc123",
  "answer": "Final polished travel plan...",
  "requires_approval": false,
  "approved": true
}

GET /health

{
  "status": "ok",
  "message": "TripMate AI API is running",
  "features": ["supervisor_agent", "input_guardrail", "human_in_the_loop"]
}

🧭 Learning Journey

State Management (TypedDict, Pydantic, MessagesState)
        ↓
Sequential Graph Workflows (nodes + edges)
        ↓
Parallel Execution with Custom Reducers
        ↓
Iterative Loops with Tool Calling
        ↓
Human-in-the-Loop (interrupt / resume)
        ↓
Conditional RAG (query routing + FAISS retrieval)
        ↓
Streamlit UI wrapping a LangGraph agent
        ↓
Multi-Agent Supervisor Architecture
        ↓
MCP Integration (client + custom server)
        ↓
Input Guardrails
        ↓
PostgreSQL Persistent Checkpointing
        ↓
Full-Stack Agentic Application (FastAPI + LangGraph + MCP)

Each step builds directly on the previous one. The repository evolves as new concepts are learned and implemented.


💡 Key Learnings

  • State is everything in LangGraph. Choosing the right state shape — and the right reducer — determines how complex your graph can become.
  • Reducers enable parallelism. Without a custom reducer, parallel branches would overwrite each other's results. The Annotated[dict, merge_score_dicts] pattern solves this cleanly.
  • interrupt() is not an exception. It is a first-class LangGraph primitive that serializes state, pauses execution, and waits for external input — enabling real human-in-the-loop workflows over HTTP.
  • Conditional routing makes graphs intelligent. A classifier node that sets a query_type field, combined with a router function, turns a static pipeline into a dynamic decision-making system.
  • MCP decouples tools from agents. Instead of hardcoding tool logic inside agents, MCP servers expose tools over a standard protocol. The agent just calls the tool by name.
  • The Supervisor pattern scales multi-agent systems. A single supervisor that reads the user query, selects agents, and extracts constraints means adding a new specialist agent requires no changes to the routing logic.
  • Guardrails belong at the entry point. Validating input before any agent runs prevents wasted LLM calls and keeps the system focused on its intended domain.
  • PostgreSQL checkpointing enables stateful HTTP APIs. Without it, the HITL pause would be lost between the /api/travel and /api/travel/approve requests.

🗺️ Future Roadmap

  • State management patterns
  • Sequential workflows
  • Parallel execution with reducers
  • Iterative loops with tool calling
  • Human-in-the-loop
  • Conditional RAG
  • Multi-agent supervisor architecture
  • MCP server and client integration
  • Input guardrails
  • PostgreSQL persistent checkpointing
  • Full-stack agentic application
  • Hybrid search (dense + sparse retrieval)
  • Reranking retrieved documents
  • Long-term agent memory
  • Agent evaluation and tracing (LangSmith)
  • Multi-modal agents (image + text)
  • Agent-to-agent communication
  • Rate limiting and authentication for deployed agents
  • Automated test coverage for agent workflows

🧪 Testing

Automated test coverage is currently being expanded as part of the learning process. To experiment with any implementation, run the scripts directly or interact with the web UIs as described in the Running the Projects section.


🔐 Security

  • Never commit .env files or API keys to version control — both .gitignore files in this repository exclude them
  • Use environment variables or a .env file for all secrets
  • The TripMate guardrail validates user input before any agent or external API is invoked
  • Validate and sanitize any user-provided input before passing it to external services
  • Protect your DATABASE_URL — it contains credentials for your PostgreSQL instance
  • MCP server subprocesses inherit only the environment variables they need

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-concept
  3. Implement your changes
  4. Verify the implementation runs correctly
  5. Open a pull request with a clear description

New learning implementations are welcome. Each new concept should include a clear explanation of what it demonstrates, either in the code comments or in an update to this README.


📄 License

This project is licensed under the MIT License. See the LICENSE file for details.


👨‍💻 Author

Sadik Mohammad

GitHub: @SadiqCodex


⭐ Support

If this repository helped you understand Agentic AI concepts, consider giving it a star. It helps others find it and motivates continued learning and documentation.


🌐 Live Demo

Live Demo — TripMate AI

TripMate AI is live on Netlify — try the full multi-agent travel planner here:
https://tripmates-ai.netlify.app/


This repository is actively maintained and grows as new Agentic AI concepts are explored and implemented.

About

AI-powered Retrieval-Augmented Generation (RAG) engine for intelligent document understanding and natural-language database querying using FastAPI, LangChain, Ollama, PostgreSQL, and FAISS.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages