Ecom chuẩn bị sản phẩm mới trên Google Sheets

Team Ecom/Thiết kế tạo danh sách SP mới: Mã SP, Link ảnh, Tên SP, Chất liệu, Form, Tính năng. Tại bước này chưa có mô tả marketing nào — đây là dữ liệu thô từ nhà sản xuất.

Đây là bước nguồn — ground truth duy nhất

Chất liệu, chứng chỉ, thành phần — chỉ có ở đây, trước khi lên web. AI không được phép bịa bất kỳ thông số nào. Dữ liệu từ bước này là mandatory input cho cả 2 lần AI generate.

AI lần 1 Sinh mô tả marketing cho web — POST /generate-web-desc

AI Vision nhìn ảnh SP → AI Writer đọc toàn bộ data từ Sheets → sinh mô tả marketing cho khách hàng đọc trên canifa.com. Output ghi ngược về cột "AI Description" trong Sheets.

Vì sao cần bước này? Magento yêu cầu có mô tả trước khi import SP. Không có mô tả → SP không thể lên web. Bước này giải phóng team Ecom khỏi việc viết tay hàng chục mô tả/ngày.

Ecom review và import lên Magento

Team Ecom copy mô tả từ Sheets vào Magento (hoặc qua n8n tự động). SP live trên canifa.com. Khách hàng đọc được mô tả marketing hoàn chỉnh.

Magento auto-sync → StarRocks DB

SP được ETL vào bảng magento_product_dimension_with_text_embedding. Từ đây các hệ thống nội bộ (chatbot AI, dashboard) có thể truy vấn theo magento_ref_code.

Đây là prerequisite bắt buộc cho AI lần 2 API /generate tra StarRocks để lấy ảnh, tên SP, chất liệu, giới tính, dòng SP. Nếu SP chưa sync → API báo lỗi "không tìm thấy sản phẩm".

AI lần 2 Sinh Ultra Description cho AI chatbot — POST /generate

AI tra DB lấy đầy đủ context → Vision nhìn ảnh → Writer sinh 28 trường structured JSON. Output lưu vào PostgreSQL. AI chatbot đọc data này để tư vấn khách hàng chính xác, đa chiều.

Endpoint này đã có sẵn và production-ready Hỗ trợ batch generate, retry logic, round-robin API key, self-critique. Chỉ cần SP đã có trong StarRocks.

AI lần 1: Mô tả cho web Mới

Đầu ra phục vụKhách hàng trên web
Input yêu cầuẢnh + data từ Sheets
Output formatText marketing (4 trường)
Cần StarRocks DB?❌ Không
Lưu kết quả vàoGoogle Sheets (qua n8n)
TriggerSP mới, chưa lên web

AI lần 2: Ultra Desc cho AI Đã có

Đầu ra phục vụAI chatbot tư vấn
Input yêu cầuMã SP (tra DB tự động)
Output format28 trường JSON structured
Cần StarRocks DB?✅ Bắt buộc
Lưu kết quả vàoPostgreSQL
TriggerSP đã live, đã sync DB

Tại sao không dùng 1 AI chạy hết?

Câu trả lời nằm ở vòng đời của sản phẩmai là người đọc output. Hai lần AI phục vụ hai audience hoàn toàn khác nhau, ở hai thời điểm khác nhau trong vòng đời SP.

Hai giai đoạn AI không thể chạy đồng thời vì phụ thuộc vào nhau theo chuỗi tuần tự bắt buộc trong hệ thống.

AI lần 1 xảy ra TRƯỚC khi SP tồn tại trong bất kỳ DB nào

SP mới chỉ nằm trong Sheets. Không có StarRocks record, không có Magento ID, không có vector embedding. AI lần 2 (/generate) tra StarRocks để lấy data — nhưng record đó chưa tồn tại. Nếu gọi lần 2 lúc này → 404 không tìm thấy SP.

AI lần 2 cần SP đã "chín" trong hệ thống

Để sinh 28 trường chính xác (giá, category, related products cho cross-sell...), AI lần 2 cần đọc từ StarRocks với đầy đủ metadata. Dữ liệu này chỉ có sau khi SP đã live trên Magento và đã sync DB — thường cách AI lần 1 vài giờ đến vài ngày.

Khách hàng đọc bằng mắt. AI chatbot đọc bằng code. Hai audience này cần hai format đầu ra căn bản khác nhau.

AI lần 1 → Text tự nhiên

