ในโลกของ AI ยุคใหม่ การค้นหาข้อมูลแบบเดิมที่อาศัย keyword matching ไม่เพียงพออีกต่อไป ผมเคยเจอปัญหากับระบบ e-commerce ที่ลูกค้าพิมพ์ว่า "เสื้อผ้าสำหรับอากาศเย็น" แต่ระบบค้นหาไม่รู้จักคำว่า "แจ็คเก็ต" หรือ "โค้ท" ที่มีความหมายเดียวกัน จนกระทั่งได้ลองใช้ Milvus vector database ร่วมกับ semantic search และทุกอย่างเปลี่ยนไป
ทำไมต้อง Milvus Vector Database
Milvus เป็น open-source vector database ที่ออกแบบมาเพื่อจัดการข้อมูลเวกเตอร์ขนาดใหญ่โดยเฉพาะ รองรับการค้นหาแบบ Approximate Nearest Neighbor (ANN) ที่มีความเร็วสูงมาก และสามารถ scale ได้ตั้งแต่ small scale จนถึง enterprise level
กรณีการใช้งานจริงในองค์กร
- RAG (Retrieval-Augmented Generation) System — ระบบค้นหาเอกสารองค์กรที่สามารถเข้าใจความหมายของคำถาม แม้คำถามจะไม่ตรงกับ keyword ในเอกสารก็ตาม
- E-commerce Semantic Search — ระบบค้นหาสินค้าที่เข้าใจความต้องการของลูกค้า เช่น "ของขวัญสำหรับแม่" ก็จะแสดงสินค้าที่เกี่ยวข้องกับของขวัญแม่ได้
- Customer Service AI — แชทบอทที่สามารถค้นหาคำตอบจาก knowledge base ที่มีความหมายใกล้เคียงกับคำถามของลูกค้ามากที่สุด
การติดตั้ง Milvus ด้วย Docker Compose
สำหรับการพัฒนาและทดสอบ ผมแนะนำให้ใช้ Milvus Standalone ผ่าน Docker Compose เพราะติดตั้งง่ายและใช้ทรัพยากรน้อยกว่า cluster mode
# สร้างไดเรกทอรีสำหรับเก็บข้อมูล
mkdir -p milvus/volumes
สร้างไฟล์ docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
milvus-etcd:
container_name: milvus-etcd
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
volumes:
- ./volumes/etcd:/etcd
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
networks:
- milvus
milvus-minio:
container_name: milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
volumes:
- ./volumes/minio:/minio_data
command: minio server /minio_data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
networks:
- milvus
milvus-standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.3.3
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: milvus-etcd:2379
MINIO_ADDRESS: milvus-minio:9000
volumes:
- ./volumes/milvus:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- milvus-etcd
- milvus-minio
networks:
- milvus
networks:
milvus:
driver: bridge
EOF
รัน Milvus
docker-compose up -d
ตรวจสอบสถานะ
docker-compose ps
หลังจากรันคำสั่งแล้ว รอประมาณ 2-3 นาทีจน Milvus พร้อมใช้งาน สามารถตรวจสอบได้ด้วยคำสั่ง:
# ตรวจสอบ logs เพื่อดูว่า Milvus พร้อมหรือยัง
docker logs milvus-standalone 2>&1 | tail -50
ทดสอบเชื่อมต่อด้วย pymilvus
pip install pymilvus
python3 << 'EOF'
from pymilvus import connections
try:
connections.connect("default", host="localhost", port="19530")
print("✅ เชื่อมต่อ Milvus สำเร็จ!")
connections.disconnect("default")
except Exception as e:
print(f"❌ เชื่อมต่อไม่ได้: {e}")
EOF
การเชื่อมต่อและสร้าง Collection
ขั้นตอนต่อไปคือการสร้าง collection สำหรับเก็บ vector embeddings ก่อนอื่นต้องติดตั้ง library ที่จำเป็นก่อน:
pip install pymilvus langchain-openai langchain-community
สร้างไฟล์ setup_milvus.py
from pymilvus import connections, Collection, CollectionSchema, FieldSchema, DataType, utility
import numpy as np
เชื่อมต่อ Milvus
connections.connect("default", host="localhost", port="19530")
กำหนด schema สำหรับ collection
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="document_id", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1536), # dimension สำหรับ OpenAI ada-002
FieldSchema(name="metadata", dtype=DataType.VARCHAR, max_length=512)
]
schema = CollectionSchema(fields=fields, description="Document embeddings collection")
สร้าง collection
collection_name = "semantic_search_docs"
if utility.collection_exists(collection_name):
collection = Collection(collection_name)
collection.drop()
print(f"🗑️ ลบ collection เดิม: {collection_name}")
collection = Collection(name=collection_name, schema=schema)
print(f"✅ สร้าง collection ใหม่: {collection_name}")
สร้าง index เพื่อเพิ่มความเร็วในการค้นหา
index_params = {
"metric_type": "IP", # Inner Product สำหรับ cosine similarity
"index_type": "IVF_FLAT",
"params": {"nlist": 128}
}
index = {"embedding": index_params}
collection.create_index(field_name="embedding", index_params=index_params)
collection.load()
print(f"✅ สร้าง index และโหลด collection เรียบร้อย")
connections.disconnect("default")
การสร้าง Embeddings และ Semantic Search
ต่อไปจะเป็นการผสมผสาน Milvus กับ HolySheep AI สำหรับสร้าง embeddings และค้นหาด้วย semantic search โดย HolySheep AI มี API ที่เข้ากันได้กับ OpenAI format รองรับ model หลากหลาย เช่น GPT-4.1 ($8/MTok), Claude Sonnet 4.5 ($15/MTok), Gemini 2.5 Flash ($2.50/MTok) และ DeepSeek V3.2 ($0.42/MTok) ซึ่งมีความคุ้มค่ามากที่สุดในตลาดปัจจุบัน
import os
from openai import OpenAI
from pymilvus import connections, Collection
ตั้งค่า HolySheep AI API
os.environ["OPENAI_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY"
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.holysheep.ai/v1" # URL ของ HolySheep AI เท่านั้น
)
def create_embedding(text):
"""สร้าง embedding จาก HolySheep AI"""
response = client.embeddings.create(
model="text-embedding-ada-002",
input=text
)
return response.data[0].embedding
def semantic_search(query, top_k=5):
"""ค้นหาเอกสารที่มีความหมายใกล้เคียงที่สุด"""
connections.connect("default", host="localhost", port="19530")
collection = Collection("semantic_search_docs")
collection.load()
# สร้าง embedding จาก query
query_embedding = create_embedding(query)
# ค้นหาใน Milvus
search_params = {"metric_type": "IP", "params": {"nprobe": 10}}
results = collection.search(
data=[query_embedding],
anns_field="embedding",
param=search_params,
limit=top_k,
output_fields=["document_id", "text", "metadata"]
)
connections.disconnect("default")
return results
ทดสอบการค้นหา
query = "วิธีการคืนสินค้าต้องทำอย่างไร"
results = semantic_search(query)
print(f"🔍 ผลการค้นหาสำหรับ: '{query}'")
print("=" * 50)
for i, hit in enumerate(results[0], 1):
print(f"\n{i}. [Score: {hit.score:.4f}]")
print(f" Document ID: {hit.entity.get('document_id')}")
print(f" Text: {hit.entity.get('text')[:100]}...")
การสร้าง RAG Pipeline สำหรับ Q&A System
ต่อไปจะเป็นการนำ Milvus มาสร้างระบบ RAG ที่สมบูรณ์ ซึ่งเป็นกรณีการใช้งานที่พบบ่อย