# 3. Logic chuyển đổi Stage (Lên / Xuống)

Phễu **không phải một chiều** — khách có thể nhảy lên, nhảy xuống, hoặc quay vòng giữa các Mode. Classifier Agent phải nhận diện tín hiệu từ tin nhắn để quyết định chuyển đổi.

## Bảng chuyển đổi Stage

| Từ | Sang | Tín hiệu | Ví dụ tin nhắn |
|---|---|---|---|
| Mode 1 (BROWSE) | Mode 2 (IDENTIFYING) | Khách nhả manh mối sản phẩm | "Mình tìm áo khoác" |
| Mode 2 (IDENTIFYING) | Mode 3 (CONSIDERING) | InsightJSON đã đủ info (giá, dịp, size) | "Áo khoác nam, mùa đông, dưới 500k" |
| Mode 3 (CONSIDERING) | Mode 4 (CLOSING) | Khách ra tín hiệu chốt | "Lấy anh cái đầu tiên", "OK lấy luôn" |
| Mode 4 (CLOSING) | Mode 5 (RETENTION) | Khách đã cho SĐT hoặc từ chối | "SĐT 0912..." hoặc "Thôi để sau" |
| Mode 3 (CONSIDERING) | Mode 2 (IDENTIFYING) | Khách đổi ý, hỏi loại khác | "Thôi, cho mình xem quần đi" |
| Mode 4 (CLOSING) | Mode 3 (CONSIDERING) | Khách lưỡng lự, hỏi thêm | "Khoan, chất liệu này có bền không?" |
| Mode 5 (RETENTION) | Mode 2 (IDENTIFYING) | Khách quay lại hỏi tiếp | "À mà cho mình xem thêm áo polo" |

## Cơ chế nhảy ngược (Downgrade)

Đây là điểm khác biệt quan trọng so với funnel truyền thống — **khách có thể quay lại bất kỳ lúc nào**:

```mermaid
graph TD
    M1["Mode 1: BROWSE"] --> M2["Mode 2: IDENTIFYING"]
    M2 --> M3["Mode 3: CONSIDERING"]
    M3 --> M4["Mode 4: CLOSING"]
    M4 --> M5["Mode 5: RETENTION"]
    M3 -.->|Đổi ý| M2
    M4 -.->|Lưỡng lự| M3
    M5 -.->|Quay lại| M2

    style M1 fill:#334155,stroke:#64748b,color:#e2e8f0
    style M2 fill:#0c4a6e,stroke:#0ea5e9,color:#e0f2fe
    style M3 fill:#5b21b6,stroke:#8b5cf6,color:#ede9fe
    style M4 fill:#92400e,stroke:#f59e0b,color:#fef3c7
    style M5 fill:#14532d,stroke:#22c55e,color:#dcfce7
```

## Classifier phán đoán Stage như thế nào?

Classifier Agent nhận 3 input đầu vào:

1. **Tin nhắn mới nhất** của khách
2. **InsightJSON cũ** (đọc từ Redis) — chứa `STAGE` hiện tại
3. **Chat history** (5 tin gần nhất)

Dựa vào 3 input này, Classifier xuất `ClassifierOutput` với `STAGE` mới. Logic:

```python
# Pseudo-code: Classifier reasoning
if no_product_intent(message):
    stage = "BROWSE"          # Vẫn ở Mode 1
elif missing_key_fields(insight):
    stage = "IDENTIFYING"     # Cần hỏi thêm
elif has_purchase_signal(message):
    stage = "CLOSING"         # Nhảy thẳng lên Mode 4
elif has_product_criteria(insight):
    stage = "CONSIDERING"     # Đủ info, vào Mode 3
elif has_contact_info(message) or has_rejection(message):
    stage = "RETENTION"       # Kết thúc
```

## Quy tắc quan trọng

- **Không bao giờ nhảy từ Mode 1 thẳng lên Mode 4.** Dù khách nói "Cho tôi mua áo khoác" ngay từ đầu, AI vẫn phải qua Mode 2 (hỏi chi tiết) và Mode 3 (search + tư vấn) trước.
- **Mode 5 là trạng thái cuối nhưng không phải dead-end.** Nếu khách nhắn tiếp sau Mode 5, hệ thống reset về Mode 2 (không phải Mode 1 vì khách đã quen).
- **InsightJSON không bị xoá khi downgrade.** Dù khách quay lại Mode 2, tất cả thông tin đã thu thập vẫn được giữ — chỉ đổi `STAGE` và `TONE`.
