---
description: Lead Bot QA Loop — Tự động test bot recommend sản phẩm có đúng context không, xác minh với DB, AI judge chấm điểm, đề xuất sửa prompt, lặp lại.
---

# 🔁 Lead Bot QA — Auto-Eval & Self-Improve Loop

**CONCEPT:** Chạy bộ câu hỏi ngữ cảnh (seasonal, situational) → Bot trả sản phẩm → Xác minh DB → AI Judge chấm → Phát hiện lỗi prompt → Đề xuất fix → Loop lại.

Script: `backend/scripts/lead_test/run_eval.py`
Output: `backend/scripts/lead_test/results/eval_YYYY-MM-DD_RX.txt`

---

## 🧠 Ý tưởng cốt lõi (Từ Prompt)

> Bot nhận câu hỏi **gián tiếp / theo ngữ cảnh** → phải **hiểu hoàn cảnh** để recommend đúng loại SP.
> Hiện tại prompt/search tool thiếu **context mapping**: "trời mưa" ≠ keyword "áo mưa" → phải map sang "áo khoác chống thấm / áo gió".

| Câu hỏi người dùng | Bot nên hiểu | Loại SP đúng |
|---|---|---|
| "áo mặc trời mưa" | chống thấm, nhẹ | Áo khoác gió, áo khoác chống thấm |
| "áo thu đông nam" | giữ ấm, thu đông | Áo nỉ, áo khoác len, áo hoodie |
| "váy dự tiệc cuối năm" | lịch sự, sang | Váy liền, đầm dự tiệc |
| "đồ đi làm công sở nữ" | thanh lịch, công sở | Sơmi, áo kiểu, quần âu |
| "áo mặc nhà thoải mái" | thường ngày | Áo phông, quần jogger |
| "đồ đi chơi cuối tuần" | casual, trẻ trung | Áo polo, áo thun, quần jean |
| "đồ đi biển" | thoáng mát, mùa hè | Áo thun cotton, short |
| "váy mặc Tết" | truyền thống, tươi | Áo dài, váy dáng A |

---

## THE LOOP

### ⚡ Phase 1: Chuẩn bị Test Set
1. Đọc `test_cases.json` — 20 câu hỏi chia 4 nhóm:
   - `seasonal` (mùa, thời tiết)
   - `occasion` (dịp: Tết, tiệc, đi làm, đi biển)
   - `demographic` (nam/nữ/trẻ em + hoàn cảnh)
   - `vague` (câu mơ hồ nhất: "có gì mặc đẹp không")
2. Xác nhận server đang chạy tại `http://localhost:5000`
3. Tạo folder `results/` nếu chưa có

*→ Phase 2*

---

### 🤖 Phase 2: Gọi Bot (Bot Call)
Với **mỗi câu hỏi** trong test set:
```
POST /api/agent/chat-lead-flow
  body: { user_query: "...", conversation_id: uuid, device_id: "eval-bot" }

→ Nhận: {
    ai_response: "...",
    products: [{ sku, name, price, product_line, ... }],
    lead_stage: { stage, tone_directive }
  }
```
- Nếu `products = []` → đánh dấu `NO_PRODUCTS`
- Nếu API lỗi → đánh dấu `API_ERROR`, tiếp tục câu tiếp theo

*→ Phase 3*

---

### 🗄️ Phase 3: Xác minh DB (DB Verify)
Với **mỗi SKU** trong `products[]`:
```
GET /api/product/lookup?skus={sku}
→ Check: product tồn tại trong DB? (200 vs 404)
→ Lấy: product_line_vn, sale_price, size_scale
```

**Đánh giá tương quan:**
- Câu hỏi: "áo mặc trời mưa" → `product_line_vn` trả về là gì?
  - `Áo khoác` → ✅ MATCH
  - `Áo thun` → ❌ MISMATCH
  - Không có SP → ⚠️ NO_PRODUCTS

*→ Phase 4*

---

### 🧑‍⚖️ Phase 4: AI Judge
Gọi LLM (Gemini Flash / GPT-4o-mini) với prompt:

