← Nguyễn Trung Tâm · Portfolio English →

Một AI chatbot bán hàng biết học từ chính những lần sai của nó

Case study — trợ lý chạy production trên cửa hàng WooCommerce thật, 1.330 SKU

Bởi Nguyễn Trung Tâm Product Owner & Thiết kế hệ thống AI 2026 Live: tanphatsolutions.vn
LLMMulti-agentHệ tự cải thiện ProductionWooCommerceAgent-orchestrated dev

Một nhà bán lẻ vật liệu xây dựng & nội thất muốn có trợ lý bán hàng 24/7 trên cửa hàng WooCommerce — trợ lý báo giá thật, gợi đúng sản phẩm giữa 1.330 SKU, điều khiển giỏ hàng, và trao cho đội sale một lead có thể xử lý trong năm giây. Phần kỹ thuật đáng nói không phải là việc chatbot trả lời câu hỏi; mà là mọi thứ được dựng quanh mô hình để khiến nó đáng tin — và một vòng tự học 48 giờ có kiểm soát giúp hệ thống tốt lên từ chính những câu nó trả lời tệ, mà không ai phải ngồi đọc log.

01Bài toán

Khách đến ngoài giờ không có ai tư vấn; nhiều người hỏi giá rồi rời đi; và những lead thật sự về đến CRM thì mỏng đến mức nhân viên gọi lại phải bắt đầu từ số không. Mục tiêu sản phẩm: một trợ lý luôn bật, báo giá LIVE, gợi đúng sản phẩm, thêm vào giỏ, và — khi khách để lại số điện thoại — gửi cho sale một bản tóm tắt nhu cầu thay vì một đoạn hội thoại thô.

02Những ràng buộc định hình kiến trúc

Ràng buộcHệ quả thiết kế
Không bao giờ bịa giá, tồn kho hay chính sách — sai một lần là mất niềm tinGiá lấy LIVE từ WooCommerce mỗi lượt; LLM không bao giờ tự gõ số; một bộ lọc phía server vẫn cắt mọi con số giá mà nó lỡ tạo ra.
Hosting chia sẻ: không CI/CD, không SSH, máy dev không có PHPDeploy bằng cách upload plugin; một cổng kiểm cú pháp PHP chạy trên Node; mọi kiểm chứng chạy trên production qua API.
Danh mục tiếng Việt: chữ có dấu / không dấu, tiếng lóng tiền tệ, tên gọi vùng miềnMột tầng chuẩn hoá truy vấn riêng; khớp có dấu và khớp bỏ dấu được xử lý khác nhau một cách có chủ đích.
Tên sản phẩm do nhiều người nhập, một số nhồi đầy tính từ quảng cáoTìm kiếm phải miễn nhiễm với trùng từ ngẫu nhiên (xem mô hình neo + bổ nghĩa).
Một phần nhu cầu (giường, tủ, kệ) đóng theo yêu cầu tại xưởng, không có sẵnMột nhánh hội thoại riêng: không hiện thẻ sản phẩm, hỏi rõ quy cách, xin số điện thoại cho đội thiết kế.
Tường lửa hosting chặn IP khi có loạt lệnh gọi API dồn dậpBộ chạy kiểm thử tự giãn nhịp và thử lại; phân biệt được "403 tường lửa" với "500 lỗi code".

03Kiến trúc, ở mức khối

Khách ─► Widget chat (vanilla JS, nhớ hội thoại qua các trang)
             │
             ▼
 ┌──────────────────────── Plugin WordPress (PHP) ────────────────────────┐
 │ 1  Chuẩn hoá truy vấn    alias · bỏ từ thừa · bóc ngân sách ·           │
 │                          tách NEO (món hàng) vs BỔ NGHĨA (phong cách)   │
 │ 2  Tìm kiếm đa tầng      tên món → phòng/không gian → danh mục → 1 từ   │
 │ 3  Kế thừa ngữ cảnh      câu nối thừa hưởng chủ đề; chủ đề mới thì cắt   │
 │ 4  Cổng liên quan        danh sách khớp yếu bị coi là "không có hàng"    │
 │ 5  LLM (OpenAI/OpenRouter) prompt mang GIÁ LIVE + bản đồ tồn kho thật   │
 │ 6  Lưới an toàn sau LLM  đối chiếu lời ↔ thẻ · cắt lời hứa suông ·      │
 │                          cắt mọi con số giá mô hình tự gõ               │
 │ 7  Tự chẩn đoán          gắn mã lý do cho mỗi lượt "bí" ──► vòng 48h
 │ 8  Đường ống lead        nhu cầu có cấu trúc → lưu local → đẩy sang CRM  │
 └─────────────────────────────────────────────────────────────────────────┘
             │                                  │
             ▼                                  ▼
    Thẻ sản phẩm + giỏ hàng          CRM nội bộ (webhook idempotent)
    (WooCommerce Store API)          + dashboard phễu & A/B test
