# Enrichment & Anti-Hallucination: Tầng bảo vệ dữ liệu

> **Tóm tắt:** Enrichment là tầng cuối cùng trong pipeline AI — sau khi Stylist viết xong câu trả lời, Enrichment kiểm tra lại toàn bộ dữ liệu cứng (giá, chất liệu, mã SP, link ảnh) và **thay thế bằng ground truth từ database**. Đây là tuyến phòng thủ cuối cùng chống hallucination.

---

## 1. Vấn đề: LLM bịa dữ liệu

| Loại hallucination | Ví dụ | Hậu quả |
|-------------------|-------|---------|
| **Bịa giá** | AI nói "Áo này giá 299k" nhưng thật ra 599k | Khách đến mua → tranh cãi → mất uy tín |
| **Bịa mã SP** | AI nói "Mã SP: CNF-99999" nhưng SP không tồn tại | Nhân viên không tra được → mất đơn |
| **Bịa chất liệu** | AI nói "100% Cotton" nhưng thật ra Polyester | Vi phạm quy định ghi nhãn → rủi ro pháp lý |
| **Bịa link ảnh** | AI sinh URL ảnh không tồn tại | Hiển thị ảnh lỗi → mất chuyên nghiệp |
| **Bịa chính sách** | AI nói "Đổi trả 60 ngày" nhưng thật ra 30 ngày | Khách khiếu nại → thiệt hại tài chính |

**Nghiên cứu:** Theo McKinsey (2024), 67% doanh nghiệp triển khai AI chatbot gặp vấn đề hallucination trong 3 tháng đầu. Chi phí sửa lỗi trung bình gấp 5x chi phí phòng ngừa.

---

## 2. Chiến lược phòng thủ 3 lớp

Canifa sử dụng mô hình **Defense-in-Depth** (phòng thủ theo chiều sâu):

### Lớp 1: Prompt Guardrails (Phòng ngừa)

Ngay trong System Prompt của Stylist, có các luật cứng:

```
KHÔNG BAO GIỜ BỊA ĐẶT - CHỈ NÓI THEO DỮ LIỆU
- KHÔNG tự bịa tính năng không có trong tool results
- KHÔNG tự bịa mã sản phẩm, giá tiền, chính sách
- Tuyệt đối KHÔNG tự bịa/ghép suffix — truyền ĐÚNG mã khách đưa
```

**Hiệu quả:** Giảm ~60% hallucination so với prompt không có guardrails.
**Hạn chế:** LLM vẫn có thể "quên" luật khi context dài.

### Lớp 2: Tool Result Binding (Ràng buộc)

Stylist chỉ được phép tham chiếu dữ liệu từ Tool Results. Kiến trúc bắt buộc:

```
[Tool Registry] → Gọi API/DB lấy data thật
                     ↓
              [Tool Results] → Dữ liệu ground truth
                     ↓
              [Stylist Prompt] = System Prompt + Tool Results
                     ↓
              [AI Response] → Chỉ được dùng data từ Tool Results
```

**Kỹ thuật:** Data từ Tool được inject trực tiếp vào prompt dưới dạng structured (JSON), không phải free-text. LLM khó bịa khi data đã có format cứng.

### Lớp 3: Post-Generation Enrichment (Sửa chữa)

Đây là **tầng cuối cùng** — sau khi Stylist sinh xong text, hệ thống chạy Enrichment:

| Check | Cơ chế | Ví dụ |
|-------|--------|-------|
| **Price verification** | So sánh giá trong response vs giá trong DB | AI viết "299k" nhưng DB = 599k → sửa thành 599k |
| **Product ID validation** | Kiểm tra mã SP có tồn tại trong catalog | AI viết "CNF-99999" → không tồn tại → xoá khỏi response |
| **Image URL injection** | Thay link ảnh AI bịa bằng URL thật từ CDN | AI sinh URL fake → thay bằng `cdn.canifa.com/...` |
| **Material override** | Force-inject chất liệu từ DB (ground truth wins) | AI viết "Cotton" nhưng DB = "Polyester" → sửa |

**Ví dụ thực tế (Ultra Description Agent):**

```python
# Force-inject ground truth fields (guardrail)
# chat_lieu: DB ground truth WINS unconditionally if found
if db_material:
    response.chat_lieu = db_material  # Override AI's guess
```

---

## 3. Ground Truth Architecture

### Data Flow

```
[StarRocks DB] ──→ [Product Search Engine] ──→ [16 core fields]
                                                     │
                                                     ├── product_id (immutable)
                                                     ├── price (immutable)
                                                     ├── material (immutable)
                                                     ├── image_urls[] (immutable)
                                                     ├── stock_status (immutable)
                                                     └── ... 11 more fields
                                                     │
                                               [Stylist uses these]
                                                     │
                                               [Enrichment verifies]
```

### Nguyên tắc Immutable Fields

| Field | Source | Có thể bị AI thay đổi? |
|-------|--------|----------------------|
| `product_id` | DB | ❌ Không — luôn inject từ DB |
| `price` | DB | ❌ Không — luôn check lại |
| `chat_lieu` | DB | ❌ Không — DB wins unconditionally |
| `image_url` | CDN | ❌ Không — luôn dùng URL thật |
| `ten_san_pham` | DB | ❌ Không — tên chính xác từ catalog |
| `mo_ta_phoi_do` | AI | ✅ Được — AI sáng tạo phối đồ |
| `loi_khuyen` | AI | ✅ Được — AI tư vấn |

---

## 4. Kỹ thuật nén dữ liệu (Token Optimization)

Dữ liệu từ DB được **nén trước khi inject** vào prompt để tiết kiệm token:

| Kỹ thuật | Mô tả | Tiết kiệm |
|----------|-------|----------|
| **16-field compression** | Chỉ gửi 16 trường cốt lõi thay vì 50+ trường raw | ~70% token |
| **description_data_cut** | Mô tả SP được pre-compressed từ SQLite | ~50% token |
| **Truncate long strings** | Cắt string dài >200 chars trong multi-product mode | ~30% token |
| **Auto-summarize** | Results >10 rows → auto-summarized thành insights | ~80% token |

---

## 5. Lộ trình nâng cấp

| Phase | Feature | Trạng thái |
|-------|---------|-----------|
| **P0** | Prompt Guardrails + Tool Binding | ✅ Done |
| **P1** | Ground Truth Override (material, price) | ✅ Done |
| **P2** | Automated Price Checker (post-generation) | 🔜 Next |
| **P3** | Langfuse Guardrail Tracing | 📋 Planned |
| **P4** | LLM-as-Judge (auto-evaluate hallucination rate) | 📋 Planned |

---

## References

- `backend/agent/ultra_descriptions_agent/agent.py` — Ground truth injection logic
- `backend/agent/lead_stage_agent/prompts.py` — Prompt guardrails
- `backend/agent/lead_stage_agent/product_search_engine.py` — 16-field compression
- McKinsey (2024) — "The state of AI in early 2024"
