langgraph-support-agent / ARCHITECTURE.md
mnoorchenar's picture
Update 2026-03-22 16:37:02
1f2bfa7

πŸ—οΈ TechStore Support Agent - Architecture Guide

Project Overview

This is an AI-powered customer support chatbot that uses LangGraph (ReAct pattern) and HuggingFace models to answer customer questions about TechStore products and services.

Goal: Automate customer support by intelligently routing questions to the right tools and providing instant answers.


How It Works: The ReAct Loop

Step 1: User Sends Message

User: "What is your return policy?"
         ↓
    Flask Backend (/api/chat)
         ↓
    Creates LangGraph session

Step 2: Agent Thinks

The Qwen AI Model receives the question and decides:

  • "I need to search the FAQ for 'return policy'"
  • Outputs in this format:
    Thought: The user is asking about return policy
    Action: search_faq
    Action Input: {"query": "return policy"}
    

Step 3: Tool Execution

The agent's decision is parsed and a tool is executed:

search_faq("return policy")
β†’ Returns best matching FAQ entries
β†’ "You may return items within 30 days..."

Step 4: Agent Responds

The tool result is fed back to the AI, which writes:

Thought: I have the information needed
Final Answer: You may return most items within 30 days...

Step 5: Stream to User

Response is streamed via Server-Sent Events (SSE) in real-time:

Browser receives: "You may return most items within 30 days..."
Shows on screen instantly

Project Structure

langgraph-support-agent/
β”œβ”€β”€ app.py                 # Main Flask server
β”œβ”€β”€ events.py              # Event streaming system
β”œβ”€β”€ requirements.txt       # Python dependencies
β”œβ”€β”€ Dockerfile             # Container config
β”œβ”€β”€ agent/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ state.py          # Agent state definition
β”‚   β”œβ”€β”€ tools.py          # 5 support tools
β”‚   β”œβ”€β”€ llm.py            # Qwen integration
β”‚   β”œβ”€β”€ nodes.py          # ReAct nodes
β”‚   └── graph.py          # LangGraph definition
β”œβ”€β”€ data/
β”‚   └── faq.json          # FAQ knowledge base
β”œβ”€β”€ templates/
β”‚   └── index.html        # Web UI
β”œβ”€β”€ static/
β”‚   └── app.js            # Frontend logic
└── docs/
    └── project-template.html

The 5 Tools

1. πŸ” search_faq(query)

  • What: Searches the FAQ knowledge base
  • Use Case: User asks "What's your return policy?"
  • Example:
    search_faq("return policy")
    β†’ Returns matching FAQ entries
    

2. πŸ“¦ check_order_status(order_id)

  • What: Looks up order status and tracking
  • Use Case: User asks "Where is my order ORD-482910?"
  • Example:
    check_order_status("ORD-482910")
    β†’ Order: ORD-482910: Shipped. Tracking #1234567890. ETA: March 25, 2026
    

3. πŸ›οΈ get_product_info(product_name)

  • What: Returns product specs, price, availability
  • Use Case: User asks "Do you have laptops in stock?"
  • Example:
    get_product_info("laptop")
    β†’ Product: ProBook X15
       Price: $1,299
       Availability: In Stock
       Specs: Intel i7-13th, 16GB RAM, 512GB NVMe SSD
    

4. 🎫 create_ticket(issue, priority)

  • What: Creates a support ticket
  • Use Case: User says "I need to report a broken product"
  • Example:
    create_ticket("Screen is broken", "high")
    β†’ Ticket TKT-ABC123 created
       Priority: HIGH
       Expected response: within 8 hours
    

5. πŸ‘€ escalate_to_human(reason)

  • What: Transfers conversation to human agent
  • Use Case: User says "I want to talk to someone"
  • Example:
    escalate_to_human("Unhappy customer")
    β†’ Escalation ESC-XYZ initiated
       Queue position: 3 | Est. wait: 15 minutes
    

Key Technologies

Component Purpose
Flask Web server & API
LangGraph Agent orchestration (ReAct pattern)
Qwen 2.5 7B AI Model (HuggingFace Inference API)
Server-Sent Events Real-time streaming
Threading Async task processing
LangChain Message handling & parsing