Đường ống ở mức khối. Ngưỡng và điều kiện nội bộ được cố ý để ngoài phạm vi.
LLM chỉ làm đúng thứ nó giỏi — diễn đạt và khai thác nhu cầu. Mọi thứ buộc phải đúng — giá, sản phẩm nào được phép hiện, lead có được lưu hay không — đều do code tất định quyết định và được đối chiếu sau khi mô hình trả lời.

04Bảy quyết định thiết kế

  1. "Thà không thẻ còn hơn thẻ sai." Một thẻ sản phẩm sai phá niềm tin nhanh hơn việc không hiện gì. Mọi danh sách sản phẩm phải qua cổng liên quan; lời của bot và thẻ của nó phải cùng một nhóm hàng, nếu không thẻ bị bỏ và bot hỏi lại.
  2. Mô hình truy hồi "neo + bổ nghĩa". Tách từ chỉ món hàng khỏi từ mô tả (phong cách, màu, "cao cấp", "thông minh"). Truy vấn không có neo thì không trả sản phẩm — chỉ một câu hỏi và các nút nhóm hàng. Khi phải nới lỏng truy vấn, bỏ bổ nghĩa trước và không bao giờ bỏ neo.
  3. Lưu lead trước, mọi thứ khác sau. Lead được ghi local trước khi đẩy CRM; nếu AI sập lead vẫn được lưu; nhu cầu của khách quay lại được gộp, không ghi đè.
  4. Ghi chú CRM là bản tóm tắt cho người sẽ gọi, không phải bản ghi hội thoại. Bảy trường nhu cầu cộng một dòng gợi ý cho sale; toàn bộ hội thoại được lưu riêng để tra cứu.
  5. Một vòng tự học có kiểm soát — điểm nhấn của dự án, ngay bên dưới.
  6. Sự thật tổng thể do code tính, AI chỉ diễn đạt. Câu "rẻ nhất / đắt nhất / mới về / đang giảm giá" chạy truy vấn trên TOÀN nhóm hàng, dựng khối "sự thật từ kho" rồi ép thẻ đúng thứ tự — LLM không tự phán "nhất". Không có dữ liệu thì bot nói thật.
  7. Mọi câu dự phòng đều có telemetry. Khách không nhận được câu trả lời thật = một dòng trên dashboard (loại lỗi, mã lỗi, trang), không phải một sự im lặng — nên sự cố núp sau câu "anh/chị thử lại giúp em" vẫn bị nhìn thấy.

★Vòng tự học 48 giờ

ý tưởng số 1 — không phải một tính năng, mà là một hệ tự cải thiện có kiểm soát

Hầu hết chatbot thương mại được "train" một lần lúc ra mắt rồi đứng yên, trong khi khách thật cứ hỏi theo hàng nghìn cách không lường trước — tiếng lóng tiền tệ, tên gọi vùng miền, hỏi theo phòng thay vì theo tên món, hỏi món shop không bán. Mỗi câu như vậy là một khách rời đi trong im lặng. Cách làm thường thấy — "thỉnh thoảng có người đọc log" — trên thực tế nghĩa là không ai đọc. Câu hỏi thiết kế: làm sao để việc học-từ-thất-bại diễn ra tự động, định kỳ và an toàn, để người chủ chỉ phải đọc một báo cáo ngắn?

Vòng tự học 48 giờ, ở mức khối
Một vòng chạy. Agent kiểm chứng lại mọi bản sửa và tự hoàn tác thứ nó không xác nhận được.

Ba quyết định làm nên điều đó

1 · Chatbot phải biết nó vừa thất bại, và vì sao. Tiền đề của mọi vòng học là một tín hiệu lỗi có chất lượng. Hệ không dùng LLM để chấm LLM (đắt, chậm, không ổn định); nó tự chẩn đoán bằng luật rẻ tiền ngay trong lượt chat, gắn cho mỗi lượt "bí" một trong hơn 10 mã lý do — tách lỗi tìm kiếm khỏi lỗi AI khỏi lỗ hổng chính sách. Mã lý do quyết định loại thuốc: lỗi tìm kiếm chữa bằng từ điển, lỗ hổng chính sách chữa bằng FAQ, lỗi AI chữa bằng code. Chẩn đoán sai gốc còn tệ hơn không chẩn đoán — nên chính hạ tầng quan sát cũng được kiểm.