```
Bạn là chuyên gia thời trang đánh giá chatbot bán hàng.

Câu hỏi user: "{question}"
Bot trả lời: "{ai_response}"
Sản phẩm gợi ý: {product_list}
[Loại SP trong DB: {product_lines}]

Đánh giá:
1. Sản phẩm có phù hợp với hoàn cảnh/mùa/dịp trong câu hỏi không? (0-10)
2. Câu trả lời AI có tự nhiên, đúng context không? (0-10)
3. Có thiếu loại SP nào quan trọng không?
4. Pattern lỗi nếu có (bot hay nhầm X → Y trong hoàn cảnh Z)

Trả về JSON: {
  "context_score": 0-10,
  "response_score": 0-10,
  "verdict": "PASS|PARTIAL|FAIL",
  "reason": "...",
  "pattern_error": "..." | null,
  "prompt_fix_hint": "..." | null
}
```

*→ Phase 5*

---

### 📝 Phase 5: Ghi Kết Quả
Ghi vào `results/eval_YYYY-MM-DD_R{round}.txt`:

```
═══════════════════════════════════════
LEAD BOT QA — Round {N} — {datetime}
═══════════════════════════════════════

📊 TỔNG KẾT:
  Tổng câu: 20 | PASS: X | PARTIAL: Y | FAIL: Z
  Avg Score: {score}/10
  Câu không có sản phẩm: {n}

────────────────────────────────────────
📋 CHI TIẾT:

[1] "áo mặc trời mưa"
    Verdict : ❌ FAIL (3/10)
    Bot trả : Áo thun cotton (product_line: Áo phông)
    Lý do   : Áo thun không phù hợp điều kiện mưa, cần áo khoác chống thấm
    Fix hint: "Thêm context: trời mưa → áo khoác / áo gió vào synonym mapping"

[2] "áo thu đông nam"
    Verdict : ✅ PASS (8/10)
    Bot trả : Áo khoác nỉ form rộng (product_line: Áo khoác)
    Lý do   : Đúng loại, đúng mùa

...

────────────────────────────────────────
🔍 PATTERN LỖI PHÁT HIỆN:
  1. Bot thiếu mapping: mô tả thời tiết → loại SP tương ứng
  2. Bot không ưu tiên mùa vụ khi filter sản phẩm
  3. Câu hỏi dịch lễ (Tết, tiệc) → bot hay recommend casual thay formal

💡 ĐỀ XUẤT SỬA PROMPT:
  → lead_search_tool.py line ~45: Thêm context_to_product_line map
  → Stylist prompt: "Ưu tiên áo khoác / áo gió khi user đề cập thời tiết mưa hoặc lạnh"
  → Synonym: "thu đông" → product_line IN ('Áo khoác', 'Áo nỉ', 'Áo len')
═══════════════════════════════════════
```

*→ Phase 6*

---

### 🔧 Phase 6: Xem Kết Quả & Quyết Định
Đọc file kết quả:
- **Avg Score ≥ 8** → ✅ Bot đang tốt, stop loop hoặc test câu khó hơn
- **Avg Score 5-7** → ⚠️ PARTIAL — apply 1-2 fix hint đơn giản → quay Phase 1 (Round N+1)
- **Avg Score < 5** → ❌ FAIL — report đầy đủ pattern lỗi, cần sửa prompt nghiêm túc

**Áp dụng fix (nếu có):**
1. Sửa `lead_search_tool.py`: thêm `context_mapping` dict
2. Sửa `stylist_prompt.py`: thêm seasonal/occasion rules
3. Chạy lại **Round N+1** với cùng test set

> **LOOP TERMINATION:** Dừng khi Score ≥ 8 trên 3 round liên tiếp HOẶC user manually stop.

---

## 📁 File Structure

```
backend/scripts/lead_test/
├── run_eval.py          ← Entry point: python run_eval.py [--round N] [--fix]
├── test_cases.json      ← 20 câu hỏi + expected_product_types
├── judge.py             ← AI Judge logic (Gemini/GPT call)
├── db_verify.py         ← Gọi /api/product/lookup check SKU
└── results/
    ├── eval_2026-04-14_R1.txt
    ├── eval_2026-04-14_R2.txt
    └── summary.json     ← Score trend qua các round
```

---

## 🚀 Cách chạy

```bash
# Round 1 — chạy test cơ bản
python backend/scripts/lead_test/run_eval.py

# Round N+1 — sau khi đã sửa prompt
python backend/scripts/lead_test/run_eval.py --round 2

# Xem summary score trend
python backend/scripts/lead_test/run_eval.py --summary
```
