A modular, multi-mode agentic AI system built on LangGraph — capable of pure conversation, real-time web search, and autonomous AI news intelligence.
Most AI chatbot demos are stateless wrappers around a single LLM call. This project is different.
LangGraph Agentic AI Chatbot is a graph-native, stateful AI system that routes user intent across three distinct execution pipelines — a lightweight conversational agent, a ReAct-style tool-using agent with live web search, and a fully autonomous multi-node AI news pipeline that fetches, summarizes, and persists intelligence reports.
Built on LangGraph's first-class StateGraph abstraction, the system demonstrates production-grade patterns: conditional edge routing, prebuilt tool nodes, state-passing across agent hops, and a clean separation between graph construction logic and UI.
This is not a chatbot. It's a graph-orchestrated agentic runtime with a chatbot interface.
| Feature | Description |
|---|---|
| 🗺️ Graph-Native Architecture | Every use case is a compiled StateGraph — not a chain, not a simple prompt loop |
| 🔀 Dynamic Mode Switching | Three fully independent graph topologies selectable at runtime via Streamlit UI |
| 🛠️ ReAct Tool Loop | The tool-use agent autonomously decides when to invoke Tavily web search and loops back until the task is complete |
| 📰 Autonomous News Pipeline | A sequential 3-node graph independently fetches AI news, summarizes it with an LLM, and saves the result — zero human in the loop |
| ⚡ Groq-Accelerated Inference | Powered by Groq's ultra-low-latency LPU inference for near-instant LLM responses |
| 🧩 Modular Node Design | Each node (BasicChatbotNode, ChatbotWithToolNode, AINewsNode) is an isolated, testable Python class |
| 🔌 Multi-LLM Ready | Architecture supports both langchain_groq and langchain_openai — swap models without changing graph logic |
| 🗃️ FAISS Vector Store Ready | faiss-cpu included for RAG extensions and semantic search augmentation |
All nodes in this system communicate through a shared State object — the single source of truth for the entire graph execution. Built on LangChain's MessagesState pattern, it carries the full conversation history as a list of BaseMessage objects, enabling every node to read prior context and append new messages atomically.
# src/langgraphAgenticAI/state/state.py
from langgraph.graph import MessagesState
class State(MessagesState):
# Inherits: messages: Annotated[list[BaseMessage], add_messages]
# Add custom fields here as the graph grows:
# summary: str
# retrieved_docs: list[str]
passThe add_messages reducer ensures messages are appended, not overwritten, on each graph step — preserving full multi-turn history across all nodes automatically.
The GraphBuilder class acts as the factory for all graph topologies. It wires nodes, edges, and conditional routing in three distinct configurations:
A minimal two-edge graph. START → chatbot → END. The BasicChatbotNode processes the current state's messages and returns a new AI message. No tool calls, no loops. Ideal for pure LLM conversation.
The core agentic pattern. The chatbot node is bound with tools; if the LLM decides a tool call is needed, the prebuilt tools_condition router fires, redirecting execution to the ToolNode. The tool result is appended to state and control returns to the chatbot — creating a self-correcting reasoning loop that terminates only when the LLM returns a final answer.
A linear 3-node DAG with no human interaction. The graph autonomously: fetches live AI news → passes results to an LLM summarizer → writes the final report to disk. This pattern demonstrates LangGraph as an agentic batch processor, not just a chatbot engine.
graph TD
A([▶ START]) --> B[🗨️ chatbot\nBasicChatbotNode.process]
B --> C([⏹ END])
style A fill:#2d6a4f,color:#fff,stroke:none
style C fill:#c1121f,color:#fff,stroke:none
style B fill:#1d3557,color:#fff,stroke:#457b9d,stroke-width:2px
graph TD
A([▶ START]) --> B
B[🧠 chatbot\nChatbotWithToolNode\nLLM + bound tools]
B -->|tools_condition router| D{🔀 Route?}
D -->|Tool call detected\nin AIMessage| E[🛠️ tools\nToolNode\nTavily Web Search]
D -->|No tool call\nfinal answer ready| F([⏹ END])
E -->|Tool result appended\nto State.messages| B
style A fill:#2d6a4f,color:#fff,stroke:none
style F fill:#c1121f,color:#fff,stroke:none
style B fill:#1d3557,color:#fff,stroke:#457b9d,stroke-width:2px
style E fill:#023e8a,color:#fff,stroke:#0077b6,stroke-width:2px
style D fill:#6a0572,color:#fff,stroke:#9d4edd,stroke-width:2px
How the router works:
tools_conditionis a LangGraph prebuilt function. It inspects the last message inState.messages. If it's anAIMessagewith atool_callsattribute populated, it routes to"tools". Otherwise, it routes toEND. This single conditional edge powers the entire ReAct reasoning cycle.
graph TD
A([▶ START via set_entry_point]) --> B
B[📡 fetch_news\nAINewsNode.fetch_news\nTavily / RSS fetch]
B --> C
C[🧠 summarize_news\nAINewsNode.summarize_news\nGroq LLM synthesis]
C --> D
D[💾 save_result\nAINewsNode.save_result\nPersist to AINews/]
D --> E([⏹ END])
style A fill:#2d6a4f,color:#fff,stroke:none
style E fill:#c1121f,color:#fff,stroke:none
style B fill:#1d3557,color:#fff,stroke:#457b9d,stroke-width:2px
style C fill:#023e8a,color:#fff,stroke:#0077b6,stroke-width:2px
style D fill:#1b4332,color:#fff,stroke:#52b788,stroke-width:2px
Agentic-Chatbot/
│
├── app.py # Entry point — launches Streamlit UI
├── requirements.txt # Python dependencies
├── pyproject.toml # Project metadata
│
├── AINews/ # Output directory for saved news reports
│
└── src/
└── langgraphAgenticAI/
├── main.py # load_langgraph_agenticai_app()
│
├── state/
│ └── state.py # Shared State definition (MessagesState)
│
├── graph/
│ └── graph.py # GraphBuilder — all graph topologies
│
├── nodes/
│ ├── basic_chatbot_node.py # BasicChatbotNode
│ ├── chatbot_with_Tool_node.py # ChatbotWithToolNode (ReAct)
│ └── ai_news_node.py # AINewsNode (fetch/summarize/save)
│
└── tools/
└── search_tool.py # Tavily tool factory & ToolNode builder
- Python 3.11+
- A Groq API Key (free tier available)
- A Tavily API Key (for web search & news modes)
git clone https://github.com/Vidit-lab/Agentic-Chatbot.git
cd Agentic-Chatbot# Using venv
python -m venv .venv
source .venv/bin/activate # Linux / macOS
.venv\Scripts\activate # Windows
# OR using uv (recommended — lockfile already included)
pip install uv
uv syncpip install -r requirements.txtCreate a .env file in the project root:
GROQ_API_KEY=your_groq_api_key_here
TAVILY_API_KEY=your_tavily_api_key_here
# Optional — for OpenAI model support
OPENAI_API_KEY=your_openai_api_key_herestreamlit run app.pyThe Streamlit UI will open at http://localhost:8501. Use the sidebar to:
- Select your LLM model (Groq / OpenAI)
- Choose a use case —
Basic Chatbot,Chatbot with Tool, orAI News - Start chatting — the corresponding graph is compiled on-demand
You: Explain the transformer architecture in simple terms.
Bot: [Pure LLM response — no tools invoked]
You: What are the latest LLM releases this week?
Bot: [Invokes Tavily web search → reads results → synthesizes answer]
# Triggered from UI — runs fully autonomously
Graph: fetch_news → summarize_news → save_result
Output: Saved to AINews/report_<timestamp>.txt
| Layer | Technology |
|---|---|
| Graph Orchestration | LangGraph |
| LLM Framework | LangChain |
| LLM Inference | Groq (LLaMA 3, Mixtral) · OpenAI |
| Web Search Tool | Tavily via tavily-python |
| Vector Store | FAISS (faiss-cpu) |
| UI | Streamlit |
| Package Management | pip · uv |
- Memory / Checkpointing — Persist conversation state across sessions using LangGraph's
SqliteSaverorPostgresSaver - Human-in-the-Loop — Add
interrupt_beforebreakpoints for approval workflows - RAG Mode — Wire FAISS vector store into a new graph topology for document Q&A
- Multi-Agent — Supervisor agent that delegates to specialized sub-agents
- LangSmith Tracing — Full observability for all graph executions
- Docker — Containerized deployment with
docker-compose
Contributions are welcome! Please open an issue first to discuss what you'd like to change, then submit a pull request.
- Fork the repository
- Create your feature branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'feat: add your feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
Built with ❤️ using LangGraph · LangChain · Groq
If you find this project useful, please consider giving it a ⭐