RAG với MongoDB + Claude — Xây chatbot có kiến thức
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Để đạt hiệu quả tối đa: Unified storage — Metadata và vectors trong cùng một collection Flexible schema — Lưu bất kỳ metadata nào cùng với. Nhiều người bỏ qua bước này và mất thời gian gấp đôi để đạt cùng kết quả.
- 2 Thành thật mà nói: Trong Atlas dashboard, vào Search tab và tạo Search Index với cấu hình sau: { "fields": { "type": "vector", "path":. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
- 3 Không thể bỏ qua: """ texts = doc"text" for doc in documents Tạo embeddings result = voyageclient.embed texts, model="voyage-3",. Đây là kiến thức nền tảng mà mọi người làm việc với AI đều cần hiểu rõ.
- 4 Hành động cụ thể: Ta xây dựng chatbot có "memory" về cuộc trò chuyện: conversations = db"conversations" def chatbotwithmemorysessionid,. Phần này hướng dẫn bạn cách triển khai thực tế, không chỉ lý thuyết suông.
- 5 Thành thật mà nói: Hãy xây dựng complete chatbot hỗ trợ khách hàng: Step 1: Index product knowledge base productkb = { "sourceid":. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
MongoDB Atlas Vector Search cho phép bạn lưu trữ embeddings trực tiếp trong MongoDB collection — không cần quản lý hạ tầng vector database riêng biệt. Kết hợp với Claude, bạn có thể xây dựng chatbot biết kiến thức từ data sẵn có trong MongoDB của mình.
Giải pháp này đặc biệt phù hợp khi bạn đã dùng MongoDB và muốn thêm khả năng AI mà không phải migrate data sang hệ thống khác.
Ưu điểm của MongoDB Vector Search
- Unified storage — Metadata và vectors trong cùng một collection
- Flexible schema — Lưu bất kỳ metadata nào cùng với vector
- Aggregation pipeline — Kết hợp vector search với MongoDB queries phức tạp
- Atlas managed — Không cần self-manage infrastructure
Cài đặt môi trường
pip install anthropic pymongo voyageai python-dotenv
Tạo MongoDB Atlas cluster và bật Vector Search. Trong Atlas dashboard, vào Search tab và tạo Search Index với cấu hình sau:
{
"fields": [
{
"type": "vector",
"path": "embedding",
"numDimensions": 1024,
"similarity": "cosine"
}
]
}
Kết nối MongoDB và thiết lập collection
import os
from pymongo import MongoClient
import voyageai
import anthropic
# Kết nối MongoDB Atlas
mongo_client = MongoClient(os.environ.get("MONGODB_URI"))
db = mongo_client["knowledge_base"]
collection = db["documents"]
# Khởi tạo clients
voyage_client = voyageai.Client(api_key=os.environ.get("VOYAGE_API_KEY"))
claude_client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
print("Connected to MongoDB Atlas")
Indexing: Lưu documents với embeddings
Trong MongoDB RAG, mỗi document có thêm field embedding chứa vector:
def embed_and_store(documents):
"""
documents: list of dicts với "text", "title", "source", etc.
"""
texts = [doc["text"] for doc in documents]
# Tạo embeddings
result = voyage_client.embed(
texts,
model="voyage-3",
input_type="document"
)
# Thêm embedding vào mỗi document
docs_to_insert = []
for doc, embedding in zip(documents, result.embeddings):
doc_with_embedding = {
**doc,
"embedding": embedding
}
docs_to_insert.append(doc_with_embedding)
# Upsert vào MongoDB
for doc in docs_to_insert:
collection.update_one(
{"source_id": doc.get("source_id", doc.get("title"))},
{"$set": doc},
upsert=True
)
print(f"Stored {len(docs_to_insert)} documents with embeddings")
Vector Search với MongoDB Aggregation Pipeline
MongoDB Vector Search sử dụng $vectorSearch operator trong aggregation pipeline:
def vector_search(query, top_k=5, filter_query=None):
"""
Tìm kiếm semantic trong MongoDB collection.
filter_query: MongoDB query để pre-filter documents
"""
# Embed câu hỏi
query_embedding = voyage_client.embed(
[query],
model="voyage-3",
input_type="query"
).embeddings[0]
# Xây dựng aggregation pipeline
vector_search_stage = {
"$vectorSearch": {
"index": "vector_index",
"path": "embedding",
"queryVector": query_embedding,
"numCandidates": top_k * 10, # Candidate pool lớn hơn cho accuracy
"limit": top_k
}
}
# Thêm pre-filter nếu có
if filter_query:
vector_search_stage["$vectorSearch"]["filter"] = filter_query
pipeline = [
vector_search_stage,
{
"$project": {
"_id": 0,
"title": 1,
"text": 1,
"source": 1,
"category": 1,
"score": {"$meta": "vectorSearchScore"}
}
}
]
results = list(collection.aggregate(pipeline))
return results
Xây dựng Chatbot với Memory
Điểm mạnh của MongoDB là lưu trữ conversation history cùng với documents. Ta xây dựng chatbot có "memory" về cuộc trò chuyện:
conversations = db["conversations"]
def chatbot_with_memory(session_id, user_message):
"""Chatbot RAG với conversation history."""
# Lấy conversation history
history = list(conversations.find(
{"session_id": session_id},
{"_id": 0, "role": 1, "content": 1}
).sort("timestamp", 1).limit(10))
# Retrieve relevant context
relevant_docs = vector_search(user_message, top_k=3)
context = "
---
".join([
f"[{doc.get('title', 'Unknown')}]
{doc['text']}"
for doc in relevant_docs
])
# Xây dựng system prompt
system_prompt = f"""Bạn là trợ lý AI thông minh của công ty.
Trả lời dựa trên kiến thức được cung cấp. Nếu không biết, hãy thành thật.
=== KIẾN THỨC LIÊN QUAN ===
{context}"""
# Format messages với history
messages = []
for msg in history:
messages.append({"role": msg["role"], "content": msg["content"]})
messages.append({"role": "user", "content": user_message})
# Gọi Claude
response = claude_client.messages.create(
model="claude-haiku-4-5",
max_tokens=1024,
system=system_prompt,
messages=messages
)
assistant_reply = response.content[0].text
# Lưu vào conversation history
import datetime
conversations.insert_many([
{
"session_id": session_id,
"role": "user",
"content": user_message,
"timestamp": datetime.datetime.utcnow()
},
{
"session_id": session_id,
"role": "assistant",
"content": assistant_reply,
"timestamp": datetime.datetime.utcnow()
}
])
return assistant_reply
Kết hợp Vector Search với MongoDB Queries
Đây là điểm mạnh độc đáo của MongoDB — bạn có thể kết hợp semantic search với traditional queries:
def smart_search(query, category=None, date_from=None):
"""
Hybrid: Vector search + MongoDB filter.
"""
filter_conditions = {}
if category:
filter_conditions["category"] = {"$eq": category}
if date_from:
filter_conditions["created_at"] = {"$gte": date_from}
results = vector_search(
query=query,
top_k=5,
filter_query=filter_conditions if filter_conditions else None
)
return results
# Ví dụ: Tìm tài liệu kỹ thuật từ tháng 1/2024 trở đi
import datetime
tech_docs = smart_search(
query="Cách cài đặt API?",
category="technical",
date_from=datetime.datetime(2024, 1, 1)
)
Ví dụ thực tế: Customer Support Chatbot
Hãy xây dựng complete chatbot hỗ trợ khách hàng:
# Step 1: Index product knowledge base
product_kb = [
{
"source_id": "product-001",
"title": "Hướng dẫn cài đặt",
"text": "Để cài đặt sản phẩm, tải file installer từ trang chủ...",
"category": "installation",
"version": "2.0"
},
{
"source_id": "product-002",
"title": "Xử lý lỗi phổ biến",
"text": "Lỗi 404: Kiểm tra lại đường dẫn API...",
"category": "troubleshooting",
"version": "2.0"
}
]
embed_and_store(product_kb)
# Step 2: Test chatbot
session = "user_12345"
reply1 = chatbot_with_memory(session, "Làm thế nào để cài đặt sản phẩm?")
print(f"Bot: {reply1}")
reply2 = chatbot_with_memory(session, "Nếu gặp lỗi thì sao?")
print(f"Bot: {reply2}")
Performance và Scaling
Index configuration
Tăng numCandidates để cải thiện recall, nhưng sẽ tăng latency. Khuyến nghị: numCandidates = top_k * 10.
Compound index
Tạo compound index trên các fields thường dùng để filter, kết hợp với vector search sẽ nhanh hơn đáng kể.
Batch embedding
Luôn embed theo batch thay vì từng document một để giảm API calls và tăng throughput.
Kết luận
MongoDB Atlas Vector Search + Claude là combo mạnh mẽ cho những team đã dùng MongoDB. Không cần học thêm infrastructure mới, chỉ cần thêm embedding pipeline và bạn có ngay hệ thống RAG production-ready.
Tiếp theo, khám phá LlamaIndex + Claude để xây dựng RAG pipeline với nhiều tính năng nâng cao hơn, hoặc đọc về RAG với Pinecone nếu bạn cần managed vector database chuyên dụng.
Bài viết liên quan
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.




