← Tất cả bài viếtHậu trường build

Tối đó tôi bật RAG thật cho sáu con bot cùng lúc — phần khó nhất không phải RAG

2026-07-10

Tối thứ Năm tuần trước tôi bật RAG thật cho sáu con bot spa cùng một lúc. 274 mẩu kiến thức được cắt nhỏ, nhúng thành vector 768 chiều, nằm trong Postgres. Bấm nút, sáu con bot đồng loạt "thông minh" hơn.

Và tôi học được một điều: dựng RAG là phần dễ. Phần khó là dạy bot biết khi nào nó không được phép thông minh.

RAG không còn là chuyện đáng sợ nữa

Vài tháng trước, nếu bạn hỏi tôi có dùng RAG cho bot spa không, tôi nói không — và tôi đã viết hẳn một bài giải thích (RAG hay Tool Use). Lý do đơn giản: một spa, bảng kiến thức nhỏ, nhét thẳng vào prompt là xong. Thêm vector database lúc đó là over-engineer.

Nhưng giờ tôi không phục vụ một spa nữa. Tôi phục vụ nhiều spa, mỗi spa có hàng trăm dịch vụ, mô tả liệu trình dài, chính sách riêng, giọng riêng. Nhồi tất cả vào prompt thì hoặc tốn tiền token kinh khủng, hoặc vượt cửa sổ ngữ cảnh. Đây đúng là lúc RAG có lý.

Phần công nghệ, thành thật mà nói, đã chín. Cắt tài liệu thành chunk, gọi một mô hình nhúng để biến mỗi chunk thành một vector, lưu vào Postgres với một index để tìm theo độ gần ngữ nghĩa. Khi khách hỏi, tôi nhúng câu hỏi của họ, tìm vài chunk gần nhất, đưa vào ngữ cảnh cho bot trả lời. Có thư viện sẵn cho từng bước. Một đêm là đủ để sáu con bot chạy được.

Nếu bài này dừng ở đây thì nó là một bài hướng dẫn kỹ thuật nhàm chán. Cái thú vị nằm ở chỗ tiếp theo.

Vấn đề thật: RAG quá giỏi việc "nghe có vẻ đúng"

RAG hoạt động bằng cách tìm đoạn văn gần nghĩa với câu hỏi, rồi để mô hình tổng hợp một câu trả lời từ đó. Nó tuyệt vời cho những câu hỏi có nhiều cách trả lời đúng: "liệu trình này hợp với da dầu không?", "công nghệ này khác gì cái kia?".

Nhưng cùng cơ chế đó trở thành cái bẫy khi khách hỏi: "liệu trình Thermage giá bao nhiêu?".

Vì RAG sẽ ngoan ngoãn tìm đoạn văn gần nghĩa nhất với câu hỏi về giá — và nếu trong kho có một mô tả cũ nhắc tới một con số khuyến mãi từ ba tháng trước, nó hoàn toàn có thể lôi con số đó ra, ghép vào một câu trả lời nghe rất trơn tru, rất tự tin. Khách không có cách nào biết con số đó đã hết hạn. Họ tin.

Đó là loại sai tệ nhất: không phải bot im lặng vì không biết, mà bot trả lời sai một cách thuyết phục. Với khách, "nhớ mang máng" về giá còn nguy hiểm hơn "không biết" — vì cái sau làm họ hỏi lại nhân viên, còn cái trước làm họ tin nhầm rồi mới vỡ lẽ.

Hai lớp, và một luật cứng ở giữa

Cách tôi giải không phải làm RAG khôn hơn. Mà là chia kiến thức của bot thành hai lớp với hai cơ chế khác hẳn nhau, và cấm chúng giẫm chân.

Lớp thứ nhất là catalog có cấu trúc — bảng giá, dịch vụ, đơn vị tính, còn áp dụng hay không. Đây là nguồn sự thật cho mọi dữ kiện phải đúng tuyệt đối. Bot đọc thẳng từ đây, đúng cái ô giá trong đúng cái dòng, không qua suy luận.