Khách cần văn xuôi hấp dẫn, có cảm xúc, storytelling. "Form regular fit vừa vặn, tôn dáng mà không gò bó..."

Đặt vào Magento description field → render trực tiếp cho khách đọc trên web.

AI lần 2 → JSON structured

Chatbot cần data có cấu trúc để tư vấn theo ngữ cảnh: "phối với quần gì?", "dịp nào mặc?", "size gì với chiều cao 1m70?"

28 trường riêng biệt → chatbot query trực tiếp từng trường phù hợp với câu hỏi của khách.

AI lần 1 viết mô tả cho 1 SP cụ thể. AI lần 2 cần hiểu SP trong bối cảnh toàn bộ catalog.

Trường cross_sell trong Ultra Desc gợi ý "Quần Chinos Slim, Giày Loafer Da, Thắt Lưng Da Reversible" — chatbot cần biết Canifa đang bán những sản phẩm đó thật sự. AI lần 2 đọc từ StarRocks catalog nên có thể gợi ý đúng dòng SP thực tế đang có hàng. AI lần 1 ở giai đoạn Sheets không có thông tin này.

Tóm lại — Design decision đúng

Tách thành 2 pipeline độc lập là intentional architecture, không phải over-engineering. Mỗi pipeline có trigger riêng, input source riêng, output destination riêng, và phục vụ một người dùng hoàn toàn khác nhau. Gộp lại thành 1 sẽ tạo ra hard dependency khiến SP không thể lên web cho đến khi toàn bộ AI pipeline (kể cả Ultra Desc phức tạp hơn) chạy xong.

Endpoint mới

Sinh mô tả marketing cho web

Dành cho team Ecom gọi khi SP mới, chưa cần có trong DB. AI Vision nhìn ảnh + AI Writer đọc data Sheets → sinh mô tả khách hàng đọc trên web.

