Khi từ khóa không còn đủ để “hiểu” người dùng
Hơn nửa năm trước, mình nhận một task khá “xương”: Xây dựng công cụ tìm kiếm cho kho tài liệu hơn 50.000 văn bản luật. Ban đầu, mình dùng Full-text search truyền thống trên PostgreSQL. Kết quả trả về rất tệ. Khi nhân viên tìm “quy định về thuế”, hệ thống hoạt động ổn. Nhưng nếu họ gõ “nghĩa vụ tài chính với nhà nước”, kết quả trả về là con số 0 tròn trĩnh, dù hai khái niệm này gần như là một.
Vấn đề nằm ở chỗ các database truyền thống chỉ xử lý dữ liệu dựa trên ký tự (lexical). Để khắc phục, mình thử chuyển sang Vector Search thuần túy với thư viện FAISS. Tuy nhiên, Vector Search lại gặp điểm yếu ngược lại. Nó tìm theo ngữ nghĩa rất hay nhưng lại thường xuyên bỏ lỡ các kết quả chính xác tuyệt đối như mã văn bản “Thông tư 123/2023”.
Tại sao Vector Search đơn thuần vẫn chưa đủ?
Sau nhiều lần thử sai, mình nhận ra hệ thống RAG (Retrieval-Augmented Generation) hiện đại cần sự giao thoa của cả hai: Keyword Search để tìm chính xác và Vector Search để hiểu ngữ cảnh. Đây chính là lúc Hybrid Search chứng minh giá trị.
Nếu bạn tự build hệ thống vector database từ đầu, bạn sẽ vấp phải ba hố vôi lớn:
- Đồng bộ hóa dữ liệu giữa text và vector cực kỳ phức tạp.
- Quản lý các embedding model (OpenAI, HuggingFace) tốn nhiều tài nguyên code.
- Khả năng mở rộng khi dữ liệu chạm mốc hàng triệu bản ghi.
Mình từng dùng qua Qdrant và Pinecone. Tuy nhiên, Weaviate là lựa chọn cuối cùng cho các dự án ưu tiên tính linh hoạt và khả năng tự host (on-premise) để bảo mật dữ liệu.
Weaviate: Hệ sinh thái lưu trữ cho ứng dụng AI
Weaviate không đơn thuần là nơi lưu trữ vector. Điểm cộng lớn nhất sau 6 tháng thực chiến là các AI module tích hợp sẵn. Thay vì phải viết code gọi API OpenAI để lấy vector rồi mới lưu vào DB, Weaviate sẽ tự động thực hiện quy trình này thông qua các vectorizers.
Cơ chế Hybrid Search của nó kết hợp thuật toán BM25 và Vector Search theo trọng số alpha linh hoạt. Đây chính là “vũ khí” giúp mình giải quyết triệt để bài toán tìm kiếm tài liệu pháp lý phức tạp trước đó.
Cài đặt Weaviate với Docker trong 5 phút
Để triển khai nhanh và ổn định, Docker là lựa chọn tối ưu nhất. Dưới đây là file docker-compose.yml mình đã tinh gọn để chạy Weaviate kèm module text2vec-openai.
version: '3.4'
services:
weaviate:
command:
- --host
- 0.0.0.0
- --port
- '8080'
- --scheme
- http
image: semitechnologies/weaviate:1.24.1
ports:
- 8080:8080
- 50051:50051
restart: on-failure:0
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'text2vec-openai'
ENABLE_MODULES: 'text2vec-openai,generative-openai,qna-openai'
CLUSTER_HOSTNAME: 'node1'
OPENAI_APIKEY: 'sk-xxxxxxxxxxxxxxxxxxxxxxxx' # Thay bằng key của bạn
Mẹo nhỏ: Nếu muốn vọc vạch miễn phí, bạn hãy thay text2vec-openai bằng text2vec-transformers để chạy model embedding local. Sau đó, khởi động hệ thống bằng lệnh:
docker-compose up -d
Thực thi Hybrid Search với Python Client
Khi container đã sẵn sàng, chúng ta sử dụng thư viện weaviate-client để thao tác. Dưới đây là cách định nghĩa Schema và thực hiện truy vấn Hybrid Search thực tế.
import weaviate
import json
client = weaviate.Client("http://localhost:8080")
# 1. Khởi tạo Schema
class_obj = {
"class": "Document",
"vectorizer": "text2vec-openai",
"properties": [
{"name": "title", "dataType": ["text"]},
{"name": "content", "dataType": ["text"]}
]
}
if not client.schema.exists("Document"):
client.schema.create_class(class_obj)
# 2. Truy vấn Hybrid Search
# alpha = 1.0: Thuần Vector | alpha = 0.0: Thuần Keyword
query_text = "nghĩa vụ tài chính với nhà nước"
result = (
client.query
.get("Document", ["title", "content"])
.with_hybrid(query=query_text, alpha=0.5)
.with_limit(3)
.do()
)
print(json.dumps(result, indent=2, ensure_ascii=False))
Kinh nghiệm thực chiến sau 6 tháng vận hành
Khi đưa Weaviate lên production, có những chi tiết kỹ thuật mà tài liệu hướng dẫn thường bỏ qua. Dưới đây là những điểm bạn cần lưu ý để tránh hệ thống bị treo đột ngột.
1. Bài toán quản lý tài nguyên
Vector database rất “đói” RAM. Index HNSW luôn nằm trên bộ nhớ để đảm bảo tốc độ tìm kiếm dưới 100ms. Với 1 triệu vector (1536 chiều từ OpenAI), bạn nên chuẩn bị ít nhất 16GB RAM. Nếu dùng nén Product Quantization (PQ), con số này có thể giảm xuống còn 4-8GB nhưng sẽ đánh đổi một chút về độ chính xác.
2. Chiến lược Backup
Đừng bao giờ chỉ copy folder data của Docker. Weaviate hỗ trợ module backup riêng cho S3 hoặc GCS. Mình từng mất trắng dữ liệu một lần do lỗi ổ cứng và chỉ có bản backup trên S3 mới cứu vãn được tình hình.
3. Tinh chỉnh chỉ số Alpha
Không có công thức chung cho alpha. Với dữ liệu luật, mình ưu tiên ngữ nghĩa nên để mức 0.7. Ngược lại, với dữ liệu thương mại điện tử cần tìm mã SKU, mình thường hạ xuống 0.3. Bạn cần chạy thử nghiệm trên tập dữ liệu mẫu để tìm ra điểm ngọt (sweet spot).
4. Tối ưu hóa RAG với Generative Module
Hãy tận dụng module generative-openai. Thay vì lấy kết quả search rồi mới gửi sang GPT-4, bạn có thể yêu cầu Weaviate tổng hợp câu trả lời ngay trong một query. Cách làm này giúp giảm đáng kể độ trễ mạng và làm code sạch hơn.
Lời kết
Weaviate là công cụ mạnh mẽ nhưng không phải là chiếc đũa thần. Bạn cần hiểu rõ đặc thù dữ liệu để cấu hình index cho đúng. Triển khai qua Docker là bước đệm hoàn hảo để bạn đưa các ứng dụng AI từ môi trường demo ra thực tế một cách chuyên nghiệp.