2 · Tách "núm huấn luyện" khỏi code. Mọi tri thức miền thay đổi theo thời gian (từ đồng nghĩa, từ thừa, từ mô tả phong cách, món đóng theo yêu cầu, FAQ bổ sung) nằm ở dạng núm — cấu hình, sửa được tức thì, không deploy. Code chỉ chứa cơ chế. Hệ quả: một agent có thể cải thiện chatbot mà không bao giờ chạm vào code. Ranh giới đó là lằn ranh an toàn cốt lõi.

3 · Agent được trao quyền theo bậc — luôn ít hơn mức nó "có thể" làm. Nó được thêm núm an toàn (chỉ khi chủ dự án đã bật chế độ tự động); nó chỉ được đề xuất thay đổi code hay prompt, kèm phân tích gốc rễ, để con người quyết; và không gì trong vòng tự động được xoá hay sửa núm đã có — agent chỉ thêm. Hai vòng đầu luôn ở chế độ chỉ-đề-xuất: niềm tin được xây theo bậc, như cách onboard một nhân viên mới.

Vì sao đủ an toàn để chạy trên production

Trao cho một AI agent quyền thay đổi một hệ thống đang bán hàng thật là việc nghiêm túc. Các lớp phòng thủ, ở mức nguyên lý: cổng API đóng theo mặc định và chỉ mở khi chủ dự án đặt khoá bí mật phía server; agent không có đường vào trang quản trị, không đăng nhập, không đọc được dữ liệu khách ngoài các câu bị bí; nội dung chat của khách được coi là dữ liệu, không phải mệnh lệnh (chống prompt injection qua chính kênh chat); chốt chặn nghiệp vụ nằm ở server và không tin agent — nếu agent đề nghị coi một từ là "từ thừa", server tự thử và từ chối nếu từ đó đang tìm ra sản phẩm thật; mọi thay đổi đều chỉ-thêm, có trần mỗi vòng, có log trước/sau và hoàn tác một chạm; và agent bị cấm tạo dữ liệu giả hay lead giả.

Điều thực sự đã xảy ra

05Kết quả đã kiểm chứng

Hạng mụcKết quả
Hồi quy hội thoại43/43 kịch bản đạt — tự chấm, chạy trên production (gồm nguyên một hội thoại thật 3 lượt)
Câu hỏi xếp hạng theo giá5/5 khớp giá thật (vd rẻ nhất 3.317.000₫, đắt nhất 113.616.000₫ trong 82 bồn cầu) — test tự tải 1.330 SP và tự tính đáp án
Tuyên bố "nhất" sai của AITrước: "rẻ nhất bên em là X" với X xếp thứ 7/84. Sau: 0 tuyên bố "nhất" vô căn cứ — đối chiếu với kho
Từ cấm của thương hiệu trong lời bot0 lần trong cả 43 ca (kiểm cho MỌI ca)
Lớp lỗi "thẻ lạc đề"0 lần tái phát trong bộ test (tái hiện được trên production trước khi sửa)
Lead khi ép AI sập0 lead mất qua cả hai kiểu lỗi (mất kết nối, trạng thái lỗi) — fault injection trên production
Hồ sơ nhu cầu khi khách đổi trang trước khi để sốGiữ đủ 7 trường + toàn bộ hội thoại
Vòng tự học54 giây/vòng; tự dừng an toàn khi có sự cố mạng
Rủi ro pháp lý trong tên sản phẩm0 / 1.324 tên (tại thời điểm quét) chứa từ ngữ cực đại bị cấm — quét toàn danh mục
Nhịp phát hànhgần 30 bản phát hành production có kiểm chứng, mỗi bản có backup + kiểm chứng sau deploy

06Vai trò của tôi — nói thật

Dự án được xây theo mô hình phát triển điều phối agent (agent-orchestrated development): tôi thiết kế hệ thống và ra quyết định; một AI coding agent (Claude Code) viết code theo một bản "điều lệ vận hành" tôi đặt ra.

Con người giữ quyền quyết định và kiểm chứng; agent giữ tốc độ thực thi. Chính sự phân vai đó là lý do một người có thể đưa gần 30 bản phát hành có kiểm chứng lên production, nhanh, mà không cần đội kỹ sư — và bản thân điều đó cũng là một năng lực.

Viết bởi Nguyễn Trung Tâm — AI Engineer & AI-native builder. Thêm dự án: nguyentrungtam-portfolio.pages.dev