2 pha AI
POST /api/product-desc/generate-web-desc
Field Kiểu Bắt buộc? Mô tả & Cột Sheets
ma_san_phamstringBắt buộcMã SP nội bộ. VD: 5TS25S021 — cột Mã sản phẩm
ten_san_phamstringBắt buộcTên đầy đủ — cột Tên sản phẩm
image_urlstringBắt buộcURL ảnh public (Vision AI download trực tiếp) — cột Link ảnh
chat_lieustringNên cóChất liệu chính xác. AI dùng verbatim, không đoán lại — cột Đặc tính chất liệu
formstringOptionalSlim / Regular / Oversize — cột Form
hoan_canhstringOptionalDịp mặc mong muốn — cột Hoàn cảnh
tinh_nangstringOptionalCo giãn, kháng khuẩn, thấm hút... — cột Tính năng
featuringstringOptionalĐiểm nhấn thiết kế đặc biệt — cột Featuring
chung_chistringOptionalOEKO-TEX, BCI Cotton... — cột Chứng chỉ
huong_dan_su_dungstringOptionalGiặt ủi, bảo quản — cột Hướng dẫn sử dụng
mo_ta_chungstringOptionalMô tả thô ban đầu. AI enrich thêm — cột Mô tả chung
gioi_tinhstringOptionalNam / Nữ / Unisex / Bé trai / Bé gái
{ "status": "success", "ma_san_pham": "5TS25S021", "ten_san_pham": "Áo Polo Nam Cotton USA Cổ Bẻ Tay Ngắn", // ── 4 trường output chính ──────────────────────────── "mo_ta_web": "Form regular fit vừa vặn, tôn dáng mà không gò bó. Thiết kế cổ bẻ tối giản lịch sự, phù hợp đi làm lẫn dạo phố cuối tuần. Cotton USA 100% mềm mại, thấm hút tốt, giữ form sau nhiều lần giặt...", "mo_ta_ngan": "Polo nam cotton USA, form regular, cổ bẻ thanh lịch", "dac_diem_noi_bat": [ "Cotton USA 100% mềm mại, thấm hút tốt", "Form Regular Fit tôn dáng, không gò bó", "Cổ bẻ lịch sự, hợp office lẫn casual" ], "huong_dan_bao_quan": "Giặt máy ≤30°C, lộn trái, không dùng tẩy, phơi bóng râm", // ── Debug / monitoring ─────────────────────────────── "elapsed_s": 8.3, "vision_data": { /* raw Vision output — bỏ đi nếu không cần debug */ } }
Lưu ý quan trọng về chất liệu Nếu có chat_lieu → AI dùng verbatim, không thêm không bớt. Nếu không có → AI ghi "Theo thông tin nhà sản xuất", không được đoán. Đây là hard rule để tránh thông tin sai lệch cho khách hàng.
curl -X POST http://localhost:5000/api/product-desc/generate-web-desc \ -H "Content-Type: application/json" \ -d '{ "ma_san_pham": "5TS25S021", "ten_san_pham": "Áo Polo Nam Cotton USA Cổ Bẻ Tay Ngắn", "image_url": "https://media.canifa.com/abc.jpg", "chat_lieu": "Cotton USA 100%", "form": "Regular Fit", "hoan_canh": "Đi làm, Dạo phố", "tinh_nang": "Co giãn nhẹ, thấm hút mồ hôi" }'
Endpoint hiện có — Production ready

Ultra Description cho AI chatbot

Sinh 28 trường structured JSON từ mã SP. SP bắt buộc phải có trong StarRocks DB. Pipeline 3 pha: Vision → Writer → Self-critique.

POST /api/product-desc/generate
// Gửi 1 trong 2 trường sau: { "magento_ref_code": "5TS25S021-SR079" } // hoặc { "internal_ref_code": "5TS25S021" }
Tại sao chỉ cần mã SP? Hệ thống tự tra StarRocks: tên SP, tất cả URL ảnh, chất liệu, giới tính, dòng SP, category, giá. AI lần 2 có context đầy đủ hơn nhiều so với AI lần 1 nhờ dữ liệu đã được enriched qua Magento pipeline.
Pha 1 · Vision
Llama 4 Scout nhìn ảnh → extract 9 trường thô: màu sắc, form, đặc trưng thiết kế...
Pha 2 · Writer
GPT-OSS 120B kết hợp Vision output + DB data → sinh đủ 28 trường JSON với giọng Stylist Canifa
Pha 3 · Critique
Self-review: kiểm tra chất liệu không bịa, FAQ có thực tế, phối đồ có logic. Tự sửa nếu cần.
MethodEndpointMô tả
GET/overviewStats: tổng SP, đã generate, đã duyệt, missing
GET/listDanh sách SP kèm trạng thái mô tả (phân trang)
GET/saved/{code}Lấy mô tả đã lưu theo mã SP
POST/generateGenerate Ultra Desc cho 1 SP
POST/approveDuyệt / hủy duyệt mô tả
POST/batch-generateGenerate hàng loạt (background task)
POST/batch-generate-allGenerate toàn bộ SP còn thiếu (max 500)
POST/saved/{code}/updateEdit nội dung JSON thủ công
POST/saved/{code}/rewrite-fieldAI viết lại 1 trường cụ thể
POST/sync-materialPatch chất liệu từ StarRocks vào existing records
DELETE/saved/{code}Xóa mô tả đã lưu

AI chatbot đọc toàn bộ 28 trường này để trả lời câu hỏi theo từng ngữ cảnh: styling, size, chất liệu, dịp mặc. Mỗi nhóm phục vụ một intent khác nhau.

Nhóm 1 — Thông tin cơ bản  (5 trường)
ten_san_pham
Tên sản phẩm ngắn gọn, chuẩn
Áo Polo Nam Cổ Bẻ Tay Ngắn
tagline
1 câu slogan hấp dẫn, gây nhớ
Lịch lãm không cần cố gắng
mo_ta_chinh
3 câu: form dáng + thiết kế + tác dụng lên cơ thể
Form regular fit vừa vặn, tôn dáng mà không gò bó...
phong_cach
1-3 từ khóa phong cách
Smart Casual, Minimalist
tags
5 tags phân loại, cách dấu phẩy
polo, nam, công sở, smart casual, tay ngắn
Nhóm 2 — Chất liệu & bảo quản  (3 trường)
chat_lieu
Chất liệu vải — dùng đúng từ DB hoặc Sheets, KHÔNG đoán
Cotton USA 100%
tinh_nang_vai
Tính năng nổi bật của vải
Co giãn 4 chiều, kháng khuẩn, thấm hút tốt
huong_dan_bao_quan
Hướng dẫn giặt/bảo quản cụ thể
Giặt máy ≤30°C, không dùng tẩy, phơi bóng râm
Nhóm 3 — Đối tượng mục tiêu  (4 trường)
do_tuoi
Khoảng tuổi phù hợp
25-40
gioi_tinh
Nam / Nữ / Unisex
Nam
loi_song
Mô tả lối sống khách hàng mục tiêu
Người đàn ông hiện đại, coi trọng phong cách nhưng không cầu kỳ
tinh_cach
Tính cách phù hợp
Tự tin, chỉn chu, thực dụng
Nhóm 4 — Dịp mặc & styling  (6 trường)
dip_mac
4+ dịp mặc cụ thể, ngăn bởi ·
Đi làm · Cafe cuối tuần · Gặp đối tác
phoi_do
3 combo phối đồ, ngăn bởi |
Chinos Beige + Loafer → Thanh lịch | Jean Slim + Sneaker → Năng động
nguyen_tac_phoi_do
Lý do và quy tắc phối đồ, tại sao combo đó hoạt động
Mix cùng độ fit — quần slim hoặc straight để cân bằng
tranh_phoi_cung
Những item KHÔNG NÊN phối — negative constraints
Tránh quần jogger nỉ quá thể thao, lệch phong cách
layer
Gợi ý layering theo mùa
Mặc đơn mùa hè. Layer cùng Bomber mùa thu
mua
Mùa phù hợp nhất
Xuân Hè
Nhóm 5 — FAQ  (6 trường)
faq_1_q / faq_1_a
FAQ về form dáng, hack dáng
Áo này có hack dáng không? → Phom vai suông che nhẹ bắp tay...
faq_2_q / faq_2_a
FAQ về size, fit
1m70 65kg mặc size gì? → Nên chọn size M...
faq_3_q / faq_3_a
FAQ về mix & match
Phối với quần gì đẹp nhất? → Combo: Chinos + Loafer...
Nhóm 6 — Hỗ trợ bán hàng  (4 trường)
hook_quang_cao
1 câu hook gây tò mò, dùng cho ads
Chiếc polo mà anh em mặc đi làm rồi đi cafe luôn
cross_sell
2-3 SP nên mua kèm — từ catalog thực tế
Quần Chinos Slim, Giày Loafer Da, Thắt Lưng Da
ly_do_mua
3 lý do nên mua, ngăn bởi |
Form hack dáng | Mặc đi làm hay đi chơi đều ổn | Cổ bẻ lịch sự
luu_y_size
Lưu ý chọn size cụ thể cho SP này
Nếu nặng trên 75kg nên lên 1 size
Cột trong Sheets→ API fieldGửi API?Ghi chú
Mã sản phẩmma_san_phamBắt buộcUnique ID
Tên sản phẩmten_san_phamBắt buộcTên đầy đủ
Link ảnhimage_urlBắt buộcURL public
Đặc tính chất liệuchat_lieuNên cóAI dùng verbatim
FormformOptional
Hoàn cảnhhoan_canhOptional
FeaturingfeaturingOptionalĐiểm nhấn thiết kế
Tính năngtinh_nangOptional
Chứng chỉchung_chiOptionalOEKO-TEX, BCI...
Thành phầnthanh_phanOptional
Hướng dẫn sử dụnghuong_dan_su_dungOptional
Mô tả chungmo_ta_chungOptionalAI enrich thêm
Ngày checkKhông gửiQuản lý nội bộ
Ecom check / Thiết kế checkKhông gửiWorkflow nội bộ
Số ký tựKhông gửiTự tính từ output
AI DescriptionOutput ghi vền8n ghi kết quả vào đây
n8n

Trigger: Schedule hoặc Webhook

n8n chạy theo lịch (VD: mỗi 30 phút) hoặc trigger khi Sheets được cập nhật. Đọc tất cả dòng chưa có giá trị trong cột "AI Description".

API

Loop: gọi /generate-web-desc cho từng SP

Với mỗi dòng: map cột Sheets → request body → POST → nhận response JSON. Recommend batch size 5-10 SP để tránh timeout.

POST /api/product-desc/generate-web-desc Body: { ma_san_pham, ten_san_pham, image_url, chat_lieu, form, ... } → Response: { mo_ta_web, mo_ta_ngan, dac_diem_noi_bat, huong_dan_bao_quan }

Ghi kết quả ngược về Sheets

n8n update cột "AI Description" với mo_ta_web. Ecom review → approve → copy vào Magento. Cột "Số ký tự" có thể tự tính bằng =LEN().

Kết quả cuối cùng của toàn bộ pipeline Ecom chỉ cần điền ảnh + info cơ bản → AI tự sinh mô tả web → lên Magento → sync DB → AI chatbot có đầy đủ 28 trường để tư vấn khách hàng chuyên nghiệp.