Lớp thứ hai là corpus ngữ nghĩa — chính cái 274 chunk vector kia. Mô tả liệu trình, tư vấn, chính sách, giọng thương hiệu. Đây là chỗ RAG được phép tỏa sáng, được phép "đủ tốt" thay vì "đúng tuyệt đối".

Luật cứng nằm chính giữa, và tôi ép nó vào cả code lẫn system prompt: dữ kiện chính xác — giá, tình trạng còn-hết, thông số cụ thể — không bao giờ được lấy từ vector. Chỉ từ catalog. Vector chỉ giúp bot tìm đúng dịch vụ để tư vấn; còn giá của dịch vụ đó thì luôn đọc lại từ database tại thời điểm trả lời.

(Vì sao tôi tin vào luật này đến mức cấm cả Claude tự nhớ giá, tôi đã kể riêng ở một bài khác — đây tôi muốn nói về chuyện vận hành nó cho nhiều bot.)

Cái khiến nó dùng được cho sáu bot, không phải một

Một luật trên giấy không giúp ích gì nếu mỗi lần thêm bot tôi phải đi dựng lại đường ống từ đầu. Nên thứ tôi thật sự dựng tuần trước không phải "RAG cho spa A" — mà là một tầng tri thức dùng chung mà mọi con bot cắm vào.

Có ba mảnh khiến nó nhân bản được:

Một là connector nguồn tri thức. Mỗi bot khai báo nguồn của nó — nhập tay qua cổng quản lý, hoặc một file xuất ra, hoặc sau này là một API sống. Cùng một đường ống nuốt cả ba.

Hai là ingest tự động. Tài liệu vào, được cắt theo loại (mô tả thì cắt theo đoạn, FAQ thì cắt theo cặp hỏi-đáp), nhúng thành vector, gắn nhãn đúng con bot sở hữu. Mỗi truy vấn vector luôn lọc theo đúng bot đó — không một chunk nào của spa này lọt sang câu trả lời của spa kia.

Ba là retrieve-then-fetch cho thứ vừa cần tìm vừa cần chính xác. Với kho lớn, tôi nhúng bản tóm tắt để tìm cho nhanh, nhưng khi cần con số thật thì quay lại lấy bản gốc đọc chính xác. Tìm bằng ngữ nghĩa, trả lời bằng sự thật.

Nhờ ba mảnh đó, bật con bot thứ sáu không khác bật con thứ nhất bao nhiêu: khai báo nguồn, chọn cách cắt, đặt ngưỡng. Không fork code, không bảng mới cho mỗi loại.

Bài học mang đi

Tôi từng nghĩ làm bot giỏi là làm nó biết nhiều hơn. Tuần trước dạy tôi điều ngược lại: làm bot đáng tin là dạy nó biết giới hạn của chính nó — chỗ nào được đoán, chỗ nào phải tra.

RAG cho bot một bộ não liên tưởng. Nhưng một bộ não liên tưởng mà không có ranh giới thì chính là một cái máy chế ra những câu trả lời nghe rất hay và sai rất êm. Cái nghề không nằm ở chỗ bật được RAG. Nó nằm ở chỗ bạn biết phần nào của câu trả lời được phép là xác suất, và phần nào bắt buộc là sự thật.

Sáu con bot bật RAG trong một đêm là phần tôi khoe được. Cái luật ngăn chúng nói nhảm về giá mới là phần tôi thật sự bán.

👉 Muốn tự tay xây một con bot và hiểu rõ khi nào nên để AI suy luận, khi nào bắt buộc tra database — đó là một trong những bài thực chiến trong mini-course miễn phí: Bot AI đầu tiên của bạn. Làm xong trong một buổi tối, có thứ chạy được ngay đêm đó.

Nhận bài thực chiến qua email

Mỗi tuần một bài về cách đưa AI vào doanh nghiệp thật. Miễn phí, huỷ bất cứ lúc nào.