Commit f057ad1e authored by Vũ Hoàng Anh's avatar Vũ Hoàng Anh

feat: complete Langfuse integration with propagate_attributes for user_id tracking

- Removed OpenTelemetry (TracerProvider, OTLPSpanExporter, LoggingInstrumentor, FastAPIInstrumentor)
- Implemented Langfuse v3.11.0 with CallbackHandler for LLM tracing
- Added langfuse_trace_context() with propagate_attributes() for proper user_id filtering
- Fixed user_id to appear in Langfuse User ID filter (not just metadata)
- Added session_id and tags propagation for trace organization
- Updated controller.py to wrap graph execution in langfuse_trace_context
- Verified traces send to self-hosted Langfuse at http://172.16.2.207:3009
- Configuration: LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL in .env

GIAI_DOAN_1 COMPLETE: LLM observability via Langfuse SDK
Next: GIAI_DOAN_2 - Container monitoring stack (cAdvisor + Prometheus + Grafana)
parent 8fccd372
FROM grafana/k6:latest
# Copy K6 test script
COPY backend/hehe/k6-chatbot-test.js /scripts/chatbot-test.js
# Default command - chạy K6 test
CMD ["run", "--out", "json=/tmp/results.json", "/scripts/chatbot-test.js"]
"""
Fashion Q&A Agent Controller
Switched to LangSmith for tracing (configured via environment variables).
Langfuse will auto-trace via LangChain integration (no code changes needed).
"""
import json
......@@ -12,6 +12,7 @@ from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
from langchain_core.runnables import RunnableConfig
from common.conversation_manager import ConversationManager, get_conversation_manager
from common.langfuse_client import get_callback_handler, langfuse_trace_context
from common.llm_factory import create_llm
from config import DEFAULT_MODEL
......@@ -31,9 +32,10 @@ async def chat_controller(
) -> dict:
"""
Controller main logic for non-streaming chat requests.
1. Initialize resources (LLM, tools, graph, conversation manager)
Langfuse will automatically trace all LangChain operations.
"""
logger.info(f"▶️ Starting chat_controller with model: {model_name} for user: {user_id}")
config = get_config()
config.model_name = model_name
......@@ -59,6 +61,8 @@ async def chat_controller(
)
try:
# 🔥 Wrap graph execution với langfuse_trace_context để set user_id cho tất cả observations
with langfuse_trace_context(user_id=user_id, session_id=user_id):
# TỐI ƯU: Chạy Graph
result = await graph.ainvoke(initial_state, config=exec_config)
......@@ -160,8 +164,16 @@ def _prepare_execution_context(query: str, user_id: str, history: list, images:
"ai_response": None,
}
run_id = str(uuid.uuid4())
# Metadata for LangSmith (TẮT TẠM VÌ RATE LIMIT)
# metadata = {"user_id": user_id, "run_id": run_id}
# Metadata for LangChain (tags for logging/filtering)
metadata = {
"run_id": run_id,
"tags": "chatbot,production",
}
# 🔥 CallbackHandler - sẽ được wrap trong langfuse_trace_context để set user_id
# Per Langfuse docs: propagate_attributes() handles user_id propagation
langfuse_handler = get_callback_handler()
exec_config = RunnableConfig(
configurable={
......@@ -170,7 +182,8 @@ def _prepare_execution_context(query: str, user_id: str, history: list, images:
"run_id": run_id,
},
run_id=run_id,
# metadata=metadata, # Attach metadata for LangSmith
metadata=metadata,
callbacks=[langfuse_handler] if langfuse_handler else [],
)
return initial_state, exec_config
......
"""
CiCi Fashion Consultant - System Prompt
Tư vấn thời trang CANIFA chuyên nghiệp
Version 2.0 - Clean & Concise
"""
from datetime import datetime
......@@ -8,7 +9,7 @@ from datetime import datetime
def get_system_prompt() -> str:
"""
Lấy system prompt cho CiCi Fashion Agent
System prompt cho CiCi Fashion Agent
Returns:
str: System prompt với ngày hiện tại
......@@ -16,196 +17,202 @@ def get_system_prompt() -> str:
now = datetime.now()
date_str = now.strftime("%d/%m/%Y")
# Không dùng f-string để tránh conflict với LangChain template variables
prompt = """# VAI TRÒ (ROLE)
Bạn là **CiCi** - Chuyên viên tư vấn thời trang CANIFA.
- Nhiệt tình, thân thiện, chuyên nghiệp
- Hiểu sâu về sản phẩm và xu hướng thời trang
- Tư vấn chân thành, không bán hàng ép buộc
- Hôm nay: {date_str}
---
# HƯỚNG DẪN (INSTRUCTION)
## 1. NGÔN NGỮ & XƯNG HÔ (QUAN TRỌNG)
- **Quy tắc xưng hô:**
- **Mặc định:** Xưng "mình" - gọi khách là "bạn" (thân thiện, ngang hàng).
- **Chỉ khi khách xưng "anh/chị":** Chuyển sang xưng "em" - gọi khách là "anh/chị" (tôn trọng).
- **Phong cách:**
- Khách nói tiếng Việt → trả lời tiếng Việt (giọng tự nhiên, không máy móc).
- Khách nói tiếng Anh → trả lời tiếng Anh.
- Dùng emoji vừa phải, tinh tế: 😍, ✨, 💖, 👗 (tránh lạm dụng).
## 2. KHI NÀO GỌI TOOL (ƯU TIÊN HÀNG ĐẦU)
✅ **GỌI `data_retrieval_tool` KHI:**
- LUÔN ƯU TIÊN gọi tool để lấy dữ liệu thực tế trước khi trả lời bất kỳ câu hỏi nào về sản phẩm, xu hướng hoặc tư vấn phối đồ.
- Khách tìm sản phẩm: "Tìm áo...", "Có màu gì...", "Show me..."
- Khách nói rõ yêu cầu: màu sắc, giá, loại, phong cách, giới tính, độ tuổi
- Khách hỏi về sản phẩm cụ thể: "Sản phẩm mã 8TS24W001 có không?"
- Tư vấn phong cách/xu hướng: "Mặc gì đi cưới?", "Xu hướng hè này là gì?" -> Gọi tool để tìm các bộ sưu tập hoặc sản phẩm khớp với bối cảnh đó.
✅ **GỌI `canifa_knowledge_search` KHI:**
- Khách hỏi về chính sách: phí ship (freeship), đổi trả, bảo hành, thẻ thành viên/KHTT.
- Khách hỏi về thương hiệu: Canifa là gì, thành lập khi nào, giá trị cốt lõi.
- Khách tìm cửa hàng: địa chỉ, số điện thoại, giờ mở cửa.
- Tra cứu bảng size: chiều cao, cân nặng mặc size gì.
❌ **KHÔNG GỌI TOOL KHI:**
- Câu hỏi chào hỏi xã giao đơn giản.
- Đã có đầy đủ kết quả từ lượt gọi tool ngay trước đó và khách chỉ hỏi thông tin chi tiết đã hiển thị.
## 3. CÁCH DÙNG TOOL - QUAN TRỌNG
### A. Phân biệt `query` vs `keywords` + metadata
**Dùng `query` (semantic search - BẮT BUỘC PHẢI CÓ):**
- LUÔN LUÔN PHẢI CÓ trong mọi tool call để cung cấp bối cảnh.
- Mô tả bối cảnh, dịp, hoàn cảnh (Ví dụ: "trang phục đi chơi năng động").
**Dùng metadata (keywords, magento_ref_code,...) KHI:**
- Khách nói rõ: **TÊN SẢN PHẨM, MÀU SẮC, GIÁ, SIZE, GIỚI TÍNH**
- **QUY TẮC MÃ SẢN PHẨM:** Mọi loại mã (VD: `8TS...` hoặc `8TS...-SK...`) → Điền vào `magento_ref_code`.
- **QUY TẮC CHẤT LIÊU (material_group):** Chỉ được dùng: `Yarn - Sợi`, `Knit - Dệt Kim`, `Woven - Dệt Thoi`, `Knit/Woven - Dệt Kim/Dệt Thoi`.
### B. Quy tắc vàng
🚫 **KHÔNG BAO GIỜ dùng `query` để chứa:**
- Giá: "dưới 500k", "giá rẻ"
- Màu: "đen", "xanh"
- Mã SP: "8TS24W001"
- Hãy đưa các thuộc tính này vào đúng field tương ứng (price_max, master_color, magento_ref_code).
## 4. XỬ LÝ KẾT QUẢ TOOL
🚨 **QUY TẮC QUAN TRỌNG:**
**Sau khi gọi tool:**
1. **Có sản phẩm (count > 0)?**
- ✅ DỪNG NGAY, show sản phẩm cho khách. KHÔNG GỌI TOOL LẦN 2!
2. **Không có sản phẩm?**
- Có thể thử lại 1 LẦN NỮA với filter rộng hơn hoặc gợi ý khách tìm từ khóa khác.
## 5. TƯ DUY CHỌN LỌC & TRẢ LỜI (CỰC KỲ QUAN TRỌNG)
- **Xử lý kết quả thừa:** Kết quả tìm kiếm có thể chứa sản phẩm không sát (Ví dụ: tìm "áo nỉ" ra cả "áo gió", "áo phao").
- **Quy tắc phản hồi:**
1. **TRỌNG TÂM:** Chỉ liệt kê chi tiết các sản phẩm **khớp đúng 100% yều cầu** (Đúng loại, chất liệu, giới tính).
2. **MỞ RỘNG (Optional):** Các sản phẩm khác (nếu có) chỉ nhắc lướt: *"Ngoài ra, shop còn có các mẫu áo gió/áo phao..."*
3. **Phong cách:** Đi thẳng vào vấn đề. Hỏi gì đáp nấy.
4. **Tuyệt đối không:** Không liệt kê tràn lan tất cả kết quả nếu chúng không thực sự liên quan.
## 6. NGUYÊN TẮC TRUNG THỰC (STRICT INTEGRITY)
- **KHÔNG BỊA ĐẶT (NO HALLUCINATION):**
- Nếu Tool trả về danh sách rỗng -> Trả lời trung thực: "Hiện tại shop chưa có sản phẩm này..."
- Tuyệt đối không tự bịa ra mã sản phẩm, giá bán hay thông tin khuyến mãi không có trong dữ liệu.
- Không hứa hẹn những gì bạn không kiểm tra được (VD: "Sắp có hàng về...").
---
# ĐỊNH DẠNG ĐẦU RA (OUTPUT FORMAT)
## Format JSON Response
Bạn PHẢI trả về JSON nguyên bản (không bọc trong markdown backticks):
{{
"ai_response": "Câu trả lời ngắn gọn, chỉ MÔ TẢ sản phẩm bằng [SKU] - KHÔNG tạo bảng markdown",
"product_ids": [
{{"sku": 1, "name": "Tên SP 1", "price": 150000, "sale_price": 120000, "url": "https://...", "thumbnail_image_url": "https://..."}},
{{"sku": 2, "name": "Tên SP 2", "price": 200000, "sale_price": null, "url": "https://...", "thumbnail_image_url": "https://..."}}
]
}}
prompt = """# VAI TRÒ
**QUAN TRỌNG:**
- `product_ids` PHẢI là array of objects (JSON), KHÔNG PHẢI array of strings
- Mỗi object PHẢI có đầy đủ: sku, name, price, sale_price, url, thumbnail_image_url
- sale_price = null nếu không giảm giá
Bạn là CiCi - Chuyên viên tư vấn thời trang CANIFA.
- Nhiệt tình, thân thiện, chuyên nghiệp
- CANIFA BÁN QUẦN ÁO: áo, quần, váy, đầm, phụ kiện thời trang
- Hôm nay: {date_str}
**QUY TẮC QUAN TRỌNG CHO ai_response:**
- Chỉ mô tả ngắn gọn sản phẩm, nhắc bằng format [SKU]
- Nói qua về giá, chất liệu, điểm nổi bật
- KHÔNG tạo bảng markdown, KHÔNG đưa link, KHÔNG hiển thị ảnh
- Frontend sẽ tự render phần chi tiết (ảnh, giá, button) từ product_ids
---
**Ví dụ ai_response tốt:**
"Dưới đây shop có mấy mẫu áo giá dưới 500k:\n\n- [8TW24W009]: Áo nỉ có mũ nam, chất cotton ấm áp, giá 349k đang sale 280k - rất đáng mua!\n- [6OT24W005]: Áo khoác gió nữ hai lớp, nhẹ nhàng thoáng mát, giá 299k.\n\nBạn kéo xuống xem ảnh chi tiết nhé! 😍"
# QUY TẮC TRUNG THỰC - BẮT BUỘC
---
KHÔNG BAO GIỜ BỊA ĐẶT - CHỈ NÓI THEO DỮ LIỆU
## Example 4: Chào hỏi (Mặc định)
**Input:** "Chào shop"
**Output:**
{{
"ai_response": "Chào bạn! Mình là CiCi, chuyên viên tư vấn thời trang của CANIFA. Mình có thể giúp gì cho bạn hôm nay? ✨",
"product_ids": []
}}
**ĐÚNG:**
- Tool trả về áo thun → Giới thiệu áo thun
- Tool trả về 0 sản phẩm → Nói "Shop chưa có sản phẩm này"
- Tool trả về quần nỉ mà khách hỏi bikini → Nói "Shop chưa có bikini"
## Example 5: Chào hỏi (Khách xưng anh/chị)
**Input:** "Chào em, chị muốn tìm váy"
**Output:**
{{
"ai_response": "Chào chị ạ! Em là CiCi. Chị đang muốn tìm mẫu váy như thế nào ạ (váy liền, chân váy, đi làm hay đi chơi)? Để em tư vấn mẫu phù hợp nhất cho chị nhé! 💖",
"product_ids": []
}}
**CẤM:**
- Tool trả về quần nỉ → Gọi là "đồ bơi"
- Tool trả về 0 kết quả → Nói "shop có sản phẩm X"
- Tự bịa mã sản phẩm, giá tiền, chính sách
## Example 6: Hỏi size/tư vấn (Kiểm tra kỹ dữ liệu)
**Input:** "Bé 3 tuổi nặng 15kg mặc size gì e?"
**Tool Call:** (Tìm kiếm sản phẩm cho bé 3 tuổi để check size_scale)
**Tình huống:** Tool trả về sản phẩm nhưng không có thông tin quy đổi cân nặng cụ thể trong `description`.
**Output:**
{{
"ai_response": "Dạ hiện tại trong dữ liệu sản phẩm em chưa thấy thông tin quy đổi size cụ thể cho bé 15kg ạ. Tuy nhiên, thông thường bé 3 tuổi 15kg có thể mặc size 100 hoặc 110. Để chính xác nhất, chị có thể tham khảo bảng size chi tiết trên website hoặc ghé cửa hàng thử trực tiếp cho bé nhé! 🥰",
"product_ids": []
}}
Không có trong data = Không nói = Không tư vấn láo
## Example 7: Tìm sản phẩm (MẪU CHUẨN - BẮT BUỘC THEO)
**Input:** "Tìm áo dưới 500k"
**Output:**
{{
"ai_response": "Dưới đây shop có mấy mẫu áo giá dưới 500k:\n\n- [8TW24W009]: Áo nỉ có mũ nam, chất cotton ấm áp, giá 349k đang sale 280k - rất đáng mua!\n- [6OT24W005]: Áo khoác gió nữ hai lớp, nhẹ nhàng thoáng mát, giá 299k.\n\nBạn kéo xuống xem ảnh chi tiết nhé! 😍",
---
# NGÔN NGỮ & XƯNG HÔ
- Mặc định: Xưng "mình" - gọi "bạn"
- Khi khách xưng anh/chị: Xưng "em" - gọi "anh/chị"
- Khách nói tiếng Việt → Trả lời tiếng Việt
- Khách nói tiếng Anh → Trả lời tiếng Anh
- Ngắn gọn, đi thẳng vào vấn đề
---
# KHI NÀO GỌI TOOL
**Gọi data_retrieval_tool khi:**
- Khách tìm sản phẩm: "Tìm áo...", "Có màu gì..."
- Khách hỏi sản phẩm cụ thể: "Mã 8TS24W001 có không?"
- Tư vấn phong cách: "Mặc gì đi cưới?", "Đồ công sở?"
**⚠️ QUY TẮC SINH QUERY (BẮT BUỘC):**
- **Query chỉ chứa MÔ TẢ SẢN PHẨM** (tên, chất liệu, màu, phong cách).
- **TUYỆT ĐỐI KHÔNG đưa giá tiền vào chuỗi `query`**.
- Giá tiền phải đưa vào tham số riêng: `price_min`, `price_max`.
Ví dụ ĐÚNG:
- Query: "Áo thun nam cotton thoáng mát basic"
- Price_max: 300000
Ví dụ SAI (Cấm):
- Query: "Áo thun nam giá dưới 300k" (SAI vì có giá trong query)
**Gọi canifa_knowledge_search khi:**
- Hỏi chính sách: freeship, đổi trả, bảo hành
- Hỏi thương hiệu: Canifa là gì, lịch sử
- Tìm cửa hàng: địa chỉ, giờ mở cửa
**Không gọi tool khi:**
- Chào hỏi đơn giản: "Hi", "Hello"
- Hỏi lại về sản phẩm vừa show
---
# XỬ LÝ KẾT QUẢ TỪ TOOL
## Sau khi gọi tool, kiểm tra kết quả:
**Trường hợp 1: CÓ sản phẩm phù hợp (đúng loại, đúng yêu cầu)**
- DỪNG LẠI, giới thiệu sản phẩm
- KHÔNG GỌI TOOL LẦN 2
**Trường hợp 2: CÓ kết quả NHƯNG SAI LOẠI**
Ví dụ: Khách hỏi bikini, tool trả về quần nỉ
→ Trả lời thẳng:
"Dạ shop chưa có bikini ạ. Shop chuyên về quần áo thời trang (áo, quần, váy). Bạn có muốn tìm sản phẩm nào khác không?"
CẤM TUYỆT ĐỐI:
- Giới thiệu quần nỉ như thể nó là bikini
- Nói "shop có đồ bơi này bạn tham khảo" khi thực tế là áo/quần thường
**Trường hợp 3: KHÔNG CÓ kết quả (count = 0)**
- Thử lại 1 LẦN với filter rộng hơn
- Nếu vẫn không có:
"Dạ shop chưa có sản phẩm [X] ạ. Bạn có thể tham khảo [loại gần nhất] hoặc ghé shop sau nhé!"
---
# FORMAT ĐẦU RA
Trả về JSON (KHÔNG có markdown backticks):
```json
{{
"ai_response": "Câu trả lời ngắn gọn, mô tả bằng [SKU]",
"product_ids": [
{{"sku": "8TW24W009", "name": "Áo nỉ có mũ nam", "price": 349000, "sale_price": 280000, "url": "https://canifa.com/ao-hoodie-nam-8tw24w009", "thumbnail_image_url": "http://mdp.canifa.com/.../image.jpg"}},
{{"sku": "6OT24W005", "name": "Áo khoác gió nữ hai lớp", "price": 299000, "sale_price": null, "url": "https://canifa.com/ao-khoac-gio-nu-6ot24w005", "thumbnail_image_url": "http://mdp.canifa.com/.../image2.jpg"}}
]
{{
"sku": "8TS24W001",
"name": "Áo thun nam basic",
"price": 200000,
"sale_price": 160000,
"url": "https://canifa.com/...",
"thumbnail_image_url": "https://..."
}}
]
}}
```
# VÍ DỤ (EXAMPLES)
## Example 1: Tìm sản phẩm đơn giản
**Input:** "Áo polo nam dưới 400k"
**Tool Call:**
`data_retrieval_tool(searches=[{{"query": "áo polo nam giá dưới 400k", "keywords": "áo polo", "gender_by_product": "male", "price_max": 400000}}])`
## Example 2: So sánh & Phối đồ
**Input:** "So sánh áo thun đen và sơ mi trắng dưới 500k"
**Tool Call:**
```python
data_retrieval_tool(searches=[
{{"query": "áo thun nam màu đen dưới 500k", "keywords": "áo thun", "master_color": "Đen", "gender_by_product": "male", "price_max": 500000}},
{{"query": "áo sơ mi nam trắng dưới 500k", "keywords": "áo sơ mi", "master_color": "Trắng", "gender_by_product": "male", "price_max": 500000}}
])
```
## Example 3: Tìm theo chất liệu (Mapping)
**Input:** "Tìm đồ vải len cho nữ"
**Tool Call:**
`data_retrieval_tool(searches=[{{"query": "trang phục vải len nữ", "gender_by_product": "female", "material_group": "Yarn - Sợi"}}])`
**Output:**
{{
"ai_response": "Shop có mấy mẫu đồ len nữ đẹp lắm:\n\n- [8SW24W001]: Áo len cổ tròn, chất Yarn - Sợi mềm mại, giá 450k.\n- [6CG24W012]: Váy len dáng A, ấm áp sang trọng, giá 680k đang sale 550k.\n\nBạn xem ảnh chi tiết bên dưới nhé! ✨",
**Quy tắc ai_response:**
- Mô tả ngắn gọn, nhắc sản phẩm bằng [SKU]
- Nói qua giá, chất liệu, điểm nổi bật
- KHÔNG tạo bảng markdown
- KHÔNG đưa link, ảnh (frontend tự render)
---
# VÍ DỤ
## Example 1: Chào hỏi
Input: "Chào shop"
Output:
```json
{{
"ai_response": "Chào bạn! Mình là CiCi, tư vấn thời trang CANIFA. Mình có thể giúp gì cho bạn?",
"product_ids": []
}}
```
## Example 2: Tìm sản phẩm CÓ
Input: "Tìm áo thun nam dưới 300k"
Tool trả về: 2 sản phẩm áo thun phù hợp
Output:
```json
{{
"ai_response": "Shop có 2 mẫu áo thun nam giá dưới 300k:\n\n- [8TS24W009]: Áo thun cotton basic, giá 250k đang sale 200k\n- [6TN24W012]: Áo thun trơn thoải mái, giá 280k\n\nBạn kéo xuống xem ảnh nhé!",
"product_ids": [
{{"sku": "8SW24W001", "name": "Áo len cổ tròn nữ", "price": 450000, "sale_price": null, "url": "https://...", "thumbnail_image_url": "https://..."}},
{{"sku": "6CG24W012", "name": "Váy len dáng A", "price": 680000, "sale_price": 550000, "url": "https://...", "thumbnail_image_url": "https://..."}}
{{"sku": "8TS24W009", "name": "Áo thun cotton basic", "price": 250000, "sale_price": 200000, "url": "...", "thumbnail_image_url": "..."}},
{{"sku": "6TN24W012", "name": "Áo thun trơn", "price": 280000, "sale_price": null, "url": "...", "thumbnail_image_url": "..."}}
]
}}
}}
```
## Example 3: Khách hỏi KHÔNG CÓ trong kho
Input: "Shop có bikini không?"
Tool trả về: 0 sản phẩm
Output:
```json
{{
"ai_response": "Dạ shop chưa có bikini ạ. CANIFA chuyên về quần áo thời trang như áo, quần, váy, đầm. Bạn có muốn tìm mẫu nào khác không?",
"product_ids": []
}}
```
## Example 4: Tool trả về SAI LOẠI
Input: "Cho tôi xem đồ bơi"
Tool trả về: Quần nỉ, áo nỉ (SAI HOÀN TOÀN so với đồ bơi)
Output:
```json
{{
"ai_response": "Dạ shop chưa có đồ bơi ạ. Shop chuyên bán quần áo thời trang (áo, quần, váy, áo khoác). Bạn có muốn tìm loại sản phẩm nào khác không?",
"product_ids": []
}}
```
TUYỆT ĐỐI KHÔNG giới thiệu sản phẩm sai loại
## Example 5: Khách xưng anh/chị
Input: "Chào em, anh muốn tìm áo sơ mi"
Output:
```json
{{
"ai_response": "Chào anh ạ! Em là CiCi. Anh đang tìm áo sơ mi dài tay hay ngắn tay ạ? Để em tư vấn mẫu phù hợp nhất cho anh nhé!",
"product_ids": []
}}
```
---
# TÓM TẮT
---
1. CANIFA bán quần áo (áo, quần, váy, đầm, phụ kiện)
2. Không có trong data = Không nói
3. Kiểm tra kỹ tên sản phẩm trước khi giới thiệu
4. Nếu sai loại → Nói thẳng "shop chưa có X"
5. Không bịa giá, mã sản phẩm, chính sách
6. Có kết quả phù hợp = DỪNG, không gọi tool lần 2
7. Trả lời ngắn gọn, dựa 100% vào dữ liệu tool trả về
# BỐI CẢNH (CONTEXT)
- ai_response: Ngắn gọn, mô tả sản phẩm qua bằng [SKU], không tạo bảng markdown.
- product_ids: Chứa danh sách SKU - frontend sẽ render chi tiết.
- Luôn trả lời đầy đủ, trau chuốt, không bỏ sót thông tin quan trọng.
---
---"""
Luôn thành thật, khéo léo, và chuyên nghiệp."""
# Format using f-string syntax (handled by prompt template mechanism or direct replace if strict)
# Since specific replacement logic was requested:
return prompt.replace("{date_str}", date_str)
\ No newline at end of file
# """
# CANIFA Data Retrieval Tool - Tối giản cho Agentic Workflow.
# Hỗ trợ Hybrid Search: Semantic (Vector) + Metadata Filter.
# """
# import asyncio
# import json
# import logging
# from decimal import Decimal
# from langchain_core.tools import tool
# from pydantic import BaseModel, Field
# from agent.tools.product_search_helpers import build_starrocks_query
# from common.starrocks_connection import StarRocksConnection
# from langsmith import traceable
# logger = logging.getLogger(__name__)
# class DecimalEncoder(json.JSONEncoder):
# """Xử lý kiểu Decimal từ Database khi convert sang JSON."""
# def default(self, obj):
# if isinstance(obj, Decimal):
# return float(obj)
# return super().default(obj)
# class SearchItem(BaseModel):
# """Cấu trúc một mục tìm kiếm đơn lẻ trong Multi-Search."""
# query: str = Field(
# ...,
# description="Câu hỏi/mục đích tự do của user (đi chơi, dự tiệc, phỏng vấn,...) - dùng cho Semantic Search",
# )
# keywords: str | None = Field(
# ..., description="Từ khóa sản phẩm cụ thể (áo polo, quần jean,...) - dùng cho LIKE search"
# )
# magento_ref_code: str | None = Field(
# ..., description="Mã sản phẩm hoặc mã màu/SKU (Ví dụ: 8TS24W001 hoặc 8TS24W001-SK010)."
# )
# product_line_vn: str | None = Field(..., description="Dòng sản phẩm. Giá trị: Áo phông, Quần short, Váy liền, Áo Polo, Áo len, Áo khoác, Quần jean, Quần Khaki, Somi, Blazer, v.v.")
# gender_by_product: str | None = Field(..., description="Giới tính. Giá trị: female, male, others")
# age_by_product: str | None = Field(..., description="Độ tuổi. Giá trị: adult, others (Kids)")
# master_color: str | None = Field(..., description="Màu sắc chính. Giá trị: Đen/ Black, Trắng/ White, Hồng/ Pink, Xanh da trời/ Blue, Be/ Beige, Đỏ/ Red, Vàng/ Yellow, Tím/ Purple, v.v.")
# material_group: str | None = Field(
# ...,
# description="Nhóm chất liệu. Giá trị: 'Knit - Dệt Kim', 'Woven - Dệt Thoi', 'Yarn - Sợi', 'Knit/Woven - Dệt Kim/Dệt Thoi'.",
# )
# season: str | None = Field(..., description="Mùa. Giá trị: Spring Summer, Fall Winter, Year, Collection")
# style: str | None = Field(..., description="Phong cách. Giá trị: Basic, Basic Update, Feminine, Dynamic, Smart Casual, Athleisure, Utility, Trend")
# fitting: str | None = Field(..., description="Form dáng. Giá trị: Regular, Slim, Slimfit, Skinny, Relax, Boxy, Oversize, Baby tee")
# size_scale: str | None = Field(..., description="Thang size. Giá trị: [Người lớn: S, M, L, XL, XS, XXL, XXXL, XXS, Free Size], [Quần/Váy: 26-33], [Trẻ em (chiều cao): 90Cm-160Cm, 92, 98, 104...], [Trẻ em (tuổi): 2/3, 4/6, 7/9, 10/12, 13/14]")
# form_neckline: str | None = Field(..., description="Kiểu cổ. Giá trị: Crew Neck, V-neck, Classic Collar, Hooded collar, Turtle Neck, Mock Neck, Square, v.v.")
# form_sleeve: str | None = Field(..., description="Kiểu tay. Giá trị: Short Sleeve, Full length Sleeve, Sleeveless, Balloon Sleeve, Puff, v.v.")
# weaving: str | None = Field(..., description="Kiểu dệt: Velvet, Twill, Plain, French Terry, Interlock, v.v.")
# graphic: str | None = Field(..., description="Họa tiết hình in: Artwork, Repeated pattern, v.v.")
# pattern: str | None = Field(..., description="Thông số định lượng/mẫu: 260G, 186G, 195G, v.v.")
# shape_detail: str | None = Field(..., description="Chi tiết kiểu dáng: Fit and Flare, Shift, A line, v.v.")
# form_length: str | None = Field(..., description="Chiều dài: Short Length, v.v.")
# form_waistline: str | None = Field(..., description="Kiểu cạp: High Rise, Mid Rise/ Regular rise, v.v.")
# form_shoulderline: str | None = Field(..., description="Kiểu vai: Drop Shoulder, Regular shoulder, v.v.")
# material: str | None = Field(..., description="Vải cụ thể: 100% Cotton, Polyester, v.v.")
# price_min: float | None = Field(..., description="Giá thấp nhất")
# price_max: float | None = Field(..., description="Giá cao nhất")
# action: str = Field(..., description="Hành động: 'search' (tìm kiếm) hoặc 'visual_search' (phân tích ảnh)")
# class MultiSearchParams(BaseModel):
# """Tham số cho Parallel Multi-Search."""
# searches: list[SearchItem] = Field(..., description="Danh sách các truy vấn tìm kiếm chạy song song")
# @tool(args_schema=MultiSearchParams)
# @traceable(run_type="tool", name="data_retrieval_tool")
# async def data_retrieval_tool(searches: list[SearchItem]) -> str:
# """
# Siêu công cụ tìm kiếm sản phẩm CANIFA - Hỗ trợ Parallel Multi-Search (Chạy song song nhiều query).
# 💡 ĐIỂM ĐẶC BIỆT:
# Công cụ này cho phép thực hiện NHIỀU truy vấn tìm kiếm CÙNG LÚC.
# Hãy dùng nó khi cần SO SÁNH sản phẩm hoặc tìm trọn bộ OUTFIT (mix & match).
# ⚠️ QUAN TRỌNG - KHI NÀO DÙNG GÌ:
# 1️⃣ DÙNG 'query' (Semantic Search - BUỘC PHẢI CÓ):
# - Áp dụng cho mọi lượt search để cung cấp bối cảnh (context).
# - Ví dụ: "áo thun nam đi biển", "quần tây công sở", "đồ cho bé màu xanh"...
# 2️⃣ DÙNG METADATA FILTERS (Exact/Partial Match):
# - Khi khách nói rõ THUỘC TÍNH: Màu sắc, giá, giới tính, độ tuổi, mã sản phẩm.
# - **QUY TẮC MÃ SẢN PHẨM:** Mọi loại mã (VD: `8TS...` hoặc `8TS...-SK...`) → Điền vào `magento_ref_code`.
# - **QUY TẮC CHẤT LIÊU (material_group):** Chỉ dùng: `Yarn - Sợi`, `Knit - Dệt Kim`, `Woven - Dệt Thoi`, `Knit/Woven - Dệt Kim/Dệt Thoi`.
# 📝 VÍ DỤ CHI TIẾT (Single Search):
# - Example 1: searches=[{"query": "áo polo nam giá dưới 400k", "keywords": "áo polo", "gender_by_product": "male", "price_max": 400000}]
# - Example 2: searches=[{"query": "sản phẩm mã 8TS24W001", "magento_ref_code": "8TS24W001"}]
# 🚀 VÍ DỤ CẤP CAO (Multi-Search Parallel):
# - Example 3 - So sánh: "So sánh áo thun nam đen và áo sơ mi trắng dưới 500k"
# Tool Call: searches=[
# {"query": "áo thun nam màu đen dưới 500k", "keywords": "áo thun", "master_color": "Đen", "gender_by_product": "male", "price_max": 500000},
# {"query": "áo sơ mi nam trắng dưới 500k", "keywords": "áo sơ mi", "master_color": "Trắng", "gender_by_product": "male", "price_max": 500000}
# ]
# - Example 4 - Phối đồ: "Tìm cho mình một cái quần jean và một cái áo khoác để đi chơi"
# Tool Call: searches=[
# {"query": "quần jean đi chơi năng động", "keywords": "quần jean"},
# {"query": "áo khoác đi chơi năng động", "keywords": "áo khoác"}
# ]
# - Example 5 - Cả gia đình: "Tìm áo phông màu xanh cho bố, mẹ và bé trai"
# Tool Call: searches=[
# {"query": "áo phông nam người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "adult"},
# {"query": "áo phông nữ người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "female", "age_by_product": "adult"},
# {"query": "áo phông bé trai màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "others"}
# ]
# """
# try:
# db = StarRocksConnection()
# # 0. Log input parameters (Đúng ý bro)
# logger.info(f"📥 [Tool Input] data_retrieval_tool received {len(searches)} items:")
# for idx, item in enumerate(searches):
# logger.info(f" 🔹 Item [{idx}]: {item.dict(exclude_none=True)}")
# # 1. Tạo tasks chạy song song (Parallel)
# tasks = []
# for item in searches:
# tasks.append(_execute_single_search(db, item))
# logger.info(f"🚀 [Parallel Search] Executing {len(searches)} queries simultaneously...")
# results = await asyncio.gather(*tasks)
# # 2. Tổng hợp kết quả
# combined_results = []
# for i, products in enumerate(results):
# combined_results.append({
# "search_index": i,
# "search_criteria": searches[i].dict(exclude_none=True),
# "count": len(products),
# "products": products
# })
# return json.dumps(
# {"status": "success", "results": combined_results},
# ensure_ascii=False,
# cls=DecimalEncoder
# )
# except Exception as e:
# logger.error(f"Error in Multi-Search data_retrieval_tool: {e}")
# return json.dumps({"status": "error", "message": str(e)})
# @traceable(name="starrocks_query", run_type="tool")
# async def _execute_db_query(db: StarRocksConnection, sql: str) -> list[dict]:
# """Execute SQL query with LangSmith tracing and local logging."""
# import time
# start_time = time.perf_counter()
# try:
# products = await db.execute_query_async(sql)
# duration_ms = (time.perf_counter() - start_time) * 1000
# logger.info(f"⏱️ [DB Latency] SQL Execution: {duration_ms:.2f}ms | Rows: {len(products)}")
# return products
# except Exception as e:
# logger.error(f"❌ DB Execution Failed: {e}")
# raise e
# async def _execute_single_search(db: StarRocksConnection, item: SearchItem) -> list[dict]:
# """Thực thi một search query đơn lẻ (Async)."""
# try:
# # build_starrocks_query handles embedding internally (async)
# sql = await build_starrocks_query(item)
# products = await _execute_db_query(db, sql)
# return _format_product_results(products)
# except Exception as e:
# logger.error(f"Single search error for item {item}: {e}")
# return []
# def _format_product_results(products: list[dict]) -> list[dict]:
# """Lọc và format kết quả trả về cho Agent."""
# allowed_fields = {
# "internal_ref_code",
# "magento_ref_code",
# "product_color_code",
# "product_name",
# "color_code",
# "master_color",
# "product_color_name",
# "season_sale",
# "season",
# "style",
# "fitting",
# "size_scale",
# "graphic",
# "pattern",
# "weaving",
# "shape_detail",
# "form_neckline",
# "form_sleeve",
# "form_length",
# "form_waistline",
# "form_shoulderline",
# "material",
# "product_group",
# "product_line_vn",
# "unit_of_measure",
# "sale_price",
# "original_price",
# "material_group",
# "product_line_en",
# "age_by_product",
# "gender_by_product",
# "product_image_url",
# "description_text",
# "product_image_url_thumbnail",
# "product_web_url",
# "product_web_material",
# "max_score",
# "similarity_score",
# }
# return [{k: v for k, v in p.items() if k in allowed_fields} for p in products[:5]]
"""
CANIFA Data Retrieval Tool - Tối giản cho Agentic Workflow.
Hỗ trợ Hybrid Search: Semantic (Vector) + Metadata Filter.
......@@ -238,7 +12,7 @@ from decimal import Decimal
from langchain_core.tools import tool
from pydantic import BaseModel, Field
from agent.tools.product_search_helpers import build_starrocks_query
from agent.tools.product_search_helpers import build_starrocks_query, save_preview_to_log
from common.starrocks_connection import StarRocksConnection
# from langsmith import traceable
......@@ -260,34 +34,19 @@ class SearchItem(BaseModel):
query: str = Field(
...,
description="Câu hỏi/mục đích tự do của user (đi chơi, dự tiệc, phỏng vấn,...) - dùng cho Semantic Search",
)
keywords: str | None = Field(
..., description="Từ khóa sản phẩm cụ thể (áo polo, quần jean,...) - dùng cho LIKE search"
description="MÔ TẢ sản phẩm chi tiết (KHÔNG phải câu hỏi thô). VD: 'Áo thun nam cotton basic trẻ trung, phù hợp đi chơi hàng ngày'. Bao gồm: tên SP, chất liệu, phong cách, giới tính (nếu có), màu sắc (nếu có), dịp sử dụng.",
)
magento_ref_code: str | None = Field(
..., description="Mã sản phẩm hoặc mã màu/SKU (Ví dụ: 8TS24W001 hoặc 8TS24W001-SK010)."
..., description="Mã sản phẩm hoặc SKU (Ví dụ: 8TS24W001). CHỈ điền khi khách hỏi mã code cụ thể."
)
product_line_vn: str | None = Field(..., description="Dòng sản phẩm (Áo phông, Quần short,...)")
gender_by_product: str | None = Field(..., description="Giới tính: male, female")
age_by_product: str | None = Field(..., description="Độ tuổi: adult, kids, baby, others")
master_color: str | None = Field(..., description="Màu sắc chính (Đen/ Black, Trắng/ White,...)")
material_group: str | None = Field(
...,
description="Nhóm chất liệu. BẮT BUỘC dùng đúng: 'Yarn - Sợi', 'Knit - Dệt Kim', 'Woven - Dệt Thoi', 'Knit/Woven - Dệt Kim/Dệt Thoi'.",
)
season: str | None = Field(..., description="Mùa (Spring Summer, Autumn Winter)")
style: str | None = Field(..., description="Phong cách (Basic Update, Fashion,...)")
fitting: str | None = Field(..., description="Form dáng (Regular, Slim, Loose,...)")
form_neckline: str | None = Field(..., description="Kiểu cổ (Crew Neck, V-neck,...)")
form_sleeve: str | None = Field(..., description="Kiểu tay (Short Sleeve, Long Sleeve,...)")
price_min: float | None = Field(..., description="Giá thấp nhất")
price_max: float | None = Field(..., description="Giá cao nhất")
price_min: float | None = Field(..., description="Giá thấp nhất (VD: 100000)")
price_max: float | None = Field(..., description="Giá cao nhất (VD: 500000)")
action: str = Field(..., description="Hành động: 'search' (tìm kiếm) hoặc 'visual_search' (phân tích ảnh)")
class MultiSearchParams(BaseModel):
"""Tham số cho Parallel Multi-Search."""
searches: list[SearchItem] = Field(..., description="Danh sách các truy vấn tìm kiếm chạy song song")
......@@ -301,37 +60,31 @@ async def data_retrieval_tool(searches: list[SearchItem]) -> str:
Công cụ này cho phép thực hiện NHIỀU truy vấn tìm kiếm CÙNG LÚC.
Hãy dùng nó khi cần SO SÁNH sản phẩm hoặc tìm trọn bộ OUTFIT (mix & match).
⚠️ QUAN TRỌNG - KHI NÀO DÙNG GÌ:
⚠️ QUAN TRỌNG - CÁCH DÙNG:
1️⃣ DÙNG 'query' (Semantic Search - BUỘC PHẢI CÓ):
- Áp dụng cho mọi lượt search để cung cấp bối cảnh (context).
- Ví dụ: "áo thun nam đi biển", "quần tây công sở", "đồ cho bé màu xanh"...
1️⃣ DÙNG 'query' (HyDE Semantic Search - BẮT BUỘC):
- MÔ TẢ chi tiết sản phẩm: tên, chất liệu, giới tính, màu sắc, phong cách, dịp sử dụng
- VD: "Áo thun nam cotton màu đỏ basic trẻ trung, phù hợp đi chơi hàng ngày"
- **KHÔNG viết câu hỏi thô**, KHÔNG ném giá vào query
2️⃣ DÙNG METADATA FILTERS (Exact/Partial Match):
- Khi khách nói rõ THUỘC TÍNH: Màu sắc, giá, giới tính, độ tuổi, mã sản phẩm.
- **QUY TẮC MÃ SẢN PHẨM:** Mọi loại mã (VD: `8TS...` hoặc `8TS...-SK...`) → Điền vào `magento_ref_code`.
- **QUY TẮC CHẤT LIÊU (material_group):** Chỉ dùng: `Yarn - Sợi`, `Knit - Dệt Kim`, `Woven - Dệt Thoi`, `Knit/Woven - Dệt Kim/Dệt Thoi`.
2️⃣ DÙNG 'magento_ref_code':
- CHỈ khi khách hỏi mã sản phẩm cụ thể: "Mã 8TS24W001", "SP 6OT25W020"
📝 VÍ DỤ CHI TIẾT (Single Search):
- Example 1: searches=[{"query": "áo polo nam giá dưới 400k", "keywords": "áo polo", "gender_by_product": "male", "price_max": 400000}]
- Example 2: searches=[{"query": "sản phẩm mã 8TS24W001", "magento_ref_code": "8TS24W001"}]
3️⃣ DÙNG 'price_min' / 'price_max':
- Khi khách nói về giá: "dưới 500k", "từ 200k đến 400k"
🚀 VÍ DỤ CẤP CAO (Multi-Search Parallel):
- Example 3 - So sánh: "So sánh áo thun nam đen và áo sơ mi trắng dưới 500k"
Tool Call: searches=[
{"query": "áo thun nam màu đen dưới 500k", "keywords": "áo thun", "master_color": "Đen", "gender_by_product": "male", "price_max": 500000},
{"query": "áo sơ mi nam trắng dưới 500k", "keywords": "áo sơ mi", "master_color": "Trắng", "gender_by_product": "male", "price_max": 500000}
]
- Example 4 - Phối đồ: "Tìm cho mình một cái quần jean và một cái áo khoác để đi chơi"
Tool Call: searches=[
{"query": "quần jean đi chơi năng động", "keywords": "quần jean"},
{"query": "áo khoác đi chơi năng động", "keywords": "áo khoác"}
📝 VÍ DỤ (Single Search):
- searches=[{"query": "Áo polo nam cotton cao cấp lịch sự công sở", "price_max": 400000}]
- searches=[{"magento_ref_code": "8TS24W001"}]
🚀 VÍ DỤ (Multi-Search):
- So sánh: searches=[
{"query": "Áo thun nam cotton màu đen basic casual đi chơi", "price_max": 500000},
{"query": "Áo sơ mi nam màu trắng lịch sự công sở", "price_max": 500000}
]
- Example 5 - Cả gia đình: "Tìm áo phông màu xanh cho bố, mẹ và bé trai"
Tool Call: searches=[
{"query": "áo phông nam người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "adult"},
{"query": "áo phông nữ người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "female", "age_by_product": "adult"},
{"query": "áo phông bé trai màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "others"}
- Phối đồ: searches=[
{"query": "Quần jean nam slim fit năng động"},
{"query": "Áo khoác nam thể thao trẻ trung"}
]
"""
logger.info("🔧 [DEBUG] data_retrieval_tool STARTED")
......@@ -359,19 +112,17 @@ async def data_retrieval_tool(searches: list[SearchItem]) -> str:
# 2. Tổng hợp kết quả
combined_results = []
for i, products in enumerate(results):
combined_results.append({
combined_results.append(
{
"search_index": i,
"search_criteria": searches[i].dict(exclude_none=True),
"count": len(products),
"products": products
})
return json.dumps(
{"status": "success", "results": combined_results},
ensure_ascii=False,
cls=DecimalEncoder
"products": products,
}
)
return json.dumps({"status": "success", "results": combined_results}, ensure_ascii=False, cls=DecimalEncoder)
except Exception as e:
logger.error(f"Error in Multi-Search data_retrieval_tool: {e}")
return json.dumps({"status": "error", "message": str(e)})
......@@ -399,6 +150,10 @@ async def _execute_single_search(db: StarRocksConnection, item: SearchItem) -> l
logger.info(f"⏱️ [TIMER] DB Query Execution Time: {db_time:.2f}ms")
logger.info(f"⏱️ [TIMER] Total Time (Build + DB): {query_build_time + db_time:.2f}ms")
# Ghi log DB Preview (Kết quả thực tế) vào Background Task
search_label = item.magento_ref_code if item.magento_ref_code else item.query
asyncio.create_task(save_preview_to_log(search_label, products))
return _format_product_results(products)
except Exception as e:
logger.error(f"Single search error for item {item}: {e}")
......@@ -409,40 +164,10 @@ def _format_product_results(products: list[dict]) -> list[dict]:
"""Lọc và format kết quả trả về cho Agent."""
allowed_fields = {
"internal_ref_code",
"magento_ref_code",
"product_color_code",
"product_name",
"color_code",
"master_color",
"product_color_name",
"season_sale",
"season",
"style",
"fitting",
"size_scale",
"graphic",
"pattern",
"weaving",
"shape_detail",
"form_neckline",
"form_sleeve",
"form_length",
"form_waistline",
"form_shoulderline",
"material",
"product_group",
"product_line_vn",
"unit_of_measure",
"description_text_full",
"sale_price",
"original_price",
"material_group",
"product_line_en",
"age_by_product",
"gender_by_product",
"product_image_url",
"description_text",
"product_image_url_thumbnail",
"product_web_url",
"product_web_material",
"discount_amount",
"max_score",
}
return [{k: v for k, v in p.items() if k in allowed_fields} for p in products[:5]]
"""
CANIFA Data Retrieval Tool - Tối giản cho Agentic Workflow.
Hỗ trợ Hybrid Search: Semantic (Vector) + Metadata Filter.
"""
import asyncio
import json
import logging
import time
from decimal import Decimal
from langchain_core.tools import tool
from pydantic import BaseModel, Field
from agent.tools.product_search_helpers import build_starrocks_query
from common.starrocks_connection import StarRocksConnection
# from langsmith import traceable
logger = logging.getLogger(__name__)
class DecimalEncoder(json.JSONEncoder):
"""Xử lý kiểu Decimal từ Database khi convert sang JSON."""
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj)
class SearchItem(BaseModel):
"""Cấu trúc một mục tìm kiếm đơn lẻ trong Multi-Search."""
query: str = Field(
...,
description="Câu hỏi/mục đích tự do của user (đi chơi, dự tiệc, phỏng vấn,...) - dùng cho Semantic Search",
)
keywords: str | None = Field(
..., description="Từ khóa sản phẩm cụ thể (áo polo, quần jean,...) - dùng cho LIKE search"
)
magento_ref_code: str | None = Field(
..., description="Mã sản phẩm hoặc mã màu/SKU (Ví dụ: 8TS24W001 hoặc 8TS24W001-SK010)."
)
product_line_vn: str | None = Field(..., description="Dòng sản phẩm (Áo phông, Quần short,...)")
gender_by_product: str | None = Field(..., description="Giới tính: male, female")
age_by_product: str | None = Field(..., description="Độ tuổi: adult, kids, baby, others")
master_color: str | None = Field(..., description="Màu sắc chính (Đen/ Black, Trắng/ White,...)")
material_group: str | None = Field(
...,
description="Nhóm chất liệu. BẮT BUỘC dùng đúng: 'Yarn - Sợi', 'Knit - Dệt Kim', 'Woven - Dệt Thoi', 'Knit/Woven - Dệt Kim/Dệt Thoi'.",
)
season: str | None = Field(..., description="Mùa (Spring Summer, Autumn Winter)")
style: str | None = Field(..., description="Phong cách (Basic Update, Fashion,...)")
fitting: str | None = Field(..., description="Form dáng (Regular, Slim, Loose,...)")
form_neckline: str | None = Field(..., description="Kiểu cổ (Crew Neck, V-neck,...)")
form_sleeve: str | None = Field(..., description="Kiểu tay (Short Sleeve, Long Sleeve,...)")
price_min: float | None = Field(..., description="Giá thấp nhất")
price_max: float | None = Field(..., description="Giá cao nhất")
action: str = Field(..., description="Hành động: 'search' (tìm kiếm) hoặc 'visual_search' (phân tích ảnh)")
class MultiSearchParams(BaseModel):
"""Tham số cho Parallel Multi-Search."""
searches: list[SearchItem] = Field(..., description="Danh sách các truy vấn tìm kiếm chạy song song")
@tool(args_schema=MultiSearchParams)
# @traceable(run_type="tool", name="data_retrieval_tool")
async def data_retrieval_tool(searches: list[SearchItem]) -> str:
"""
Siêu công cụ tìm kiếm sản phẩm CANIFA - Hỗ trợ Parallel Multi-Search (Chạy song song nhiều query).
💡 ĐIỂM ĐẶC BIỆT:
Công cụ này cho phép thực hiện NHIỀU truy vấn tìm kiếm CÙNG LÚC.
Hãy dùng nó khi cần SO SÁNH sản phẩm hoặc tìm trọn bộ OUTFIT (mix & match).
⚠️ QUAN TRỌNG - KHI NÀO DÙNG GÌ:
1️⃣ DÙNG 'query' (Semantic Search - BUỘC PHẢI CÓ):
- Áp dụng cho mọi lượt search để cung cấp bối cảnh (context).
- Ví dụ: "áo thun nam đi biển", "quần tây công sở", "đồ cho bé màu xanh"...
2️⃣ DÙNG METADATA FILTERS (Exact/Partial Match):
- Khi khách nói rõ THUỘC TÍNH: Màu sắc, giá, giới tính, độ tuổi, mã sản phẩm.
- **QUY TẮC MÃ SẢN PHẨM:** Mọi loại mã (VD: `8TS...` hoặc `8TS...-SK...`) → Điền vào `magento_ref_code`.
- **QUY TẮC CHẤT LIÊU (material_group):** Chỉ dùng: `Yarn - Sợi`, `Knit - Dệt Kim`, `Woven - Dệt Thoi`, `Knit/Woven - Dệt Kim/Dệt Thoi`.
📝 VÍ DỤ CHI TIẾT (Single Search):
- Example 1: searches=[{"query": "áo polo nam giá dưới 400k", "keywords": "áo polo", "gender_by_product": "male", "price_max": 400000}]
- Example 2: searches=[{"query": "sản phẩm mã 8TS24W001", "magento_ref_code": "8TS24W001"}]
🚀 VÍ DỤ CẤP CAO (Multi-Search Parallel):
- Example 3 - So sánh: "So sánh áo thun nam đen và áo sơ mi trắng dưới 500k"
Tool Call: searches=[
{"query": "áo thun nam màu đen dưới 500k", "keywords": "áo thun", "master_color": "Đen", "gender_by_product": "male", "price_max": 500000},
{"query": "áo sơ mi nam trắng dưới 500k", "keywords": "áo sơ mi", "master_color": "Trắng", "gender_by_product": "male", "price_max": 500000}
]
- Example 4 - Phối đồ: "Tìm cho mình một cái quần jean và một cái áo khoác để đi chơi"
Tool Call: searches=[
{"query": "quần jean đi chơi năng động", "keywords": "quần jean"},
{"query": "áo khoác đi chơi năng động", "keywords": "áo khoác"}
]
- Example 5 - Cả gia đình: "Tìm áo phông màu xanh cho bố, mẹ và bé trai"
Tool Call: searches=[
{"query": "áo phông nam người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "adult"},
{"query": "áo phông nữ người lớn màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "female", "age_by_product": "adult"},
{"query": "áo phông bé trai màu xanh", "keywords": "áo phông", "master_color": "Xanh", "gender_by_product": "male", "age_by_product": "others"}
]
"""
logger.info("🔧 [DEBUG] data_retrieval_tool STARTED")
try:
logger.info("🔧 [DEBUG] Creating StarRocksConnection instance")
db = StarRocksConnection()
logger.info("🔧 [DEBUG] StarRocksConnection created successfully")
# 0. Log input parameters (Đúng ý bro)
logger.info(f"📥 [Tool Input] data_retrieval_tool received {len(searches)} items:")
for idx, item in enumerate(searches):
logger.info(f" 🔹 Item [{idx}]: {item.dict(exclude_none=True)}")
# 1. Tạo tasks chạy song song (Parallel)
logger.info("🔧 [DEBUG] Creating parallel tasks")
tasks = []
for item in searches:
tasks.append(_execute_single_search(db, item))
logger.info(f"🚀 [Parallel Search] Executing {len(searches)} queries simultaneously...")
logger.info("🔧 [DEBUG] About to call asyncio.gather()")
results = await asyncio.gather(*tasks)
logger.info(f"🔧 [DEBUG] asyncio.gather() completed with {len(results)} results")
# 2. Tổng hợp kết quả
combined_results = []
for i, products in enumerate(results):
combined_results.append(
{
"search_index": i,
"search_criteria": searches[i].dict(exclude_none=True),
"count": len(products),
"products": products,
}
)
return json.dumps({"status": "success", "results": combined_results}, ensure_ascii=False, cls=DecimalEncoder)
except Exception as e:
logger.error(f"Error in Multi-Search data_retrieval_tool: {e}")
return json.dumps({"status": "error", "message": str(e)})
async def _execute_single_search(db: StarRocksConnection, item: SearchItem) -> list[dict]:
"""Thực thi một search query đơn lẻ (Async)."""
try:
logger.info(f"🔧 [DEBUG] _execute_single_search STARTED for query: {item.query[:50] if item.query else 'None'}")
# ⏱️ Timer: Build query (bao gồm embedding nếu có)
query_build_start = time.time()
logger.info("🔧 [DEBUG] Calling build_starrocks_query()")
sql = await build_starrocks_query(item)
query_build_time = (time.time() - query_build_start) * 1000 # Convert to ms
logger.info(f"🔧 [DEBUG] SQL query built, length: {len(sql)}")
logger.info(f"⏱️ [TIMER] Query Build Time (bao gồm embedding): {query_build_time:.2f}ms")
# ⏱️ Timer: Execute DB query
db_start = time.time()
logger.info("🔧 [DEBUG] Calling db.execute_query_async()")
products = await db.execute_query_async(sql)
db_time = (time.time() - db_start) * 1000 # Convert to ms
logger.info(f"🔧 [DEBUG] Query executed, got {len(products)} products")
logger.info(f"⏱️ [TIMER] DB Query Execution Time: {db_time:.2f}ms")
logger.info(f"⏱️ [TIMER] Total Time (Build + DB): {query_build_time + db_time:.2f}ms")
return _format_product_results(products)
except Exception as e:
logger.error(f"Single search error for item {item}: {e}")
return []
def _format_product_results(products: list[dict]) -> list[dict]:
"""Lọc và format kết quả trả về cho Agent."""
allowed_fields = {
"internal_ref_code",
"description_text_full",
}
return [{k: v for k, v in p.items() if k in allowed_fields} for p in products[:5]]
# import logging
# from common.embedding_service import create_embedding_async
# logger = logging.getLogger(__name__)
# def _escape(val: str) -> str:
# """Thoát dấu nháy đơn để tránh SQL Injection cơ bản."""
# return val.replace("'", "''")
# def _get_where_clauses(params) -> list[str]:
# """
# Xây dựng WHERE clauses theo thứ tự ưu tiên dựa trên selectivity thực tế
# FILTER PRIORITY (Based on Canifa catalog analysis):
# 🔥 TIER 1 (99% selectivity):
# 1. SKU Code → 1-5 records
# 🎯 TIER 2 (50-70% selectivity):
# 2. Gender → Splits catalog in half
# 3. Age → Kids vs Adults split
# 4. Product Category → 10-15 categories
# 💎 TIER 3 (30-50% selectivity):
# 5. Material Group → Knit vs Woven (2 groups)
# 6. Price Range → Numeric filtering
# 🎨 TIER 4 (10-30% selectivity):
# 7. Season → 4 seasons
# 8. Style/Fitting → Multiple options
# ⚠️ TIER 5 (<10% selectivity):
# 9. Form details → Granular attributes
# 10. Color → LOWEST selectivity (many SKUs share colors)
# Early return: If SKU exists, skip low-selectivity filters
# """
# clauses = []
# # 🔥 TIER 1: SKU/Product Code (Unique identifier)
# # Selectivity: ~99% → 1 SKU = 1 style (3-5 colors max)
# sku_clause = _get_sku_clause(params)
# if sku_clause:
# clauses.append(sku_clause)
# # Early return optimization: SKU đã xác định product rõ ràng
# # CHỈ GIỮ LẠI price filter (nếu có) để verify budget constraint
# # BỎ QUA: gender, color, style, fitting... vì SKU đã unique
# price_clauses = _get_price_clauses(params)
# if price_clauses:
# clauses.extend(price_clauses)
# return clauses # ⚡ STOP - Không thêm filter khác!
# # 🎯 TIER 2: High-level categorization (50-70% reduction)
# # Gender + Age + Category có selectivity cao nhất trong non-SKU filters
# clauses.extend(_get_high_selectivity_clauses(params))
# # 💎 TIER 3: Material & Price (30-50% reduction)
# material_clause = _get_material_clause(params)
# if material_clause:
# clauses.append(material_clause)
# clauses.extend(_get_price_clauses(params))
# # 🎨 TIER 4: Attributes (10-30% reduction)
# clauses.extend(_get_attribute_clauses(params))
# # ⚠️ TIER 5: Granular details & Color (LAST - lowest selectivity)
# clauses.extend(_get_form_detail_clauses(params))
# color_clause = _get_color_clause(params)
# if color_clause:
# clauses.append(color_clause) # Color ALWAYS LAST!
# return clauses
# def _get_sku_clause(params) -> str | None:
# """
# TIER 1: SKU/Product Code (Highest selectivity - 99%)
# 1 SKU code = 1 product style (may have 3-5 color variants)
# WHY SKU is always priority #1:
# - 1 code = 1 unique product design
# - Adding other filters (color, style, gender) is redundant
# - Only price filter may be kept for budget validation
# Example queries:
# - "Mã 6OT25W010" → Only SKU needed
# - "Mã 6OT25W010 màu xám" → Only SKU (color is for display/selection, not filtering)
# - "Mã 6OT25W010 dưới 500k" → SKU + price (validate budget)
# """
# m_code = getattr(params, "magento_ref_code", None)
# if m_code:
# m = _escape(m_code)
# return f"(magento_ref_code = '{m}' OR internal_ref_code = '{m}')"
# return None
# def _get_color_clause(params) -> str | None:
# """
# TIER 5: Color (LOWEST selectivity - 5-10%)
# Multiple SKUs share the same color (e.g., 50+ gray products)
# ALWAYS filter color LAST after other constraints
# """
# color = getattr(params, "master_color", None)
# if color:
# c = _escape(color).lower()
# return f"(LOWER(master_color) LIKE '%{c}%' OR LOWER(product_color_name) LIKE '%{c}%')"
# return None
# def _get_high_selectivity_clauses(params) -> list[str]:
# """
# TIER 2: High-level categorization (50-70% reduction per filter)
# Order: Gender → Age → Product Category
# """
# clauses = []
# # Gender: Male/Female/Unisex split (50-70% reduction)
# gender = getattr(params, "gender_by_product", None)
# if gender:
# clauses.append(f"gender_by_product = '{_escape(gender)}'")
# # Age: Kids/Adults split (50% reduction of remaining)
# age = getattr(params, "age_by_product", None)
# if age:
# clauses.append(f"age_by_product = '{_escape(age)}'")
# # Product Category: Váy/Áo/Quần... (30-50% reduction)
# product_line = getattr(params, "product_line_vn", None)
# if product_line:
# p = _escape(product_line).lower()
# clauses.append(f"LOWER(product_line_vn) LIKE '%{p}%'")
# return clauses
# def _get_material_clause(params) -> str | None:
# """TIER 3: Material Group - Knit vs Woven (50% split)"""
# material = getattr(params, "material_group", None)
# if material:
# m = _escape(material).lower()
# return f"LOWER(material_group) LIKE '%{m}%'"
# return None
# def _get_price_clauses(params) -> list[str]:
# """TIER 3: Price Range - Numeric filtering (30-40% reduction)"""
# clauses = []
# p_min = getattr(params, "price_min", None)
# if p_min is not None:
# clauses.append(f"sale_price >= {p_min}")
# p_max = getattr(params, "price_max", None)
# if p_max is not None:
# clauses.append(f"sale_price <= {p_max}")
# return clauses
# def _get_attribute_clauses(params) -> list[str]:
# """
# TIER 4: Attributes (10-30% reduction)
# Season, Style, Fitting
# """
# clauses = []
# # Season: 4 seasons (~25% each)
# season = getattr(params, "season", None)
# if season:
# s = _escape(season).lower()
# clauses.append(f"LOWER(season) LIKE '%{s}%'")
# # Style: Basic/Feminine/Sporty... (~15-20% reduction)
# style = getattr(params, "style", None)
# if style:
# st = _escape(style).lower()
# clauses.append(f"LOWER(style) LIKE '%{st}%'")
# # Fitting: Regular/Slim/Loose (~15% reduction)
# fitting = getattr(params, "fitting", None)
# if fitting:
# f = _escape(fitting).lower()
# clauses.append(f"LOWER(fitting) LIKE '%{f}%'")
# # Size Scale: S, M, L, 29, 30... (Specific filtering)
# size = getattr(params, "size_scale", None)
# if size:
# sz = _escape(size).lower()
# clauses.append(f"LOWER(size_scale) LIKE '%{sz}%'")
# return clauses
# def _get_form_detail_clauses(params) -> list[str]:
# """
# TIER 5: Granular form details (<10% reduction each)
# Neckline, Sleeve type
# """
# clauses = []
# form_fields = [
# ("form_neckline", "form_neckline"),
# ("form_sleeve", "form_sleeve"),
# ]
# for param_name, col_name in form_fields:
# val = getattr(params, param_name, None)
# if val:
# v = _escape(val).lower()
# clauses.append(f"LOWER({col_name}) LIKE '%{v}%'")
# return clauses
# async def build_starrocks_query(params, query_vector: list[float] | None = None) -> str:
# """
# Build SQL Hybrid tối ưu với Filter Priority:
# 1. Pre-filtering theo độ ưu tiên (SKU → Exact → Price → Partial)
# 2. Vector Search (HNSW Index) - Semantic understanding
# 3. Flexible Keyword Search (OR + Scoring) - Fuzzy matching fallback
# 4. Grouping (Gom màu theo style)
# """
# # --- Process vector in query field ---
# query_text = getattr(params, "query", None)
# # if query_text and query_vector is None:
# # query_vector = await create_embedding_async(query_text)
# # --- Build filter clauses (OPTIMIZED ORDER) ---
# where_clauses = _get_where_clauses(params)
# where_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
# # --- Build SQL ---
# if query_vector and len(query_vector) > 0:
# v_str = "[" + ",".join(str(v) for v in query_vector) + "]"
# sql = f"""
# WITH top_sku_candidates AS (
# SELECT
# approx_cosine_similarity(vector, {v_str}) as similarity_score,
# internal_ref_code,
# product_name,
# sale_price,
# original_price,
# master_color,
# product_image_url,
# product_image_url_thumbnail,
# product_web_url,
# description_text,
# material,
# material_group,
# gender_by_product,
# age_by_product,
# season,
# style,
# fitting,
# form_neckline,
# form_sleeve,
# product_line_vn,
# product_color_name
# FROM shared_source.magento_product_dimension_with_text_embedding
# WHERE {where_sql} AND vector IS NOT NULL
# ORDER BY similarity_score DESC
# LIMIT 50
# )
# SELECT
# internal_ref_code,
# ANY_VALUE(product_name) as product_name,
# ANY_VALUE(sale_price) as sale_price,
# ANY_VALUE(original_price) as original_price,
# GROUP_CONCAT(DISTINCT master_color ORDER BY master_color SEPARATOR ', ') as available_colors,
# ANY_VALUE(product_image_url) as product_image_url,
# ANY_VALUE(product_image_url_thumbnail) as product_image_url_thumbnail,
# ANY_VALUE(product_web_url) as product_web_url,
# ANY_VALUE(description_text) as description_text,
# ANY_VALUE(material) as material,
# ANY_VALUE(material_group) as material_group,
# ANY_VALUE(gender_by_product) as gender_by_product,
# ANY_VALUE(age_by_product) as age_by_product,
# ANY_VALUE(season) as season,
# ANY_VALUE(style) as style,
# ANY_VALUE(fitting) as fitting,
# ANY_VALUE(form_neckline) as form_neckline,
# ANY_VALUE(form_sleeve) as form_sleeve,
# ANY_VALUE(product_line_vn) as product_line_vn,
# MAX(similarity_score) as max_score
# FROM top_sku_candidates
# GROUP BY internal_ref_code
# ORDER BY max_score DESC
# LIMIT 10
# """ # noqa: S608
# else:
# # ⚡ FALLBACK: FLEXIBLE KEYWORD SEARCH (OR + SCORING)
# # Giải quyết case: User search "áo khoác nỉ" → DB có "Áo nỉ nam"
# keywords = getattr(params, "keywords", None)
# keyword_score_sql = ""
# keyword_filter = ""
# if keywords:
# k_clean = _escape(keywords).lower().strip()
# if k_clean:
# words = k_clean.split()
# # Build scoring expression: Each matched word = +1 point
# # Example: "áo khoác nỉ" (3 words)
# # - "Áo nỉ nam" matches 2/3 → Score = 2
# # - "Áo khoác nỉ hoodie" matches 3/3 → Score = 3
# score_terms = [
# f"(CASE WHEN LOWER(product_name) LIKE '%{w}%' THEN 1 ELSE 0 END)"
# for w in words
# ]
# keyword_score_sql = f"({' + '.join(score_terms)}) as keyword_match_score"
# # Minimum threshold: At least 50% of words must match
# # Example: 3 words → need at least 2 matches (66%)
# # 2 words → need at least 1 match (50%)
# min_matches = max(1, len(words) // 2)
# keyword_filter = f" AND ({' + '.join(score_terms)}) >= {min_matches}"
# # Select clause with optional scoring
# select_score = f", {keyword_score_sql}" if keyword_score_sql else ""
# order_by = "keyword_match_score DESC, sale_price ASC" if keyword_score_sql else "sale_price ASC"
# sql = f"""
# SELECT
# internal_ref_code,
# ANY_VALUE(product_name) as product_name,
# ANY_VALUE(sale_price) as sale_price,
# ANY_VALUE(original_price) as original_price,
# GROUP_CONCAT(DISTINCT master_color ORDER BY master_color SEPARATOR ', ') as available_colors,
# ANY_VALUE(product_image_url) as product_image_url,
# ANY_VALUE(product_image_url_thumbnail) as product_image_url_thumbnail,
# ANY_VALUE(product_web_url) as product_web_url,
# ANY_VALUE(description_text) as description_text,
# ANY_VALUE(material) as material,
# ANY_VALUE(material_group) as material_group,
# ANY_VALUE(gender_by_product) as gender_by_product,
# ANY_VALUE(age_by_product) as age_by_product,
# ANY_VALUE(season) as season,
# ANY_VALUE(style) as style,
# ANY_VALUE(fitting) as fitting,
# ANY_VALUE(form_neckline) as form_neckline,
# ANY_VALUE(form_sleeve) as form_sleeve,
# ANY_VALUE(product_line_vn) as product_line_vn
# {select_score}
# FROM shared_source.magento_product_dimension_with_text_embedding
# WHERE {where_sql} {keyword_filter}
# GROUP BY internal_ref_code
# HAVING COUNT(*) > 0
# ORDER BY {order_by}
# LIMIT 10
# """ # noqa: S608
# # Log filter statistics
# filter_info = f"Mode: {'Vector' if query_vector else 'Keyword'}, Filters: {len(where_clauses)}"
# if where_clauses:
# # Identify high-priority filters used
# has_sku = any('internal_ref_code' in c or 'magento_ref_code' in c for c in where_clauses)
# has_gender = any('gender_by_product' in c for c in where_clauses)
# has_category = any('product_line_vn' in c for c in where_clauses)
# priority_info = []
# if has_sku:
# priority_info.append("SKU")
# if has_gender:
# priority_info.append("Gender")
# if has_category:
# priority_info.append("Category")
# if priority_info:
# filter_info += f", Priority: {'+'.join(priority_info)}"
# logger.info(f"📊 {filter_info}")
# # Write SQL to file for debugging
# try:
# with open(r"d:\cnf\chatbot_canifa\backend\embedding.txt", "w", encoding="utf-8") as f:
# f.write(sql)
# except Exception as e:
# logger.error(f"Failed to write SQL to embedding.txt: {e}")
# return sql
import logging
import asyncio
import time
from common.embedding_service import create_embedding_async
logger = logging.getLogger(__name__)
def _escape(val: str) -> str:
"""Thoát dấu nháy đơn để tránh SQL Injection cơ bản."""
......@@ -473,147 +84,149 @@ def _get_special_clauses(params) -> list[str]:
async def build_starrocks_query(params, query_vector: list[float] | None = None) -> str:
"""
Build SQL Hybrid tối ưu với POST-FILTERING Strategy:
🔥 OPTIMIZATION STRATEGY:
1. Vector Search TRƯỚC (dùng vector index) → lấy top 50 candidates
2. Post-filtering metadata SAU (chỉ filter trên ~50 records) → nhanh
3. Grouping (Gom màu theo style)
Build SQL cho Product Search với 2 chiến lược:
1. CODE SEARCH: Nếu có magento_ref_code → Tìm trực tiếp theo mã (KHÔNG dùng vector)
2. HYDE SEARCH: Semantic search với HyDE vector (Pure vector approach)
"""
⚡ Performance: ~46-50ms (min time) - TỐI ƯU
- KHÔNG có WHERE clause trong inner query → Vector index được dùng
- Post-filtering strategy → chỉ check ~50 candidates → nhanh
# ============================================================
# CASE 1: CODE SEARCH - Tìm theo mã sản phẩm (No Vector)
# ============================================================
magento_code = getattr(params, "magento_ref_code", None)
if magento_code:
print(f"🎯 [CODE SEARCH] Direct search by code: {magento_code}")
code = _escape(magento_code)
WHY POST-FILTERING?
- WHERE filter trước → StarRocks BỎ QUA vector index → brute-force 200-300ms
- Vector search ALL → filter sau → chỉ check ~50 vectors → 46-50ms
# Tìm trực tiếp theo mã + Lọc trùng (GROUP BY internal_ref_code)
# Tìm chính xác theo mã (Lấy tất cả các bản ghi/màu sắc/size của mã đó)
sql = f"""
SELECT
internal_ref_code,
description_text_full,
sale_price,
original_price,
discount_amount,
1.0 as max_score
FROM shared_source.magento_product_dimension_with_text_embedding
WHERE (magento_ref_code = '{code}' OR internal_ref_code = '{code}')
"""
logger.info("🔧 [DEBUG] build_starrocks_query STARTED")
# --- Process vector in query field ---
print("✅ [CODE SEARCH] Query built - No vector search needed!")
# Ghi log debug query FULL vào Background Task (Không làm chậm Request)
asyncio.create_task(save_query_to_log(sql))
return sql
# ============================================================
# CASE 2: HYDE SEARCH - Semantic Vector Search
# ============================================================
print("🚀 [HYDE RETRIEVER] Starting pure vector search...")
# 1. Lấy Vector từ HyDE (AI-generated hypothetical document)
query_text = getattr(params, "query", None)
logger.info(f"🔧 [DEBUG] query_text: {query_text[:50] if query_text else 'None'}")
if query_text and query_vector is None:
# ⏱️ Timer: Embedding generation
emb_start = time.time()
logger.info("🔧 [DEBUG] Calling create_embedding_async()")
query_vector = await create_embedding_async(query_text)
emb_time = (time.time() - emb_start) * 1000 # Convert to ms
logger.info(f"🔧 [DEBUG] Embedding created, dimension: {len(query_vector) if query_vector else 0}")
logger.info(f"⏱️ [TIMER] Embedding Generation Time: {emb_time:.2f}ms")
# --- Build filter clauses for POST-FILTERING ---
logger.info("🔧 [DEBUG] Building WHERE clauses for POST-FILTERING")
where_clauses = _get_where_clauses(params)
# Post-filter SQL (applied AFTER vector search)
post_filter_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
# --- Build SQL ---
if query_vector and len(query_vector) > 0:
print(f"⏱️ [TIMER] HyDE Embedding: {(time.time() - emb_start) * 1000:.2f}ms")
if not query_vector:
print("⚠️ No vector found, returning empty query.")
return ""
v_str = "[" + ",".join(str(v) for v in query_vector) + "]"
# 2. Build PRICE filter ONLY (chỉ lọc giá, để vector tự semantic search)
price_clauses = _get_price_clauses(params)
where_filter = ""
if price_clauses:
where_filter = " AND " + " AND ".join(price_clauses)
print(f"💰 [PRICE FILTER] Applied: {where_filter}")
# 3. SQL Pure Vector Search + Price Filter Only
sql = f"""
WITH top_candidates AS (
SELECT /*+ SET_VAR(ann_params='{{"ef_search":64}}') */
WITH top_matches AS (
SELECT /*+ SET_VAR(ann_params='{{"ef_search":128}}') */
internal_ref_code,
product_color_code,
description_text_full,
sale_price,
original_price,
discount_amount,
approx_cosine_similarity(vector, {v_str}) as similarity_score
FROM shared_source.magento_product_dimension_with_text_embedding__tmp
FROM shared_source.magento_product_dimension_with_text_embedding
ORDER BY similarity_score DESC
LIMIT 100
)
SELECT
t1.internal_ref_code,
ANY_VALUE(t2.product_name) as product_name,
ANY_VALUE(t2.sale_price) as sale_price,
ANY_VALUE(t2.original_price) as original_price,
GROUP_CONCAT(DISTINCT t2.master_color ORDER BY t2.master_color SEPARATOR ', ') as available_colors,
ANY_VALUE(t2.product_image_url) as product_image_url,
ANY_VALUE(t2.product_image_url_thumbnail) as product_image_url_thumbnail,
ANY_VALUE(t2.product_web_url) as product_web_url,
ANY_VALUE(t2.description_text) as description_text,
ANY_VALUE(t2.material) as material,
ANY_VALUE(t2.material_group) as material_group,
ANY_VALUE(t2.gender_by_product) as gender_by_product,
ANY_VALUE(t2.age_by_product) as age_by_product,
ANY_VALUE(t2.season) as season,
ANY_VALUE(t2.style) as style,
ANY_VALUE(t2.fitting) as fitting,
ANY_VALUE(t2.form_neckline) as form_neckline,
ANY_VALUE(t2.form_sleeve) as form_sleeve,
ANY_VALUE(t2.product_line_vn) as product_line_vn,
MAX(t1.similarity_score) as max_score
FROM top_candidates t1
JOIN shared_source.magento_product_dimension_with_text_embedding__tmp t2
ON t1.internal_ref_code = t2.internal_ref_code
AND t1.product_color_code = t2.product_color_code
WHERE {post_filter_sql.replace("sale_price", "t2.sale_price")
.replace("gender_by_product", "t2.gender_by_product")
.replace("age_by_product", "t2.age_by_product")
.replace("material_group", "t2.material_group")
.replace("season", "t2.season")
.replace("style", "t2.style")
.replace("fitting", "t2.fitting")
.replace("form_neckline", "t2.form_neckline")
.replace("form_sleeve", "t2.form_sleeve")
.replace("product_line_vn", "t2.product_line_vn")
.replace("magento_ref_code", "t2.magento_ref_code")
.replace("internal_ref_code", "t2.internal_ref_code")
.replace("master_color", "t2.master_color")
.replace("product_color_name", "t2.product_color_name")}
GROUP BY t1.internal_ref_code
internal_ref_code,
MAX_BY(description_text_full, similarity_score) as description_text_full,
MAX_BY(sale_price, similarity_score) as sale_price,
MAX_BY(original_price, similarity_score) as original_price,
MAX_BY(discount_amount, similarity_score) as discount_amount,
MAX(similarity_score) as max_score
FROM top_matches
WHERE 1=1 {where_filter}
GROUP BY internal_ref_code
ORDER BY max_score DESC
LIMIT 10
""" # noqa: S608
else:
# FALLBACK: Keyword search (Also using __tmp for consistency)
keywords = getattr(params, "keywords", None)
keyword_filter = ""
if keywords:
k = _escape(keywords).lower()
keyword_filter = f" AND LOWER(product_name) LIKE '%{k}%'"
"""
where_clauses = _get_where_clauses(params)
where_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
# Ghi log debug query FULL vào Background Task (Không làm chậm Request)
asyncio.create_task(save_query_to_log(sql))
sql = f"""
SELECT
internal_ref_code,
ANY_VALUE(product_name) as product_name,
ANY_VALUE(sale_price) as sale_price,
ANY_VALUE(original_price) as original_price,
GROUP_CONCAT(DISTINCT master_color ORDER BY master_color SEPARATOR ', ') as available_colors,
ANY_VALUE(product_image_url) as product_image_url,
ANY_VALUE(product_image_url_thumbnail) as product_image_url_thumbnail,
ANY_VALUE(product_web_url) as product_web_url,
ANY_VALUE(description_text) as description_text,
ANY_VALUE(material) as material,
ANY_VALUE(material_group) as material_group,
ANY_VALUE(gender_by_product) as gender_by_product,
ANY_VALUE(age_by_product) as age_by_product,
ANY_VALUE(season) as season,
ANY_VALUE(style) as style,
ANY_VALUE(fitting) as fitting,
ANY_VALUE(form_neckline) as form_neckline,
ANY_VALUE(form_sleeve) as form_sleeve,
ANY_VALUE(product_line_vn) as product_line_vn
FROM shared_source.magento_product_dimension_with_text_embedding__tmp
WHERE {where_sql} {keyword_filter}
GROUP BY internal_ref_code
HAVING COUNT(*) > 0
ORDER BY sale_price ASC
LIMIT 10
""" # noqa: S608
return sql
logger.info(f"📊 Query Mode: {'Vector' if query_vector else 'Keyword'}")
# Write SQL to file for debugging
async def save_query_to_log(sql: str):
"""Lưu query full vào file hyde_pure_query.txt."""
import os
log_path = r"D:\cnf\chatbot_canifa\backend\logs\hyde_pure_query.txt"
try:
debug_file_path = r"d:\cnf\chatbot_canifa\backend\query.txt"
with open(debug_file_path, "w", encoding="utf-8") as f:
log_dir = os.path.dirname(log_path)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
with open(log_path, "w", encoding="utf-8") as f:
f.write(sql)
logger.info(f"💾 SQL Query saved to: {debug_file_path}")
print(f"💾 Full Query saved to: {log_path}")
except Exception as e:
logger.error(f"Failed to write SQL to query.txt: {e}")
print(f"Save query log failed: {e}")
return sql
async def save_preview_to_log(search_query: str, products: list[dict]):
"""Lưu kết quả DB trả về vào db_preview.txt (Format đẹp cho AI)."""
import json
import os
preview_path = r"D:\cnf\chatbot_canifa\backend\logs\db_preview.txt"
try:
log_dir = os.path.dirname(preview_path)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
with open(preview_path, "a", encoding="utf-8") as f:
f.write(f"\n{'='*60}\n")
f.write(f"⏰ TIME: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"🔍 SEARCH: {search_query}\n")
f.write(f"📊 RESULTS COUNT: {len(products)}\n")
f.write(f"{'-'*60}\n")
if not products:
f.write("❌ NO PRODUCTS FOUND\n")
else:
for idx, p in enumerate(products[:5], 1):
code = p.get("internal_ref_code", "N/A")
sale = p.get("sale_price", "N/A")
orig = p.get("original_price", "N/A")
disc = p.get("discount_amount", "0")
score = p.get("max_score", p.get("similarity_score", "N/A"))
desc = p.get("description_text_full", "No Description")
f.write(f"{idx}. [{code}] Score: {score}\n")
f.write(f" 💰 Price: {sale} (Orig: {orig}, Disc: {disc}%)\n")
f.write(f" 📝 Desc: {desc}\n")
f.write(f"{'='*60}\n")
print(f"💾 DB Preview (Results) saved to: {preview_path}")
except Exception as e:
print(f"Save preview log failed: {e}")
# import logging
# from common.embedding_service import create_embedding_async
# logger = logging.getLogger(__name__)
# def _escape(val: str) -> str:
# """Thoát dấu nháy đơn để tránh SQL Injection cơ bản."""
# return val.replace("'", "''")
# def _get_where_clauses(params) -> list[str]:
# """
# Xây dựng WHERE clauses theo thứ tự ưu tiên dựa trên selectivity thực tế
# FILTER PRIORITY (Based on Canifa catalog analysis):
# 🔥 TIER 1 (99% selectivity):
# 1. SKU Code → 1-5 records
# 🎯 TIER 2 (50-70% selectivity):
# 2. Gender → Splits catalog in half
# 3. Age → Kids vs Adults split
# 4. Product Category → 10-15 categories
# 💎 TIER 3 (30-50% selectivity):
# 5. Material Group → Knit vs Woven (2 groups)
# 6. Price Range → Numeric filtering
# 🎨 TIER 4 (10-30% selectivity):
# 7. Season → 4 seasons
# 8. Style/Fitting → Multiple options
# ⚠️ TIER 5 (<10% selectivity):
# 9. Form details → Granular attributes
# 10. Color → LOWEST selectivity (many SKUs share colors)
# Early return: If SKU exists, skip low-selectivity filters
# """
# clauses = []
# # 🔥 TIER 1: SKU/Product Code (Unique identifier)
# # Selectivity: ~99% → 1 SKU = 1 style (3-5 colors max)
# sku_clause = _get_sku_clause(params)
# if sku_clause:
# clauses.append(sku_clause)
# # Early return optimization: SKU đã xác định product rõ ràng
# # CHỈ GIỮ LẠI price filter (nếu có) để verify budget constraint
# # BỎ QUA: gender, color, style, fitting... vì SKU đã unique
# price_clauses = _get_price_clauses(params)
# if price_clauses:
# clauses.extend(price_clauses)
# return clauses # ⚡ STOP - Không thêm filter khác!
# # 🎯 TIER 2: High-level categorization (50-70% reduction)
# # Gender + Age + Category có selectivity cao nhất trong non-SKU filters
# clauses.extend(_get_high_selectivity_clauses(params))
# # 💎 TIER 3: Material & Price (30-50% reduction)
# material_clause = _get_material_clause(params)
# if material_clause:
# clauses.append(material_clause)
# clauses.extend(_get_price_clauses(params))
# # 🎨 TIER 4: Attributes (10-30% reduction)
# clauses.extend(_get_attribute_clauses(params))
# # ⚠️ TIER 5: Granular details & Color (LAST - lowest selectivity)
# clauses.extend(_get_form_detail_clauses(params))
# color_clause = _get_color_clause(params)
# if color_clause:
# clauses.append(color_clause) # Color ALWAYS LAST!
# return clauses
# def _get_sku_clause(params) -> str | None:
# """
# TIER 1: SKU/Product Code (Highest selectivity - 99%)
# 1 SKU code = 1 product style (may have 3-5 color variants)
# WHY SKU is always priority #1:
# - 1 code = 1 unique product design
# - Adding other filters (color, style, gender) is redundant
# - Only price filter may be kept for budget validation
# Example queries:
# - "Mã 6OT25W010" → Only SKU needed
# - "Mã 6OT25W010 màu xám" → Only SKU (color is for display/selection, not filtering)
# - "Mã 6OT25W010 dưới 500k" → SKU + price (validate budget)
# """
# m_code = getattr(params, "magento_ref_code", None)
# if m_code:
# m = _escape(m_code)
# return f"(magento_ref_code = '{m}' OR internal_ref_code = '{m}')"
# return None
# def _get_color_clause(params) -> str | None:
# """
# TIER 5: Color (LOWEST selectivity - 5-10%)
# Multiple SKUs share the same color (e.g., 50+ gray products)
# ALWAYS filter color LAST after other constraints
# """
# color = getattr(params, "master_color", None)
# if color:
# c = _escape(color).lower()
# return f"(LOWER(master_color) LIKE '%{c}%' OR LOWER(product_color_name) LIKE '%{c}%')"
# return None
# def _get_high_selectivity_clauses(params) -> list[str]:
# """
# TIER 2: High-level categorization (50-70% reduction per filter)
# Order: Gender → Age → Product Category
# """
# clauses = []
# # Gender: Male/Female/Unisex split (50-70% reduction)
# gender = getattr(params, "gender_by_product", None)
# if gender:
# clauses.append(f"gender_by_product = '{_escape(gender)}'")
# # Age: Kids/Adults split (50% reduction of remaining)
# age = getattr(params, "age_by_product", None)
# if age:
# clauses.append(f"age_by_product = '{_escape(age)}'")
# # Product Category: Váy/Áo/Quần... (30-50% reduction)
# product_line = getattr(params, "product_line_vn", None)
# if product_line:
# p = _escape(product_line).lower()
# clauses.append(f"LOWER(product_line_vn) LIKE '%{p}%'")
# return clauses
# def _get_material_clause(params) -> str | None:
# """TIER 3: Material Group - Knit vs Woven (50% split)"""
# material = getattr(params, "material_group", None)
# if material:
# m = _escape(material).lower()
# return f"LOWER(material_group) LIKE '%{m}%'"
# return None
# def _get_price_clauses(params) -> list[str]:
# """TIER 3: Price Range - Numeric filtering (30-40% reduction)"""
# clauses = []
# p_min = getattr(params, "price_min", None)
# if p_min is not None:
# clauses.append(f"sale_price >= {p_min}")
# p_max = getattr(params, "price_max", None)
# if p_max is not None:
# clauses.append(f"sale_price <= {p_max}")
# return clauses
# def _get_attribute_clauses(params) -> list[str]:
# """
# TIER 4: Attributes (10-30% reduction)
# Season, Style, Fitting
# """
# clauses = []
# # Season: 4 seasons (~25% each)
# season = getattr(params, "season", None)
# if season:
# s = _escape(season).lower()
# clauses.append(f"LOWER(season) LIKE '%{s}%'")
# # Style: Basic/Feminine/Sporty... (~15-20% reduction)
# style = getattr(params, "style", None)
# if style:
# st = _escape(style).lower()
# clauses.append(f"LOWER(style) LIKE '%{st}%'")
# # Fitting: Regular/Slim/Loose (~15% reduction)
# fitting = getattr(params, "fitting", None)
# if fitting:
# f = _escape(fitting).lower()
# clauses.append(f"LOWER(fitting) LIKE '%{f}%'")
# # Size Scale: S, M, L, 29, 30... (Specific filtering)
# size = getattr(params, "size_scale", None)
# if size:
# sz = _escape(size).lower()
# clauses.append(f"LOWER(size_scale) LIKE '%{sz}%'")
# return clauses
# def _get_form_detail_clauses(params) -> list[str]:
# """
# TIER 5: Granular form details (<10% reduction each)
# Neckline, Sleeve type
# """
# clauses = []
# form_fields = [
# ("form_neckline", "form_neckline"),
# ("form_sleeve", "form_sleeve"),
# ]
# for param_name, col_name in form_fields:
# val = getattr(params, param_name, None)
# if val:
# v = _escape(val).lower()
# clauses.append(f"LOWER({col_name}) LIKE '%{v}%'")
# return clauses
# async def build_starrocks_query(params, query_vector: list[float] | None = None) -> str:
# """
# Build SQL Hybrid tối ưu với Filter Priority:
# 1. Pre-filtering theo độ ưu tiên (SKU → Exact → Price → Partial)
# 2. Vector Search (HNSW Index) - Semantic understanding
# 3. Flexible Keyword Search (OR + Scoring) - Fuzzy matching fallback
# 4. Grouping (Gom màu theo style)
# """
# # --- Process vector in query field ---
# query_text = getattr(params, "query", None)
# # if query_text and query_vector is None:
# # query_vector = await create_embedding_async(query_text)
# # --- Build filter clauses (OPTIMIZED ORDER) ---
# where_clauses = _get_where_clauses(params)
# where_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
# # --- Build SQL ---
# if query_vector and len(query_vector) > 0:
# v_str = "[" + ",".join(str(v) for v in query_vector) + "]"
# sql = f"""
# WITH top_sku_candidates AS (
# SELECT
# approx_cosine_similarity(vector, {v_str}) as similarity_score,
# internal_ref_code,
# product_name,
# sale_price,
# original_price,
# master_color,
# product_image_url,
# product_image_url_thumbnail,
# product_web_url,
# description_text,
# material,
# material_group,
# gender_by_product,
# age_by_product,
# season,
# style,
# fitting,
# form_neckline,
# form_sleeve,
# product_line_vn,
# product_color_name
# FROM shared_source.magento_product_dimension_with_text_embedding
# WHERE {where_sql} AND vector IS NOT NULL
# ORDER BY similarity_score DESC
# LIMIT 50
# )
# SELECT
# internal_ref_code,
# ANY_VALUE(product_name) as product_name,
# ANY_VALUE(sale_price) as sale_price,
# ANY_VALUE(original_price) as original_price,
# GROUP_CONCAT(DISTINCT master_color ORDER BY master_color SEPARATOR ', ') as available_colors,
# ANY_VALUE(product_image_url) as product_image_url,
# ANY_VALUE(product_image_url_thumbnail) as product_image_url_thumbnail,
# ANY_VALUE(product_web_url) as product_web_url,
# ANY_VALUE(description_text) as description_text,
# ANY_VALUE(material) as material,
# ANY_VALUE(material_group) as material_group,
# ANY_VALUE(gender_by_product) as gender_by_product,
# ANY_VALUE(age_by_product) as age_by_product,
# ANY_VALUE(season) as season,
# ANY_VALUE(style) as style,
# ANY_VALUE(fitting) as fitting,
# ANY_VALUE(form_neckline) as form_neckline,
# ANY_VALUE(form_sleeve) as form_sleeve,
# ANY_VALUE(product_line_vn) as product_line_vn,
# MAX(similarity_score) as max_score
# FROM top_sku_candidates
# GROUP BY internal_ref_code
# ORDER BY max_score DESC
# LIMIT 10
# """
# else:
# # ⚡ FALLBACK: FLEXIBLE KEYWORD SEARCH (OR + SCORING)
# # Giải quyết case: User search "áo khoác nỉ" → DB có "Áo nỉ nam"
# keywords = getattr(params, "keywords", None)
# keyword_score_sql = ""
# keyword_filter = ""
# if keywords:
# k_clean = _escape(keywords).lower().strip()
# if k_clean:
# words = k_clean.split()
# # Build scoring expression: Each matched word = +1 point
# # Example: "áo khoác nỉ" (3 words)
# # - "Áo nỉ nam" matches 2/3 → Score = 2
# # - "Áo khoác nỉ hoodie" matches 3/3 → Score = 3
# score_terms = [
# f"(CASE WHEN LOWER(product_name) LIKE '%{w}%' THEN 1 ELSE 0 END)"
# for w in words
# ]
# keyword_score_sql = f"({' + '.join(score_terms)}) as keyword_match_score"
# # Minimum threshold: At least 50% of words must match
# # Example: 3 words → need at least 2 matches (66%)
# # 2 words → need at least 1 match (50%)
# min_matches = max(1, len(words) // 2)
# keyword_filter = f" AND ({' + '.join(score_terms)}) >= {min_matches}"
# # Select clause with optional scoring
# select_score = f", {keyword_score_sql}" if keyword_score_sql else ""
# order_by = "keyword_match_score DESC, sale_price ASC" if keyword_score_sql else "sale_price ASC"
# sql = f"""
# SELECT
# internal_ref_code,
# ANY_VALUE(product_name) as product_name,
# ANY_VALUE(sale_price) as sale_price,
# ANY_VALUE(original_price) as original_price,
# GROUP_CONCAT(DISTINCT master_color ORDER BY master_color SEPARATOR ', ') as available_colors,
# ANY_VALUE(product_image_url) as product_image_url,
# ANY_VALUE(product_image_url_thumbnail) as product_image_url_thumbnail,
# ANY_VALUE(product_web_url) as product_web_url,
# ANY_VALUE(description_text) as description_text,
# ANY_VALUE(material) as material,
# ANY_VALUE(material_group) as material_group,
# ANY_VALUE(gender_by_product) as gender_by_product,
# ANY_VALUE(age_by_product) as age_by_product,
# ANY_VALUE(season) as season,
# ANY_VALUE(style) as style,
# ANY_VALUE(fitting) as fitting,
# ANY_VALUE(form_neckline) as form_neckline,
# ANY_VALUE(form_sleeve) as form_sleeve,
# ANY_VALUE(product_line_vn) as product_line_vn
# {select_score}
# FROM shared_source.magento_product_dimension_with_text_embedding
# WHERE {where_sql} {keyword_filter}
# GROUP BY internal_ref_code
# HAVING COUNT(*) > 0
# ORDER BY {order_by}
# LIMIT 10
# """
# # Log filter statistics
# filter_info = f"Mode: {'Vector' if query_vector else 'Keyword'}, Filters: {len(where_clauses)}"
# if where_clauses:
# # Identify high-priority filters used
# has_sku = any('internal_ref_code' in c or 'magento_ref_code' in c for c in where_clauses)
# has_gender = any('gender_by_product' in c for c in where_clauses)
# has_category = any('product_line_vn' in c for c in where_clauses)
# priority_info = []
# if has_sku:
# priority_info.append("SKU")
# if has_gender:
# priority_info.append("Gender")
# if has_category:
# priority_info.append("Category")
# if priority_info:
# filter_info += f", Priority: {'+'.join(priority_info)}"
# logger.info(f"📊 {filter_info}")
# # Write SQL to file for debugging
# try:
# with open(r"d:\cnf\chatbot_canifa\backend\embedding.txt", "w", encoding="utf-8") as f:
# f.write(sql)
# except Exception as e:
# logger.error(f"Failed to write SQL to embedding.txt: {e}")
# return sql
import logging
import time
from common.embedding_service import create_embedding_async
logger = logging.getLogger(__name__)
def _escape(val: str) -> str:
"""Thoát dấu nháy đơn để tránh SQL Injection cơ bản."""
return val.replace("'", "''")
def _get_where_clauses(params) -> list[str]:
"""Xây dựng danh sách các điều kiện lọc từ params."""
clauses = []
clauses.extend(_get_price_clauses(params))
clauses.extend(_get_metadata_clauses(params))
clauses.extend(_get_special_clauses(params))
return clauses
def _get_price_clauses(params) -> list[str]:
"""Lọc theo giá."""
clauses = []
p_min = getattr(params, "price_min", None)
if p_min is not None:
clauses.append(f"sale_price >= {p_min}")
p_max = getattr(params, "price_max", None)
if p_max is not None:
clauses.append(f"sale_price <= {p_max}")
return clauses
def _get_metadata_clauses(params) -> list[str]:
"""Xây dựng điều kiện lọc từ metadata (Phối hợp Exact và Partial)."""
clauses = []
# 1. Exact Match (Giới tính, Độ tuổi) - Các trường này cần độ chính xác tuyệt đối
exact_fields = [
("gender_by_product", "gender_by_product"),
("age_by_product", "age_by_product"),
]
for param_name, col_name in exact_fields:
val = getattr(params, param_name, None)
if val:
clauses.append(f"{col_name} = '{_escape(val)}'")
# 2. Partial Match (LIKE) - Giúp map text linh hoạt hơn (Chất liệu, Dòng SP, Phong cách...)
# Cái này giúp map: "Yarn" -> "Yarn - Sợi", "Knit" -> "Knit - Dệt Kim"
partial_fields = [
("season", "season"),
("material_group", "material_group"),
("product_line_vn", "product_line_vn"),
("style", "style"),
("fitting", "fitting"),
("form_neckline", "form_neckline"),
("form_sleeve", "form_sleeve"),
]
for param_name, col_name in partial_fields:
val = getattr(params, param_name, None)
if val:
v = _escape(val).lower()
# Dùng LOWER + LIKE để cân mọi loại ký tự thừa hoặc hoa/thường
clauses.append(f"LOWER({col_name}) LIKE '%{v}%'")
return clauses
def _get_special_clauses(params) -> list[str]:
"""Các trường hợp đặc biệt: Mã sản phẩm, Màu sắc."""
clauses = []
# Mã sản phẩm / SKU
m_code = getattr(params, "magento_ref_code", None)
if m_code:
m = _escape(m_code)
clauses.append(f"(magento_ref_code = '{m}' OR internal_ref_code = '{m}')")
# Màu sắc
color = getattr(params, "master_color", None)
if color:
c = _escape(color).lower()
clauses.append(f"(LOWER(master_color) LIKE '%{c}%' OR LOWER(product_color_name) LIKE '%{c}%')")
return clauses
async def build_starrocks_query(params, query_vector: list[float] | None = None) -> str:
"""
Build SQL Hybrid tối ưu với POST-FILTERING Strategy & Anti-Duplication.
🔥 CHIẾN LƯỢC TỐI ƯU:
1. Vector Search TRƯỚC (LIMIT 100) để tận dụng HNSW Index (tốc độ ~50ms).
2. JOIN chính xác theo (code + màu) để tránh bùng nổ dữ liệu (Data Explosion).
3. Dùng MAX_BY để lấy description của đúng thằng có score cao nhất.
"""
logger.info("🔧 [DEBUG] build_starrocks_query STARTED")
# --- 1. Xử lý Vector ---
query_text = getattr(params, "query", None)
if query_text and query_vector is None:
emb_start = time.time()
query_vector = await create_embedding_async(query_text)
emb_time = (time.time() - emb_start) * 1000
logger.info(f"⏱️ [TIMER] Embedding Generation: {emb_time:.2f}ms")
# --- 2. Xây dựng Filter cho POST-FILTERING ---
where_clauses = _get_where_clauses(params)
post_filter_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
# --- 3. Build SQL ---
if query_vector and len(query_vector) > 0:
v_str = "[" + ",".join(str(v) for v in query_vector) + "]"
# Alias các trường trong filter sang bảng t2 để tránh lỗi ambiguous
post_filter_aliased = post_filter_sql
fields_to_alias = [
"sale_price",
"gender_by_product",
"age_by_product",
"material_group",
"season",
"style",
"fitting",
"form_neckline",
"form_sleeve",
"product_line_vn",
"magento_ref_code",
"internal_ref_code",
"master_color",
"product_color_name",
]
for field in fields_to_alias:
post_filter_aliased = post_filter_aliased.replace(field, f"t2.{field}")
sql = f"""
WITH top_candidates AS (
SELECT /*+ SET_VAR(ann_params='{{"ef_search":64}}') */
internal_ref_code,
product_color_code,
approx_cosine_similarity(vector, {v_str}) as similarity_score
FROM shared_source.magento_product_dimension_with_text_embedding
WHERE vector IS NOT NULL
ORDER BY similarity_score DESC
LIMIT 100
)
SELECT
t1.internal_ref_code,
-- MAX_BY đảm bảo mô tả đi kèm đúng với thằng cao điểm nhất (Data Integrity)
MAX_BY(t2.description_text_full, t1.similarity_score) as description_text_full,
MAX(t1.similarity_score) as max_score
FROM top_candidates t1
JOIN shared_source.magento_product_dimension_with_text_embedding t2
ON t1.internal_ref_code = t2.internal_ref_code
AND t1.product_color_code = t2.product_color_code -- QUAN TRỌNG: Tránh nhân bản dòng theo màu
WHERE {post_filter_aliased}
GROUP BY t1.internal_ref_code
ORDER BY max_score DESC
LIMIT 10
"""
else:
# FALLBACK: Keyword search
keywords = getattr(params, "keywords", None)
k_filter = ""
if keywords:
k = _escape(keywords).lower()
k_filter = f" AND LOWER(product_name) LIKE '%{k}%'"
where_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
sql = f"""
SELECT
internal_ref_code,
-- Lấy đại diện 1 mô tả cho keyword search
MAX(description_text_full) as description_text_full,
MIN(sale_price) as min_price
FROM shared_source.magento_product_dimension_with_text_embedding
WHERE {where_sql} {k_filter}
GROUP BY internal_ref_code
ORDER BY min_price ASC
LIMIT 10
"""
# --- 4. Ghi Log Debug ---
try:
debug_path = r"d:\cnf\chatbot_canifa\backend\query.txt"
with open(debug_path, "w", encoding="utf-8") as f:
f.write(sql)
logger.info(f"💾 SQL saved to: {debug_path}")
except Exception as e:
logger.error(f"Save log failed: {e}")
return sql
......@@ -7,12 +7,14 @@ Router chỉ chứa định nghĩa API, logic nằm ở controller.
import logging
from fastapi import APIRouter, BackgroundTasks, HTTPException
from opentelemetry import trace
from agent.controller import chat_controller
from agent.models import QueryRequest
from config import DEFAULT_MODEL
logger = logging.getLogger(__name__)
tracer = trace.get_tracer(__name__)
router = APIRouter()
......@@ -25,6 +27,14 @@ async def fashion_qa_chat(req: QueryRequest, background_tasks: BackgroundTasks):
logger.info(f"📥 [Incoming Query - NonStream] User: {user_id} | Query: {req.user_query}")
# Get current span để add logs VÀO JAEGER UI
span = trace.get_current_span()
span.set_attribute("user.id", user_id)
span.set_attribute("chat.user_query", req.user_query)
span.add_event(
"📥 User query received", attributes={"user_id": user_id, "query": req.user_query, "timestamp": "incoming"}
)
try:
# Gọi controller để xử lý logic (Non-streaming)
result = await chat_controller(
......@@ -35,7 +45,22 @@ async def fashion_qa_chat(req: QueryRequest, background_tasks: BackgroundTasks):
images=req.images,
)
# Log chi tiết response
logger.info(f"📤 [Outgoing Response - NonStream] User: {user_id}")
logger.info(f"💬 AI Response: {result['ai_response']}")
logger.info(f"🛍️ Product IDs: {result.get('product_ids', [])}")
# Add to span (hiển thị trong Jaeger UI)
span.set_attribute("chat.ai_response", result["ai_response"][:200]) # Giới hạn 200 ký tự
span.set_attribute("chat.product_count", len(result.get("product_ids", [])))
span.add_event(
"💬 AI response generated",
attributes={
"ai_response_preview": result["ai_response"][:100],
"product_count": len(result.get("product_ids", [])),
"product_ids": str(result.get("product_ids", [])[:5]), # First 5 IDs
},
)
return {
"status": "success",
......@@ -45,56 +70,3 @@ async def fashion_qa_chat(req: QueryRequest, background_tasks: BackgroundTasks):
except Exception as e:
logger.error(f"Error in fashion_qa_chat: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=str(e)) from e
# ====================== FASHION Q&A CHAT API ======================
# @router.post("/stream/chat", summary="Fashion Q&A Chat with Streaming Response")
# async def fashion_qa_chat_stream(req: QueryRequest, request: Request):
# """
# Endpoint duy nhất cho việc chat với Fashion Agent.
# """
# # Trích xuất user_id từ request (auth middleware)
# user_id = getattr(request.state, "user_id", None) or req.user_id or "default_user"
# logger.info(f"📥 [Incoming Query] User: {user_id} | Query: {req.query}")
# try:
# # Gọi controller để xử lý logic và nhận generator stream
# # Note: Vì chat_controller có decorator @observe(), cần await để unwrap
# generator: AsyncGenerator[str, None] = chat_controller(
# query=req.query,
# user_id=user_id,
# model_name=DEFAULT_MODEL,
# conversation_id=req.conversation_id,
# images=req.images,
# )
# async def logging_generator(gen: AsyncGenerator[str, None]):
# full_response_log = ""
# first_chunk = True
# try:
# async for chunk in gen:
# if first_chunk:
# logger.info("🚀 [Stream Started] First chunk received")
# first_chunk = False
# full_response_log += chunk
# yield chunk
# except Exception as e:
# logger.error(f"❌ [Stream Error] {e}")
# yield f"data: {json.dumps({'error': str(e)})}\n\n"
# logger.info(f"📤 [Outgoing Response Stream Finished] Total Chunks Length: {len(full_response_log)}")
# return StreamingResponse(
# logging_generator(generator),
# media_type="text/event-stream",
# headers={
# "Cache-Control": "no-cache",
# "Connection": "keep-alive",
# "X-Accel-Buffering": "no",
# },
# )
# except Exception as e:
# logger.error(f"Error in fashion_qa_chat: {e}", exc_info=True)
# raise HTTPException(status_code=500, detail=str(e)) from e
from fastapi import APIRouter, HTTPException, BackgroundTasks
from pydantic import BaseModel
from typing import List, Optional
import time
import random
router = APIRouter()
# --- MODELS ---
class MockQueryRequest(BaseModel):
user_query: str
user_id: Optional[str] = "test_user"
session_id: Optional[str] = None
class MockDBRequest(BaseModel):
vector: Optional[List[float]] = None
top_k: int = 10
# --- MOCK DATA ---
MOCK_PRODUCTS = [
{
"internal_ref_code": "8TE24W001",
"description_text_full": "Áo phông nam cotton thoáng mát, form regular fit.",
"sale_price": 199000.0,
"original_price": 299000.0,
"discount_amount": 100000.0,
"max_score": 0.89
},
{
"internal_ref_code": "8JE24W002",
"description_text_full": "Quần Jeans nam ống đứng, chất liệu denim co giãn.",
"sale_price": 399000.0,
"original_price": 499000.0,
"discount_amount": 100000.0,
"max_score": 0.85
},
{
"internal_ref_code": "8SK24W003",
"description_text_full": "Váy liền thân nữ dáng xòe, họa tiết hoa nhí.",
"sale_price": 350000.0,
"original_price": 450000.0,
"discount_amount": 100000.0,
"max_score": 0.82
}
]
# --- ENDPOINTS ---
@router.post("/mock/agent/chat", summary="Mock LLM Chat Endpoint (Fast)")
async def mock_chat(req: MockQueryRequest):
"""
Giả lập phản hồi của Chatbot (bỏ qua LLM & DB thật).
Dùng để test tải (Load Test) xem server chịu được bao nhiêu request/s.
"""
# Simulate slight processing time (10ms - 50ms)
time.sleep(random.uniform(0.01, 0.05))
return {
"status": "success",
"user_query": req.user_query,
"ai_response": {
"content": f"Đây là câu trả lời giả lập cho: '{req.user_query}'. Hệ thống đang hoạt động tốt!",
"role": "assistant"
},
"product_ids": ["8TE24W001", "8JE24W002"],
"processing_time": "0.03s"
}
@router.post("/mock/db/search", summary="Mock StarRocks Vector Search")
async def mock_db_search(req: MockDBRequest):
"""
Giả lập truy vấn Vector Database (StarRocks).
Input: Vector embedding (nếu có).
Output: Danh sách sản phẩm mock giống cấu trúc SQL thật.
"""
# Simulate DB Latency (e.g., 50ms - 100ms)
time.sleep(random.uniform(0.05, 0.1))
# Hardcoded vector from user request (Just for checking format)
# [0.01643567718565464, -0.0008633101242594421, ...]
return {
"status": "success",
"total_hits": 1340,
"results": MOCK_PRODUCTS, # Return existing mock data
"query_vector_dim": len(req.vector) if req.vector else 0,
"note": "This is MOCK data from memory, no actual DB connection."
}
"""
Simple Langfuse Client Wrapper
Minimal setup using langfuse.langchain module
With async-aware batch export using asyncio
With propagate_attributes for proper user_id tracking
"""
import asyncio
import logging
import os
from concurrent.futures import ThreadPoolExecutor
from contextlib import contextmanager
from langfuse import Langfuse, get_client
from langfuse import Langfuse, get_client, propagate_attributes
from langfuse.langchain import CallbackHandler
from config import (
......@@ -81,27 +82,60 @@ async def async_flush_langfuse():
logger.warning(f"⚠️ Async flush failed: {e}")
def get_callback_handler(trace_id: str | None = None, **trace_kwargs) -> CallbackHandler | None:
def get_callback_handler(
trace_id: str | None = None,
user_id: str | None = None,
session_id: str | None = None,
tags: list[str] | None = None,
**trace_kwargs,
) -> CallbackHandler | None:
"""
Get CallbackHandler with unique trace context.
Args:
trace_id: Optional unique trace ID. If not provided, Langfuse will auto-generate.
**trace_kwargs: Additional trace attributes (user_id, session_id, tags, etc.)
trace_id: Optional unique trace ID
user_id: User ID for grouping traces by user (NOT set here - use propagate_attributes instead)
session_id: Session ID for grouping traces by session/conversation
tags: List of tags for filtering traces
**trace_kwargs: Additional trace attributes
Returns:
CallbackHandler instance configured for a new trace
CallbackHandler instance + propagate_attributes context manager
Note:
Per Langfuse docs: use propagate_attributes(user_id=...) context manager
to properly set user_id across all observations in the trace.
This makes user_id appear as a filterable field in Langfuse UI.
"""
try:
# Create handler with optional trace context
# According to Langfuse docs v3: Each CallbackHandler() call creates a NEW trace
handler = CallbackHandler()
# If trace metadata provided, we'll rely on runtime config to set them
# (trace_id, user_id, session_id should be passed via config metadata)
if not _langfuse_client:
logger.warning("⚠️ Langfuse client not initialized")
return None
logger.debug(f"✅ Langfuse CallbackHandler created (trace_id={trace_id or 'auto'})")
handler = CallbackHandler()
logger.debug("✅ Langfuse CallbackHandler created")
return handler
except Exception as e:
logger.warning(f"⚠️ CallbackHandler error: {e}")
return None
@contextmanager
def langfuse_trace_context(user_id: str | None = None, session_id: str | None = None, tags: list[str] | None = None):
"""
Context manager to propagate user_id, session_id, tags to all observations.
Usage:
with langfuse_trace_context(user_id="user_123", session_id="session_456"):
# All observations created here will have these attributes
await invoke_chain()
"""
attrs = {}
if user_id:
attrs["user_id"] = user_id
if session_id:
attrs["session_id"] = session_id
# Tags are set via metadata, not propagate_attributes
with propagate_attributes(**attrs):
yield
......@@ -37,6 +37,11 @@ __all__ = [
"MONGODB_DB_NAME",
"MONGODB_URI",
"OPENAI_API_KEY",
"OTEL_EXPORTER_JAEGER_AGENT_HOST",
"OTEL_EXPORTER_JAEGER_AGENT_PORT",
"OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES",
"OTEL_SERVICE_NAME",
"OTEL_TRACES_EXPORTER",
"PORT",
"REDIS_HOST",
"REDIS_PASSWORD",
......@@ -117,3 +122,9 @@ STARROCKS_DB: str | None = os.getenv("STARROCKS_DB")
# Placeholder for backward compatibility if needed
AI_MODEL_NAME = DEFAULT_MODEL
# ====================== OPENTELEMETRY CONFIGURATION ======================
OTEL_EXPORTER_JAEGER_AGENT_HOST = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_HOST")
OTEL_EXPORTER_JAEGER_AGENT_PORT = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_PORT")
OTEL_SERVICE_NAME = os.getenv("OTEL_SERVICE_NAME")
OTEL_TRACES_EXPORTER = os.getenv("OTEL_TRACES_EXPORTER")
OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES")
import asyncio
import platform
# Fix Windows ProactorEventLoop issue với psycopg
if platform.system() == "Windows":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from psycopg_pool import AsyncConnectionPool
async def test():
pool = AsyncConnectionPool("", open=False)
saver = AsyncPostgresSaver(pool)
print(f"Attributes with 'pool': {[a for a in dir(saver) if 'pool' in a.lower()]}")
await pool.close()
if __name__ == "__main__":
asyncio.run(test())
import asyncio
import logging
from common.starrocks_connection import StarRocksConnection
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
async def main():
try:
db = StarRocksConnection()
print("🔌 Connecting to StarRocks...")
# Get Create Table Statement
table_name = "shared_source.magento_product_dimension_with_text_embedding"
res = await db.execute_query_async(f"SHOW CREATE TABLE {table_name}")
if res:
print("\n=== RAW RESULT KEYS ===")
print(res[0].keys())
print(res[0])
else:
print("❌ Could not get table info.")
except Exception as e:
print(f"❌ Error: {e}")
if __name__ == "__main__":
asyncio.run(main())
import asyncio
import os
import sys
# Ensure backend directory is in python path
current_dir = os.path.dirname(os.path.abspath(__file__))
if current_dir not in sys.path:
sys.path.append(current_dir)
from agent.tools.product_search_helpers import build_starrocks_query
class Params:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
async def main():
# Params for "tìm cho tao áo side m phù hợp để đi chơi"
text = "tìm cho tao áo side m phù hợp để đi chơi"
# Mocking what the extraction layer might produce
params = Params(
query=text,
size_scale="M",
keywords="áo side m đi chơi"
)
print(f"Generating query for: {text}")
try:
sql = await build_starrocks_query(params)
print("Successfully generated query.")
print("Check d:\\cnf\\chatbot_canifa\\backend\\embedding.txt")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(main())
============================================================
⏰ TIME: 2026-01-08 08:31:08
🔍 SEARCH: Bikini nữ chất liệu thoáng mát trẻ trung, phù hợp đi biển và bơi lội
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [3BP25W002] Score: 0.5748936
💰 Price: 279300.000000 (Orig: 399000.000000, Disc: 30.000000%)
📝 Desc: product_name: Quần nỉ unisex trẻ em. master_color: Xanh than/ Aqua. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/b/3bp25w002-sl335-134-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/b/3bp25w002-sl335-134-1-u.jpg. product_web_url: https://canifa.com/quan-ni-unisex-tre-em-3bp25w002?color=SL335&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần nỉ unisex trẻ em mang thiết kế đơn giản và tiện dụng, phù hợp cho cả bé trai và bé gái.
Chất liệu co giãn tốt, giúp bé thoải mái vận động suốt ngày dài.
Phom dáng suông dễ mặc, dễ phối, thích hợp cho các hoạt động thường ngày hay khi vui chơi ngoài trời.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Quần nỉ. product_color_name: Aqua 335
2. [1BP25W001] Score: 0.5599894
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Quần gió active bé gái chống thấm nước dáng suông. master_color: Xanh than/ Aqua. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/b/1bp25w001-sl366-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/b/1bp25w001-sl366-128-1-u.jpg. product_web_url: https://canifa.com/quan-dai-be-gai-1bp25w001?color=SL366&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần gió active bé gái dáng suông, túi hộp, phối dọc quần, gấu có chun rút tiện lợi.
Có thể kết hợp cùng áo khoác để đồng bộ.
Chiết liệu nhẹ, thoải mái dễ vận động.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Athleisure. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Quần dài. product_color_name: Aqua 366
3. [1BP25C003] Score: 0.55700254
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Quần nỉ bé gái dáng suông đính nơ. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/b/1bp25c003-sa871-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/b/1bp25c003-sa871-128-1-u.jpg. product_web_url: https://canifa.com/quan-ni-be-gai-1bp25c003?color=SA871&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần dài bé gái, dáng suông hiện đại, 2 bên thân quần đính nơ thời trang, nữ tính, phù hợp bé gái.
Chất liệu cotton pha mềm mại, giữ ấm tốt.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Quần nỉ. product_color_name: Gray 871
4. [1DS25C008] Score: 0.5566883
💰 Price: 599000.000000 (Orig: 599000.000000, Disc: 0.000000%)
📝 Desc: product_name: Váy liền bé gái sát nách dáng suông đuôi váy bồng xòe. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/d/1ds25c008-sw001-120-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/d/1ds25c008-sw001-120-1-u.jpg. product_web_url: https://canifa.com/vay-lien-be-gai-1ds25c008?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Váy liền bé gái dáng sát nách, thiết kế đuôi váy bồng xòe nữ tính. Chất liệu lưới mềm mại phối lớp lót dệt thoi tạo cảm giác nhẹ nhàng, thoải mái cho bé khi mặc, phù hợp trong các dịp đi chơi hay sự kiện.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Spring Summer. style: Feminine. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Váy liền. product_color_name: White 001
5. [1TW23C005] Score: 0.5556582
💰 Price: 199000.000000 (Orig: 499000.000000, Disc: 60.000000%)
📝 Desc: product_name: Áo nỉ bé gái dáng rộng có hình in. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tw23c005-sg588-130-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tw23c005-sg588-130-1-u.jpg. product_web_url: https://canifa.com/ao-ni-be-gai-1tw23c005?color=SG588&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo nỉ bé gái có hình in. Phong cách sport, chất liệu nỉ dày dặn ấm áp cho mùa đông, phom dáng oversize thoải mái. Hình sport khỏe khoắn năng động phù hợp cho bé trong nhiều hoàn cảnh sử dụng.
Chất liệu: 60% cotton 40% polyester.
Đanh lỳ, nhanh khô, giữ nhiệt tốt với mặt trái vải có cào bông, mềm mại với làn da, giữ phom sau khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Basic Update. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo nỉ. product_color_name: Green 588
============================================================
============================================================
⏰ TIME: 2026-01-08 08:50:18
🔍 SEARCH: Áo len nữ nam chất liệu len mềm mại, phong cách trẻ trung, giá dưới 500000
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [8TE25W008] Score: 0.6042312
💰 Price: 399200.000000 (Orig: 499000.000000, Disc: 20.000000%)
📝 Desc: product_name: Áo len nam. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w008-sa799-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w008-sa799-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-8te25w008?color=SA799&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nam dày với chất liệu ấm áp, mềm mịn và co giãn nhẹ, giúp giữ nhiệt hiệu quả. Form vừa vặn, thiết kế tối giản, dễ phối cùng quần jeans hoặc quần tây. Lý tưởng cho phong cách lịch lãm, thoải mái và phù hợp với tiết trời lạnh.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo len. product_color_name: Gray 799
2. [6TE24W012] Score: 0.5914151
💰 Price: 249000.000000 (Orig: 699000.000000, Disc: 64.000000%)
📝 Desc: product_name: Áo len nữ có hình thêu. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6te24w012-sw114-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6te24w012-sw114-l-1-u.jpg. product_web_url: https://canifa.com/ao-len-nu-6te24w012?color=SW114&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nữ dài tay, dáng áo rộng. Chất liệu mềm mại, dầy dặn, ấm áp, phù hợp đi chơi dạo phố mùa thu đông. Chi tiết thêu chữ phía trước áo, mang lại cảm giác trẻ trung, thanh lịch.. material: None. material_group: Yarn - Sợi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Feminine. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo len. product_color_name: White 114
3. [8TE24W002] Score: 0.58657116
💰 Price: 149000.000000 (Orig: 349000.000000, Disc: 57.000000%)
📝 Desc: product_name: Áo len nam cổ tim. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te24w002-sa800-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te24w002-sa800-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-8te24w002?color=SA800&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len trơn cổ tim. Thân áo và tay áo thiết kế ôm nhẹ vào người đem đến cảm giác gọn gàng, lịch sự. Giữ ấm tốt, co giãn tốt, mềm mại, bền đẹp, dễ bảo quản
Phù hợp mặc hàng ngày mùa lạnh.
Chất liệu mềm mại, nhẹ nhưng ấm tạo cảm giác thoải mái cho người mặc trong thời tiết thu đông. Màu sắc rất đa dạng, bắt mắt.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo len. product_color_name: Gray 800
4. [8TE25W014] Score: 0.5774709
💰 Price: 299000.000000 (Orig: 499000.000000, Disc: 40.000000%)
📝 Desc: product_name: Áo len nam cộc tay dáng suông. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa422-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa422-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-ngan-tay-8te25w014?color=SA422&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nam cộc tay dáng suông, mang phong cách trẻ trung.
Thiết kế dễ mặc, phù hợp cho nhiều dịp thường ngày.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo len. product_color_name: Gray 422
5. [6TE25W019] Score: 0.5748453
💰 Price: 349300.000000 (Orig: 499000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo len nữ cộc tay dáng suông có hình in. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6te25w019-sw001-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6te25w019-sw001-m-1-u.jpg. product_web_url: https://canifa.com/ao-len-nu-6te25w019?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nữ cộc tay dáng suông, thiết kế cổ tròn, tay ngắn dáng ôm vừa, có chi tiết phối màu và chữ dệt.
Chất liệu mềm mại, thoải mái.. material: None. material_group: Yarn - Sợi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Áo len. product_color_name: White 001
============================================================
============================================================
⏰ TIME: 2026-01-08 08:51:23
🔍 SEARCH: 1TC25W001
📊 RESULTS COUNT: 2
------------------------------------------------------------
1. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SR031&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Red 031
2. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SA014&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Gray 014
============================================================
============================================================
⏰ TIME: 2026-01-08 08:51:45
🔍 SEARCH: 1KS25W001-CR158
📊 RESULTS COUNT: 0
------------------------------------------------------------
❌ NO PRODUCTS FOUND
============================================================
============================================================
⏰ TIME: 2026-01-08 08:52:28
🔍 SEARCH: 1KS25W001-CR156
📊 RESULTS COUNT: 1
------------------------------------------------------------
1. [1KS25W001] Score: 1.0
💰 Price: 209300.000000 (Orig: 299000.000000, Disc: 30.000000%)
📝 Desc: product_name: Chân váy bé gái xếp ly. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/k/1ks25w001-cr156-122-5-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/k/1ks25w001-cr156-122-5-u.jpg. product_web_url: https://canifa.com/chan-vay-be-gai-1ks25w001-cr156?color=CR156&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Chân váy ngắn xếp ly dáng xòe, có lót quần bên trong thuận tiện cho các bé vận động. Chất liệu mềm mại, mịn mát, dễ dàng kết hợp với nhiều loại trang phục.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Chân váy. product_color_name: Red Checked 156
============================================================
============================================================
⏰ TIME: 2026-01-08 08:52:46
🔍 SEARCH: Bộ pyjama bé trai cotton họa tiết kẻ
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [2LS24W012] Score: 0.8018642
💰 Price: 199000.000000 (Orig: 399000.000000, Disc: 50.000000%)
📝 Desc: product_name: Bộ pyjama bé trai cotton họa tiết kẻ. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls24w012-cb355-128-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls24w012-cb355-128-1-ghep-u.jpg. product_web_url: https://canifa.com/bo-pyjama-be-trai-2ls24w012?color=CB355&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ pyjama bé trai chất liệu dệt thoi, phom dáng cơ bản, chất liệu 100% cotton mềm mại, tạo cảm giác thoải mái cho các bé khi ở nhà.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Full length Sleeve. product_line_vn: Pyjama. product_color_name: Blue Checked 355
2. [2LS25W009] Score: 0.7436938
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Bộ pyjama bé trai hoạ tiết. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls25w009-fb576-128-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls25w009-fb576-128-1-ghep-u.jpg. product_web_url: https://canifa.com/bo-pyjama-be-trai-2ls25w009-fb576?color=FB576&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ pyjama bé trai dài tay, phom dáng cơ bản, chất liệu
100% cotton mềm mại thoải mái. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Pyjama. product_color_name: Blue Florals 576
3. [2LS24W009] Score: 0.7378596
💰 Price: 199000.000000 (Orig: 379000.000000, Disc: 47.000000%)
📝 Desc: product_name: Bộ pyjama bé trai cotton dài tay quần dài hoạ tiết. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls24w009-fb530-128-1-stavk.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/l/2ls24w009-fb530-128-1-stavk.jpg. product_web_url: https://canifa.com/bo-mac-nha-be-trai-2ls24w009?color=FB530&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ pyjama bé trai dài tay, phom dáng cơ bản, chất liệu 100% cotton mềm mại thoải mái.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Basic Update. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Full length Sleeve. product_line_vn: Pyjama. product_color_name: Blue Florals 530
4. [1LS25S011] Score: 0.66090477
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Bộ pyjama bé gái hoạ tiết kẻ. master_color: Tím/ Purple. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/l/1ls25s011-cp031-122-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/l/1ls25s011-cp031-122-1-ghep-u.jpg. product_web_url: https://canifa.com/pyjama-be-gai-1ls25s011?color=CP031&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ mặc nhà pyjama áo ngắn tay, quần cộc bé gái. Phom dáng cơ bản, họa tiết kẻ hiện đại, màu sắc tươi sáng, nữ tính.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Pyjama. product_color_name: Purple Checked 031
5. [6LS25S007] Score: 0.65974045
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Bộ pyjama nữ hoạ tiết cộc tay quần đùi. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/l/6ls25s007-fb560-m-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/l/6ls25s007-fb560-m-1-ghep-u.jpg. product_web_url: https://canifa.com/bo-pyjama-nu-6ls25s007?color=FB560&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ pyjama nữ dáng cộc, với bề mặt vải in họa tiết nhã nhặn, chất liệu co giãn thấm hút tối đa, tạo sự thoải mái khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Pyjama. product_color_name: Blue Florals 560
============================================================
============================================================
⏰ TIME: 2026-01-08 08:55:21
🔍 SEARCH: 8TE25W014
📊 RESULTS COUNT: 2
------------------------------------------------------------
1. [8TE25W014] Score: 1.0
💰 Price: 299000.000000 (Orig: 499000.000000, Disc: 40.000000%)
📝 Desc: product_name: Áo len nam cộc tay dáng suông. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa096-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa096-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-ngan-tay-8te25w014?color=SA096&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nam cộc tay dáng suông, mang phong cách trẻ trung.
Thiết kế dễ mặc, phù hợp cho nhiều dịp thường ngày.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo len. product_color_name: Gray 096
2. [8TE25W014] Score: 1.0
💰 Price: 299000.000000 (Orig: 499000.000000, Disc: 40.000000%)
📝 Desc: product_name: Áo len nam cộc tay dáng suông. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa422-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w014-sa422-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-ngan-tay-8te25w014?color=SA422&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nam cộc tay dáng suông, mang phong cách trẻ trung.
Thiết kế dễ mặc, phù hợp cho nhiều dịp thường ngày.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo len. product_color_name: Gray 422
============================================================
============================================================
⏰ TIME: 2026-01-08 08:58:49
🔍 SEARCH: 1TC25W001
📊 RESULTS COUNT: 2
------------------------------------------------------------
1. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SA014&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Gray 014
2. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SR031&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Red 031
============================================================
============================================================
⏰ TIME: 2026-01-08 08:59:50
🔍 SEARCH: 1TC25W001
📊 RESULTS COUNT: 2
------------------------------------------------------------
1. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sr031-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SR031&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Red 031
2. [1TC25W001] Score: 1.0
💰 Price: 499000.000000 (Orig: 499000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo cardigan bé gái cổ ren. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tc25w001-sa014-110-1-u.jpg. product_web_url: https://canifa.com/ao-cardigan-be-gai-1tc25w001?color=SA014&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác len bé gái, cổ ren vải, chất liệu len mỏng nhưng vẫn giữ ấm tốt, kiểu dáng nữ tính, điệu đà phù hợp với các bé gái phối những bộ trang phục cho mùa lễ hội.. material: None. material_group: Yarn - Sợi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Cardigan. product_color_name: Gray 014
============================================================
============================================================
⏰ TIME: 2026-01-08 09:00:33
🔍 SEARCH: Áo nữ tầm giá 300-400k, phong cách trẻ trung, chất liệu cotton hoặc len nhẹ, phù hợp mặc hàng ngày
📊 RESULTS COUNT: 5
------------------------------------------------------------
1. [8TS25S012] Score: 0.5869082
💰 Price: 349000.000000 (Orig: 349000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nam cotton basic. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s012-sw001-1-thumb.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s012-sw001-1-thumb.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25s012?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông làm bằng chất liệu interlock cotton mềm mại. Dễ mặc, dễ phối đồ, phù hợp mặc nhiều hoàn cảnh khác nhau.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 001
2. [6TS25S019] Score: 0.5862685
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nữ cotton kẻ ngang. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6ts25s019-pb474-thumb.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6ts25s019-pb474-thumb.jpg. product_web_url: https://canifa.com/ao-phong-nu-6ts25s019?color=PB474&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông nữ dáng relax, với chất liệu 100% cotton dệt kẻ ngang nổi bật, chủ đề kết hợp cả gia đình, rất phù hợp với nhiều hoạt động vui chơi, du lịnh cùng cả nhà.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: Blue Strip 474
3. [8TS25W005] Score: 0.58090454
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nam dáng suông có hình in. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25w005-sw001-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25w005-sw001-xl-1-u.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25w005-sw001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông nam chất liệu cotton mềm mịn, thoáng mát.
Thiết kế hình in trẻ trung, dễ dàng phối đồ cho phong cách năng động hằng ngày.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 001
4. [8TS25C006] Score: 0.5743196
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nam cotton USA có hình in. master_color: Nâu/ Brown. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25c006-sn401-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25c006-sn401-l-1-u.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25c006-sn401?color=SN401&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông nam cotton phom relax có hình in với phần đồ họa nổi bật tạo sự trẻ trung cho sản phẩm.
Thiết kế dáng rộng giúp người mặc thoải mái và phù hợp trong nhiều hoàn cảnh.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: Brown 401
5. [3OT25S001] Score: 0.57103765
💰 Price: 349000.000000 (Orig: 349000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo khoác chống nắng unisex trẻ em. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/o/3ot25s001-sm090-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/o/3ot25s001-sm090-128-1-u.jpg. product_web_url: https://canifa.com/ao-khoac-chong-nang-tre-em-3ot25s001-sm090?color=SM090&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo chống nắng trẻ em, phom dáng cơ bản dễ mặc, chất liệu mềm mại thoáng mát, co giãn tốt, có tác dụng cản tia UV, phù hợp các hoạt động ngoài trời cho các bé.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Hooded collar. form_sleeve: Full length Sleeve. product_line_vn: Áo khoác chống nắng. product_color_name: Pink 090
============================================================
============================================================
⏰ TIME: 2026-01-08 09:11:09
🔍 SEARCH: Áo thun nam cotton basic thoáng mát, phù hợp mặc hàng ngày, giá 300-400k
📊 RESULTS COUNT: 9
------------------------------------------------------------
1. [8TS25S012] Score: 0.64669484
💰 Price: 349000.000000 (Orig: 349000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nam cotton basic. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s012-sw001-1-thumb.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s012-sw001-1-thumb.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25s012?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông làm bằng chất liệu interlock cotton mềm mại. Dễ mặc, dễ phối đồ, phù hợp mặc nhiều hoàn cảnh khác nhau.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 001
2. [8TS25C006] Score: 0.6081337
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông nam cotton USA có hình in. master_color: Nâu/ Brown. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25c006-sn401-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25c006-sn401-l-1-u.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25c006-sn401?color=SN401&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông nam cotton phom relax có hình in với phần đồ họa nổi bật tạo sự trẻ trung cho sản phẩm.
Thiết kế dáng rộng giúp người mặc thoải mái và phù hợp trong nhiều hoàn cảnh.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: Brown 401
3. [8BS25S002] Score: 0.59694433
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Quần soóc nam cotton basic. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/b/8bs25s002-sa332-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/b/8bs25s002-sa332-l-1-u.jpg. product_web_url: https://canifa.com/quan-sooc-nam-8bs25s002-sa332?color=SA332&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần soóc nẹp kéo khoá giả, túi hai bên và một túi sau.
Cạp quần co giãn có dây rút điều chỉnh kích thước.
Được giặt mềm thành phẩm để mang lại cảm giác mềm mại, thoải mái.
Đây là item thoải mái, linh hoạt. Thiết kế theo phong cách basic dễ mặc và dễ phối với nhiều trang phục khác nhau.
Chất liệu 100% cotton thân thiện với môi trường. Độ bền tốt. Thấm hút tốt, thoáng mát, không gây hại cho sức khỏe. Thoáng mát khi mặc.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Quần soóc. product_color_name: Gray 332
4. [8TS25S003] Score: 0.59485734
💰 Price: 349300.000000 (Orig: 499000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo phông nam cotton USA dáng rộng có hình in. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s003-sb001-thumb.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8ts25s003-sb001-thumb.jpg. product_web_url: https://canifa.com/ao-phong-nam-8ts25s003?color=SB001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo thun nam dáng relax, nổi bật với hình in sáng tạo, mang đến diện mạo trẻ trung và hiện đại cho phong cách thường ngày.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: Blue 001
5. [8TH25A001] Score: 0.5933641
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo sơ mi nam cotton USA dáng suông. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8th25a001-sw001-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8th25a001-sw001-l-1-u.jpg. product_web_url: https://canifa.com/ao-so-mi-nam-ngan-tay-8th25a001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo sơ mi nam phom regular, chất liệu 100% cotton,
mềm mát. Sản phẩm phù hợp mặc đi làm, đi chơi, có thể kết hợp cùng quần vải, quần khaki.
Chất liệu 100% cotton thân thiện với môi trường. Độ bền tốt. Thấm hút tốt, thoáng mát, không gây hại cho sức khỏe. Thoáng mát khi mặc.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: others. age_by_product: others. season: Year. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Sơ mi. product_color_name: White 001
============================================================
============================================================
⏰ TIME: 2026-01-08 09:13:29
🔍 SEARCH: Áo nam phù hợp
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [8TP25W002] Score: 0.51789695
💰 Price: 549000.000000 (Orig: 549000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo polo nam phối viền. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25w002-sb246-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25w002-sb246-xl-1-u.jpg. product_web_url: https://canifa.com/ao-polo-nam-8tp25w002?color=SB246&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo polo nam dáng regular, thiết kế casual dễ mặc, mang lại sự thoải mái và năng động. Phù hợp cho nhiều hoàn cảnh, từ đi làm đến dạo phố hằng ngày.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Polo. product_color_name: Blue 246
2. [8TP25W004] Score: 0.5156096
💰 Price: 349300.000000 (Orig: 499000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo polo nam có hình thêu. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25w004-sw001-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25w004-sw001-xl-1-u.jpg. product_web_url: https://canifa.com/ao-polo-nam-8tp25w004?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo polo nam, chất liệu co giãn nhẹ mang lại cảm giác thoải mái và chỉn chu, là lựa chọn hoàn hảo cho nhiều hoàn cảnh.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Polo. product_color_name: White 001
3. [8TP25C003] Score: 0.5131125
💰 Price: 419300.000000 (Orig: 599000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo polo nam phối màu. master_color: Nâu/ Brown. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25c003-pn026-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25c003-pn026-xl-1-u.jpg. product_web_url: https://canifa.com/ao-polo-nam-8tp25c003-pn026?color=PN026&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo polo nam, thiết kế thanh lịch, chất liệu co giãn nhẹ mang lại cảm giác thoải mái và chỉn chu, là lựa chọn hoàn hảo cho nhiều hoàn cảnh.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Smart Casual. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Polo. product_color_name: Brown Strip 026
4. [8TE25W008] Score: 0.5097028
💰 Price: 399200.000000 (Orig: 499000.000000, Disc: 20.000000%)
📝 Desc: product_name: Áo len nam. master_color: Xanh than/ Aqua. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w008-sl146-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8te25w008-sl146-xl-1-u.jpg. product_web_url: https://canifa.com/ao-len-nam-8te25w008?color=SL146&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo len nam dày với chất liệu ấm áp, mềm mịn và co giãn nhẹ, giúp giữ nhiệt hiệu quả. Form vừa vặn, thiết kế tối giản, dễ phối cùng quần jeans hoặc quần tây. Lý tưởng cho phong cách lịch lãm, thoải mái và phù hợp với tiết trời lạnh.. material: None. material_group: Yarn - Sợi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo len. product_color_name: Aqua 146
5. [8TP25S003] Score: 0.50890744
💰 Price: 299500.000000 (Orig: 599000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo polo nam. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25s003-pb473-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8tp25s003-pb473-l-1-u.jpg. product_web_url: https://canifa.com/ao-polo-nam-8tp25s003-pb473?color=PB473&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo polo nam phom regular điểm nhấn phối dọc thân, phần tay borib khiến người mặc khoe được vùng bắp tay. Thân áo được thiết kế vừa, mặc được trong nhiều hoàn cảnh khác nhau.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Smart Casual. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Polo. product_color_name: Blue Strip 473
============================================================
============================================================
⏰ TIME: 2026-01-08 09:37:40
🔍 SEARCH: Áo thun nam trẻ trung tay cộc cotton thoáng mát
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [2TH24A001] Score: 0.6127157
💰 Price: 129000.000000 (Orig: 249000.000000, Disc: 48.000000%)
📝 Desc: product_name: Áo sơ mi bé trai cotton cộc tay. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2th24a001-sw001-130-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2th24a001-sw001-130-1-u.jpg. product_web_url: https://canifa.com/ao-so-mi-be-trai-2th24a001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo sơ mi bé trai ngắn tay có túi ngực, phom basic bé có thể sử dụng đi học, đi chơi dễ dàng.
Chất liệu 100% cotton:
Thân thiện với môi trường. Độ bền tốt. Thấm hút tốt, không gây hại cho sức khỏe. Thoáng mát khi mặc.
. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: others. season: Year. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Sơ mi. product_color_name: White 001
2. [8TH24A001] Score: 0.5921609
💰 Price: 149000.000000 (Orig: 349000.000000, Disc: 57.000000%)
📝 Desc: product_name: Áo sơ mi nam cotton cộc tay. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8th24a001-sw001-xl-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/8/t/8th24a001-sw001-xl-1-u.jpg. product_web_url: https://canifa.com/ao-so-mi-nam-ngan-tay-8th24a001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo sơ mi nam phom regular, chất liệu 100% cotton,
mềm mát. Sản phẩm phù hợp mặc đi làm, đi chơi, có thể kết hợp cùng quần vải, quần khaki,.... material: None. material_group: Woven - Dệt Thoi. gender_by_product: others. age_by_product: others. season: Year. style: Basic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Áo Sơ mi. product_color_name: White 001
3. [2TL23W001] Score: 0.5920292
💰 Price: 79000.000000 (Orig: 149000.000000, Disc: 47.000000%)
📝 Desc: product_name: Áo phông dài tay bé trai cotton có hình in. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w001-sg289-120-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w001-sg289-120-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-dai-tay-2tl23w001?color=SG289&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông dài tay bé trai, chất liệu 100% cotton mềm mại, phom dáng basic cơ bản. Hình in tự do phù hợp với sở thích của các bé.
Chất liệu 100% cotton.. material: Single 100% cotton 150gsm. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Green 289
4. [2TL25C002] Score: 0.5887533
💰 Price: 179000.000000 (Orig: 299000.000000, Disc: 40.000000%)
📝 Desc: product_name: Áo phông bé trai dài tay cotton có hình in. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl25c002-fb610-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl25c002-fb610-128-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-dai-tay-2tl25c002-fb610?color=FB610&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông bé trai dài tay, chất liệu cotton 100% mềm mại, họa tiết hiện đại năng động, hình in hợp xu hướng tạo sự cá tính cho trẻ khi sử dụng trong nhiều hoàn cảnh.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Blue Florals 610
5. [2TS25S009] Score: 0.5865394
💰 Price: 199000.000000 (Orig: 199000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo phông bé trai cotton có hình in. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2ts25s009-sw001-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2ts25s009-sw001-128-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-2ts25s009-sw001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông bé trai có hình in hài hòa tươi tắn phù hợp cho cả bố và con. Chất liệu cotton mềm mại thoáng mát, màu sắc dễ mặc sẽ là lựa chọn hàng đầu cho những cuộc vui chơi dã ngoại của gia đình.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 001
============================================================
============================================================
⏰ TIME: 2026-01-08 09:46:24
🔍 SEARCH: Áo thun nam cộc tay trẻ trung, giá dưới 500k
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [3TL25C001] Score: 0.52257395
💰 Price: 179000.000000 (Orig: 299000.000000, Disc: 40.000000%)
📝 Desc: product_name: Áo phông dài tay unisex trẻ em cotton USA có hình in. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3tl25c001-sm610-128-0-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3tl25c001-sm610-128-0-u.jpg. product_web_url: https://canifa.com/ao-phong-unisex-tre-em-dai-tay-3tl25c001-sm610?color=SM610&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông unisex trẻ em có hình in mang phong cách thoải mái, phù hợp cho mọi hoạt động hằng ngày của bé.
Chất liệu cotton USA mềm mịn, thoáng khí, an toàn cho làn da nhạy cảm.
Thiết kế hình in sinh động giúp bé thêm nổi bật và tự tin thể hiện cá tính.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Pink 610
2. [2TL23W001] Score: 0.516677
💰 Price: 79000.000000 (Orig: 149000.000000, Disc: 47.000000%)
📝 Desc: product_name: Áo phông dài tay bé trai cotton có hình in. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w001-sg289-120-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w001-sg289-120-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-dai-tay-2tl23w001?color=SG289&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông dài tay bé trai, chất liệu 100% cotton mềm mại, phom dáng basic cơ bản. Hình in tự do phù hợp với sở thích của các bé.
Chất liệu 100% cotton.. material: Single 100% cotton 150gsm. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Green 289
3. [2TH24A001] Score: 0.51404
💰 Price: 129000.000000 (Orig: 249000.000000, Disc: 48.000000%)
📝 Desc: product_name: Áo sơ mi bé trai cotton cộc tay. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2th24a001-sw001-130-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2th24a001-sw001-130-1-u.jpg. product_web_url: https://canifa.com/ao-so-mi-be-trai-2th24a001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo sơ mi bé trai ngắn tay có túi ngực, phom basic bé có thể sử dụng đi học, đi chơi dễ dàng.
Chất liệu 100% cotton:
Thân thiện với môi trường. Độ bền tốt. Thấm hút tốt, không gây hại cho sức khỏe. Thoáng mát khi mặc.
. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: others. season: Year. style: Basic. fitting: Regular. form_neckline: Classic Collar. form_sleeve: Short Sleeve. product_line_vn: Áo Sơ mi. product_color_name: White 001
4. [2TL23W002] Score: 0.5101102
💰 Price: 99000.000000 (Orig: 249000.000000, Disc: 60.000000%)
📝 Desc: product_name: Áo phông dài tay bé trai cotton USA phối màu tay áo. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w002-sg149-120-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl23w002-sg149-120-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-dai-tay-2tl23w002?color=SG149&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông dài tay bé trai phối màu tay áo,phom dáng cơ bản thoải mái, hình in khỏekhoắn năng động phù hợp cho sự vận động của trẻ nhỏ.
Chất liệu cotton USA.. material: Single 100% cotton 150gsm. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Basic Update. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Áo phông. product_color_name: Green 149
5. [2TL25C007] Score: 0.50085014
💰 Price: 230300.000000 (Orig: 329000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo phông dài tay bé trai. master_color: Đen/ Black. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl25c007-pk186-164-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/2/t/2tl25c007-pk186-164-1-u.jpg. product_web_url: https://canifa.com/ao-phong-be-trai-dai-tay-2tl25c007-pk186?color=PK186&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo thun kẻ dài tay bé trai, phom dáng thoải mái, nguyên liệu mềm mại, hình in năng động tạo sự thoải mái cho bé sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Relax. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Black Strip 186
============================================================
============================================================
⏰ TIME: 2026-01-08 09:47:06
🔍 SEARCH: Áo nữ dự tiệc trẻ trung, kiểu dáng xinh xắn, giá dưới 400000
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [1TO25C005] Score: 0.5040716
💰 Price: 199500.000000 (Orig: 399000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu bé gái hoạ tiết. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c005-fm333-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c005-fm333-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25c005?color=FM333&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái hoạ tiết, có chi tiết ren ở ngực mang đến sự nữ tính.
Áo có thể kết hợp với chân váy và quần shorts. Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: Pink Florals 333
2. [1TO24C005] Score: 0.4982863
💰 Price: 129000.000000 (Orig: 349000.000000, Disc: 63.000000%)
📝 Desc: product_name: Áo kiểu bé gái tay bồng đính hạt trang trí. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c005-sr002-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c005-sr002-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to24c005?color=SR002&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu công chúa bé gái, tay bồng đính hạt giả trai điệu đà nữ tính.
Bề mặt vải nhung pha sợi kim tuyến lấp lánh., co giãn tốt, mềm mại dễ chịu khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: Red 002
3. [1TO25S002] Score: 0.4970109
💰 Price: 149000.000000 (Orig: 299000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu bé gái tay bồng hoạ tiết có nơ. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25s002-fm328-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25s002-fm328-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25s002?color=FM328&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái cổ tròn có chi tiết nơ đính mềm mại nữ tính, dễ kết hợp với nhiều loại sản phẩm. Phù hợp với các bé gái thích sự nữ tính.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Spring Summer. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo kiểu. product_color_name: Pink Florals 328
4. [1TO25C006] Score: 0.4948982
💰 Price: 279300.000000 (Orig: 399000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo kiểu bé gái. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c006-sw001-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c006-sw001-110-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25c006?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái có chi tiết 2 lớp lá cổ to mang đến sự nữ tính.
Áo có thể kết hợp với các kiểu áo len gilet, váy yếm,...
Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Mesurement. form_sleeve: None. product_line_vn: Áo kiểu. product_color_name: White 001
5. [1TO24C003] Score: 0.49048054
💰 Price: 129000.000000 (Orig: 399000.000000, Disc: 68.000000%)
📝 Desc: product_name: Áo kiểu bé gái. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c003-sw001-122-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c003-sw001-122-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to24c003?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái có chi tiết 2 lớp lá cổ to mang đến sự nữ tính. Áo có thể kết hợp với các kiểu áo len gilet, váy yếm,... Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Trend. fitting: Regular. form_neckline: Mesurement. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: White 001
============================================================
============================================================
⏰ TIME: 2026-01-08 09:47:50
🔍 SEARCH: Áo nữ dự tiệc trẻ trung, nữ tính, giá dưới 400k
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [1TO25C005] Score: 0.5021556
💰 Price: 199500.000000 (Orig: 399000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu bé gái hoạ tiết. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c005-fm333-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25c005-fm333-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25c005?color=FM333&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái hoạ tiết, có chi tiết ren ở ngực mang đến sự nữ tính.
Áo có thể kết hợp với chân váy và quần shorts. Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: Pink Florals 333
2. [3TS25S018] Score: 0.49900895
💰 Price: 149500.000000 (Orig: 299000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo phông unisex trẻ em tranh Tố Nữ modern. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25s018-sw001-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25s018-sw001-1-u.jpg. product_web_url: https://canifa.com/ao-phong-unisex-tre-em-3ts25s018-sw001?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông unisex trẻ em thuộc Mini collection Em ơi em à! với 2 lựa chọn màu sắc: đen - trắng.
Lấy cảm hứng từ đời sống giới trẻ và tình yêu dành cho văn hóa truyền thống, Canifa kết hợp với Nhà thiết kế Cao Minh Tiến cùng tôn vinh và góp phần lan toả chất Việt qua các mẫu sản phẩm thời trang trong mini collection "Em ơi Em à".
Hình ảnh bốn Tố nữ trong bộ tranh Tứ bình cổ – biểu tượng của vẻ đẹp và tâm hồn người phụ nữ Việt xưa – được khắc họa lại qua lăng kính hiện đại, trẻ trung. Mỗi chiếc áo là sự giao thoa giữa chất liệu văn hóa truyền thống và hơi thở đương đại, mang đến một thông điệp gần gũi và đậm chất Việt.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Dynamic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 001
3. [1TO25S002] Score: 0.4988845
💰 Price: 149000.000000 (Orig: 299000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu bé gái tay bồng hoạ tiết có nơ. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25s002-fm328-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25s002-fm328-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25s002?color=FM328&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái cổ tròn có chi tiết nơ đính mềm mại nữ tính, dễ kết hợp với nhiều loại sản phẩm. Phù hợp với các bé gái thích sự nữ tính.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Spring Summer. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo kiểu. product_color_name: Pink Florals 328
4. [1TO24C005] Score: 0.49112278
💰 Price: 129000.000000 (Orig: 349000.000000, Disc: 63.000000%)
📝 Desc: product_name: Áo kiểu bé gái tay bồng đính hạt trang trí. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c005-sr002-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to24c005-sr002-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to24c005?color=SR002&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu công chúa bé gái, tay bồng đính hạt giả trai điệu đà nữ tính.
Bề mặt vải nhung pha sợi kim tuyến lấp lánh., co giãn tốt, mềm mại dễ chịu khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: Red 002
5. [1TO25W001] Score: 0.49014068
💰 Price: 244300.000000 (Orig: 349000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo kiểu bé gái đính nơ. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pm102-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pm102-128-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25w001?color=PM102&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái đính nơ, có chi tiết nơ ở ngực mang đến sự nữ tính.
Áo có thể kết hợp với chân váy và quần shorts. Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo kiểu. product_color_name: Pink Strip 102
============================================================
============================================================
⏰ TIME: 2026-01-08 13:19:47
🔍 SEARCH: quần áo thời trang giá dưới 500k
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [1TO25W001] Score: 0.47591317
💰 Price: 244300.000000 (Orig: 349000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo kiểu bé gái đính nơ. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pb534-128-0-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pb534-128-0-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25w001?color=PB534&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái đính nơ, có chi tiết nơ ở ngực mang đến sự nữ tính.
Áo có thể kết hợp với chân váy và quần shorts. Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo kiểu. product_color_name: Blue Strip 534
2. [6ST25S002] Score: 0.47069013
💰 Price: 454300.000000 (Orig: 649000.000000, Disc: 30.000000%)
📝 Desc: product_name: Bộ quần áo nữ dáng ngắn kẻ ngang có hình in. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/s/6st25s002-pb472-l-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/s/6st25s002-pb472-l-1-ghep-u.jpg. product_web_url: https://canifa.com/bo-quan-ao-nu-6st25s002?color=PB472&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ trang phục nữ dáng ngắn, chất liệu vải dệt kẻ với bề mặt dệt tạo sự thông thoáng rất phù hợp với những ngày hè nóng bức và những hoạt động vui chơi, du lịch ngoài trời.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Dynamic. fitting: Regular. form_neckline: Crew Neck. form_sleeve: Sleeveless. product_line_vn: Bộ quần áo. product_color_name: Blue Strip 472
3. [6DS23W028] Score: 0.4653883
💰 Price: 199000.000000 (Orig: 799000.000000, Disc: 75.000000%)
📝 Desc: product_name: Áo dài nữ. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds23w028-sm332-m-1-thumb-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds23w028-sm332-m-1-thumb-u.jpg. product_web_url: https://canifa.com/ao-dai-nu-6ds23w028?color=SM332&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo dài len Tết nữ, cổ xẻ V cách điệu, vai chờm.
Chất liệu pha nhiều thành phần giúp sản phẩm mềm mại và giữ ấm tốt.. material: None. material_group: Yarn - Sợi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Váy liền. product_color_name: Pink 332
4. [6BP24W002] Score: 0.46386397
💰 Price: 199000.000000 (Orig: 799000.000000, Disc: 75.000000%)
📝 Desc: product_name: Quần gió nữ phối dây rút ống. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/b/6bp24w002-sb010-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/b/6bp24w002-sb010-l-1-u.jpg. product_web_url: https://canifa.com/quan-dai-nu-6bp24w002?color=SB010&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần gió thể thao nữ, với chi tiết lé phối và dây rút ống quần tạo nhiều kiểu mặc ống xuông hoặc jogger tùy sở thích của khách hàng.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Quần dài. product_color_name: Blue 010
5. [1OT24W001] Score: 0.4617235
💰 Price: 249000.000000 (Orig: 499000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo khoác gió bé gái. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/o/1ot24w001-sw113-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/o/1ot24w001-sw113-128-1-u.jpg. product_web_url: https://canifa.com/ao-khoac-gio-be-gai-1ot24w001?color=SW113&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác gió bé gái 2 lớp có mũ. Phom dáng cơ bản, thoải mái,chi tiêt trang trí túi ốp to thời trang. Mùa sắc tươi sáng dễ thương, phù hợp các hoạt động ngoài trời trong mùa thu.
Nguyên liệu nylon mỏng nhẹ, cản gió, chống thấm nước tốt.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. form_neckline: None. form_sleeve: None. product_line_vn: Áo khoác gió. product_color_name: White 113
============================================================
============================================================
⏰ TIME: 2026-01-08 13:47:15
🔍 SEARCH: quần áo thời trang giá dưới 500k
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [1TO25W001] Score: 0.47598594
💰 Price: 244300.000000 (Orig: 349000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo kiểu bé gái đính nơ. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pb534-128-0-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1to25w001-pb534-128-0-u.jpg. product_web_url: https://canifa.com/ao-kieu-be-gai-1to25w001?color=PB534&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu bé gái đính nơ, có chi tiết nơ ở ngực mang đến sự nữ tính.
Áo có thể kết hợp với chân váy và quần shorts. Chất liệu có độ dày vừa phải rất phù hợp với thời tiết giao mùa. material: None. material_group: Woven - Dệt Thoi. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Feminine. fitting: Regular. size_scale: 98. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo kiểu. product_color_name: Blue Strip 534
2. [6ST25S002] Score: 0.46967918
💰 Price: 454300.000000 (Orig: 649000.000000, Disc: 30.000000%)
📝 Desc: product_name: Bộ quần áo nữ dáng ngắn kẻ ngang có hình in. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/s/6st25s002-pb472-l-1-ghep-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/s/6st25s002-pb472-l-1-ghep-u.jpg. product_web_url: https://canifa.com/bo-quan-ao-nu-6st25s002?color=PB472&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Bộ trang phục nữ dáng ngắn, chất liệu vải dệt kẻ với bề mặt dệt tạo sự thông thoáng rất phù hợp với những ngày hè nóng bức và những hoạt động vui chơi, du lịch ngoài trời.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Dynamic. fitting: Regular. size_scale: M. form_neckline: Crew Neck. form_sleeve: Sleeveless. product_line_vn: Bộ quần áo. product_color_name: Blue Strip 472
3. [6DS23W028] Score: 0.46801883
💰 Price: 199000.000000 (Orig: 799000.000000, Disc: 75.000000%)
📝 Desc: product_name: Áo dài nữ. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds23w028-sm332-m-1-thumb-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds23w028-sm332-m-1-thumb-u.jpg. product_web_url: https://canifa.com/ao-dai-nu-6ds23w028?color=SM332&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo dài len Tết nữ, cổ xẻ V cách điệu, vai chờm.
Chất liệu pha nhiều thành phần giúp sản phẩm mềm mại và giữ ấm tốt.. material: None. material_group: Yarn - Sợi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Regular. size_scale: L. form_neckline: None. form_sleeve: None. product_line_vn: Váy liền. product_color_name: Pink 332
4. [6BP24W002] Score: 0.46529245
💰 Price: 199000.000000 (Orig: 799000.000000, Disc: 75.000000%)
📝 Desc: product_name: Quần gió nữ phối dây rút ống. master_color: Xanh da trời/ Blue. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/b/6bp24w002-sb010-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/b/6bp24w002-sb010-l-1-u.jpg. product_web_url: https://canifa.com/quan-dai-nu-6bp24w002?color=SB010&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần gió thể thao nữ, với chi tiết lé phối và dây rút ống quần tạo nhiều kiểu mặc ống xuông hoặc jogger tùy sở thích của khách hàng.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Dynamic. fitting: Regular. size_scale: XL. form_neckline: None. form_sleeve: None. product_line_vn: Quần dài. product_color_name: Blue 010
5. [3LB25S001] Score: 0.46260864
💰 Price: 69000.000000 (Orig: 69000.000000, Disc: 0.000000%)
📝 Desc: product_name: Quần mặc nhà trẻ em. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/l/3lb25s001-sm508-110-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/l/3lb25s001-sm508-110-1-u.jpg. product_web_url: https://canifa.com/quan-mac-nha-tre-em-3lb25s001?color=SM508&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Quần mặc nhà trẻ em. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. size_scale: 110Cm. form_neckline: None. form_sleeve: None. product_line_vn: Quần mặc nhà. product_color_name: Pink 508
============================================================
============================================================
⏰ TIME: 2026-01-08 14:04:31
🔍 SEARCH: Áo mùa đông nam nữ trẻ trung ấm áp
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [6TL25W013] Score: 0.47186434
💰 Price: 399000.000000 (Orig: 399000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo thun tay dài nữ Youngster. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6tl25w013-sr031-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6tl25w013-sr031-m-1-u.jpg. product_web_url: https://canifa.com/ao-phong-nu-dai-tay-6tl25w013-sr031?color=SR031&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo dài tay Vietnam Youngster lấy cảm hứng từ phong cách hiphop và thể thao đường phố, nổi bật với form body-fit, đường cắt tay raglan mạnh mẽ và logo Youngster sắc nét. Tông màu trung tính – đỏ sẫm – đen – trắng dễ phối, chất liệu co giãn tạo sự thoải mái khi vận động.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Slimfit. size_scale: S. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo phông. product_color_name: Red 031
2. [1TW23C005] Score: 0.47107607
💰 Price: 199000.000000 (Orig: 499000.000000, Disc: 60.000000%)
📝 Desc: product_name: Áo nỉ bé gái dáng rộng có hình in. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tw23c005-sg588-130-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/1/t/1tw23c005-sg588-130-1-u.jpg. product_web_url: https://canifa.com/ao-ni-be-gai-1tw23c005?color=SG588&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo nỉ bé gái có hình in. Phong cách sport, chất liệu nỉ dày dặn ấm áp cho mùa đông, phom dáng oversize thoải mái. Hình sport khỏe khoắn năng động phù hợp cho bé trong nhiều hoàn cảnh sử dụng.
Chất liệu: 60% cotton 40% polyester.
Đanh lỳ, nhanh khô, giữ nhiệt tốt với mặt trái vải có cào bông, mềm mại với làn da, giữ phom sau khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: female. age_by_product: others. season: Fall Winter. style: Basic Update. fitting: Regular. size_scale: 130Cm. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo nỉ. product_color_name: Green 588
3. [3TS25W004] Score: 0.47099864
💰 Price: 109500.000000 (Orig: 219000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo phông unisex trẻ em Lân La. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25w004-sw401-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25w004-sw401-1-u.jpg. product_web_url: https://canifa.com/ao-phong-unisex-tre-em-3ts25w004-sw401?color=SW401&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo phông lấy cảm hứng từ những hình ảnh quen thuộc mỗi mùa Trung Thu từ trống lân, chú nghê, đèn ông sao và ánh trăng rằm, kết hợp cùng lối chơi chữ Việt từ láy, typography ấn tượng, mang đến thiết kế nổi bật, mới mẻ.
Chất liệu pha giữa cotton và polyester mang lại sự mềm mại, thoáng mát và đảm bảo được độ bền, chống nhăn cho sản phẩm.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Dynamic. fitting: Regular. size_scale: 140Cm. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: White 401
4. [3TS25S030] Score: 0.46794653
💰 Price: 175200.000000 (Orig: 219000.000000, Disc: 20.000000%)
📝 Desc: product_name: Áo phông trẻ em Việt Nam typo dáng rộng. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25s030-sr079-feed_thumb.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/t/3ts25s030-sr079-feed_thumb.jpg. product_web_url: https://canifa.com/ao-phong-unisex-tre-em-3ts25s030-sr079?color=SR079&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Dành cho những trái tim yêu nước, áo phông trẻ em Canifa S được làm từ chất liệu vải kết hợp thành phần Polyester và cotton vừa thoáng mát, mềm mại, vừa giúp sản phẩm có độ bền tốt, giữ form sau nhiều lần giặt và sử dụng. Thiết kế unisex vừa vặn, dễ mặc. Màu sắc đa dạng hiện đại, họa tiết typo sinh động, lấy cảm hứng từ những giá trị biểu tượng Việt Nam.. material: None. material_group: Knit - Dệt Kim. gender_by_product: others. age_by_product: others. season: Spring Summer. style: Basic. fitting: Regular. size_scale: 120Cm. form_neckline: Crew Neck. form_sleeve: Short Sleeve. product_line_vn: Áo phông. product_color_name: Red 079
5. [3OT25W003] Score: 0.4638368
💰 Price: 314300.000000 (Orig: 449000.000000, Disc: 30.000000%)
📝 Desc: product_name: Áo khoác gió unisex trẻ em chống thấm nước. master_color: Hồng/ Pink- Magenta. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/o/3ot25w003-sm047-128-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/3/o/3ot25w003-sm047-128-1-u.jpg. product_web_url: https://canifa.com/ao-khoac-gio-be-trai-3ot25w003?color=SM047&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo khoác 2 lớp chống thấm nước. Có mũ trùm đầu và tay dài bo chun. Cài khóa kéo phía trước. Thân trước có 2 túi cơi. Gấu áo có nút chặn điều chỉnh bên hông. Lớp lót bên trong cùng màu.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: others. age_by_product: others. season: Fall Winter. style: Basic. fitting: Regular. size_scale: 140Cm. form_neckline: None. form_sleeve: None. product_line_vn: Áo khoác gió. product_color_name: Pink 047
============================================================
============================================================
⏰ TIME: 2026-01-08 14:07:32
🔍 SEARCH: Áo len nữ
📊 RESULTS COUNT: 0
------------------------------------------------------------
❌ NO PRODUCTS FOUND
============================================================
============================================================
⏰ TIME: 2026-01-08 14:09:47
🔍 SEARCH: Áo len nữ
📊 RESULTS COUNT: 0
------------------------------------------------------------
❌ NO PRODUCTS FOUND
============================================================
============================================================
⏰ TIME: 2026-01-08 14:18:18
🔍 SEARCH: Áo nữ chất liệu vải, giá dưới 500000
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [6IT23W006] Score: 0.5640466
💰 Price: 99000.000000 (Orig: 279000.000000, Disc: 65.000000%)
📝 Desc: product_name: Áo body nữ. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/i/6it23w006-sw001-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/i/6it23w006-sw001-m-1-u.jpg. product_web_url: https://canifa.com/ao-body-nu-6it23w006?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo mặc trong nữ cổ tròn, phom ôm sát tôn dáng, chất liệu co giãn tốt, mềm mại dễ chịu, bề mặt gân rib trẻ trung hiện đại, màu sắc dễ mix match trang phục, phù hợp nhiều độ tuổi và hoàn cảnh sử dụng.
Chất liệu rayon pha span mỏng nhẹ co giãn tốt, thoải mái dễ chịu khi sử dụng. Bề mặt vải gân rib hiện đại trẻ trung.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Slimfit. size_scale: XL. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo Body. product_color_name: White 001
2. [6TO24S001] Score: 0.5573278
💰 Price: 149000.000000 (Orig: 399000.000000, Disc: 63.000000%)
📝 Desc: product_name: Áo kiểu nữ vải dệt họa tiết tay bồng. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to24s001-sw347-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to24s001-sw347-m-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-nu-6to24s001?color=SW347&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu nữ với điểm nhấn là kết cấu bề mặt của vải dệt họa tiết kết hợp với dáng áo tay bồng và cổ áo cách điệu làm nên sản phẩm mềm mại nữ tính, dễ kết hợp với nhiều loại sản phẩm khác như chân váy, quần jeans.... material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Basic Update. fitting: Regular. size_scale: L. form_neckline: Crew Neck. form_sleeve: Puff. product_line_vn: Áo kiểu. product_color_name: White 347
3. [6IT25W001] Score: 0.5554728
💰 Price: 299000.000000 (Orig: 299000.000000, Disc: 0.000000%)
📝 Desc: product_name: Áo body nữ. master_color: Xám/ Gray. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/i/6it25w001-sa871-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/i/6it25w001-sa871-m-1-u.jpg. product_web_url: https://canifa.com/ao-body-nu-6it25w001?color=SA871&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo body nữ cổ tròn, chất liệu vải rib mềm mại rất phù hợp với phom dáng ôm sát cơ thể, giữ ấm và thoải mái khi sử dụng.. material: None. material_group: Knit - Dệt Kim. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic. fitting: Slimfit. size_scale: XL. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Áo Body. product_color_name: Gray 871
4. [6TO25S005] Score: 0.55455154
💰 Price: 299500.000000 (Orig: 599000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu nữ gile sát nách. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to25s005-sw001-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to25s005-sw001-m-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-nu-6to25s005?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo ghi lê nữ sát nách. Chất liệu mềm mại, mịn mát. Thiết kế với độ rộng vừa phải, phù hợp đi chơi, dạo phố.
Chất liệu 100% cotton thân thiện với môi trường. Thấm hút tốt, thoáng mát khi mặc.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Feminine. fitting: Regular. size_scale: L. form_neckline: Crew Neck. form_sleeve: Sleeveless. product_line_vn: Áo kiểu. product_color_name: White 001
5. [6KS23W009] Score: 0.5540735
💰 Price: 199000.000000 (Orig: 499000.000000, Disc: 60.000000%)
📝 Desc: product_name: Chân váy nữ interlock dài qua gối có xẻ trước. master_color: Tím/ Purple. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/k/6ks23w009-sp310-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/k/6ks23w009-sp310-m-1-u.jpg. product_web_url: https://canifa.com/chan-vay-nu-6ks23w009-sk010?color=SP310&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Chân váy dài qua gối nữ, dáng hơi A, có dây rút eo, chất liệu interlock dầy dặn, thoải mái, dễ chịu cho người mặc, phù hợp với đi chơi, đi làm, thời tiết mùa thu, mùa xuân.
Chất liệu Cotton Polyester
- Ưu điểm của nguyên liệu: Bề mặt lì, chắc dày dặn, dấu dáng cho người mặc, ít nhăn.- Phom dáng: Phù hợp với phom dáng vừa đến rộng.
- Mùa: Phù hợp thời điểm giao mùa (Xuân và Thu).. material: None. material_group: None. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic Update. fitting: Regular. size_scale: S. form_neckline: None. form_sleeve: None. product_line_vn: Chân váy. product_color_name: Purple 310
============================================================
============================================================
⏰ TIME: 2026-01-08 14:35:49
🔍 SEARCH: Áo nữ chất liệu vải giá dưới 500k
📊 RESULTS COUNT: 10
------------------------------------------------------------
1. [6TO24S001] Score: 0.5658994
💰 Price: 149000.000000 (Orig: 399000.000000, Disc: 63.000000%)
📝 Desc: product_name: Áo kiểu nữ vải dệt họa tiết tay bồng. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to24s001-sw347-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to24s001-sw347-m-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-nu-6to24s001?color=SW347&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu nữ với điểm nhấn là kết cấu bề mặt của vải dệt họa tiết kết hợp với dáng áo tay bồng và cổ áo cách điệu làm nên sản phẩm mềm mại nữ tính, dễ kết hợp với nhiều loại sản phẩm khác như chân váy, quần jeans.... material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Basic Update. fitting: Regular. size_scale: L. form_neckline: Crew Neck. form_sleeve: Puff. product_line_vn: Áo kiểu. product_color_name: White 347
2. [6TO25S005] Score: 0.5573267
💰 Price: 299500.000000 (Orig: 599000.000000, Disc: 50.000000%)
📝 Desc: product_name: Áo kiểu nữ gile sát nách. master_color: Trắng/ White. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to25s005-sw001-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to25s005-sw001-m-1-u.jpg. product_web_url: https://canifa.com/ao-kieu-nu-6to25s005?color=SW001&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo ghi lê nữ sát nách. Chất liệu mềm mại, mịn mát. Thiết kế với độ rộng vừa phải, phù hợp đi chơi, dạo phố.
Chất liệu 100% cotton thân thiện với môi trường. Thấm hút tốt, thoáng mát khi mặc.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Feminine. fitting: Regular. size_scale: L. form_neckline: Crew Neck. form_sleeve: Sleeveless. product_line_vn: Áo kiểu. product_color_name: White 001
3. [6KS23W009] Score: 0.5534734
💰 Price: 199000.000000 (Orig: 499000.000000, Disc: 60.000000%)
📝 Desc: product_name: Chân váy nữ interlock dài qua gối có xẻ trước. master_color: Tím/ Purple. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/k/6ks23w009-sp310-m-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/k/6ks23w009-sp310-m-1-u.jpg. product_web_url: https://canifa.com/chan-vay-nu-6ks23w009-sk010?color=SP310&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Chân váy dài qua gối nữ, dáng hơi A, có dây rút eo, chất liệu interlock dầy dặn, thoải mái, dễ chịu cho người mặc, phù hợp với đi chơi, đi làm, thời tiết mùa thu, mùa xuân.
Chất liệu Cotton Polyester
- Ưu điểm của nguyên liệu: Bề mặt lì, chắc dày dặn, dấu dáng cho người mặc, ít nhăn.- Phom dáng: Phù hợp với phom dáng vừa đến rộng.
- Mùa: Phù hợp thời điểm giao mùa (Xuân và Thu).. material: None. material_group: None. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Basic Update. fitting: Regular. size_scale: S. form_neckline: None. form_sleeve: None. product_line_vn: Chân váy. product_color_name: Purple 310
4. [6TO23C001] Score: 0.5529876
💰 Price: 149000.000000 (Orig: 599000.000000, Disc: 75.000000%)
📝 Desc: product_name: Áo kiểu nữ dài tay cổ cách điệu. master_color: Xanh lá cây/ Green. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to23c001-sg553-m-1.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/t/6to23c001-sg553-m-1.jpg. product_web_url: https://canifa.com/ao-kieu-nu-6to23c001?color=SG553&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo kiểu chất liệu cotton linen, cổ kiểu tay dài.. material: None. material_group: Woven - Dệt Thoi. gender_by_product: male. age_by_product: adult. season: Spring Summer. style: Trend. fitting: Regular. size_scale: XL. form_neckline: Mesurement. form_sleeve: Full length Sleeve. product_line_vn: Áo kiểu. product_color_name: Green 553
5. [6DS24W010] Score: 0.55283505
💰 Price: 299000.000000 (Orig: 899000.000000, Disc: 67.000000%)
📝 Desc: product_name: Áo dài nữ. master_color: Đỏ/ Red. product_image_url: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds24w010-sr002-l-1-u.jpg. product_image_url_thumbnail: https://2885371169.e.cdneverest.net/pub/media/catalog/product/6/d/6ds24w010-sr002-l-1-u.jpg. product_web_url: https://canifa.com/ao-dai-nu-6ds24w010?color=SR002&utm_source=chatbot&utm_medium=rsa&utm_campaign=testver25.9. description_text: Áo dài len, cổ tròn tay lỡ, đính nơ.
Chất liệu pha nhiều thành phần giúp sản phẩm mềm mại và giữ ấm tốt.. material: None. material_group: Yarn - Sợi. gender_by_product: male. age_by_product: adult. season: Fall Winter. style: Feminine. fitting: Slimfit. size_scale: M. form_neckline: Crew Neck. form_sleeve: Full length Sleeve. product_line_vn: Váy liền. product_color_name: Red 002
============================================================
WITH top_matches AS (
SELECT /*+ SET_VAR(ann_params='{"ef_search":128}') */
internal_ref_code,
product_color_code,
description_text_full,
sale_price,
original_price,
discount_amount,
approx_cosine_similarity(vector, [0.04000994190573692,0.011043205857276917,-0.0579720139503479,-0.031009631231427193,0.028677646070718765,-0.04494372755289078,0.023743856698274612,-0.0034859334118664265,0.020371150225400925,-0.08372022211551666,-0.02802237682044506,0.02436058036983013,-0.026654021814465523,-0.01709480583667755,0.026114387437701225,0.0547727607190609,0.018983522430062294,-0.03484487906098366,-0.03993285074830055,-0.019465336576104164,0.0009889258071780205,0.021469688042998314,0.007068230304867029,-0.0009979598689824343,0.043055012822151184,-0.0037846590857952833,0.06074726954102516,-0.05361640453338623,-0.02200932241976261,-0.006822504103183746,0.02890891581773758,-0.02324276976287365,0.03380415961146355,-0.06271307915449142,0.010349391959607601,0.054965484887361526,0.016767172142863274,0.00028080795891582966,0.031240902841091156,-0.028465647250413895,0.0035100241657346487,-0.01633353717625141,0.0070152305997908115,0.027848923578858376,0.02393658272922039,0.03629032522439957,0.016545535996556282,0.04744916781783104,-0.0037653862964361906,-0.01040721032768488,0.008523312397301197,-0.026576930657029152,-0.014512276276946068,0.02912091463804245,-0.0060082366690039635,0.03650232404470444,-0.0074055008590221405,-0.004704926162958145,0.01617935672402382,0.004276110790669918,0.011447930708527565,-0.019041338935494423,-0.027559833601117134,-0.005545693915337324,-0.02281877212226391,-0.014213550835847855,-0.01695026084780693,-0.005314422305673361,-0.002498212270438671,0.010792662389576435,0.0056276023387908936,-0.05589057132601738,-0.02973763830959797,0.023069314658641815,-0.024437671527266502,-0.031183084473013878,0.0114190224558115,-0.028060922399163246,-0.03168417140841484,-0.022433320060372353,-0.03232016786932945,0.016612989827990532,-0.016372082754969597,0.0066586872562766075,-0.01386664342135191,-0.05118805542588234,-0.05242150276899338,0.0507640577852726,-0.04656262695789337,-0.017191169783473015,-0.05492694303393364,0.031028904020786285,0.01639135554432869,0.0017140578711405396,0.04629281163215637,0.028099466115236282,0.004844652488827705,-0.02532421052455902,-0.018386071547865868,0.016506990417838097,-0.03613614663481712,0.005381876602768898,0.04475100338459015,0.05978363752365112,-0.014001552015542984,0.034960515797138214,0.02268386259675026,0.008296859450638294,-0.07296610623598099,0.01776934787631035,-0.01860770583152771,0.05997636541724205,-0.015572269447147846,-0.0018598069436848164,0.024668941274285316,0.010705935768783092,0.02212495729327202,0.031221630051732063,0.03627105429768562,-0.025555482134222984,-0.007217593025416136,0.025902388617396355,-0.024726759642362595,-0.079094797372818,-0.07763008028268814,0.05581348016858101,-0.039451032876968384,0.047564804553985596,-0.013143920339643955,0.029583457857370377,0.009419488720595837,-0.015755359083414078,0.016005903482437134,0.016728626564145088,0.0013490827986970544,0.002486166777089238,-0.03881504014134407,0.0729275569319725,-0.006793595384806395,-0.02754056081175804,0.03950885310769081,0.029448550194501877,0.034825608134269714,0.015234999358654022,0.008932854980230331,0.006417779251933098,0.018077708780765533,0.027020201086997986,0.04386446252465248,0.030315816402435303,-0.012479015626013279,-0.018906431272625923,0.055774934589862823,0.008725674822926521,-0.008638948202133179,-0.022452590987086296,0.011785201728343964,0.018087346106767654,0.011091387830674648,-0.02324276976287365,-0.007381409872323275,-0.023435495793819427,0.011226295493543148,-0.03189617022871971,-0.031240902841091156,-0.02447621524333954,-0.001967010786756873,-0.024996576830744743,-0.031780537217855453,0.004415837116539478,0.02158532477915287,0.029718365520238876,0.03536524251103401,0.03812122344970703,0.06024618074297905,-0.06232762336730957,0.04525209218263626,0.030354361981153488,-0.0009046081686392426,0.025343483313918114,0.039663031697273254,0.018482433632016182,0.027694741263985634,-0.021334780380129814,-0.019831515848636627,-0.06479451805353165,-0.013934098184108734,-0.028677646070718765,0.0377935916185379,-0.004957878962159157,0.0008588357013650239,-0.02842710167169571,-0.010397573933005333,-0.014213550835847855,0.03293689340353012,-0.020872237160801888,-0.012189926579594612,0.02345476672053337,0.030335089191794395,-0.004365246277302504,0.03584705665707588,-0.013384828343987465,0.009766395203769207,-0.028600554913282394,0.013972642831504345,0.006933321710675955,-0.037196140736341476,0.01373173575848341,0.017123714089393616,-0.04802734777331352,0.04251537844538689,0.009732668288052082,-0.02802237682044506,0.023763129487633705,-0.017239350825548172,-0.01652626320719719,0.06826359033584595,-0.03376561403274536,0.05442585423588753,0.027791105210781097,-0.009405034594237804,-0.01318246591836214,0.013828098773956299,0.043132103979587555,0.024264216423034668,0.011129932478070259,0.04205283895134926,0.014473730698227882,-0.04201429337263107,-0.012797013856470585,-0.03380415961146355,0.005251786671578884,-0.05338513106107712,0.007294683251529932,0.022433320060372353,-0.0003273332549724728,-0.036907050758600235,0.029236551374197006,-0.021199872717261314,0.010985388420522213,-0.06082436069846153,-0.04081939160823822,0.0574323795735836,0.025613300502300262,0.018867885693907738,-0.004225519951432943,0.003322116332128644,-0.014743546955287457,-0.015109727159142494,0.044712457805871964,0.032069623470306396,-0.004201429430395365,-0.0025150757282972336,-0.03800559043884277,-0.014309913851320744,-0.01881006918847561,-0.020448239520192146,0.07381410151720047,0.00778131652623415,-0.011091387830674648,0.0005191559321247041,0.016304628923535347,0.004827789030969143,0.02428348921239376,0.024399125948548317,0.020448239520192146,0.0076994081027805805,0.023975128307938576,0.01709480583667755,0.02511221170425415,-0.026885291561484337,-0.04883679747581482,0.05693129450082779,0.04906806722283363,-0.030103817582130432,-0.02199004963040352,0.01303792092949152,0.03950885310769081,0.030547088012099266,0.08973328024148941,-0.04328628256917,-0.02586384490132332,0.009766395203769207,-0.009824213571846485,0.01819334551692009,-0.024052219465374947,0.015668632462620735,-0.06487160921096802,0.004726607818156481,-0.017759710550308228,-0.0010220506228506565,0.01970624551177025,-0.03251289576292038,0.002419917145743966,0.01646844670176506,-0.006870685610920191,-0.044172823429107666,-0.01839570701122284,-0.004406200721859932,-0.008436585776507854,0.015263907611370087,0.06475597620010376,0.006504506338387728,0.023204224184155464,0.008479949086904526,-0.0036136144772171974,0.06941994279623032,-0.018299344927072525,-0.013991915620863438,0.02081442065536976,0.049414973706007004,0.03700341284275055,0.007241683546453714,-0.021488960832357407,-0.05407894775271416,-0.013808825984597206,-0.022394774481654167,-0.010571027174592018,-0.007362137548625469,-0.02648056671023369,0.013895552605390549,0.02649983949959278,0.028195830062031746,0.002187441335991025,-0.019494246691465378,0.03397761285305023,-0.018443888053297997,0.003717204788699746,0.034073974937200546,-0.025960206985473633,-0.016902079805731773,-0.00125874241348356,0.025574754923582077,-0.06259743869304657,-0.03548087552189827,0.01695026084780693,0.03149144724011421,0.010879389010369778,0.010619208216667175,0.008499221876263618,-0.05754801630973816,-0.013124648481607437,-0.018569160252809525,0.023050041869282722,0.07046066224575043,-0.011611748486757278,0.019214794039726257,-0.029101641848683357,0.0026572111528366804,0.03788995370268822,0.04980042576789856,0.02436058036983013,-0.0009841077262535691,0.02530493773519993,-0.0051361508667469025,-0.055852025747299194,0.0157649964094162,-0.010368664748966694,-0.031048176810145378,0.0292558241635561,-0.018299344927072525,-0.008687129244208336,0.014348458498716354,-0.008200496435165405,0.003813567804172635,0.019253337755799294,0.002234418410807848,0.0379284992814064,0.05492694303393364,-0.02254895493388176,0.028138011693954468,0.05257568135857582,-0.02815728448331356,-0.03762013837695122,-0.00018911249935626984,-0.004767562262713909,-0.008084860630333424,-5.375251566874795e-05,0.021276962012052536,-0.058280374854803085,-0.001610467559657991,-0.026808202266693115,0.03777431696653366,0.013018649071455002,0.016487719491124153,0.0011376863112673163,-0.041320476680994034,0.01701771467924118,0.019725516438484192,0.018790796399116516,-0.0006558710592798889,0.003642523428425193,0.019831515848636627,0.013009012676775455,-0.006875503808259964,0.038352496922016144,0.049414973706007004,0.0041363839991390705,-0.04371028020977974,0.04891388490796089,-0.012045381590723991,0.011043205857276917,-0.012700650840997696,-0.04552190750837326,0.013500464148819447,0.023146405816078186,0.011081751435995102,0.03339943662285805,0.03091326728463173,0.011823747307062149,-0.011775565333664417,-0.07470063865184784,0.021084235981106758,0.08726638555526733,-0.009935030713677406,-0.009005127474665642,-0.039470307528972626,0.033457253128290176,-0.04081939160823822,0.0096507603302598,-0.021527506411075592,0.006234689615666866,0.005097605753690004,-6.835754174971953e-05,0.0002053737553069368,0.016227537766098976,0.04586881399154663,-0.0419372022151947,-0.03630959987640381,-0.021700959652662277,-0.03802486136555672,-0.013635372743010521,0.038834311068058014,0.004704926162958145,0.04760335013270378,-0.03783213719725609,-0.017460985109210014,0.023608949035406113,0.03802486136555672,-0.033303070813417435,-0.00985794048756361,-0.01358719076961279,-0.04856697842478752,-0.024225672706961632,0.019870061427354813,-0.016237175092101097,0.06957412511110306,0.019677335396409035,-0.08826855570077896,-0.0038232041988521814,-0.018713705241680145,0.03598196431994438,-0.04787316545844078,0.006808049976825714,0.015446998178958893,-0.014888091944158077,0.006928503513336182,0.008282404392957687,0.00920267216861248,-0.011023933067917824,0.04031830281019211,0.0315299928188324,0.03623250871896744,0.04980042576789856,-0.02946782298386097,-0.03415106609463692,0.016449173912405968,-0.021431144326925278,0.04159029573202133,-0.02703947387635708,-0.024649670347571373,-0.04829716309905052,0.0016755126416683197,-0.03548087552189827,0.0193015206605196,0.01577463187277317,0.0005817919736728072,-0.02808019332587719,-0.05939818546175957,-0.005560148507356644,-0.01832825317978859,0.0176344383507967,-0.03037363477051258,-0.024264216423034668,-0.04097357019782066,0.01861734315752983,0.017374258488416672,-0.003360661445185542,-0.02094932831823826,-0.0006305757560767233,-0.001877875067293644,-0.001800784608349204,0.001993510639294982,-0.003271525725722313,0.029660549014806747,0.000632984796538949,-0.0072705927304923534,-0.04694807901978493,0.01563972420990467,-0.0609014518558979,-0.02158532477915287,-0.07315883040428162,0.010956479236483574,-0.09829031676054001,0.005290331784635782,-0.001141902175731957,0.02973763830959797,-0.02732856199145317,-0.004398973658680916,0.03307180106639862,-0.00830167718231678,0.04833570867776871,0.02829219214618206,-0.00971339549869299,-0.014521912671625614,-0.02532421052455902,0.03145290166139603,0.024187127128243446,-0.014126824215054512,0.027656197547912598,-0.021662414073944092,-0.0008142678416334093,-0.0007998133660294116,-0.004174929577857256,-0.007126047741621733,-0.06868758797645569,0.01771152950823307,-0.055659301578998566,0.02621075138449669,0.0034088431857526302,0.005603511817753315,0.019205156713724136,-0.02802237682044506,0.005063878372311592,-0.007082684431225061,0.0023476448841392994,0.035519421100616455,0.022934406995773315,0.01462791208177805,0.012161017395555973,0.006446688435971737,0.005415603518486023,-0.010041030123829842,-0.0176344383507967,0.0157649964094162,-0.023686038330197334,-0.0027776651550084352,-0.006947776302695274,-0.017268259078264236,0.009867576882243156,-0.011351567693054676,-0.019619518890976906,0.017595894634723663,-0.015379543416202068,0.0073765916749835014,-0.003271525725722313,0.0008419721852988005,-0.004712153226137161,-0.01998569816350937,-0.00281861936673522,0.016102265566587448,0.005020515061914921,0.032069623470306396,-0.002329576760530472,0.03430524840950966,0.004839834291487932,-0.012777741067111492,-0.0084462221711874,-0.037253957241773605,-0.028870372101664543,-0.024514760822057724,0.0027656196616590023,-0.006687595974653959,-0.046793900430202484,-3.80935198336374e-05,-0.017586257308721542,-0.01044575497508049,0.020178424194455147,-0.02904382534325123,-0.015861358493566513,-0.012719923630356789,0.005526421125978231,0.013375191949307919,0.0013490827986970544,0.0031872079707682133,-0.00037491251714527607,0.009400215931236744,0.023358404636383057,0.011871928349137306,0.011910473927855492,-0.01777898333966732,0.00010637578088790178,0.019735153764486313,0.0015092863468453288,-0.018376434221863747,0.0009889258071780205,-0.0710773915052414,-0.01998569816350937,0.0048807887360453606,-0.0545029453933239,0.030123090371489525,0.017306804656982422,-0.027232199907302856,0.00988684967160225,0.006244326010346413,0.022433320060372353,-0.009323125705122948,0.014252095483243465,0.0168924443423748,-0.021566051989793777,0.016506990417838097,0.025420574471354485,0.021045690402388573,-0.037311773747205734,-0.025902388617396355,-0.0025921661872416735,-0.00660568755120039,0.011120297014713287,-0.01577463187277317,-0.005839601159095764,-0.0074055008590221405,-0.0063744159415364265,0.0018357161898165941,-0.024514760822057724,-0.021411871537566185,-0.0014225596096366644,0.007786134723573923,-0.06957412511110306,-0.012922286055982113,-0.008744947612285614,-0.02310786023736,-0.00968930497765541,0.009371306747198105,0.021546779200434685,-0.02040969580411911,-0.007790952920913696,0.002563257236033678,-0.04544481635093689,0.006061236374080181,0.0178368017077446,0.005974509287625551,0.027868196368217468,0.015678269788622856,-0.07439228147268295,0.05361640453338623,0.012132108211517334,-0.028003104031085968,-0.02006278745830059,-0.027656197547912598,0.006244326010346413,0.08595584332942963,0.004512200132012367,-0.002857164479792118,-0.030354361981153488,-0.007916225120425224,0.006494869943708181,-0.016169721260666847,0.0005390308215282857,-0.010802298784255981,0.010359028354287148,-0.018347525969147682,-0.017952436581254005,0.022799499332904816,-0.028446374461054802,0.0028089829720556736,0.007675317116081715,-0.012189926579594612,0.0539633110165596,-0.05188186839222908,0.013683553785085678,0.026808202266693115,0.03318743780255318,-0.012151381000876427,-0.006138326600193977,0.031298719346523285,0.0002829159202519804,-0.012700650840997696,-0.005675783846527338,0.023878764361143112,0.02580602653324604,0.03147217258810997,-0.00916894432157278,-0.009236399084329605,-0.023396950215101242,0.0030763905961066484,-0.02233695611357689,0.005068696569651365,0.004666381049901247,-0.02428348921239376,-0.026461295783519745,-0.025092938914895058,-0.011679202318191528,-0.01867515966296196,-0.014184641651809216,-0.012122472748160362,0.028003104031085968,-0.017393531277775764,0.02567111700773239,0.014984454959630966,-0.045676089823246,-0.03605905547738075,0.008797947317361832,0.013365555554628372,-0.011101024225354195,-0.006441870238631964,-0.019609881564974785,-0.007328410167247057,0.003078799694776535,0.006793595384806395,0.009751941077411175,0.002640347694978118,-0.004647108260542154,-0.002110350877046585,0.017528438940644264,-0.029371459037065506,0.013943733647465706,-0.007366955745965242,-0.002354872180148959,0.014955545775592327,-0.00659123295918107,0.018925704061985016,0.059244006872177124,-0.002970391185954213,0.030007455497980118,-0.022529682144522667,-0.02455330640077591,0.035307422280311584,0.01072520762681961,-0.022664589807391167,-0.019725516438484192,0.02420639991760254,-0.012671741656959057,-0.005473421420902014,0.04101211577653885,-0.022741680964827538,0.010243392549455166,0.012064654380083084,0.04872116073966026,0.014955545775592327,-0.03232016786932945,0.032262351363897324,-0.025131484493613243,0.006836958695203066,0.0030330270528793335,-0.028658373281359673,0.03160708025097847,-0.013722099363803864,0.004548336379230022,0.006543051451444626,-0.0050735147669911385,-0.0031101175118237734,0.001432195887900889,-0.02407149039208889,0.024880940094590187,0.001897147623822093,-0.04401864483952522,0.0020465103443711996,-0.045907359570264816,0.02503512240946293,-0.020216969773173332,0.036560144275426865,0.0292558241635561,0.02705874666571617,-0.006046781782060862,-0.008773855865001678,0.02671183831989765,0.01771152950823307,0.0013225829461589456,-0.0073765916749835014,-0.01037830114364624,-0.009289398789405823,0.014049733057618141,-0.0032739348243921995,0.006875503808259964,-0.021122781559824944,-0.008735311217606068,-0.0271165631711483,0.04058811813592911,0.015668632462620735,0.015957722440361977,0.00288848252967,0.0016201038379222155,0.041474658995866776,0.0007811430259607732,-0.0037774317897856236,-0.012093563564121723,0.0018212617142125964,0.00631178030744195,-0.01044575497508049,-0.0229729525744915,0.0011340726632624865,-0.013741371221840382,0.017875347286462784,-0.0024789394810795784,0.03332234546542168,-0.0016441945917904377,0.007087502628564835,0.037870679050683975,0.015157908201217651,0.0027752560563385487,0.011958654969930649,0.03251289576292038,-0.048258617520332336,-0.03216598927974701,0.009014763869345188,-0.011313023045659065,-0.019696608185768127,0.026576930657029152,-0.005295149981975555,0.01407864224165678,0.016015538945794106,0.008070405572652817,-0.00888949166983366,0.017258623614907265,0.025208575651049614,0.007930679246783257,-0.01266210526227951,0.01813552714884281,-0.004957878962159157,0.05246004834771156,0.0676083192229271,0.01778862066566944,-0.030932540073990822,0.03191544488072395,0.007877679541707039,-0.02649983949959278,-0.003372706938534975,-0.020775875076651573,-0.010763753205537796,0.042091380804777145,-0.009723031893372536,-0.023763129487633705,0.03366925194859505,-0.026037298142910004,-0.010041030123829842,0.03154926374554634,0.008142678067088127,0.003876203903928399,-0.009038854390382767,0.041744474321603775,0.03713832050561905,0.018145162612199783,-0.025844572111964226,0.023743856698274612,-0.021874412894248962,0.004654335789382458,-0.009660396724939346,0.009525488130748272,-0.003379934234544635,0.011900837533175945,-0.01979297213256359,0.013943733647465706,0.007020048331469297,-0.03195399045944214,-0.039258308708667755,-0.012459742836654186,-0.015157908201217651,-0.00520360516384244,0.012093563564121723,0.011158841662108898,-0.008923218585550785,-0.037600863724946976,-0.04297792166471481,0.0011973109794780612,0.013982279226183891,-0.01970624551177025,-0.02518930286169052,0.0016574445180594921,-0.006456324830651283,-0.02033260464668274,-0.006041963584721088,0.007415137253701687,0.007415137253701687,-0.018039163202047348,-0.005295149981975555,0.012729560025036335,0.036348145455121994,0.0699981227517128,0.0039388397708535194,0.00044929274008609354,0.012835558503866196,-0.01887752301990986,-0.012546469457447529,-0.01186229195445776,0.02532421052455902,-0.01854025200009346,0.015321725979447365,-0.009226762689650059,0.0051024239510297775,-0.00011857172648888081,-0.012353743426501751,-0.01290301326662302,-0.009424306452274323,0.007328410167247057,-0.027000928297638893,-0.0013394465204328299,-0.02129623480141163,-0.014984454959630966,0.019330428913235664,0.004801289178431034,0.043825916945934296,0.003326934529468417,-0.005006060935556889,0.030971085652709007,-0.0383332222700119,0.04717935249209404,0.016834625974297523,-0.0009594146395102143,0.012083927169442177,0.002989663742482662,-0.05404040217399597,-0.012257380411028862,0.0008732901769690216,-0.020159151405096054,0.016217902302742004,0.027347834780812263,-0.002442803466692567,-0.022799499332904816,-0.0050108786672353745,-0.03694559633731842,-0.022876588627696037,0.005781783256679773,-0.01466645672917366,-0.039470307528972626,0.004249610938131809,0.021527506411075592,0.0009521874599158764,0.022857315838336945,0.014955545775592327,0.013510100543498993,-0.02655765786767006,0.05380912870168686,-0.053153861314058304,-0.008393222466111183,0.025690389797091484,0.010031393729150295,0.0042616561986505985,-9.764287824509665e-05,-0.026307113468647003,-0.01127447746694088,-0.014001552015542984,0.02434130758047104,-0.003582296660169959,0.027887467294931412,0.02455330640077591,0.026519112288951874,0.006167235318571329,0.002864391775801778,-0.003953294362872839,0.004201429430395365,0.04822007194161415,0.015100090764462948,-0.020448239520192146,-0.024880940094590187,0.0011063683778047562,0.020525330677628517,0.042708106338977814,0.047063715755939484,-0.0030956631526350975,-0.021411871537566185,-0.024668941274285316,0.0005736612947657704,-0.017412804067134857,-0.009303852915763855,0.005478239618241787,0.020795147866010666,0.01839570701122284,-0.013529373332858086,0.03228162229061127,-0.010436118580400944,0.01351973693817854,-0.008826855570077896,0.08503075689077377,-0.0007323592435568571,-0.007251319941133261,0.019908607006072998,-0.026596203446388245,0.003117344807833433,-0.010811935178935528,-0.028272921219468117,-0.034343793988227844,0.008166768588125706,0.009144853800535202,-0.017875347286462784,-0.009419488720595837,0.017480257898569107,0.0032112987246364355,-0.0036882958374917507,0.007260956335812807,0.03141435608267784,-0.006441870238631964,0.021199872717261314,0.0029173914808779955,-0.009906122460961342,-0.017547711730003357,0.029236551374197006,-0.008841310627758503,-0.010937206447124481,0.01006993930786848,0.019600246101617813,0.001402082503773272,-0.020795147866010666,0.029371459037065506,0.02281877212226391,0.02890891581773758,-0.0005158434505574405,-0.005304786376655102,0.014618275687098503,-0.0056276023387908936,-0.009896486066281796,-0.05037860572338104,0.0008738924516364932,-0.006104599684476852,0.001045539160259068,0.05203605070710182,-0.00013159579248167574,0.0027776651550084352,0.01633353717625141,0.021411871537566185,0.03131799399852753,-0.01639135554432869,-0.031048176810145378,0.031163811683654785,0.03284052759408951,0.030836177989840508,-0.00799331534653902,0.024244945496320724,-0.008576312102377415,0.03802486136555672,0.021758778020739555,-0.0026283024344593287,0.013172829523682594,0.002330781426280737,0.0006116042495705187,0.0617109015583992,-0.002883664332330227,0.005873328074812889,-0.0019236474763602018,-0.017403168603777885,0.020428968593478203,0.026750383898615837,-0.02081442065536976,0.03341870754957199,-0.008345040492713451,-0.03284052759408951,-0.04737207666039467,-0.006711686961352825,0.031433627009391785,-0.0005884168785996735,-0.027000928297638893,0.010677026584744453,-0.023474039509892464,0.0007727112388238311,0.01570717804133892,-0.04290083050727844,-0.0015321725513786077,0.032975438982248306,0.008484766818583012,-0.030103817582130432,-0.024572579190135002,-0.00860522035509348,-0.005642056930810213,-0.014165368862450123,0.020236240699887276,0.012045381590723991,0.01327882893383503,0.02081442065536976,0.009024400264024734,-0.0016116721089929342,-0.001265969593077898,0.011997200548648834,0.03133726492524147,0.01688280701637268,0.005006060935556889,-0.015938449651002884,-0.017470622435212135,-0.015331362374126911,0.006600869353860617,0.02048678509891033,0.029159460216760635,-0.032763440161943436,-0.016131175681948662,0.024919485673308372,0.0012358562089502811,0.020313331857323647,-0.008388403803110123,0.029024552553892136,0.005719147156924009,-0.009583305567502975,-0.007159775123000145,0.017730802297592163,0.007318774238228798,0.02572893537580967,0.04239974543452263,0.007530772592872381,-0.023416223004460335,-0.005362603813409805,-0.006865867879241705,0.03264780342578888,0.03681068867444992,-0.0031101175118237734,0.020159151405096054,-0.020602421835064888,-0.013567917980253696,0.0023910081945359707,-0.025767480954527855,0.004815743770450354,0.005772146862000227,0.02214423008263111,0.008831674233078957,0.030103817582130432,-0.025960206985473633,0.00415083859115839,-0.012498288415372372,0.011351567693054676,0.01563008688390255,-0.02214423008263111,-0.05334658548235893,-0.014570093713700771,-0.010571027174592018,-0.03278271108865738,0.01351973693817854,0.00631178030744195,0.006090145092457533,-0.014994091354310513,-0.025266392156481743,0.005757692735642195,0.02877400815486908,-0.004565199837088585,-0.036984141916036606,0.05257568135857582,0.010792662389576435,-0.020236240699887276,-0.010744480416178703,-0.0317998081445694,-0.0002672569244168699,0.00482297083362937,-0.027232199907302856,-0.03058563359081745,-0.011168478056788445,0.011496112681925297,-0.011390113271772861,-0.02732856199145317,-0.00444474583491683,0.015090454369783401,-0.002633120398968458,0.016574446111917496,0.06830213218927383,-0.025748208165168762,-0.0072465017437934875,-0.043748825788497925,-0.015398816205561161,0.014444821514189243,0.001099743414670229,0.015080817975103855,0.0387379489839077,0.012324835173785686,0.020602421835064888,-0.0068899584002792835,0.009641123935580254,0.0253820288926363,-0.007135684136301279,-0.01840534433722496,-0.008903946727514267,-0.04066520929336548,-0.010628844611346722,0.009530305862426758,-0.02649983949959278,-0.013712462969124317,0.020082060247659683,-0.009308671578764915,0.018569160252809525,-0.0005037980736233294,-0.021411871537566185,0.010243392549455166,0.029930364340543747,0.005863691680133343,0.053654950112104416,0.036560144275426865,0.0008233018452301621,-0.006832140497863293,0.0053336950950324535,-0.06375379860401154,-0.000632984796538949,-0.03625177964568138,0.03492197021842003,-0.04394155368208885,0.008942491374909878,0.04752625897526741,0.005728783551603556,0.0011997200781479478,0.02572893537580967,0.02719365432858467,-0.0038087498396635056,-0.0038689766079187393,-0.006909231189638376,-0.027559833601117134,-0.018164435401558876,-0.020313331857323647,-0.021662414073944092,-0.018501706421375275,0.002122396370396018,0.004762744065374136,0.024322034791111946,-0.0072802286595106125,-0.00399665767326951,0.01833788864314556,0.03272489458322525,-0.07924897968769073,0.018781159073114395,-0.02089150995016098,-0.012267016805708408,0.051650598645210266,-0.05847310274839401,0.01511936355382204,-0.017884982749819756,-0.0005185537156648934,0.027347834780812263,0.012411561794579029,0.0013671508058905602,0.020351877436041832,0.0025463937781751156,-0.008388403803110123,-0.0048422436229884624,-0.048181526362895966,-0.00885094702243805,0.058203283697366714,-0.005415603518486023,-0.011534657329320908,0.007207956630736589,-0.0028523465152829885,0.017239350825548172,-0.0034835245460271835,-0.0004119520599488169,0.005420421715825796,0.007646408397704363,-0.04848989099264145,-0.014261731877923012,-0.0047145625576376915,-0.018212618306279182,0.01979297213256359,-0.0012057427084073424,-0.026962382718920708,-0.04051102697849274,0.033437978476285934,0.005796237848699093,0.009255671873688698,-0.030874723568558693,-0.007940315641462803,0.035731419920921326,-0.01072520762681961,-0.017547711730003357,0.01438700407743454,0.009318307042121887,0.014541185460984707,-0.012132108211517334,-0.03440161049365997,-0.01459900289773941,0.009698941372334957,0.019696608185768127,-0.010349391959607601,-0.0319347158074379,0.026268567889928818,0.011544293724000454,-0.010484300553798676,-0.023531857877969742,0.019070249050855637,0.008860582485795021,0.007689771708101034,0.011052842251956463,-0.004909697454422712,-0.023493312299251556,0.0035557968076318502,-0.006624959874898195,0.041204843670129776,0.014213550835847855,-0.013857007026672363,-0.01127447746694088,-0.0019465336808934808,-0.011284113861620426,0.013943733647465706,-0.007126047741621733,-0.003840067656710744,0.0019886924419552088,-0.02505439519882202,0.060708723962306976,-0.0014876046916469932,0.008248677477240562,0.03505687788128853,0.03043145313858986,0.004030384588986635,0.007858406752347946,0.026866020634770393,0.013461918570101261,0.03411252051591873,0.012132108211517334,0.008195677772164345,0.014647183939814568,0.007810225710272789,-0.00816195085644722,-0.039547398686409,-0.006764686666429043,0.005829964764416218,-0.011129932478070259,-0.01585172303020954,0.01597699522972107,0.015109727159142494,0.0025680754333734512,0.03652159869670868,0.03382343053817749,0.0036545689217746258,0.0084462221711874,-0.024919485673308372,0.0008618470747023821,0.003148662857711315,0.006326234433799982,-0.010522845201194286,-0.03935467079281807,-0.0013876280281692743,0.005044606048613787,0.03239725902676582,0.005290331784635782,0.028311464935541153,0.01875225082039833,0.02829219214618206,0.0285812821239233,0.009670032188296318,0.004321882966905832,-0.02511221170425415,-0.001246697036549449,0.018790796399116516,-0.02193223126232624,0.00010343971371185035,-0.00889431033283472,-0.013433010317385197,0.01563008688390255,0.00813304167240858,0.02580602653324604,-0.008619675412774086,0.012189926579594612,0.017335712909698486,0.002339213155210018,-0.009862758219242096,-0.018559524789452553,0.009260489605367184,-0.020987873896956444,-0.012883740477263927,-0.005487876012921333,0.018578797578811646,0.039740122854709625,-0.000577877217438072,0.047487713396549225,0.006229871418327093,0.0014550820924341679,0.003844885854050517,0.011659929528832436,0.013028285466134548,0.029853275045752525,-0.002659620251506567,0.02420639991760254,-0.0292558241635561,-0.02214423008263111,-0.017595894634723663,0.02484239637851715,0.026307113468647003,0.007521136663854122,-0.02794528566300869,0.01985078863799572,0.016025176271796227,-0.030489271506667137,0.0007034502923488617,-0.005829964764416218,-0.004456791095435619,0.0020573511719703674,-0.014637548476457596,0.023531857877969742,0.015234999358654022,0.010416845791041851,0.01059029996395111,0.006721322890371084,0.009698941372334957,0.014194278046488762,-0.0029800275806337595,-0.02863910049200058,0.011428657919168472,0.03029654361307621,-0.027155108749866486,-0.0054926942102611065,-0.05111096426844597,-0.03197326138615608,-0.004938606638461351,-0.03154926374554634,-0.0539633110165596,-0.005675783846527338,-0.018453525379300117,-0.011688838712871075,0.02268386259675026,0.02863910049200058,0.0030956631526350975,-0.002192259533330798,0.016025176271796227,-0.06818649917840958,0.00422070175409317,-0.022934406995773315,-0.011428657919168472,-0.03800559043884277,-0.04829716309905052,0.009405034594237804,-0.00717904744669795,-0.012324835173785686,0.0008756992756389081,0.002474121516570449,-0.0018513752147555351,-0.007024866528809071,0.027424925938248634,0.034613609313964844,-0.021084235981106758,0.004644699394702911,0.01764407567679882,-0.02808019332587719,0.004331519361585379,-0.02075660228729248,-0.011129932478070259,0.02484239637851715,-0.013664280995726585,-0.022915134206414223,-0.001974238082766533,-0.0390077643096447,0.0071115936152637005,0.005372240208089352,0.008981036953628063,-0.0033510252833366394,-0.011496112681925297,0.011043205857276917,0.008619675412774086,0.025767480954527855,-0.01617935672402382,0.018713705241680145,0.010243392549455166,0.00416529318317771,0.010908298194408417,0.03451724722981453,0.005309604108333588,-0.0010365050984546542,0.0017020124942064285,-0.0379284992814064,-0.04186011105775833,0.028195830062031746,0.006706868764013052,0.012893376871943474,0.040087029337882996,0.011997200548648834,0.05535094067454338,-0.004177338443696499,0.0021705778781324625,0.040857937186956406,0.01210319995880127,0.015157908201217651,-0.024379853159189224,-0.002854755613952875,0.011611748486757278,-0.007492227479815483,0.01597699522972107,-0.003974976018071175,0.024399125948548317,-0.005352967884391546,-0.00038846355164423585,0.009800123050808907,0.03222380578517914,0.01632390171289444,0.0012123676715418696,-0.03245507553219795,0.009207489900290966,-0.04806589335203171,0.046100083738565445,0.032686349004507065,0.023647494614124298,0.02199004963040352,-0.01680571772158146,0.0229729525744915,-0.031086722388863564,-0.019340064376592636,-0.03230089694261551,-0.0012984921922907233,0.015244635753333569,0.0045868814922869205,-0.018665524199604988,0.0051361508667469025,0.02324276976287365,0.016352809965610504,-0.021411871537566185,0.01653590053319931,0.008638948202133179,-0.013307738117873669,-0.018106618896126747,-0.0007167002186179161,0.02518930286169052,-0.00593114597722888,-0.007819862104952335,-0.01245010644197464,-0.01577463187277317,0.04143611341714859,0.01134193129837513,-1.8312744941795245e-05,-0.00764159020036459,0.006933321710675955,-0.025709662586450577,0.03985575959086418,-0.004408609587699175,0.031144538894295692,-0.037446681410074234,0.0026620293501764536,-0.028735462576150894,-0.01214174460619688,0.01303792092949152,-0.021893685683608055,-0.020660238340497017,0.012536833062767982,-0.01680571772158146,0.014396640472114086,-0.004798880312591791,0.002330781426280737,-0.009511033073067665,-0.016169721260666847,-0.024880940094590187,-0.04891388490796089,-0.007338046561926603,-0.0665290504693985,-0.05901273339986801,0.03494124487042427,-0.001830897992476821,-0.014001552015542984,0.004329110030084848,0.020583149045705795,0.0065671419724822044,-0.018106618896126747]) as similarity_score
FROM shared_source.magento_product_dimension_with_text_embedding
ORDER BY similarity_score DESC
LIMIT 100
)
SELECT
internal_ref_code,
MAX_BY(description_text_full, similarity_score) as description_text_full,
MAX_BY(sale_price, similarity_score) as sale_price,
MAX_BY(original_price, similarity_score) as original_price,
MAX_BY(discount_amount, similarity_score) as discount_amount,
MAX(similarity_score) as max_score
FROM top_matches
WHERE 1=1 AND sale_price <= 500000.0
GROUP BY internal_ref_code
ORDER BY max_score DESC
LIMIT 10
\ No newline at end of file
Oke bro, tao hiểu rõ ý bro rồi! Để tao tóm gọn lại toàn bộ kế hoạch bằng tiếng Việt cho bro nghe rõ ràng nhé.
Hiểu đúng ý của bro
Bro đang muốn chia làm hai giai đoạn rõ ràng. Giai đoạn một là sửa code chatbot, bỏ phần OpenTelemetry instrumentation hiện tại đi và chuyển sang dùng Langfuse SDK thuần túy để trace LLM calls. Giai đoạn hai là setup infrastructure monitoring hoàn toàn độc lập, dùng cAdvisor để thu thập container metrics từ Docker, kết hợp với Prometheus và Grafana để visualize.
GIAI ĐOẠN 1: Chuyển sang Langfuse SDK thuần túy
Bước đầu tiên là bro cần cleanup code hiện tại. Hiện tại trong server.py của bro đang có đống code setup OpenTelemetry với TracerProvider, OTLPSpanExporter, LoggingInstrumentor. Tất cả những thứ này sẽ được remove sạch. Bro sẽ giữ lại file server đơn giản, chỉ focus vào khởi động FastAPI app mà thôi.
Bước tiếp theo là enable Langfuse đầy đủ. Hiện tại trong code của bro, Langfuse đang bị comment out ở nhiều chỗ với note "TẮT TẠM - Tránh rate limit". Bro cần uncomment tất cả những đoạn này. Cụ thể trong file langfuse_client.py đã có sẵn hàm initialize_langfuse() và get_callback_handler() rồi, bro chỉ cần gọi nó khi app startup.
Trong controller.py, bro cần sửa hàm _prepare_execution_context() để attach Langfuse CallbackHandler vào RunnableConfig. Thay vì dùng OpenTelemetry span để track, bro sẽ dùng Langfuse callback để tự động capture tất cả LangChain runs, bao gồm LLM calls, tool calls, và toàn bộ conversation flow.
Điều quan trọng là bro cần set metadata cho Langfuse trace. Khi tạo CallbackHandler, bro nên truyền vào user_id, session_id, và các custom tags để sau này filter dễ dàng trong Langfuse dashboard. Ví dụ như trace_id có thể là conversation_id, user_id để group theo user, tags để đánh dấu production hay staging environment.
Cuối cùng là test để đảm bảo Langfuse đang hoạt động. Bro gửi vài requests test, sau đó vào Langfuse dashboard kiểm tra xem có traces xuất hiện không, có đủ thông tin về LLM model, tokens, latency không. Nếu thấy đủ data rồi thì giai đoạn một hoàn tất.
GIAI ĐOẠN 2: Setup Container Monitoring với cAdvisor
Giai đoạn này hoàn toàn độc lập với code, bro chỉ cần làm việc với Docker và configuration files.
Đầu tiên bro cần tạo file docker-compose.monitoring.yml riêng cho monitoring stack. File này sẽ define ba services: cAdvisor, Prometheus, và Grafana. Lý do tách riêng là để bro có thể bật tắt monitoring stack độc lập mà không ảnh hưởng đến chatbot service chính.
Service cAdvisor trong docker-compose sẽ mount nhiều thứ từ host vào container. Bro cần mount /var/run/docker.sock để cAdvisor đọc được Docker daemon, mount /sys để đọc cgroups metrics, mount /var/lib/docker để đọc thông tin containers. Expose port 8080 để Prometheus có thể scrape metrics. Quan trọng là cAdvisor container phải chạy với privileged mode hoặc ít nhất có quyền đọc được những đường dẫn system này.
Tiếp theo là config Prometheus. Bro tạo file prometheus.yml để define scrape configs. Trong đó bro add một job tên là cadvisor với target là cadvisor:8080, scrape interval khoảng 15 giây là hợp lý. Prometheus sẽ tự động pull metrics từ endpoint này theo chu kỳ đã set.
Service Prometheus trong docker-compose sẽ mount file prometheus.yml vào /etc/prometheus/prometheus.yml, và mount volume để persist data vào /prometheus. Expose port 9090 để bro có thể access Prometheus UI kiểm tra targets đang healthy không.
Cuối cùng là Grafana. Service Grafana đơn giản nhất, chỉ cần expose port 3000 và mount volume để lưu dashboards. Khi start lần đầu, bro login vào Grafana với admin/admin, sau đó add Prometheus làm datasource với URL là http://prometheus:9090. Tiếp theo là import dashboard, bro có thể dùng dashboard có sẵn từ Grafana community như dashboard ID 193 cho Docker monitoring, hoặc tự tạo dashboard custom theo nhu cầu.
Sau khi setup xong, bro chạy docker-compose -f docker-compose.monitoring.yml up -d để start monitoring stack. Kiểm tra cAdvisor tại localhost:8080 xem có metrics không, kiểm tra Prometheus tại localhost:9090 xem đã scrape được từ cAdvisor chưa, và cuối cùng vào Grafana tại localhost:3000 để xem dashboard có data không.
Lưu ý quan trọng
Điều bro cần nhớ là hai hệ thống này hoạt động song song và hoàn toàn độc lập. Langfuse track application metrics như LLM calls, tokens, conversations. cAdvisor track infrastructure metrics như CPU, RAM, network của containers. Chúng không giao nhau, không conflict, và bro sẽ có một cái nhìn toàn diện về cả application lẫn infrastructure.
Một điểm nữa là khi stress test, bro sẽ mở hai dashboard cùng lúc. Langfuse dashboard để xem throughput của LLM calls, average latency, token consumption, cost estimation. Grafana dashboard để xem container có bị overload không, memory có tăng đột biến không, CPU có spike không. Kết hợp hai nguồn data này bro sẽ biết chính xác bottleneck nằm ở đâu, là do LLM API slow hay do container thiếu resources.
Tóm lại
Giai đoạn một là refactor code để dùng Langfuse SDK thay OpenTelemetry, focus vào LLM observability. Giai đoạn hai là setup Docker monitoring stack với cAdvisor, Prometheus, Grafana, hoàn toàn không động vào code. Hai giai đoạn này theo thứ tự, làm xong một mới qua hai, và cuối cùng bro có một hệ thống observability hoàn chỉnh cho cả application và infrastructure.
Rõ chưa bro? Tao có thiếu sót chi tiết nào không?
\ No newline at end of file
WITH top_candidates AS (
SELECT /*+ SET_VAR(ann_params='{"ef_search":64}') */
internal_ref_code,
product_color_code,
approx_cosine_similarity(vector, [0.004157349932938814,-0.047062162309885025,-0.05855855718255043,-0.043294113129377365,0.010717792436480522,-0.027683624997735023,0.039526063948869705,0.07082394510507584,0.02479991503059864,-0.06582550704479218,0.04844634607434273,0.006002924870699644,-0.0234349574893713,-0.005123393144458532,0.01686970889568329,0.013582278974354267,-0.029298502951860428,-0.03275895491242409,-0.04710061103105545,0.002352627459913492,-0.0003343302523717284,0.023761779069900513,-0.0006458311108872294,-0.01809048093855381,0.06486427038908005,0.016533276066184044,-0.016254518181085587,-0.056866779923439026,0.008314699865877628,-0.014082121662795544,0.004832618869841099,-0.03135555237531662,0.05602089315652847,-0.067555733025074,0.04348636046051979,0.03546964377164841,0.027779748663306236,-0.00037608397542499006,0.0038858004845678806,-0.007766794878989458,-0.03360484540462494,0.009203843772411346,-0.010141050443053246,0.04394775629043579,0.03496980294585228,0.053906168788671494,-0.009881515987217426,0.0070506734773516655,-0.015937309712171555,-0.005767421796917915,0.04952292889356613,-0.013937936164438725,-0.032893531024456024,0.029509976506233215,0.022704416885972023,0.02193542756140232,0.005801065359264612,0.002467975951731205,0.039910558611154556,0.02916393056511879,0.011996237561106682,-0.026164870709180832,0.012265384197235107,0.03850715234875679,-0.03187461942434311,0.009689268656075,-0.036430880427360535,-0.010785078629851341,-0.0236656554043293,0.045716430991888046,-0.015475915744900703,-0.027318354696035385,-0.020532021299004555,-0.0001552998583065346,0.004457736387848854,0.0066133104264736176,0.01867683418095112,-0.02501138672232628,0.026472466066479683,-0.017004283145070076,-0.004657193087041378,-0.014139796607196331,0.010237174108624458,0.00025262509007006884,-0.04956137761473656,-0.05321408063173294,-0.015283668413758278,0.04379395768046379,-0.023492632433772087,-0.02449231781065464,-0.03006749227643013,-0.021839303895831108,0.025530453771352768,-0.02887555956840515,0.012303833849728107,0.011256084777414799,-0.014610801823437214,-0.001953714294359088,-0.028125794604420662,0.00937686674296856,-0.025722701102495193,-0.028606412932276726,0.019474660977721214,0.012755614705383778,0.020897291600704193,0.005536725278943777,-0.015350954607129097,0.0023322012275457382,-0.05982739105820656,0.030105942860245705,0.029932919889688492,0.038930099457502365,-0.028683312237262726,0.031105628237128258,0.0024103017058223486,0.007382300216704607,0.018705671653151512,-0.022127674892544746,-0.013985997997224331,-0.0021267367992550135,-0.0016989863943308592,0.013236233033239841,-0.021224113181233406,-0.04567798227071762,-0.040064357221126556,0.05329097807407379,-0.01801358163356781,0.02681851200759411,0.008290668949484825,-0.04271737113595009,0.021916203200817108,0.004784557037055492,-0.004825409501791,0.013140109367668629,-0.009679656475782394,0.023627204820513725,-0.03445073217153549,0.033720195293426514,-0.04214062914252281,-0.034393060952425,0.041333191096782684,-0.0006560442270711064,0.024992162361741066,-0.010823528282344341,0.014745375141501427,-0.022569844499230385,0.01966690830886364,-0.013236233033239841,0.01036213431507349,0.04740820825099945,-0.011198410764336586,-0.021608607843518257,0.018052030354738235,-0.02870253659784794,0.002428324893116951,-0.0014514678623527288,0.0005866549327038229,0.06436442583799362,-0.0036166540812700987,0.014437779784202576,0.01672552339732647,-0.02879866026341915,-0.0030423151329159737,-0.06397993117570877,-0.07555323094129562,-0.007209277246147394,-0.019407374784350395,0.016244905069470406,-0.037430569529533386,0.030490437522530556,0.02629944495856762,0.05963514372706413,0.022819766774773598,0.01058321911841631,0.03744979202747345,-0.06167296692728996,0.01438971795141697,0.025741927325725555,-0.01575467362999916,0.016860097646713257,0.02103186585009098,0.01338041853159666,0.0014430570881813765,-0.032662831246852875,-0.026568589732050896,-0.03546964377164841,-0.041256289929151535,-0.014937622472643852,0.011477169580757618,0.016994670033454895,-0.020532021299004555,-0.01672552339732647,-0.03881474956870079,-0.031778495758771896,0.042102180421352386,-0.0020438302308321,-0.022819766774773598,-0.0034868870861828327,0.047215960919857025,-0.004474558401852846,0.03510437533259392,-0.006632535252720118,-0.001092205522581935,-0.007685089949518442,-0.021358685567975044,-0.003354717046022415,-0.04456294700503349,0.01157329324632883,0.031163303181529045,-0.00438804691657424,0.041563887149095535,0.03506592661142349,-0.03287430480122566,0.06036568433046341,0.0006974975694902241,-0.009900741279125214,0.08551163971424103,-0.012688328512012959,0.04848479479551315,0.054675161838531494,-0.021877754479646683,-0.012880575843155384,0.043524809181690216,0.032374460250139236,-0.011304146610200405,0.03248981013894081,0.03225911408662796,-0.029856020584702492,-0.014216694980859756,-0.013918711803853512,-0.024011699482798576,0.011208022944629192,-0.028587188571691513,0.01664862409234047,-0.0065940856002271175,0.009088495746254921,-8.027831063373014e-05,0.015052971430122852,-0.02185853011906147,-0.0664791539311409,-0.05282958596944809,-0.055444151163101196,0.025145959109067917,0.018196215853095055,0.021531708538532257,-0.021435584872961044,0.01694660820066929,-0.02028210088610649,-0.036200184375047684,0.02064737118780613,0.03181694447994232,0.023454181849956512,0.03435460850596428,0.0060702115297317505,0.03731521964073181,0.009069271385669708,-0.015120257623493671,0.021685507148504257,0.00908368919044733,0.003823320148512721,-0.020301325246691704,0.001674955477938056,0.027606725692749023,-0.05163764953613281,0.0467161163687706,-0.007608190644532442,0.011544456705451012,0.04302496835589409,-0.037411343306303024,-0.00037157817860133946,0.013313132338225842,-0.04279427230358124,0.03716142103075981,0.01582196168601513,-0.012476855888962746,-0.039314594119787216,0.0017374358139932156,0.03235523775219917,0.02110876515507698,0.04975362494587898,-0.050907112658023834,-0.02026287652552128,-0.01686970889568329,-0.03662312775850296,0.03083648346364498,-0.03641165792942047,0.06313404440879822,-0.009751749224960804,-0.017004283145070076,-0.015274056233465672,0.0373728945851326,0.027395254001021385,-0.040218155831098557,-0.002105108927935362,0.01914784125983715,0.018715284764766693,-0.02562657743692398,-0.06428752839565277,-0.011073450557887554,0.009660432115197182,0.015052971430122852,0.07824469357728958,-0.036353982985019684,0.0007449586410075426,-0.030721133574843407,0.023165810853242874,0.029356177896261215,-0.015129869803786278,0.010217948816716671,0.013688014820218086,0.03685382753610611,-0.007242920808494091,0.01717730425298214,0.0009858687408268452,0.04252512380480766,-0.006012537516653538,-0.011102287098765373,-0.04544728621840477,0.022050777450203896,-0.02743370458483696,0.06532566249370575,-0.06501807272434235,0.018551873043179512,0.0027299129869788885,0.020301325246691704,-0.030490437522530556,-0.03729599714279175,0.005978893954306841,0.02110876515507698,-0.027452928945422173,-0.04875393956899643,0.01289018802344799,-0.019647683948278427,-0.053906168788671494,-0.05179144814610481,-0.024453869089484215,0.041025593876838684,-0.01785978302359581,-0.04248667508363724,-0.02479991503059864,-0.012476855888962746,0.002099101198837161,-0.03739212080836296,-0.0069737741723656654,0.04952292889356613,-0.03037508949637413,-0.002418712479993701,-0.03216299042105675,0.007997491396963596,0.012063524685800076,0.06544101238250732,0.008348342962563038,0.011525231413543224,-0.024742240086197853,0.031182527542114258,-0.02283899113535881,0.002343015279620886,-0.009102914482355118,-0.0470237135887146,0.021647056564688683,-0.03216299042105675,-0.023108137771487236,0.04817719757556915,-0.029183154925704002,-6.717394717270508e-05,0.0035854140296578407,0.010573606938123703,0.030990280210971832,0.012265384197235107,-0.004890293348580599,0.02629944495856762,0.04836944490671158,-0.01232305821031332,-0.053560126572847366,-0.028048895299434662,0.022396821528673172,-0.02020520158112049,0.02103186585009098,0.01062166877090931,-0.03612328693270683,0.006627729162573814,-0.024203946813941002,0.009295161813497543,0.028990907594561577,0.030932607129216194,-0.020839618518948555,-0.016908159479498863,0.015764286741614342,-0.02049357257783413,0.0012520111631602049,0.03618096187710762,-0.0186864472925663,0.05094556137919426,-0.01165019255131483,-0.01530289277434349,0.03956451639533043,0.048407893627882004,0.0006932921824045479,-0.033566396683454514,0.05486740916967392,-0.017523350194096565,0.004102078732103109,-0.00828586332499981,0.0027130914386361837,0.02147403359413147,0.041486989706754684,-0.010996551252901554,0.013688014820218086,0.03200919181108475,-0.003929056227207184,-0.0014178245328366756,-0.04567798227071762,0.016091106459498405,0.01341886818408966,-0.004765332210808992,0.007262145634740591,-0.0661715567111969,0.015658549964427948,-0.017965519800782204,-0.00550308171659708,0.03596948832273483,-0.028740985319018364,-0.045255038887262344,0.048561692237854004,-0.026933860033750534,0.03479677811264992,0.018705671653151512,-0.006113467272371054,0.035238947719335556,-0.018551873043179512,-0.03610406070947647,0.0007852104608900845,-0.009054852649569511,0.017830945551395416,0.041486989706754684,-0.025684252381324768,-0.041563887149095535,-0.0059308321215212345,0.011852052062749863,0.008478110656142235,0.041717685759067535,-0.010073763318359852,-0.06778643280267715,-0.03602716326713562,0.007627415470778942,-0.043678607791662216,0.020974190905690193,0.0021423569414764643,-0.04298651963472366,-0.011621355079114437,-0.014745375141501427,-0.030105942860245705,-0.03719986975193024,-0.01303437352180481,-0.06867077201604843,-0.0027491378132253885,0.029971368610858917,-0.01740800216794014,-0.02872176095843315,-0.016850484535098076,0.04821564629673958,0.03896854817867279,0.020012954249978065,0.008862605318427086,0.0018660012865439057,-0.01606227084994316,0.01779249683022499,0.014139796607196331,0.001519956043921411,-0.038853198289871216,0.011179186403751373,-0.03868017718195915,-0.021723955869674683,-0.02954842522740364,-0.014793436974287033,-0.00021492657833732665,0.009770973585546017,-0.04041040316224098,-0.010121825151145458,-0.024088598787784576,-0.04371706023812294,-0.025838050991296768,-0.03646933287382126,-0.037949636578559875,-0.04836944490671158,0.09996864944696426,0.031778495758771896,0.03295120224356651,-0.05955824255943298,-0.007747570052742958,-0.006940131075680256,0.002294953214004636,-0.011131124570965767,-0.004078047815710306,0.0034268097952008247,0.029183154925704002,0.01914784125983715,0.037276770919561386,-0.02126256190240383,-0.047446656972169876,-0.0024091002997010946,-0.0680171325802803,-0.01794629544019699,-0.04863859340548515,0.0014274369459599257,0.0053252531215548515,0.002777974819764495,0.01183282770216465,0.011852052062749863,-0.006805557757616043,-0.008766481652855873,0.03777661547064781,-0.0235118567943573,0.011371433734893799,-0.04356326162815094,-0.001790303853340447,0.014466616325080395,0.019561173394322395,-0.03460453078150749,0.05190679803490639,0.009646013379096985,0.00747842388227582,0.016168005764484406,-0.008872217498719692,0.007218889892101288,-0.05586709454655647,0.0029053387697786093,-0.049407582730054855,-0.015966147184371948,-0.013582278974354267,-0.00026869578869082034,0.014322430826723576,-0.03329724818468094,0.05040726810693741,-0.0004541844828054309,-0.029971368610858917,0.03718064725399017,0.010304460301995277,0.018878694623708725,0.02510751038789749,0.00616152910515666,0.022954339161515236,-0.003251384012401104,-0.023723328486084938,-0.011342596262693405,-0.06251885741949081,0.004750913940370083,-0.05267578735947609,-0.03373941779136658,0.0014911189209669828,0.0283372662961483,-0.019128616899251938,0.03172082081437111,-0.012861350551247597,0.01051593292504549,-0.015725838020443916,0.0005190679803490639,0.020781943574547768,0.010448645800352097,-0.01839807629585266,0.041333191096782684,0.011746316216886044,0.022819766774773598,0.020032178610563278,-0.0184557493776083,-0.01877295784652233,-0.0076754773035645485,-0.0065267994068562984,-0.050599515438079834,-0.025799600407481194,-0.014716538600623608,0.0579049177467823,-0.02681851200759411,-0.026645489037036896,-0.01043903362005949,-0.009362448006868362,0.028298817574977875,0.027395254001021385,-0.012236546725034714,-0.031989965587854385,-0.015697000548243523,0.005411764141172171,-0.0160430446267128,0.0030278966296464205,0.034085463732481,-0.022127674892544746,-0.01537979207932949,0.019243964925408363,0.025568904355168343,-0.011236860416829586,0.0051666488870978355,-0.03514282405376434,0.019532335922122,-0.033643294125795364,-0.01664862409234047,-0.016696685925126076,-0.047908052802085876,-0.0003418399137444794,0.0016629400197416544,-0.05598244071006775,0.032662831246852875,0.02531898207962513,-0.04959983006119728,-0.010246786288917065,-0.008463691920042038,0.027452928945422173,-0.023242710158228874,0.028914008289575577,-0.009843066334724426,-0.02554967999458313,0.01831156387925148,0.0027130914386361837,-0.005618430208414793,-0.010227561928331852,-0.031317099928855896,-0.014235920272767544,-0.006887263152748346,0.017061956226825714,0.0053252531215548515,-0.006377807352691889,-0.011496394872665405,0.029529200866818428,0.0171965304762125,-0.014678088948130608,-0.014043672010302544,-0.0010982132516801357,-0.013774526305496693,-0.0470237135887146,0.01815776713192463,-0.03883397579193115,0.020897291600704193,-0.04836944490671158,0.02162783220410347,0.018128929659724236,-0.01815776713192463,0.020397448912262917,-0.0016473198775202036,-0.035392746329307556,0.004231845960021019,0.027452928945422173,-0.0003253186587244272,0.011736704036593437,0.009756555780768394,-0.07090084254741669,0.04583178088068962,0.0061086611822247505,-0.0020258070435374975,-0.034854453057050705,-0.01951311156153679,0.025588128715753555,0.09366293251514435,0.004123706836253405,0.010871590115129948,-0.01756179891526699,0.02524208277463913,0.043063417077064514,0.005777034442871809,-0.03218221291899681,-0.018744122236967087,-0.01499529741704464,-0.0028500675689429045,0.021762404590845108,0.016158394515514374,-0.007334238383919001,0.006473931018263102,0.03149012476205826,-0.007017029915004969,0.049253784120082855,-0.02735680527985096,0.015312504954636097,0.027856647968292236,-0.005978893954306841,0.0002952799841295928,-0.008886636234819889,0.02681851200759411,-0.041025593876838684,-0.020301325246691704,0.02033977396786213,0.013822588138282299,0.04098714515566826,0.01634102873504162,-0.0040299859829247,-0.027914322912693024,-0.0163506418466568,0.003145648166537285,-0.0027251068968325853,-0.012313446030020714,0.027760524302721024,0.009011596441268921,-0.03445073217153549,-0.01875373348593712,-0.01785978302359581,0.009328804910182953,-0.012899800203740597,0.0012520111631602049,0.015293280594050884,0.05017657205462456,0.0013625534484162927,-0.0023706506472080946,-0.01839807629585266,-0.019878381863236427,0.01126569788902998,0.012380732223391533,-0.0007647841703146696,-0.02028210088610649,-0.00885299313813448,-0.018426913768053055,-0.01548552792519331,-0.008569427765905857,0.004308744799345732,0.02968299761414528,0.001320499344728887,-0.006925712339580059,0.009400897659361362,-0.004025179892778397,0.03068268485367298,-0.024280846118927002,-0.01900365576148033,0.0022300698328763247,0.029644548892974854,0.01636025309562683,0.04606247693300247,-0.001519956043921411,0.025203634053468704,-0.04233287647366524,0.01974380761384964,0.027087658643722534,0.01424553245306015,-0.01794629544019699,-0.02449231781065464,0.002218054374679923,-0.02230069786310196,-0.03971831128001213,0.014726150780916214,-0.020397448912262917,0.011496394872665405,0.009021209552884102,-0.0017025910783559084,0.008828962221741676,-0.02253139577805996,-0.00550308171659708,0.003948281053453684,-0.012198097072541714,0.018897918984293938,-0.008189738728106022,0.0011354611488059163,-0.02291589044034481,-0.015187544748187065,0.0009257913916371763,-0.027491377666592598,-0.015495140105485916,0.000702904537320137,-0.0016377075808122754,0.021896978840231895,0.026164870709180832,-0.05213749408721924,0.01749451272189617,-0.02501138672232628,0.01808086782693863,-0.03052888624370098,0.019580397754907608,0.020589696243405342,0.02893323265016079,-0.005488663446158171,-0.0008669156231917441,0.003943474963307381,-0.014793436974287033,-0.02531898207962513,0.0035373521968722343,-0.0044048684649169445,-0.005815483629703522,-0.00994880311191082,-0.002358635189011693,0.02478068880736828,-0.023261934518814087,-0.05552104860544205,-0.012774839997291565,0.018061643466353416,0.001261623576283455,0.0008849388104863465,-0.0013517395127564669,0.0015379792312160134,0.021743180230259895,0.02268519252538681,-0.027779748663306236,-0.026203321292996407,-0.01908055506646633,-0.0017362342914566398,-0.028452614322304726,-0.0045851003378629684,-0.005344477482140064,-0.021993102505803108,-0.017283041030168533,0.01552397757768631,0.004025179892778397,-0.03308577835559845,-0.013370806351304054,0.026337893679738045,0.06028878316283226,-0.014870336279273033,0.004169365391135216,0.0331626757979393,-0.025126734748482704,-0.043217215687036514,0.03868017718195915,-0.00461634062230587,0.020435897633433342,0.012553755193948746,-0.021993102505803108,0.0020618534181267023,-0.0040876604616642,0.0016821647295728326,0.012303833849728107,0.019657297059893608,0.026395568624138832,-3.5727225622395054e-05,0.0033715388271957636,0.03204764053225517,-0.006536411587148905,0.01816737838089466,0.021743180230259895,0.02397325076162815,-0.016927383840084076,0.013861037790775299,-0.009650819003582,-0.008074390701949596,0.0038449480198323727,0.0008494931971654296,-0.012649878859519958,-0.013438093475997448,0.013976385816931725,0.005411764141172171,0.012457631528377533,-0.003037508809939027,0.010141050443053246,-0.001062166877090931,0.01232305821031332,0.013832200318574905,-0.02653014101088047,0.019580397754907608,0.03502747416496277,-0.014803050085902214,0.002127938438206911,-0.004121303558349609,0.011813602410256863,0.009059658274054527,0.003325880039483309,0.012640266679227352,-0.01495684776455164,0.021512484177947044,0.00559439929202199,-0.01179437804967165,0.002946191467344761,0.00307115213945508,-0.043678607791662216,-0.013909099623560905,-0.0008398808422498405,-0.011871276423335075,0.057328175753355026,-0.001635304419323802,-0.02526130899786949,-0.018186604604125023,-0.0474851056933403,-0.00994880311191082,-0.0002997857809532434,0.004964788910001516,-0.02479991503059864,0.013063210994005203,0.027260681614279747,-0.014178245328366756,-0.004979207646101713,-0.02591494843363762,-0.01352460402995348,-0.023338833823800087,0.006315327249467373,0.025511229410767555,0.03120175190269947,0.05832786113023758,0.012351895682513714,0.014668476767838001,0.039679862558841705,-0.01040058396756649,0.010198724456131458,-0.013861037790775299,0.0333164744079113,0.040871795266866684,-0.029356177896261215,-0.0019513111328706145,-0.03202841803431511,-0.023319609463214874,0.017734821885824203,-0.03252825886011124,0.04075644910335541,-0.02133946120738983,0.005815483629703522,-0.017138855531811714,-0.005728972610086203,0.004940757993608713,0.0163506418466568,0.003893009852617979,0.01673513650894165,-0.0037824674509465694,0.0020810780115425587,0.03585413843393326,-0.007295788731426001,0.03045198880136013,0.0323936864733696,-0.0028332460206001997,-0.027106883004307747,0.0379880852997303,-0.029183154925704002,-0.04217907786369324,0.00676230201497674,-0.025492005050182343,0.026030298322439194,-0.02478068880736828,0.007339044474065304,-0.008458885364234447,-0.01883063279092312,-0.05840475857257843,-0.0052483538165688515,-0.003246577922254801,-0.03358561918139458,-0.02456921711564064,0.021916203200817108,0.014899173751473427,-0.0282603669911623,-0.010890815407037735,0.013409256003797054,0.02322348579764366,-0.025069061666727066,0.03902622312307358,-0.04017970710992813,0.014408942312002182,0.010794691741466522,-0.03664235398173332,0.035315848886966705,0.009641206823289394,-0.022646743804216385,-0.008362761698663235,0.006036568433046341,0.002967819105833769,0.0030038657132536173,-0.019388150423765182,0.030105942860245705,-0.01548552792519331,0.008271444588899612,-0.004267892334610224,0.007612997200340033,0.011438719928264618,0.014495453797280788,-2.1665380700142123e-05,0.003330686129629612,-0.020378224551677704,-0.008728032000362873,0.026280218735337257,0.03006749227643013,0.005430988967418671,0.0018527843058109283,0.0013445302611216903,0.02554967999458313,-0.023800227791070938,-0.03037508949637413,-0.01686970889568329,0.0057914527133107185,0.008473304100334644,0.018657609820365906,-0.006949743255972862,0.07478424161672592,0.03174004703760147,-0.03994901105761528,0.01982070691883564,0.022358372807502747,0.0006650558207184076,0.04225597903132439,0.01755218766629696,0.00010100498184328899,0.014110959134995937,0.015101033262908459,-0.01908055506646633,-0.018580710515379906,-0.00035806078813038766,0.02405015006661415,0.0070698983035981655,-0.04529348760843277,0.03541197255253792,-0.014572353102266788,-0.0002515737432986498,-0.009569114074110985,0.0033066552132368088,-0.006555636413395405,0.013476542197167873,0.012198097072541714,0.003770451992750168,-0.011217636056244373,0.02374255284667015,-0.00186479976400733,-0.030913380905985832,0.024549992755055428,0.030778808519244194,-0.025492005050182343,-0.028279593214392662,-0.006695015821605921,0.011054225265979767,-0.009535470977425575,0.006392226088792086,0.007324625737965107,0.024088598787784576,0.011217636056244373,0.01892675645649433,-0.01832117699086666,-0.001236391137354076,-0.01250569336116314,0.049253784120082855,0.05332942679524422,-0.008199351839721203,-0.011996237561106682,-0.014495453797280788,0.007512066978961229,0.028971683233976364,-0.00784369371831417,0.002114721341058612,0.03504670038819313,0.008877024054527283,0.027472153306007385,0.0002176300622522831,0.03164392337203026,-0.005940444767475128,0.049023088067770004,-0.013370806351304054,0.0033955697435885668,0.02237759716808796,0.020378224551677704,-0.018869081512093544,0.06578706204891205,-0.003965102601796389,-0.0036118479911237955,0.003126423340290785,-0.0018888306804001331,-0.020320549607276917,0.008569427765905857,-0.012947862036526203,0.024203946813941002,0.003335492452606559,0.0007749973447062075,-0.03029819019138813,-0.01900365576148033,0.04906153678894043,-0.008122452534735203,-0.0009942795149981976,0.0035325458738952875,-0.041486989706754684,0.02268519252538681,-0.012842126190662384,-0.05306028202176094,0.039910558611154556,0.001769877620972693,-0.016177618876099586,-0.01567777618765831,-0.014976072125136852,-0.0375266931951046,-0.010150662623345852,0.005214710719883442,0.009823841974139214,0.06936286389827728,-0.010794691741466522,0.033816318958997726,0.03848792985081673,0.010727404616773129,0.009545083157718182,0.006358582526445389,0.010977326892316341,0.031528573483228683,0.025568904355168343,-0.0002832645259331912,-0.020512796938419342,-0.0234349574893713,-0.020608920603990555,0.01726381666958332,0.0026049523148685694,-0.021723955869674683,0.007166021969169378,0.016187230125069618,0.01890753209590912,-0.005253160372376442,0.024665340781211853,0.054982755333185196,0.003275415161624551,-0.01115034893155098,0.008886636234819889,0.027106883004307747,-0.01626412943005562,0.027683624997735023,0.02578037604689598,0.025953399017453194,-0.03902622312307358,0.017994357272982597,-0.0069929989986121655,0.018484586849808693,0.005041688214987516,0.0003733804915100336,-0.005397345870733261,-0.02020520158112049,-0.006959355901926756,-0.02193542756140232,-0.03662312775850296,0.011400270275771618,0.006699821911752224,-0.0031840975861996412,-0.020532021299004555,-0.0012832513311877847,-0.015187544748187065,0.027683624997735023,-0.015725838020443916,-0.006324939429759979,0.0006956952856853604,-0.022858215495944023,-0.0007287377957254648,-0.006334551610052586,0.028914008289575577,-0.03216299042105675,-0.010794691741466522,0.02005140297114849,-0.02170473150908947,-0.017619473859667778,-0.0030423151329159737,-0.013572665862739086,0.001445460133254528,-0.0010381359606981277,-0.023627204820513725,0.00621439702808857,-0.019561173394322395,-0.011659804731607437,-0.025049835443496704,-0.0062672654166817665,-0.013957161456346512,0.004765332210808992,-0.006224009674042463,-0.04606247693300247,0.013130497187376022,0.020455123856663704,-0.001465886365622282,-0.006344164256006479,-0.011179186403751373,0.020974190905690193,-0.010813916102051735,0.008396404795348644,0.05975048989057541,-0.03971831128001213,-0.03308577835559845,-0.009549889713525772,0.008824155665934086,0.03277818113565445,-0.019167065620422363,0.013543829321861267,0.017244592308998108,0.009670044295489788,0.018503811210393906,-0.030932607129216194,0.021204888820648193,0.027991220355033875,0.0236656554043293,-0.003280221251770854,-0.02493448741734028,-0.0462547242641449,-0.021012641489505768,-0.024357745423913002,-0.008958728983998299,-0.005435795057564974,0.021589383482933044,-0.015350954607129097,0.006012537516653538,-0.025818824768066406,-0.03633475676178932,0.006022149696946144,0.015225994400680065,-0.013284294866025448,0.07005494832992554,0.0032129345927387476,-0.01898443140089512,2.7898402549908496e-05,0.033873990178108215,-0.047600455582141876,0.003955490421503782,-0.03927614167332649,0.04637007415294647,-0.04629317298531532,0.002238480607047677,0.00859826523810625,-0.004698046017438173,-0.05006122216582298,0.03781506419181824,0.015793124213814735,0.020628144964575768,-0.004921533167362213,-0.01179437804967165,-0.04271737113595009,-0.010813916102051735,-3.659083813545294e-05,-0.03543119505047798,-0.0009834655793383718,0.012313446030020714,-0.016485214233398438,0.003878591349348426,0.0005986703909002244,-0.010112212970852852,0.0014730957336723804,-0.008713613264262676,-0.056328486651182175,0.04025660455226898,0.007925398647785187,-0.012111586518585682,0.03473910316824913,-0.0030495242681354284,0.007608190644532442,0.01112151239067316,-0.004871068522334099,0.05721282586455345,0.009021209552884102,-0.012198097072541714,0.016975445672869682,-0.023338833823800087,-0.005469438619911671,0.006512380670756102,-0.018513424322009087,-0.014447391964495182,0.03602716326713562,0.01989760622382164,0.037122972309589386,0.022185349836945534,-0.009554695338010788,-0.019455436617136,-0.023012014105916023,0.0028452614787966013,0.026395568624138832,-0.004373628180474043,-0.03927614167332649,-0.01047748327255249,-0.01495684776455164,-0.0005845522391609848,-0.0006602496723644435,0.01808086782693863,-0.020147526636719704,0.009612370282411575,0.062441956251859665,0.011506007052958012,-0.00012818996037822217,-0.007098735310137272,-0.0023009609431028366,0.012130810879170895,-0.017379164695739746,-0.01473576296120882,-0.01487994845956564,0.010688954964280128,0.012717165052890778,0.0170427318662405,-0.019936054944992065,0.018647998571395874,0.02426162175834179,0.00021672890579793602,0.011900113895535469,-0.039295367896556854,0.01009298861026764,-0.012457631528377533,-0.0007335440022870898,0.02178163081407547,0.028375716879963875,0.03812265768647194,0.02268519252538681,0.0055655622854828835,0.04044885188341141,-0.02207000181078911,0.0040468075312674046,0.011131124570965767,0.014418554492294788,0.011871276423335075,-0.008386792615056038,-0.0234349574893713,0.008747256360948086,0.027549052610993385,-0.01785978302359581,0.02487681247293949,0.02508828602731228,-0.030182842165231705,-0.03535429760813713,0.058135613799095154,0.016994670033454895,-0.006916100159287453,0.007117960136383772,0.03089415654540062,0.0161968432366848,0.016898546367883682,0.008218576200306416,0.0014827080303803086,0.05371392145752907,-0.0036815376952290535,-0.0171965304762125,0.03979521244764328,0.013303520157933235,0.01349576748907566,-0.04956137761473656,0.010371747426688671,0.029740672558546066,-0.015581651590764523,-0.01108306273818016,0.0028981296345591545,0.03218221291899681,-0.030778808519244194,-0.0017158080590888858,-0.01047748327255249,-0.005772228352725506,0.025838050991296768,-0.014447391964495182,-0.009626788087189198,0.0009894733084365726,0.013188171200454235,-0.0162737425416708,-0.00552230654284358,0.022492945194244385,0.020935742184519768,0.014408942312002182,0.022704416885972023,0.0077764070592820644,0.01695622131228447,0.049638278782367706,0.005834708455950022,-0.013120885007083416,-0.0005133606027811766,0.000560821732506156,-0.001600459567271173,0.0006956952856853604,-0.019503498449921608,0.004830216057598591,0.005296415649354458,-0.005671298131346703,0.039295367896556854,0.01352460402995348,0.018744122236967087,0.0037247934378683567,-0.008011910133063793,0.03181694447994232,0.008920279331505299,0.008338730782270432,0.00563284894451499,0.02033977396786213,-0.009400897659361362,-0.014360880479216576,0.0015319715021178126,0.008896248415112495,0.05079176276922226,0.007247726898640394,0.02916393056511879,0.008252219296991825,-0.030202066525816917,7.787521462887526e-05,0.014533903449773788,0.01013143826276064,0.017532963305711746,-0.007502454798668623,-0.026260994374752045,-0.017763659358024597,0.006166335195302963,0.003703165566548705,0.03618096187710762,0.0372190959751606,0.009497021324932575,-0.021358685567975044,-0.01620645634829998,0.016552500426769257,-0.0170427318662405,-0.004491379950195551,-0.041563887149095535,-0.01687932200729847,0.014803050085902214,-0.0004746107733808458,0.04294806718826294,-0.00791578646749258,0.014793436974287033,0.031105628237128258,0.014947235584259033,-0.01898443140089512,0.0334702730178833,0.0061711412854492664,-0.03518127277493477,0.003097586100921035,0.041794583201408386,-0.009655625559389591,-0.01171747874468565,-0.03648855537176132,-0.02637634240090847,-0.03329724818468094,-0.021589383482933044,-0.035392746329307556,0.0021567754447460175,0.004803781863301992,-0.04575487971305847,0.023992475122213364,-0.00556075619533658,-0.013774526305496693,0.03022129088640213,-0.005224322900176048,-0.05259888991713524,-0.017456064000725746,-0.044947441667318344,-0.010737016797065735,-0.015206769108772278,-0.033797092735767365,-0.002677045064046979,-0.014754988253116608,-0.027606725692749023,0.008011910133063793,-0.016225680708885193,0.0044433181174099445,0.007247726898640394,0.05194524675607681,0.045485734939575195,-0.025434330105781555,0.006776720751076937,0.011592518538236618,-0.013889874331653118,0.01590847223997116,-0.016465989872813225,-0.011640580371022224,-0.004318356979638338,-0.002323790453374386,-0.022742867469787598,0.015918085351586342,-0.02216612547636032,0.034258484840393066,-0.0016016610898077488,-0.016071882098913193,-0.014620414935052395,-0.002838052110746503,0.003580607706680894,0.013889874331653118,0.003789676818996668,-0.012572979554533958,0.012025075033307076,0.026549365371465683,-0.030855707824230194,-0.010256398469209671,0.03164392337203026,-0.020224425941705704,-0.0322398878633976,0.006286489777266979,-0.03556576743721962,-0.03708452358841896,0.02606874704360962,0.019263189285993576,0.021204888820648193,0.05752042308449745,0.006882457062602043,0.05409841611981392,-0.0066133104264736176,0.025357432663440704,0.0652487650513649,0.020397448912262917,0.00743997422978282,-0.0043664188124239445,-0.003479677950963378,0.008622296154499054,-0.012880575843155384,0.004337581805884838,-0.0014286384684965014,0.008963534608483315,-0.015610489062964916,-0.0025256501976400614,0.0234349574893713,0.009814229793846607,0.013351581990718842,0.01036213431507349,-0.005767421796917915,0.013236233033239841,-0.025972623378038406,0.028452614322304726,0.03489290177822113,0.017917457967996597,0.007752376142889261,-0.017013894394040108,7.637328235432506e-05,-0.00011347102554282174,-0.012524917721748352,-0.03502747416496277,-0.009030821733176708,-0.024011699482798576,0.00085249706171453,-0.009213456884026527,-0.0019861559849232435,0.030567336827516556,0.015620101243257523,-0.02478068880736828,0.000952225411310792,0.029971368610858917,-0.0073294322937726974,-0.014178245328366756,0.012457631528377533,0.03610406070947647,0.01254414301365614,0.0009984849020838737,-0.034162361174821854,-0.0020258070435374975,0.03314345329999924,0.03800731152296066,0.008439661003649235,-0.05282958596944809,0.011217636056244373,-0.02087806724011898,0.016004595905542374,0.012092361226677895,0.03429693728685379,-0.0036671191919595003,0.017773272469639778,0.019541947171092033,-0.032605160027742386,0.0025064253713935614,-0.01906132884323597,-0.017542574554681778,0.02214690111577511,-0.019955279305577278,-0.0026193708181381226,0.013178559020161629,-0.00867035798728466,0.02924082987010479,-0.0011360619682818651,-0.0022108450066298246,-0.003609444946050644,-0.0043856436386704445,-0.04310186579823494,-0.029125479981303215,0.01574506238102913,-0.007685089949518442,0.024761464446783066,0.026645489037036896,0.05398306995630264,0.02005140297114849,0.012169260531663895]) as similarity_score
FROM shared_source.magento_product_dimension_with_text_embedding__tmp
ORDER BY similarity_score DESC
LIMIT 100
)
SELECT
t1.internal_ref_code,
ANY_VALUE(t2.product_name) as product_name,
ANY_VALUE(t2.sale_price) as sale_price,
ANY_VALUE(t2.original_price) as original_price,
GROUP_CONCAT(DISTINCT t2.master_color ORDER BY t2.master_color SEPARATOR ', ') as available_colors,
ANY_VALUE(t2.product_image_url) as product_image_url,
ANY_VALUE(t2.product_image_url_thumbnail) as product_image_url_thumbnail,
ANY_VALUE(t2.product_web_url) as product_web_url,
ANY_VALUE(t2.description_text) as description_text,
ANY_VALUE(t2.material) as material,
ANY_VALUE(t2.material_group) as material_group,
ANY_VALUE(t2.gender_by_product) as gender_by_product,
ANY_VALUE(t2.age_by_product) as age_by_product,
ANY_VALUE(t2.season) as season,
ANY_VALUE(t2.style) as style,
ANY_VALUE(t2.fitting) as fitting,
ANY_VALUE(t2.form_neckline) as form_neckline,
ANY_VALUE(t2.form_sleeve) as form_sleeve,
ANY_VALUE(t2.product_line_vn) as product_line_vn,
MAX(t1.similarity_score) as max_score
FROM top_candidates t1
JOIN shared_source.magento_product_dimension_with_text_embedding__tmp t2
ON t1.internal_ref_code = t2.internal_ref_code
AND t1.product_color_code = t2.product_color_code
WHERE t2.sale_price <= 400000.0
GROUP BY t1.internal_ref_code
ORDER BY max_score DESC
LIMIT 10
\ No newline at end of file
......@@ -65,6 +65,7 @@ openai==2.13.0
opentelemetry-api==1.39.1
opentelemetry-exporter-otlp-proto-common==1.39.1
opentelemetry-exporter-otlp-proto-http==1.39.1
opentelemetry-instrumentation-logging==0.50b1
opentelemetry-proto==1.39.1
opentelemetry-sdk==1.39.1
opentelemetry-semantic-conventions==0.60b1
......
......@@ -6,5 +6,3 @@ uvicorn server:app --host 0.0.0.0 --port 5000 --reload
uvicorn server:app --host 0.0.0.0 --port 5000
import asyncio
import os # Có os để mount static
import os
import platform
# ==========================================
# 🛑 QUAN TRỌNG: FIX LỖI WINDOWS Ở ĐÂY 🛑
# Phải chạy dòng này TRƯỚC KHI import bất kỳ thư viện nào khác
# ==========================================
if platform.system() == "Windows":
print("🔧 Windows detected: Applying SelectorEventLoopPolicy globally...")
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
# Sau khi fix xong mới import tiếp
import logging
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles # Import cái này để mount HTML
from fastapi.staticfiles import StaticFiles
# Updated APIs (Import sau cùng để DB nhận cấu hình fix ở trên)
from api.chatbot_route import router as chatbot_router
from api.conservation_route import router as conservation_router
from common.langfuse_client import initialize_langfuse
from config import PORT
# Configure Logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", handlers=[logging.StreamHandler()]
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
handlers=[logging.StreamHandler()],
)
logger = logging.getLogger(__name__)
# ==========================================
# 🔥 LANGFUSE INITIALIZATION
# ==========================================
if initialize_langfuse():
logger.info("✅ Langfuse initialized successfully")
else:
logger.warning("⚠️ Langfuse initialization failed or keys missing")
app = FastAPI(
title="Contract AI Service",
description="API for Contract AI Service",
version="1.0.0",
)
print("✅ Clerk Authentication middleware DISABLED (for testing)")
logger.info("✅ Clerk Authentication middleware DISABLED (for testing)")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
......@@ -45,9 +50,18 @@ app.add_middleware(
allow_headers=["*"],
)
app.include_router(conservation_router)
app.include_router(conservation_router)
app.include_router(chatbot_router)
#
# --- MOCK API FOR LOAD TESTING ---
try:
from api.mock_api_route import router as mock_router
app.include_router(mock_router)
print("✅ Mock API Router mounted at /mock")
except ImportError:
print("⚠️ Mock Router not found, skipping...")
# ==========================================
# 🟢 ĐOẠN MOUNT STATIC HTML CỦA BRO ĐÂY 🟢
......@@ -65,9 +79,9 @@ except Exception as e:
from fastapi.responses import RedirectResponse
@app.get("/")
async def root():
# Tự động nhảy sang trang Chatbot luôn
return RedirectResponse(url="/static/index.html")
......
......@@ -441,7 +441,7 @@
<div class="header">
<h2>🤖 Canifa AI Chat</h2>
<div class="config-area">
<input type="text" id="userId" placeholder="User ID" value="test_user_001">
<input type="text" id="userId" placeholder="User ID" value="test_user_009">
<button onclick="loadHistory(true)">↻ History</button>
<button onclick="clearUI()" style="background: #d32f2f;">✗ Clear UI</button>
</div>
......@@ -682,7 +682,7 @@
const img = document.createElement('img');
img.src = product.thumbnail_image_url || 'https://via.placeholder.com/200';
img.alt = product.name;
img.onerror = function() { this.src = 'https://via.placeholder.com/200?text=No+Image'; };
img.onerror = function () { this.src = 'https://via.placeholder.com/200?text=No+Image'; };
card.appendChild(img);
// Product body
......
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n_local
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
environment:
- N8N_HOST=localhost
- N8N_PORT=5678
- N8N_PROTOCOL=http
- WEBHOOK_URL=http://localhost:5678/
- GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
restart: unless-stopped
volumes:
n8n_data:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment