Hệ thống tìm kiếm là trái tim của mọi nền tảng thương mại điện tử (TMĐT). Nếu khách hàng không thể tìm thấy sản phẩm, họ không thể mua nó. Tuy nhiên, hành vi tìm kiếm của người dùng hiện nay đã phát triển mạnh mẽ: từ việc gõ các từ khóa ngắn, cộc lốc (ví dụ: “giày chạy bộ nam”) sang việc đưa ra các truy vấn phức tạp, hướng tới mục tiêu cụ thể (ví dụ: “tìm cho tôi một đôi giày chạy địa hình chống nước cho nam, size 42, dưới 2 triệu, giao hàng trước ngày mai”). Trước những ý đồ đa diện này, các công cụ tìm kiếm truyền thống bắt đầu bộc lộ giới hạn.
Đây chính là điểm bùng phát mà chúng ta phải chuyển dịch từ Tìm kiếm Ngữ nghĩa (Semantic Search) sang Tìm kiếm dạng Agent (Agentic Search) — biến thanh tìm kiếm từ một “Thủ thư” thụ động thành một “Trợ lý mua sắm” chủ động.
📚 Bạn muốn xem bản triển khai đầy đủ? Bài viết này là tổng quan về mặt kiến trúc. Để xem hướng dẫn xây dựng thực tế gồm 6 phần (Golang + Qdrant + vòng lặp phản biện + vận hành production), hãy đọc trọn bộ Series Tìm kiếm TMĐT dạng Agent.
1. Sự sụp đổ của Tìm kiếm Từ vựng (Elasticsearch) trong kỷ nguyên AI
Trong thập kỷ qua, Elasticsearch (chạy trên thuật toán BM25) là tiêu chuẩn vàng. Tìm kiếm từ vựng (Lexical Search) hoạt động dựa trên việc khớp từ khóa chính xác theo nghĩa đen. Do đó, nó thất bại hoàn toàn khi đối mặt với các từ đồng nghĩa, lỗi chính tả hoặc các truy vấn mang tính khái niệm cao.
Gần đây, nhiều hệ thống đã nâng cấp lên Tìm kiếm Ngữ nghĩa (Semantic Search) bằng cách tích hợp Vector Embeddings vào Elasticsearch (tìm kiếm kNN). Tìm kiếm ngữ nghĩa giải quyết được bài toán ngữ cảnh (hiểu rằng “áo phao” và “áo ấm mùa đông” là tương tự nhau). Tuy nhiên, Semantic Search vẫn là một hệ thống thụ động: nó nhận một Vector Query, tính toán khoảng cách hình học, và trả về một danh sách tĩnh (quy trình 1 bước).
Nó hoàn toàn bất lực trước các logic nghiệp vụ (Business Logic) thời gian thực, chẳng hạn như: “Lọc bỏ các sản phẩm hiện không còn hàng tại Kho trung tâm”. Bạn không thể lưu trữ các dữ liệu biến động cao như tồn kho thời gian thực bên trong một Vector Database.
2. Agentic Search là gì? So sánh Semantic Search vs. Agentic AI
Tìm kiếm dạng Agent (Agentic Search) giải quyết vấn đề này bằng cách đưa một “Bộ não” (Tầng điều phối - Orchestration Layer) đứng trước các cơ sở dữ liệu. Thay vì truy vấn trực tiếp vào database, hệ thống sử dụng một Autonomous AI Agent (Agent tự trị).
Agentic Search chia nhỏ một truy vấn phức tạp thành một quy trình suy luận gồm nhiều bước:
Phân tích Ý định Người dùng (User Intent Parsing)
Khi nhận câu lệnh “giày chạy bộ chống nước dưới 2 triệu, giao ngay”, Agent không tìm kiếm lập tức. Nó phân tích truy vấn:
- Ý định Ngữ nghĩa (Semantic Intent): Giày chạy bộ, chống nước (Yêu cầu Vector Search để tìm độ tương đồng ngữ nghĩa).
- Bộ lọc cứng (Hard Filters): Giá < 2.000.000 VNĐ.
- Bộ lọc thời gian thực (Real-time Filters): Giao ngay (Yêu cầu gọi API của Inventory Service để kiểm tra tồn kho tại vị trí hiện tại của người dùng).
RAG kết hợp với Tool-calling
Sau khi phân tích, Agent không “đoán mò” kết quả. Nó sử dụng cơ chế Tool-calling (gọi công cụ/hàm). Agent ra lệnh cho backend Golang thực thi các hàm cụ thể:
- Gọi hàm
VectorSearch(query: "giày chạy bộ chống nước", limit: 50). - Lấy danh sách ID sản phẩm kết quả và gọi
FilterByPrice(ids, max_price: 2000000). - Gọi
CheckLiveInventory(ids, location: "kho_trung_tam"). - Cuối cùng, nó tổng hợp dữ liệu và trả về chính xác các sản phẩm kèm theo câu trả lời bằng ngôn ngữ tự nhiên.
3. Kiến trúc Hệ thống: Golang, LLM và Vector Database
Để xây dựng hệ thống AI Lai Tự Trị (Autonomous Hybrid AI) này cho nền tảng TMĐT, chúng ta cần một ranh giới kiến trúc sạch sẽ giữa Tầng Điều phối (Orchestrator) và Tầng Dữ liệu (Data Layer).
Biểu đồ Luồng Dữ liệu (Data Flow)
sequenceDiagram
participant User
participant API Gateway
participant Orchestrator (Golang)
participant LLM Agent (Gemini/OpenAI)
participant Vector DB (Qdrant)
participant RDBMS (PostgreSQL)
User->>API Gateway: "Tìm giày chạy địa hình size 42 có sẵn giao ngay"
API Gateway->>Orchestrator (Golang): Forward Query
Orchestrator (Golang)->>LLM Agent (Gemini/OpenAI): Parse ngữ cảnh & Gợi ý Công cụ
LLM Agent (Gemini/OpenAI)-->>Orchestrator (Golang): Trả về JSON yêu cầu gọi `VectorSearch` & `CheckStock`
par Thực thi Công cụ (Goroutines)
Orchestrator (Golang)->>Vector DB (Qdrant): VectorSearch("giày chạy địa hình")
Vector DB (Qdrant)-->>Orchestrator (Golang): Trả về Top 20 Product IDs
end
Orchestrator (Golang)->>RDBMS (PostgreSQL): CheckStock(IDs, size: 42, in_stock: true)
RDBMS (PostgreSQL)-->>Orchestrator (Golang): Trả về 3 IDs hợp lệ
Orchestrator (Golang)->>LLM Agent (Gemini/OpenAI): Cung cấp dữ liệu (3 sản phẩm) để tạo phản hồi
LLM Agent (Gemini/OpenAI)-->>Orchestrator (Golang): "Tôi tìm thấy 3 mẫu có sẵn size 42..."
Orchestrator (Golang)-->>User: Trả về JSON kết quả + Giao diện Chat
Tại sao Golang là Lựa chọn Hoàn hảo cho Agentic Backend
Hầu hết các bài hướng dẫn AI hiện nay đều được viết bằng Python (sử dụng LangChain/LlamaIndex). Tuy nhiên, khi đưa lên môi trường production của hệ thống TMĐT, điểm yếu về xử lý đồng thời (concurrency) của Python sẽ trở thành một điểm nghẽn khổng lồ.
Trong mô hình Agentic Search, hệ thống phải gọi đồng thời hàng chục Công cụ (APIs) phụ thuộc lẫn nhau. Goroutines của Golang giải quyết việc này một cách thanh lịch. Khả năng chạy song song các truy vấn Vector DB và SQL Database giúp giảm thiểu độ trễ tối đa. Hơn nữa, tính năng Type Safety (an toàn kiểu dữ liệu) nghiêm ngặt của Go đảm bảo các JSON Schema trả về từ LLM (khi tool-calling) ánh xạ hoàn hảo vào các Struct nội bộ, ngăn ngừa lỗi crash ứng dụng khi chạy. Các framework như Eino hoặc LangChainGo thường được tận dụng cho mục đích này.
4. Xây dựng Domain “Search Service” trong hệ thống Microservices
Nếu bạn từng tìm hiểu cách phân rã Domain Thương mại Điện tử, bạn sẽ biết Search Service không đứng độc lập; nó phụ thuộc vào luồng Nạp dữ liệu liên tục (Data Ingestion).
Data Ingestion: Chuyển đổi Metadata sản phẩm thành Vector Embeddings
Sản phẩm mới được tạo hoặc cập nhật liên tục qua RabbitMQ/Kafka. Search Service (Golang Worker) lắng nghe sự kiện ProductUpdated.
- Chia nhỏ (Chunking) dữ liệu văn bản: Tên sản phẩm, Mô tả, Danh mục, Thẻ tag.
- Đẩy các chunk này qua một Model Embedding để tạo Vector (mảng float 32-bit).
- Lưu trữ Vector kèm theo Metadata (Brand ID, Category ID) vào Qdrant hoặc Milvus. Lưu ý: Chúng tôi khuyên dùng Qdrant cho TMĐT vì tính năng “Filtered Vector Search” cực nhanh của nó, cho phép áp dụng các bộ lọc cứng (ví dụ: chỉ tìm trong danh mục “Giày”) trực tiếp tại tầng engine vector.
Tầng Điều phối: Xử lý Ngữ cảnh Đa luồng
Tại tầng điều phối, mã nguồn Golang định nghĩa các Công cụ (hàm) và xuất schema của chúng cho LLM:
// Định nghĩa Công cụ Kiểm tra Tồn kho cho LLM
var GetStockTool = llm.Tool{
Name: "get_realtime_stock",
Description: "Check real-time inventory of a list of products by warehouse location",
Parameters: jsonschema.Definition{
Type: jsonschema.Object,
Properties: map[string]jsonschema.Definition{
"product_ids": {Type: jsonschema.Array, Items: &jsonschema.Definition{Type: jsonschema.String}},
"warehouse_location": {Type: jsonschema.String},
},
Required: []string{"product_ids"},
},
}
Nhờ cơ chế này, thay vì tự bịa ra (ảo tưởng) số lượng tồn kho, LLM sẽ trả về một yêu cầu bắt buộc Golang thực thi hàm get_realtime_stock, đảm bảo độ chính xác tuyệt đối 100%.
5. Thử thách khi Triển khai: Độ trễ và Chi phí
Triển khai Agentic Search trên thực tế mang tới hai bài toán khó:
- Độ trễ (Latency): Việc chờ LLM suy luận và gọi công cụ có thể mất 1-3 giây. Giải pháp là sử dụng các mô hình gọn nhẹ, siêu nhanh như Gemini 3.5 Flash hoặc gpt-4o-mini làm “Routing Agent” ban đầu, kết hợp với luồng stream Server-Sent Events (SSE) trong Golang để trả về một phần kết quả lên giao diện UI của khách hàng ngay lập tức.
- Chi phí (Cost): Các API LLM tính phí theo token. Việc định tuyến mọi truy vấn qua LLM là không thực tế về mặt tài chính. Bạn bắt buộc phải thiết lập một Semantic Cache (như Redis) đứng trước Orchestrator. Nếu truy vấn của người dùng giống tới 95% với một truy vấn đã được lưu cache trước đó, hệ thống sẽ trả về kết quả cũ ngay lập tức, bỏ qua cả LLM và Vector DB.
Kết luận
Việc dịch chuyển từ Elasticsearch BM25 sang kiến trúc Tìm kiếm TMĐT hướng Agent không đơn thuần là thay thế cơ sở dữ liệu này bằng cơ sở dữ liệu khác. Đó là một sự thay đổi mô hình kiến trúc cốt lõi: phân tách rõ ràng năng lực Lưu trữ dữ liệu tĩnh (Vector DB/RDBMS) ra khỏi năng lực Suy luận (LLM Agent), và sử dụng Golang làm bộ điều phối mạnh mẽ, tốc độ cao làm cầu nối giữa hai bên.
Các hệ thống TMĐT trong tương lai sẽ từ bỏ các thanh tìm kiếm khô khan, cứng nhắc để chuyển sang mô hình Thương mại Hội thoại (Conversational Commerce) được cá nhân hóa cho từng khách hàng đơn lẻ.
FAQ
Agentic Search có thay thế hoàn toàn Elasticsearch không?
Không hoàn toàn. Đối với các tác vụ tổng hợp (tính tổng, đếm số lượng sản phẩm theo thương hiệu) hoặc khớp chính xác mã SKU, Elasticsearch vẫn không có đối thủ. Tuy nhiên, nếu bạn xây dựng một hệ thống mới hoàn toàn (greenfield), Qdrant kết hợp với một RDBMS (PostgreSQL) có thể thay thế Elasticsearch trong 90% các trường hợp tìm kiếm TMĐT.
Vector Database nào phù hợp nhất với Backend Golang?
Qdrant hiện là lựa chọn được ưu tiên vì nó được viết bằng Rust (cho hiệu năng cực cao) và cung cấp SDK client gRPC chính thức cho Golang rất tốt. Nếu dữ liệu của bạn đạt quy mô hàng tỷ vector, hãy cân nhắc sử dụng Milvus.
Chi phí API LLM có quá đắt đỏ cho Agentic Search không?
Sẽ rất đắt nếu bạn dùng các mô hình suy luận nặng nề cho mọi thao tác. Bí quyết nằm ở việc sử dụng các mô hình siêu nhanh/rẻ (như Gemini 3.5 Flash) kết hợp với cơ chế Semantic Caching quyết liệt. Việc này giúp giảm 90% chi phí, khoản tiền này hoàn toàn có thể được bù đắp dễ dàng bởi sự tăng vọt của Tỷ lệ Chuyển đổi (Conversion Rates) mua hàng.
📚 Series Triển khai Đầy đủ: Bài viết này đề cập đến tổng quan kiến trúc. Để tự tay xây dựng hệ thống này từ đầu đến cuối — từ điều phối Golang, nạp dữ liệu Qdrant cho đến các vòng lặp phản biện và tối ưu hóa chi phí production — hãy theo dõi Series Tìm kiếm TMĐT dạng Agent (gồm 6 phần chuyên sâu).