The ReAct Pattern

ReAct = Reasoning + Acting

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. Router Node                         β”‚
β”‚     ↓                                   β”‚
β”‚  2. Agent Loop (Reasoning)              β”‚
β”‚     - Qwen thinks about question        β”‚
β”‚     - Decides which tool to use         β”‚
β”‚     ↓                                   β”‚
β”‚  3. Tool Executor (Acting)              β”‚
β”‚     - Executes the chosen tool          β”‚
β”‚     - Returns result                    β”‚
β”‚     ↓                                   β”‚
β”‚  4. Back to Agent (Loop)                β”‚
β”‚     - Has tool result                   β”‚
β”‚     - Decides: use another tool or end? β”‚
β”‚     ↓                                   β”‚
β”‚  5. Responder Node                      β”‚
β”‚     - Final answer sent to user         β”‚
β”‚     ↓                                   β”‚
β”‚  6. END                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Max 4 tool calls per turn (to prevent infinite loops)


UI Layout (60% Chat Focus)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ›οΈ TechStore Support Agent  β”‚ Orders Β· FAQs Β· Tickets β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚          β”‚                              β”‚            β”‚
β”‚          β”‚                              β”‚            β”‚
β”‚  20%     β”‚         60% Chat             β”‚   20%      β”‚
β”‚ Sidebar  β”‚  (Messages & Input)          β”‚  Panel     β”‚
β”‚          β”‚                              β”‚ (Tools &   β”‚
β”‚ β€’ Model  β”‚  User: "What is return      β”‚  Trace)    β”‚
β”‚ β€’ Status β”‚         policy?"             β”‚            β”‚
β”‚ β€’ Stats  β”‚                              β”‚ β€’ Tool     β”‚
β”‚          β”‚  Agent: "You may return     β”‚   Calls    β”‚
β”‚          β”‚  items within 30 days..."   β”‚ β€’ Executionβ”‚
β”‚          β”‚                              β”‚  Trace     β”‚
β”‚          β”‚                              β”‚            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   User     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
       β”‚ "What is your return policy?"
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Flask API /api/chat            β”‚
β”‚   - Validates input              β”‚
β”‚   - Gets HF_TOKEN from .env      β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   LangGraph StateGraph           β”‚
β”‚   - Manages Agent State          β”‚
β”‚   - Orchestrates nodes           β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”œβ”€ Router Node β†’ sends to Agent
       β”‚
       β”œβ”€ Agent Node
       β”‚   - Calls Qwen AI model
       β”‚   - Parses: "Action: search_faq"
       β”‚
       β”œβ”€ Tool Executor Node
       β”‚   - Executes tool
       β”‚   - search_faq("return policy")
       β”‚
       β”œβ”€ Agent Node (again)
       β”‚   - Decides: Final Answer or more tools?
       β”‚
       └─ Responder Node
           - Finalizes response
           - Emits events via SSE
           β”‚
           ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  Browser (SSE)      β”‚
    β”‚  Receives events    β”‚
    β”‚  in real-time       β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  User sees answer   β”‚
    β”‚  "You may return... β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How to Extend This

Add a New Tool

  1. Create function in agent/tools.py:

    def my_tool(param: str) -> str:
        """My new tool."""
        return "result"
    
  2. Add to TOOLS dict:

    TOOLS = {
        ...
        "my_tool": {"fn": my_tool, "desc": "My tool", "icon": "πŸ”§"},
    }
    
  3. Update system prompt in agent/llm.py to mention it

Change AI Model

Edit app.py:

AVAILABLE_MODELS = [
    {"id":"different-model/name","name":"Display Name","badge":"βœ“"},
]

Update FAQ

Edit data/faq.json - add/modify entries


Deployment

This is designed for HuggingFace Spaces:

  1. Set HF_TOKEN in Space Secrets
  2. Push code to repo
  3. Space auto-deploys with Docker
  4. Runs on port 7860

Summary

  • What: Customer support chatbot for TechStore
  • How: LangGraph orchestrates an AI agent through a ReAct loop
  • Why: Automate support & provide instant answers
  • Tech: Flask + LangGraph + Qwen + SSE streaming
  • Scalable: Can add more tools/FAQs without changing architecture