Weaviate의 오브젝트 지향 스키마, 모듈화 아키텍처, 내장 벡터라이저, 멀티테넌시, BlockMax WAND 하이브리드 검색, GraphQL API, 배포 옵션과 Python 실습을 다룹니다.
Weaviate는 Go로 작성된 오픈소스 벡터 검색 엔진입니다. 2019년에 출시된 이후 활발한 커뮤니티와 함께 발전해 왔으며, 오픈소스 벡터 데이터베이스 중 가장 풍부한 기능을 제공합니다.
Pinecone이 "벡터 저장소"에 가깝다면, Weaviate는 "벡터 기반 애플리케이션 플랫폼"에 가깝습니다. 임베딩 생성부터 검색, 생성형 AI 통합까지 하나의 시스템 안에서 처리할 수 있습니다.
Weaviate에서는 데이터를 **컬렉션(Collection)**으로 구성합니다. 각 컬렉션은 **프로퍼티(property)**를 가진 오브젝트들의 집합입니다. 이는 관계형 DB의 테이블과 유사하지만, 각 오브젝트에 벡터가 자동으로 연결됩니다.
import weaviate
import weaviate.classes.config as wc
client = weaviate.connect_to_local()
# 컬렉션 생성 (스키마 정의)
articles = client.collections.create(
name="Article",
vectorizer_config=wc.Configure.Vectorizer.text2vec_openai(
model="text-embedding-3-small"
),
properties=[
wc.Property(
name="title",
data_type=wc.DataType.TEXT,
),
wc.Property(
name="content",
data_type=wc.DataType.TEXT,
),
wc.Property(
name="category",
data_type=wc.DataType.TEXT,
skip_vectorization=True # 이 필드는 벡터화에서 제외
),
wc.Property(
name="published_year",
data_type=wc.DataType.INT,
skip_vectorization=True
),
]
)Weaviate의 skip_vectorization 옵션은 매우 유용합니다. 카테고리, 날짜, ID 같은 메타데이터 필드는 벡터화에 포함시키면 오히려 검색 품질이 떨어질 수 있습니다. 의미적 검색 대상이 되는 필드만 벡터화하는 것이 좋습니다.
Weaviate의 핵심 강점 중 하나는 모듈 기반 아키텍처입니다. 주요 모듈 유형은 다음과 같습니다.
텍스트나 이미지를 벡터로 변환하는 모듈입니다.
| 모듈 | 제공자 | 특징 |
|---|---|---|
| text2vec-openai | OpenAI | text-embedding-3 시리즈 |
| text2vec-cohere | Cohere | embed-multilingual 시리즈 |
| text2vec-transformers | 셀프호스트 | 오픈소스 모델 직접 실행 |
| multi2vec-clip | OpenAI | 텍스트+이미지 멀티모달 |
검색 결과를 기반으로 LLM 응답을 생성하는 모듈입니다. Weaviate 내에서 RAG 파이프라인을 구현할 수 있습니다.
# Weaviate 내장 RAG (Generative Search)
articles = client.collections.get("Article")
response = articles.generate.near_text(
query="벡터 데이터베이스의 장점",
limit=5,
grouped_task="다음 검색 결과를 바탕으로 벡터 데이터베이스의 장점을 요약해 주세요."
)
print(response.generated) # LLM이 생성한 요약
for obj in response.objects:
print(f"- {obj.properties['title']}")초기 검색 결과를 재순위화하는 모듈입니다. Cohere Rerank나 Cross-Encoder 기반 리랭커를 사용하여 검색 정확도를 높일 수 있습니다.
articles = client.collections.get("Article")
# 배치 삽입 (내장 벡터라이저가 자동으로 임베딩 생성)
with articles.batch.dynamic() as batch:
for item in data_list:
batch.add_object(
properties={
"title": item["title"],
"content": item["content"],
"category": item["category"],
"published_year": item["year"]
}
# 벡터를 직접 제공할 수도 있음
# vector=item["embedding"]
)articles = client.collections.get("Article")
# 텍스트 기반 시맨틱 검색
response = articles.query.near_text(
query="ANN 알고리즘의 성능 비교",
limit=10,
filters=weaviate.classes.query.Filter.by_property("category").equal("algorithm"),
return_metadata=weaviate.classes.query.MetadataQuery(
distance=True,
certainty=True
)
)
for obj in response.objects:
print(f"Title: {obj.properties['title']}")
print(f"Distance: {obj.metadata.distance:.4f}")Weaviate는 네이티브 멀티테넌시를 지원합니다. 각 테넌트는 독립적인 저장 공간을 가지며, 테넌트별로 활성화/비활성화가 가능합니다. 비활성 테넌트의 데이터는 디스크로 오프로드되어 메모리를 절약합니다.
from weaviate.classes.tenants import Tenant, TenantActivityStatus
# 멀티테넌시 활성화된 컬렉션 생성
client.collections.create(
name="UserDocument",
multi_tenancy_config=wc.Configure.multi_tenancy(enabled=True),
# ... 나머지 설정
)
collection = client.collections.get("UserDocument")
# 테넌트 추가
collection.tenants.create([
Tenant(name="tenant-a"),
Tenant(name="tenant-b"),
])
# 특정 테넌트에 데이터 삽입
tenant_a = collection.with_tenant("tenant-a")
tenant_a.data.insert(properties={"title": "테넌트 A의 문서"})
# 특정 테넌트에서 검색 (다른 테넌트 데이터 접근 불가)
results = tenant_a.query.near_text(query="검색어", limit=5)
# 비활성 테넌트 (디스크로 오프로드, 메모리 절약)
collection.tenants.update([
Tenant(name="tenant-b", activity_status=TenantActivityStatus.INACTIVE)
])SaaS 애플리케이션에서 수천 개의 고객을 지원해야 한다면, Weaviate의 멀티테넌시가 매우 효과적입니다. 비활성 테넌트를 콜드 스토리지로 내리면 활성 사용자만큼의 리소스만 사용합니다. Pinecone의 네임스페이스보다 더 세밀한 리소스 관리가 가능합니다.
Weaviate의 하이브리드 검색은 BlockMax WAND 알고리즘을 사용합니다. 이는 BM25 키워드 검색의 효율적인 구현 기법으로, 불필요한 문서 평가를 건너뛰어 속도를 높입니다.
하이브리드 검색에서는 벡터 검색(시맨틱)과 BM25 검색(키워드)의 결과를 Reciprocal Score Fusion(RSF) 또는 Relative Score Fusion으로 결합합니다.
articles = client.collections.get("Article")
# 하이브리드 검색
response = articles.query.hybrid(
query="HNSW 인덱스 파라미터 튜닝",
alpha=0.75, # 0 = 키워드만, 1 = 벡터만, 0.75 = 벡터 비중 높게
limit=10,
fusion_type="relative_score"
)
for obj in response.objects:
print(f"Title: {obj.properties['title']}")
print(f"Score: {obj.metadata.score:.4f}")alpha 파라미터로 벡터 검색과 키워드 검색의 비중을 조절합니다. 일반적으로 0.5-0.8 사이에서 최적의 결과를 얻으며, 도메인과 쿼리 유형에 따라 실험적으로 튜닝해야 합니다.
관리형 클라우드 서비스입니다. 서버리스 클러스터와 전용 클러스터를 선택할 수 있습니다.
| 티어 | 비용 | 특징 |
|---|---|---|
| 서버리스 | 무료 ~ $25+/월 | 자동 스케일링, 빠른 시작 |
| 전용 | $50 ~ $400+/월 | 고성능, SLA 보장 |
| BYOC | 커스텀 | 자체 클라우드에 배포, 데이터 주권 |
Docker나 Kubernetes로 직접 운영할 수 있습니다.
version: '3.4'
services:
weaviate:
image: cr.weaviate.io/semitechnologies/weaviate:1.27.0
ports:
- "8080:8080"
- "50051:50051" # gRPC
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,reranker-cohere'
OPENAI_APIKEY: ${OPENAI_APIKEY}
CLUSTER_HOSTNAME: 'node1'
volumes:
- weaviate_data:/var/lib/weaviate
volumes:
weaviate_data:셀프호스트 시 프로덕션 환경에서는 반드시 인증을 활성화하고, 백업 전략을 수립해야 합니다. AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: true는 개발 환경에서만 사용하세요. OIDC나 API 키 인증을 설정하는 것을 권장합니다.
이번 장에서는 Weaviate의 오브젝트 지향 스키마, 모듈화 아키텍처, 멀티테넌시, 하이브리드 검색을 살펴보았습니다. Weaviate는 내장 벡터라이저와 생성 모듈을 통해 별도의 임베딩 파이프라인 없이도 완전한 AI 검색 시스템을 구축할 수 있다는 점이 큰 장점입니다. GraphQL 기반의 유연한 쿼리 API와 네이티브 멀티테넌시는 복잡한 애플리케이션 요구사항을 충족시킵니다.
다음 장에서는 Qdrant와 pgvector 두 가지 특화 솔루션을 비교 분석합니다. Rust 기반의 고성능 엔진 Qdrant와 PostgreSQL 생태계의 벡터 확장 pgvector의 강점과 적합한 사용 사례를 다루겠습니다.
이 글이 도움이 되셨나요?
Rust 기반 고성능 벡터 엔진 Qdrant의 페이로드 필터링, 명명된 벡터, 하이브리드 배포를 분석하고, PostgreSQL 확장 pgvector의 트랜잭션 일관성과 pgvectorscale 성능을 비교합니다.
Pinecone의 완전 관리형 아키텍처, 서버리스와 팟 배포 모델, 네임스페이스, 메타데이터 필터링, 하이브리드 검색, 보안 컴플라이언스, Python SDK 실습을 다룹니다.
시맨틱 검색과 키워드 검색을 결합하는 하이브리드 검색의 원리, BM25+벡터 퓨전 전략, Reciprocal Rank Fusion, 리랭커 통합, 프레임워크별 구현 방법을 다룹니다.