6.3 FAISS, Pinecone, Weaviate 등의 통합
Chapter 6. Embedding API와 벡터 검색 기반 검색엔진 구축
6.3 FAISS, Pinecone, Weaviate 등의 통합
벡터 검색은 OpenAI의 Embedding API를 활용한 정보 검색 및 Q&A 시스템 구축에서 핵심적인 구성요소입니다. 이 절에서는 Embedding한 벡터 데이터를 저장하고, 빠르게 유사도를 기반으로 검색하기 위한 대표적인 벡터 DB와 라이브러리인 FAISS, Pinecone, Weaviate의 개념, 특징, 기본 사용법, OpenAI Embedding API와의 연동 방식을 자세하게 설명합니다.
6.3.1 벡터 검색이란?
기존의 키워드 기반 검색은 단어의 정확한 일치나 일부 매칭에 초점을 두지만, 벡터 검색은 문장이나 문서를 벡터로 변환한 후, 벡터 간의 유사도(예: 코사인 유사도)를 기준으로 가장 관련성 높은 데이터를 찾습니다.
OpenAI Embedding API를 통해 벡터화된 데이터는 float32 타입의 다차원 배열로 제공되며, 이를 빠르게 검색하려면 효율적인 검색 인덱스를 구성할 수 있는 벡터 DB가 필수적입니다.
OpenAI Embedding 예시:
from openai import OpenAI
client = OpenAI(api_key="..."
response = client.embeddings.create(
model="text-embedding-3-small",
input="오늘 날씨는 어때요?"
)
vector = response.data[0].embedding
이제 이 vector를 벡터 저장소에 저장하고 이후 검색에 활용해야 합니다.
6.3.2 FAISS: Facebook AI Similarity Search
FAISS란?
Facebook AI에서 개발한 오픈소스 라이브러리로, CPU와 GPU에서 대규모 벡터 데이터를 빠르게 검색할 수 있도록 설계됨
Standalone한 C++/Python 라이브러리 (서버 기능 없음)
고속 근사 근접 검색(ANN: Approximate Nearest Neighbor) 용도에 최적화됨
기본 특징:
다양한 인덱싱 전략 지원 (Flat, IVF, HNSW 등)
매우 빠른 검색 속도 (in-memory 기반)
Embedding 벡터 직접 저장/불러오기 가능
간단 예제:
import faiss
import numpy as np
# 예제 벡터 5개
vectors = np.random.random((5, 1536)).astype('float32')
# 인덱스 생성 (L2 거리 기준)
index = faiss.IndexFlatL2(1536) # 차원 수
index.add(vectors) # 벡터 저장
# 쿼리 벡터로 검색 (k=3개의 가장 유사한 결과 반환)
query = np.random.random((1, 1536)).astype('float32')
distances, indices = index.search(query, k=3)
print(indices)
장점:
로컬에서 빠르게 테스트 및 구축 가능
Embedding 크기와 검색 성능 제어가 쉬움
파이썬 환경과 잘 통합
단점:
데이터가 커질수록 메모리 부담
RESTful API나 분산 구조 없음 (서버 직접 구성 필요)
사용 적합 예:
PoC, 로컬 문서 검색기, 데스크탑 앱용 검색 등
초기 단계 빠른 구현 시 효율적
6.3.3 Pinecone: 클라우드 기반 벡터 DB
Pinecone은 벡터 검색에 최적화된 완전 관리형(manged) 클라우드 서비스입니다. 사용자는 복잡한 서버 구성 없이 REST API 또는 Python SDK만으로도 대규모 Embedding 데이터를 저장하고 검색할 수 있습니다.
핵심 특징:
완전 RESTful API 제공
Scalable: 수억 개 이상의 벡터 처리 가능
Persistent storage 지원: 데이터가 영속적으로 저장됨
필터 기반 검색 (metadata filtering)
Hybrid search (벡터 + 키워드 연계 가능)
설정 시 주요 구성 요소:
index: 벡터가 저장되는 공간 (특정 차원 수 지정 필요, 예: 1536)
namespace: 벡터를 그룹핑하는 논리적 단위
metadata: 각 벡터에 태그처럼 key-value 정보를 부여 가능
사용 예:
Pinecone 계정 생성 후 API 키 및 환경 설정
import pinecone
from openai import OpenAI
# Pinecone 초기화
pinecone.init(api_key="YOUR_PINECONE_API_KEY", environment="gcp-starter")
# 인덱스 생성 (Embedding 크기 지정이 중요)
pinecone.create_index("my-index", dimension=1536)
# 인덱스 연결
index = pinecone.Index("my-index")
Embedding 연동하여 벡터 삽입
# OpenAI Embedding 생성
response = client.embeddings.create(
model="text-embedding-3-small",
input="대한민국의 수도는 어디인가요?"
)
vec = response.data[0].embedding
# metadata 예시와 함께 저장
index.upsert([
("doc-1", vec, {"category": "지리", "lang": "ko"})
])
검색 요청
query = client.embeddings.create(
model="text-embedding-3-small",
input="서울은 어느 나라 수도인가요?"
).data[0].embedding
result = index.query(
vector=query,
top_k=3,
include_metadata=True
)
print(result)
장점:
구축 속도가 빠르며 운영이 간편함
대규모 데이터에도 강력한 성능 발휘
필터링 기능을 통한 정교한 검색 가능
단점:
유료 과금 모델 (용량, 호출 수 기준)
오프라인 사용 불가 (클라우드 의존적)
사용 적합 예:
대규모 문서 기반 FAQ 챗봇
서비스 수준의 Q&A 시스템
검색 정확도가 중요한 프로덕션 서비스
6.3.4 Weaviate: 오픈소스 및 클라우드 검색 엔진
Weaviate는 오픈소스로 제공되며, 벡터 검색 기능과 함께 내장 그래프 구조, 필터, 하이브리드(벡터+키워드) 검색 기능도 지원하는 고기능 DB입니다.
주요 특징:
REST & GraphQL API 동시지원
클래스 기반 스키마 시스템 (Document, FAQ 등 객체)
metadata 필터, 타임스탬프 검색
자체적으로 텍스트 임베딩 가능 (third-party 모델도 가능)
오픈소스 배포 + Weaviate Cloud (SaaS)
기본 구조:
Class: 데이터 대상 유형 (예: Article)
Object: 실제 데이터 전자적 표현
Vector: Embedding 결과값 저장
Property: Object의 메타데이터 정보
사용 예:
Docker로 로컬 서버 실행:
# docker-compose.yml
version: '3.4'
services:
weaviate:
image: semitechnologies/weaviate:latest
ports:
- "8080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 10
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
DEFAULT_VECTORIZER_MODULE: "none"
Python에서 삽입 및 검색 예:
import weaviate
import openai
# 연결
client = weaviate.Client("http://localhost:8080")
# 임베딩 생성
embedding = client.embeddings.create(
model="text-embedding-3-small",
input="세계에서 가장 높은 산은?"
).data[0].embedding
# 스키마 설정 + 데이터 삽입
client.schema.create_class({
"class": "Question",
"vectorIndexType": "hnsw",
"properties": [{"name": "text", "dataType": ["text"]}]
})
client.data_object.create({
"text": "에베레스트산은 세계에서 가장 높습니다."
}, class_name="Question", vector=embedding)
# 검색
query = client.embeddings.create(
model="text-embedding-3-small",
input="높은 산 이름 알려줘"
).data[0].embedding
near_vector = {"vector": query}
result = client.query.get("Question", ["text"]) \
.with_near_vector(near_vector) \
.with_limit(3) \
.do()
print(result)
장점:
로컬에서 시작해 클라우드 확장이 수월
GraphQL 기반 필터링 및 질의가 강력
구축 유연성: 자체 Embedding 서버 없이도 동작
단점:
학습 곡선이 있음 (스키마 설계 필요)
Docker 기반 초기화나 설정이 다소 복잡
사용 적합 예:
의미 기반 검색 서비스
다중 카테고리 문서 분류 시스템
개발자 친화적인 오픈소스 환경 활용 시
6.3.5 비교 요약
설치 방식
Python/C++ 라이브러리
클라우드 (SaaS)
오픈소스 or 클라우드
REST API 제공
❌
✅
✅ (REST + GraphQL)
스토리지
메모리 기반
영속 저장 (cloud)
영속 저장 (local/cloud 선택)
Embedding 내장
❌
❌
일부 내장 지원 (Vectorizer 모듈)
필터 검색
❌
✅ (metadata filter)
✅
적합 용도
개인/로컬용 검색기
SaaS 데이터서비스, 상용 챗봇
데이터 관계형 검색, 하이브리드 질의
6.3.6 OpenAI Embedding 기반 검색 실습 흐름 요약
다음은 OpenAI Embedding API와 벡터 DB 통합의 흐름 요약입니다:
사용 문서 또는 문장을 분할 (예: 문단 단위로)
각 문장을 Embedding API로 벡터화
벡터 DB (FAISS, Pinecone, Weaviate 등)에 저장
사용자 쿼리 입력 → Embedding 생성
벡터 DB에서 유사 벡터 검색
검색된 문장을 OpenAI의 GPT 모델로 전달해 응답
이 실습 흐름을 마치면, 독자는 문서 기반 질문응답 시스템, 키워드 없이 의미 기반 검색엔진, PDF 검색 챗봇 같은 응용 기술을 자유롭게 구현할 수 있게 됩니다.
다음 절(6.4)에서는 이러한 Embedding 검색결과와 GPT 응답을 결합한 실전형 문서 검색 챗봇 구축을 다루겠습니다.
Last updated