File size: 9,884 Bytes
1f2bfa7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# πŸ—οΈ 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**:
```python
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`:
   ```python
   def my_tool(param: str) -> str:
       """My new tool."""
       return "result"
   ```

2. Add to TOOLS dict:
   ```python
   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`:
```python
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