본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
AI Generated
2025. 12. 18. · 47 Views
벡터 데이터베이스 완벽 가이드
AI와 LLM 시대에 필수적인 벡터 데이터베이스를 처음부터 차근차근 배워봅니다. 전통적인 데이터베이스와의 차이점부터 AWS OpenSearch Serverless, Pinecone, PostgreSQL pgvector까지 실무에서 바로 활용할 수 있는 내용을 담았습니다.
목차
- 벡터_DB란_무엇인가
- Amazon_OpenSearch_Serverless
- Pinecone_소개
- PostgreSQL_pgvector
- 벡터_DB_선택_기준
- Bedrock_지원_벡터_DB
1. 벡터 DB란 무엇인가
어느 날 김개발 씨는 회사에서 새로운 프로젝트를 맡게 되었습니다. AI 챗봇 서비스를 만드는 일이었습니다.
선배 개발자가 말했습니다. "이번엔 벡터 데이터베이스를 사용해야 해요." 김개발 씨는 궁금해졌습니다.
지금까지 MySQL, PostgreSQL을 써왔는데, 벡터 데이터베이스는 또 무엇일까요?
벡터 데이터베이스는 데이터를 숫자 배열인 벡터 형태로 저장하고 검색하는 특별한 데이터베이스입니다. 전통적인 데이터베이스가 정확한 키워드 매칭으로 데이터를 찾는다면, 벡터 데이터베이스는 의미의 유사성으로 데이터를 찾습니다.
AI 시대에 필수적인 기술로, 텍스트, 이미지, 음성 등 다양한 데이터의 의미를 수치화하여 저장합니다.
다음 코드를 살펴봅시다.
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 텍스트를 벡터로 표현한 예시
# "고양이"라는 단어의 벡터 (실제로는 수백~수천 차원)
cat_vector = np.array([0.8, 0.3, 0.1, 0.9])
# "강아지"라는 단어의 벡터
dog_vector = np.array([0.7, 0.4, 0.2, 0.85])
# "자동차"라는 단어의 벡터
car_vector = np.array([0.1, 0.2, 0.9, 0.1])
# 코사인 유사도로 의미적 거리 계산
similarity_cat_dog = cosine_similarity([cat_vector], [dog_vector])[0][0]
similarity_cat_car = cosine_similarity([cat_vector], [car_vector])[0][0]
print(f"고양이와 강아지 유사도: {similarity_cat_dog:.4f}") # 높은 값
print(f"고양이와 자동차 유사도: {similarity_cat_car:.4f}") # 낮은 값
김개발 씨는 입사 1년 차 개발자입니다. 지금까지 전통적인 관계형 데이터베이스를 사용해서 웹 서비스를 만들어왔습니다.
그런데 이번 프로젝트는 조금 달랐습니다. 회사는 고객 문의에 자동으로 답변하는 AI 챗봇을 만들기로 했습니다.
기존 데이터베이스로는 한계가 있다는 것을 금방 깨달았습니다. 고객이 "배송이 언제 오나요?"라고 물어봐도, "배송 시간이 궁금합니다"라고 물어봐도 같은 답변을 해야 하는데, 정확한 키워드 매칭으로는 불가능했습니다.
그렇다면 벡터 데이터베이스란 정확히 무엇일까요? 쉽게 비유하자면, 벡터 데이터베이스는 마치 사람의 기억과 같습니다.
우리는 어떤 개념을 떠올릴 때 정확한 단어가 아니라 비슷한 의미로도 기억을 찾아냅니다. "저번에 먹었던 그 맛있는 음식"이라고 하면 "파스타"가 떠오르는 것처럼요.
벡터 데이터베이스도 이처럼 의미의 유사성으로 데이터를 찾아냅니다. 전통적인 데이터베이스가 없던 시절은 아니지만, AI와 LLM이 보편화되기 전에는 어땠을까요?
개발자들은 키워드 기반 검색에 의존했습니다. 사용자가 입력한 단어와 정확히 일치하는 데이터만 찾을 수 있었습니다.
"배송 시간"으로 검색하면 결과가 나오지만 "언제 도착하나요"로 검색하면 결과가 없었습니다. 더 큰 문제는 다국어 서비스였습니다.
같은 의미라도 언어가 다르면 완전히 다른 쿼리를 작성해야 했습니다. 바로 이런 문제를 해결하기 위해 벡터 데이터베이스가 등장했습니다.
벡터 데이터베이스를 사용하면 의미 기반 검색이 가능해집니다. 사용자가 어떤 단어를 사용하든 비슷한 의미라면 관련 정보를 찾아줍니다.
또한 다국어 지원도 자연스럽게 됩니다. 같은 의미는 어떤 언어로 표현되든 비슷한 벡터 값을 갖기 때문입니다.
무엇보다 AI 모델과의 완벽한 통합이라는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 4번째 줄을 보면 "고양이"라는 개념을 숫자 배열로 표현했습니다. 실제로는 OpenAI의 임베딩 모델을 사용하면 1536차원의 벡터가 생성됩니다.
이 부분이 핵심입니다. 다음으로 7번째 줄에서는 "강아지"를 벡터로 표현합니다.
고양이와 비슷한 동물이므로 벡터 값도 비슷합니다. 13번째 줄에서는 코사인 유사도라는 수학적 방법으로 두 벡터의 유사성을 계산합니다.
결과는 0에서 1사이의 값으로 나타나며, 1에 가까울수록 의미가 유사합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 이커머스 추천 시스템을 개발한다고 가정해봅시다. 사용자가 "여름 휴가에 입을 편한 옷"이라고 검색하면, 벡터 데이터베이스는 "린넨 셔츠", "면 반바지", "샌들" 같은 상품을 추천합니다.
정확히 "여름", "휴가", "옷"이라는 단어가 없어도 의미적으로 연관된 상품을 찾아내는 것입니다. Netflix, Spotify, Amazon 같은 기업에서 이런 기술을 적극적으로 사용하고 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 데이터를 벡터 데이터베이스에 저장하려는 것입니다.
사용자의 이메일, 주문번호 같은 정형 데이터는 전통적인 데이터베이스가 훨씬 효율적입니다. 벡터 데이터베이스는 비정형 데이터나 의미 검색이 필요한 경우에만 사용해야 합니다.
또한 벡터 생성에는 AI 모델이 필요하므로 추가 비용과 시간이 발생한다는 점도 고려해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
선배의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 그래서 AI 서비스에는 벡터 데이터베이스가 필요한 거군요!" 벡터 데이터베이스를 제대로 이해하면 더 똑똑한 검색 시스템과 추천 시스템을 만들 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 벡터 데이터베이스는 의미 검색이 필요할 때만 사용하고, 정형 데이터는 전통적인 DB를 사용하세요
- 임베딩 모델 선택이 중요합니다. OpenAI, Cohere, AWS Bedrock 등 다양한 옵션을 비교해보세요
- 벡터 차원이 높을수록 정확도는 높지만 저장 공간과 검색 속도가 느려집니다. 적절한 균형을 찾으세요
2. Amazon OpenSearch Serverless
김개발 씨는 벡터 데이터베이스의 개념을 이해했습니다. 이제 실제로 구축할 차례입니다.
회사는 AWS를 주로 사용하고 있었습니다. 선배가 추천했습니다.
"Amazon OpenSearch Serverless를 써보세요. 서버 관리 없이 바로 시작할 수 있어요." 김개발 씨는 노트북을 열고 AWS 콘솔에 접속했습니다.
Amazon OpenSearch Serverless는 AWS에서 제공하는 완전 관리형 검색 및 분석 서비스입니다. 서버를 프로비저닝하거나 관리할 필요 없이 벡터 검색 기능을 바로 사용할 수 있습니다.
자동 스케일링과 고가용성을 제공하며, AWS의 다른 서비스들과 완벽하게 통합됩니다. 특히 k-NN 알고리즘을 지원하여 빠른 유사도 검색이 가능합니다.
다음 코드를 살펴봅시다.
from opensearchpy import OpenSearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth
import boto3
# AWS 인증 설정
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key,
'ap-northeast-2', 'aoss', session_token=credentials.token)
# OpenSearch Serverless 클라이언트 생성
client = OpenSearch(
hosts=[{'host': 'your-collection.ap-northeast-2.aoss.amazonaws.com', 'port': 443}],
http_auth=awsauth,
use_ssl=True,
connection_class=RequestsHttpConnection
)
# 벡터 인덱스 생성
index_body = {
"settings": {"index.knn": True},
"mappings": {
"properties": {
"content": {"type": "text"},
"vector": {"type": "knn_vector", "dimension": 1536}
}
}
}
client.indices.create(index="documents", body=index_body)
# 문서 벡터 저장
doc = {
"content": "AWS 벡터 데이터베이스 사용법",
"vector": [0.1, 0.2, 0.3, ...] # 1536차원 벡터
}
client.index(index="documents", body=doc)
김개발 씨는 클라우드 서비스를 사용한 경험이 있었습니다. EC2 인스턴스를 띄우고, RDS를 설정하고, 모니터링을 구성하는 일련의 과정을 알고 있었습니다.
하지만 이번에는 달랐습니다. 선배가 말했습니다.
"OpenSearch Serverless는 설정이 정말 간단해요. 컬렉션 하나만 만들면 바로 사용할 수 있습니다." 김개발 씨는 반신반의했습니다.
정말 그렇게 쉬울까요? 그렇다면 OpenSearch Serverless란 정확히 무엇일까요?
쉽게 비유하자면, OpenSearch Serverless는 마치 전기 콘센트와 같습니다. 우리는 전기를 사용하기 위해 발전소를 지을 필요가 없습니다.
그냥 플러그를 꽂으면 전기가 나옵니다. OpenSearch Serverless도 마찬가지입니다.
서버 크기를 고민하거나, 클러스터를 구성하거나, 장애 대응을 준비할 필요가 없습니다. 필요한 만큼만 사용하고 비용을 지불합니다.
서버리스가 아닌 전통적인 OpenSearch를 사용한다면 어땠을까요? 개발자들은 먼저 클러스터 크기를 결정해야 했습니다.
인스턴스 타입은 무엇으로 할지, 노드는 몇 개로 할지 고민이 많았습니다. 트래픽이 갑자기 늘어나면 수동으로 스케일 아웃을 해야 했습니다.
더 큰 문제는 야간이나 주말에 장애가 발생하는 경우였습니다. 누군가는 항상 대기하고 있어야 했습니다.
바로 이런 문제를 해결하기 위해 OpenSearch Serverless가 등장했습니다. OpenSearch Serverless를 사용하면 자동 스케일링이 가능해집니다.
트래픽이 늘어나면 자동으로 용량이 증가하고, 줄어들면 자동으로 축소됩니다. 또한 고가용성도 기본으로 제공됩니다.
AWS가 알아서 여러 가용 영역에 데이터를 복제하고 관리합니다. 무엇보다 운영 부담 제로라는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 6번째 줄을 보면 AWS 인증 정보를 가져옵니다.
OpenSearch Serverless는 IAM 기반 인증을 사용하므로 안전합니다. 이 부분이 핵심입니다.
11번째 줄에서는 OpenSearch 클라이언트를 생성합니다. 일반 OpenSearch와 달리 포트는 항상 443(HTTPS)을 사용합니다.
19번째 줄에서 knn_vector 타입을 지정하는데, 이것이 벡터 검색을 가능하게 만듭니다. 마지막으로 31번째 줄에서 실제 문서와 벡터를 저장합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 기업 내부 문서 검색 시스템을 개발한다고 가정해봅시다.
수천 개의 PDF, 워드 문서, 이메일이 있습니다. 직원들이 "작년 예산 회의록"이라고 검색하면 정확한 파일명이 아니어도 관련 문서들을 찾아줘야 합니다.
OpenSearch Serverless를 사용하면 모든 문서를 벡터로 변환하여 저장하고, 의미 기반 검색을 제공할 수 있습니다. AWS Lambda와 연동하면 새 문서가 S3에 업로드될 때 자동으로 벡터화하여 인덱싱할 수도 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 비용을 고려하지 않는 것입니다.
OpenSearch Serverless는 사용한 만큼만 비용을 내지만, 데이터 양이 많거나 쿼리가 빈번하면 생각보다 비용이 높을 수 있습니다. 따라서 CloudWatch로 비용을 모니터링하고, 필요 없는 컬렉션은 즉시 삭제해야 합니다.
또한 프로덕션 환경에서는 데이터 접근 정책을 반드시 설정해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
코드를 실행한 김개발 씨는 감탄했습니다. "정말 5분 만에 벡터 검색이 가능하네요!" OpenSearch Serverless를 제대로 이해하면 빠르게 프로토타입을 만들고 운영 부담 없이 서비스를 런칭할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 개발 환경에서는 작은 컬렉션으로 시작하고, 프로덕션 배포 전에 비용을 미리 계산하세요
- AWS Bedrock과 함께 사용하면 벡터 생성부터 검색까지 완전한 파이프라인을 구축할 수 있습니다
- 데이터 접근 정책과 네트워크 정책을 꼭 설정하여 보안을 강화하세요
3. Pinecone 소개
며칠 후 김개발 씨는 기술 블로그를 읽다가 Pinecone이라는 서비스를 발견했습니다. 많은 스타트업들이 사용하고 있었습니다.
선배에게 물었습니다. "OpenSearch와 Pinecone은 뭐가 다른가요?" 선배가 웃으며 대답했습니다.
"Pinecone은 처음부터 벡터 검색만을 위해 만들어진 서비스예요."
Pinecone은 벡터 검색에 특화된 완전 관리형 데이터베이스 서비스입니다. 별도의 인프라 구성 없이 API 호출만으로 벡터를 저장하고 검색할 수 있습니다.
수십억 개의 벡터를 밀리초 단위로 검색할 수 있는 성능을 자랑하며, 메타데이터 필터링과 하이브리드 검색을 지원합니다. OpenAI, Anthropic 같은 LLM과의 통합도 매우 간편합니다.
다음 코드를 살펴봅시다.
import pinecone
from pinecone import Pinecone, ServerlessSpec
# Pinecone 초기화
pc = Pinecone(api_key="your-api-key")
# 인덱스 생성 (한 번만 실행)
pc.create_index(
name="documents",
dimension=1536, # OpenAI embedding 차원
metric="cosine", # 유사도 측정 방식
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# 인덱스 연결
index = pc.Index("documents")
# 벡터 저장 (메타데이터 포함)
vectors_to_upsert = [
("doc1", [0.1, 0.2, ...], {"title": "AWS 가이드", "category": "cloud"}),
("doc2", [0.3, 0.4, ...], {"title": "Python 튜토리얼", "category": "programming"})
]
index.upsert(vectors=vectors_to_upsert)
# 벡터 검색 (메타데이터 필터 적용)
query_vector = [0.15, 0.25, ...]
results = index.query(
vector=query_vector,
top_k=5,
filter={"category": {"$eq": "cloud"}}, # cloud 카테고리만 검색
include_metadata=True
)
print(results)
김개발 씨는 OpenSearch Serverless로 프로토타입을 완성했습니다. 하지만 코드를 작성하면서 조금 복잡하다고 느꼈습니다.
인덱스 설정, 매핑 정의, 쿼리 작성까지 신경 쓸 것이 많았습니다. 그러던 중 동료 개발자가 Pinecone을 추천했습니다.
"저는 Pinecone을 쓰는데, 정말 간단해요. API 몇 줄이면 끝나요." 김개발 씨는 호기심이 생겼습니다.
그렇다면 Pinecone이란 정확히 무엇일까요? 쉽게 비유하자면, Pinecone은 마치 전문 택배 서비스와 같습니다.
일반 택배는 다양한 물품을 배송하지만, 전문 택배는 특정 물품(예: 꽃, 케이크)만 배송하면서 더 빠르고 안전하게 처리합니다. Pinecone도 마찬가지입니다.
일반적인 검색 엔진은 텍스트 검색, 로그 분석 등 여러 기능을 제공하지만, Pinecone은 오직 벡터 검색만을 위해 최적화되어 있습니다. 벡터 검색 전용 서비스가 없던 시절에는 어땠을까요?
개발자들은 범용 데이터베이스에 벡터를 저장했습니다. Elasticsearch나 PostgreSQL에 확장 플러그인을 설치하고, 복잡한 설정을 해야 했습니다.
벡터 개수가 백만 개를 넘어가면 검색 속도가 느려졌습니다. 더 큰 문제는 스케일링이었습니다.
데이터가 계속 늘어나면 클러스터를 직접 확장하고 샤딩을 구성해야 했습니다. 바로 이런 문제를 해결하기 위해 Pinecone이 등장했습니다.
Pinecone을 사용하면 초고속 검색이 가능해집니다. 수억 개의 벡터 중에서도 밀리초 단위로 유사한 벡터를 찾아냅니다.
또한 메타데이터 필터링도 제공됩니다. 벡터 유사도와 함께 카테고리, 날짜, 태그 같은 조건도 동시에 적용할 수 있습니다.
무엇보다 완벽한 API 중심 설계라는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 5번째 줄을 보면 API 키만으로 간단히 초기화합니다. AWS처럼 복잡한 IAM 설정이 필요 없습니다.
이 부분이 핵심입니다. 8번째 줄에서는 인덱스를 생성하는데, 차원과 측정 방식만 지정하면 됩니다.
서버리스 스펙을 사용하면 자동으로 스케일링됩니다. 19번째 줄에서 메타데이터를 함께 저장하는 것을 주목하세요.
이렇게 하면 나중에 필터링이 가능합니다. 26번째 줄에서는 벡터 검색과 동시에 메타데이터 필터를 적용합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 패션 쇼핑몰의 이미지 검색 기능을 개발한다고 가정해봅시다.
사용자가 마음에 드는 옷 사진을 업로드하면 비슷한 스타일의 상품을 추천해줘야 합니다. 이미지를 벡터로 변환하여 Pinecone에 저장하고, 사용자의 이미지도 벡터로 만들어 검색합니다.
여기에 가격대, 브랜드, 재고 여부 같은 메타데이터 필터를 추가하면 더 정확한 추천이 가능합니다. Shopify, Notion, Replit 같은 기업들이 Pinecone을 실제로 사용하고 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 무료 티어로 프로덕션을 운영하려는 것입니다.
Pinecone의 무료 티어는 100만 개의 벡터만 저장할 수 있고, 성능도 제한적입니다. 프로덕션 환경에서는 반드시 유료 플랜을 사용해야 합니다.
또한 Pinecone은 클라우드 서비스이므로 민감한 데이터는 암호화하거나 별도의 보안 조치를 취해야 합니다. 데이터 주권이 중요한 경우 한국 리전이 없다는 점도 고려해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. Pinecone을 테스트한 김개발 씨는 놀라움을 감추지 못했습니다.
"정말 코드 10줄로 벡터 검색이 되네요!" Pinecone을 제대로 이해하면 복잡한 인프라 없이 빠르게 벡터 검색 서비스를 구축할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 무료 티어로 먼저 테스트하고, 프로덕션에서는 유료 플랜을 사용하세요
- LangChain이나 LlamaIndex 같은 프레임워크와 통합하면 개발이 더 쉬워집니다
- 벡터 업데이트가 빈번하면 배치로 처리하는 것이 비용 효율적입니다
4. PostgreSQL pgvector
프로젝트가 진행되면서 김개발 씨는 고민에 빠졌습니다. 이미 회사는 PostgreSQL을 주 데이터베이스로 사용하고 있었습니다.
사용자 정보, 주문 데이터 등이 모두 PostgreSQL에 있습니다. 벡터 검색을 위해 별도의 데이터베이스를 추가하는 것이 부담스러웠습니다.
선배가 해결책을 제시했습니다. "PostgreSQL에 pgvector 확장을 설치하면 벡터 검색도 할 수 있어요."
pgvector는 PostgreSQL에 벡터 저장 및 검색 기능을 추가하는 오픈소스 확장입니다. 기존 PostgreSQL 데이터베이스에 설치만 하면 벡터와 일반 데이터를 함께 저장하고 쿼리할 수 있습니다.
별도의 벡터 데이터베이스 없이 SQL 쿼리로 벡터 검색이 가능하며, 트랜잭션과 ACID 속성도 그대로 유지됩니다. 중소규모 프로젝트나 이미 PostgreSQL을 사용 중인 경우에 이상적입니다.
다음 코드를 살펴봅시다.
-- pgvector 확장 설치 (데이터베이스에서 한 번만 실행)
CREATE EXTENSION vector;
-- 벡터 컬럼이 있는 테이블 생성
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
category VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
embedding VECTOR(1536) -- 1536차원 벡터
);
-- 벡터 인덱스 생성 (검색 속도 향상)
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
-- 문서와 벡터 함께 저장
INSERT INTO documents (title, content, category, embedding)
VALUES (
'PostgreSQL 벡터 검색 가이드',
'pgvector를 사용하면 PostgreSQL에서 벡터 검색이 가능합니다.',
'database',
'[0.1, 0.2, 0.3, ...]' -- 1536개의 실수 배열
);
-- 벡터 유사도 검색 (코사인 유사도 사용)
SELECT title, category, 1 - (embedding <=> '[0.15, 0.25, ...]') AS similarity
FROM documents
WHERE category = 'database' -- 일반 SQL 조건과 함께 사용 가능
ORDER BY embedding <=> '[0.15, 0.25, ...]' -- 유사도 순 정렬
LIMIT 5;
김개발 씨는 벡터 데이터베이스의 장점을 충분히 이해했습니다. 하지만 현실적인 문제가 있었습니다.
사용자가 "배송 관련 문의"를 검색하면 과거 문의 내역도 함께 보여줘야 하는데, 이 데이터는 PostgreSQL에 있었습니다. 두 개의 데이터베이스를 조인하는 것은 불가능했습니다.
API 레벨에서 두 번 쿼리하고 합치는 방법밖에 없었습니다. 코드가 복잡해지고 성능도 걱정되었습니다.
그렇다면 pgvector란 정확히 무엇일까요? 쉽게 비유하자면, pgvector는 마치 스마트폰 케이스와 같습니다.
새 폰을 살 필요 없이 기존 폰에 케이스를 씌워 기능을 추가합니다. pgvector도 마찬가지입니다.
새로운 데이터베이스를 도입할 필요 없이 이미 사용 중인 PostgreSQL에 벡터 검색 기능을 추가합니다. 기존의 모든 기능은 그대로 유지되면서 벡터 검색만 추가되는 것입니다.
pgvector가 없던 시절에는 어땠을까요? 개발자들은 벡터 검색을 위해 별도의 시스템을 구축해야 했습니다.
Elasticsearch나 Pinecone 같은 전용 서비스를 추가하고, 데이터를 동기화하는 파이프라인을 만들었습니다. 사용자 데이터는 PostgreSQL에, 벡터는 다른 곳에 저장되어 관리가 복잡했습니다.
더 큰 문제는 데이터 일관성이었습니다. PostgreSQL에서 데이터가 업데이트되면 벡터 데이터베이스도 업데이트해야 하는데, 이 과정에서 오류가 발생하기 쉬웠습니다.
바로 이런 문제를 해결하기 위해 pgvector가 등장했습니다. pgvector를 사용하면 단일 데이터베이스 관리가 가능해집니다.
사용자 정보, 주문 데이터, 벡터가 모두 한 곳에 있어 관리가 간편합니다. 또한 SQL의 강력한 기능을 그대로 사용할 수 있습니다.
JOIN, WHERE, GROUP BY 같은 익숙한 SQL 문법으로 벡터 검색을 수행합니다. 무엇보다 트랜잭션 보장이라는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 2번째 줄을 보면 간단한 SQL 명령으로 확장을 설치합니다.
이것만으로 PostgreSQL이 벡터를 다룰 수 있게 됩니다. 이 부분이 핵심입니다.
11번째 줄에서는 VECTOR(1536) 타입을 지정합니다. 일반 컬럼과 똑같이 취급됩니다.
15번째 줄에서 ivfflat 인덱스를 생성하는데, 이것이 빠른 벡터 검색을 가능하게 합니다. 27번째 줄을 주목하세요.
<=> 연산자가 코사인 거리를 계산합니다. WHERE 절에서 일반 SQL 조건과 함께 사용할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 고객 지원 시스템을 개발한다고 가정해봅시다.
고객이 문의를 남기면 과거 유사한 문의를 찾아 자동으로 답변을 제안해야 합니다. pgvector를 사용하면 고객 정보, 문의 내역, 문의 내용의 벡터를 모두 같은 테이블에 저장할 수 있습니다.
하나의 SQL 쿼리로 "같은 고객의 과거 문의 중 의미가 유사한 것"을 찾을 수 있습니다. Discord, Supabase, Neon 같은 서비스가 pgvector를 실제로 활용하고 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 pgvector가 전문 벡터 데이터베이스만큼 빠를 것이라 기대하는 것입니다.
pgvector는 편리하지만 수억 개의 벡터를 다루는 대규모 시스템에서는 Pinecone이나 OpenSearch보다 느릴 수 있습니다. 따라서 벡터 개수가 천만 개 이하인 중소규모 프로젝트에 적합합니다.
또한 인덱스 생성 시간이 오래 걸릴 수 있으므로 배치 작업으로 처리하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
pgvector를 적용한 김개발 씨는 만족스러웠습니다. "이제 하나의 데이터베이스로 모든 것을 관리할 수 있네요!" pgvector를 제대로 이해하면 기존 인프라를 활용하면서도 벡터 검색 기능을 추가할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 벡터 개수가 많지 않다면 pgvector가 가장 경제적이고 관리하기 쉬운 선택입니다
- AWS RDS PostgreSQL에서도 pgvector를 지원하므로 관리형 서비스로 사용할 수 있습니다
- 인덱스는 데이터 삽입 후 한 번에 생성하는 것이 효율적입니다
5. 벡터 DB 선택 기준
김개발 씨는 세 가지 벡터 데이터베이스를 모두 테스트해봤습니다. 각각 장단점이 명확했습니다.
이제 실제 프로젝트에 어떤 것을 선택해야 할지 결정해야 했습니다. 선배가 조언했습니다.
"정답은 없어요. 프로젝트의 요구사항에 따라 달라집니다." 김개발 씨는 요구사항을 정리하기 시작했습니다.
벡터 데이터베이스 선택은 프로젝트 규모, 예산, 기존 인프라, 성능 요구사항에 따라 달라집니다. pgvector는 소규모 프로젝트와 기존 PostgreSQL 사용자에게 적합하고, Pinecone은 빠른 개발과 극한의 성능이 필요할 때 좋으며, OpenSearch Serverless는 AWS 생태계와의 통합이 중요할 때 선택합니다.
각 솔루션의 특징을 이해하고 프로젝트에 맞는 최적의 선택을 해야 합니다.
다음 코드를 살펴봅시다.
# 벡터 DB 선택 의사결정 트리를 코드로 표현
def choose_vector_database(project_specs):
"""프로젝트 요구사항에 따른 벡터 DB 추천"""
# 이미 PostgreSQL을 사용 중인가?
if project_specs['uses_postgresql']:
# 벡터 개수가 1천만 개 미만인가?
if project_specs['vector_count'] < 10_000_000:
return "PostgreSQL + pgvector"
# AWS 생태계를 주로 사용하는가?
if project_specs['cloud_provider'] == 'AWS':
# Bedrock, Lambda 등과 통합이 필요한가?
if project_specs['needs_aws_integration']:
return "Amazon OpenSearch Serverless"
# 극한의 성능이 필요한가?
if project_specs['vector_count'] > 100_000_000:
return "Pinecone Enterprise"
# 빠른 프로토타이핑이 목표인가?
if project_specs['project_stage'] == 'prototype':
return "Pinecone Free Tier"
# 기본 추천: 관리 부담이 적은 Pinecone
return "Pinecone Standard"
# 사용 예시
my_project = {
'uses_postgresql': True,
'vector_count': 5_000_000,
'cloud_provider': 'AWS',
'needs_aws_integration': False,
'project_stage': 'production'
}
recommendation = choose_vector_database(my_project)
print(f"추천 벡터 DB: {recommendation}") # PostgreSQL + pgvector
김개발 씨는 의사결정 스프레드시트를 만들었습니다. 각 벡터 데이터베이스의 장점과 단점을 나열했습니다.
그런데 복잡했습니다. 어떤 기준으로 선택해야 할까요?
팀장님이 물었습니다. "우리 프로젝트에 가장 중요한 것이 뭐죠?" 김개발 씨는 생각했습니다.
빠른 개발? 저렴한 비용?
높은 성능? 모든 것을 만족시킬 수는 없었습니다.
그렇다면 벡터 데이터베이스 선택 기준이란 정확히 무엇일까요? 쉽게 비유하자면, 벡터 데이터베이스 선택은 마치 교통수단을 고르는 것과 같습니다.
자전거, 자동차, 기차, 비행기 중 무엇이 좋을까요? 정답은 없습니다.
거리가 짧으면 자전거가 좋고, 시간이 급하면 비행기가 좋습니다. 벡터 데이터베이스도 마찬가지입니다.
프로젝트의 상황에 따라 최적의 선택이 달라집니다. 벡터 데이터베이스 선택 가이드가 없던 시절에는 어땠을까요?
개발자들은 유행하는 기술을 따라갔습니다. 어떤 기업이 Pinecone을 쓴다고 하면 무조건 Pinecone을 선택했습니다.
프로젝트 요구사항을 제대로 분석하지 않았습니다. 그 결과 과도한 비용을 지불하거나, 성능이 부족하거나, 관리가 어려운 시스템을 만들었습니다.
더 큰 문제는 나중에 변경하기 어렵다는 것이었습니다. 바로 이런 문제를 해결하기 위해 체계적인 선택 기준이 필요합니다.
선택 기준을 명확히 하면 비용 최적화가 가능해집니다. 필요 이상으로 고가의 솔루션을 쓰지 않아도 됩니다.
또한 개발 속도 향상도 얻을 수 있습니다. 팀이 익숙한 기술을 활용하면 학습 시간이 줄어듭니다.
무엇보다 장기적 유지보수를 고려한 현명한 선택이라는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 7번째 줄을 보면 가장 먼저 PostgreSQL 사용 여부를 확인합니다. 이미 사용 중이라면 pgvector가 가장 간단한 선택입니다.
이 부분이 핵심입니다. 13번째 줄에서는 클라우드 제공자를 확인합니다.
AWS를 주로 쓴다면 OpenSearch Serverless가 통합이 쉽습니다. 19번째 줄에서 벡터 개수를 체크합니다.
1억 개 이상이라면 전문 벡터 데이터베이스가 필수입니다. 23번째 줄에서는 프로젝트 단계를 확인합니다.
프로토타입이라면 무료 티어로 시작하는 것이 현명합니다. 실제 현업에서는 어떻게 결정할까요?
예를 들어 스타트업에서 MVP를 개발한다고 가정해봅시다. 예산이 제한적이고, 빠른 출시가 중요합니다.
이미 팀이 PostgreSQL을 사용하고 있고, 예상 벡터 개수는 백만 개 정도입니다. 이런 경우 pgvector가 최선의 선택입니다.
추가 비용이 없고, 팀이 익숙한 기술이며, 성능도 충분합니다. 반대로 대기업에서 글로벌 서비스를 개발한다면 어떨까요?
수억 명의 사용자, 수억 개의 벡터, 밀리초 단위의 응답 속도가 필요합니다. 이런 경우 Pinecone Enterprise나 OpenSearch Serverless가 적합합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 처음부터 완벽한 선택을 하려는 것입니다.
프로젝트는 계속 변합니다. 처음에는 작은 프로젝트였다가 나중에 대규모 서비스로 성장할 수 있습니다.
따라서 마이그레이션 가능성을 항상 염두에 두어야 합니다. pgvector로 시작해서 나중에 Pinecone으로 전환하는 것도 충분히 가능합니다.
처음부터 과도하게 투자하는 것보다, 현재 필요한 수준에서 시작하는 것이 현명합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
요구사항을 정리한 김개발 씨는 결정을 내렸습니다. "우리는 pgvector로 시작하고, 나중에 필요하면 확장하자!" 벡터 데이터베이스 선택 기준을 제대로 이해하면 프로젝트에 최적화된 기술 스택을 구축할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 프로토타입 단계에서는 무료 티어나 pgvector로 시작하고, 프로덕션에서 업그레이드하세요
- 벡터 개수, QPS(초당 쿼리 수), 지연시간 요구사항을 명확히 정의하세요
- 마이그레이션 비용을 고려하되, 과도한 최적화는 피하세요
6. Bedrock 지원 벡터 DB
프로젝트가 거의 완성되어 갈 때쯤 김개발 씨는 AWS Bedrock을 알게 되었습니다. Claude, Llama 같은 AI 모델을 API로 사용할 수 있는 서비스였습니다.
선배가 말했습니다. "Bedrock과 벡터 데이터베이스를 연동하면 RAG 시스템을 쉽게 만들 수 있어요." 김개발 씨는 Bedrock이 어떤 벡터 데이터베이스를 지원하는지 찾아봤습니다.
AWS Bedrock은 다양한 파운데이션 모델을 제공하는 완전 관리형 AI 서비스로, 벡터 데이터베이스와의 통합을 통해 RAG(Retrieval Augmented Generation) 시스템을 구축할 수 있습니다. Bedrock Knowledge Base는 OpenSearch Serverless, Pinecone, pgvector를 포함한 여러 벡터 데이터베이스를 기본 지원합니다.
데이터 소스를 연결하고 몇 번의 클릭만으로 자동으로 벡터를 생성하고 저장하며 검색합니다.
다음 코드를 살펴봅시다.
import boto3
from botocore.exceptions import ClientError
# Bedrock 클라이언트 생성
bedrock = boto3.client('bedrock-agent', region_name='us-east-1')
# Knowledge Base 생성 (OpenSearch Serverless 사용)
try:
response = bedrock.create_knowledge_base(
name='company-documents-kb',
description='회사 내부 문서 검색을 위한 Knowledge Base',
roleArn='arn:aws:iam::123456789012:role/BedrockKBRole',
knowledgeBaseConfiguration={
'type': 'VECTOR',
'vectorKnowledgeBaseConfiguration': {
'embeddingModelArn': 'arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1'
}
},
storageConfiguration={
'type': 'OPENSEARCH_SERVERLESS',
'opensearchServerlessConfiguration': {
'collectionArn': 'arn:aws:aoss:us-east-1:123456789012:collection/abc123',
'vectorIndexName': 'bedrock-knowledge-base-index',
'fieldMapping': {
'vectorField': 'vector',
'textField': 'text',
'metadataField': 'metadata'
}
}
}
)
kb_id = response['knowledgeBase']['knowledgeBaseId']
print(f"Knowledge Base 생성 완료: {kb_id}")
# Knowledge Base를 사용한 검색
bedrock_runtime = boto3.client('bedrock-agent-runtime', region_name='us-east-1')
search_response = bedrock_runtime.retrieve(
knowledgeBaseId=kb_id,
retrievalQuery={'text': '회사 휴가 정책이 어떻게 되나요?'},
retrievalConfiguration={
'vectorSearchConfiguration': {'numberOfResults': 5}
}
)
# 검색 결과 출력
for result in search_response['retrievalResults']:
print(f"관련 문서: {result['content']['text']}")
print(f"유사도 점수: {result['score']}\n")
except ClientError as e:
print(f"오류 발생: {e}")
김개발 씨는 벡터 데이터베이스를 성공적으로 구축했습니다. 하지만 새로운 요구사항이 생겼습니다.
AI가 회사 내부 문서를 참고하여 질문에 답변해야 한다는 것입니다. 이것을 RAG 시스템이라고 부릅니다.
사용자 질문과 관련된 문서를 벡터 검색으로 찾고, 그 내용을 AI에게 제공하여 정확한 답변을 생성하는 방식입니다. 김개발 씨는 이것을 처음부터 구현하려니 막막했습니다.
그렇다면 Bedrock Knowledge Base란 정확히 무엇일까요? 쉽게 비유하자면, Bedrock Knowledge Base는 마치 개인 비서와 도서관을 합친 것과 같습니다.
도서관이 모든 자료를 체계적으로 보관하고, 비서가 필요한 자료를 찾아 요약해서 알려주는 것처럼요. Bedrock Knowledge Base는 여러분의 문서를 자동으로 벡터화하여 저장하고, 사용자 질문이 들어오면 관련 문서를 찾아 AI 모델에 제공합니다.
모든 과정이 자동화되어 있습니다. RAG 시스템을 직접 구축하던 시절에는 어땠을까요?
개발자들은 여러 단계를 직접 구현해야 했습니다. 먼저 문서를 적절한 크기로 나누고, 각 조각을 임베딩 모델에 넣어 벡터로 변환하고, 벡터 데이터베이스에 저장하고, 검색 로직을 만들고, 검색 결과를 LLM 프롬프트에 포함시키는 복잡한 파이프라인을 작성해야 했습니다.
더 큰 문제는 각 단계마다 최적화가 필요하다는 것이었습니다. 문서 청크 크기, 벡터 차원, 검색 개수 등을 실험으로 찾아야 했습니다.
바로 이런 문제를 해결하기 위해 Bedrock Knowledge Base가 등장했습니다. Bedrock Knowledge Base를 사용하면 자동 벡터화가 가능해집니다.
S3에 문서를 업로드하기만 하면 자동으로 처리됩니다. 또한 다양한 벡터 DB 지원도 제공됩니다.
OpenSearch Serverless는 물론 Pinecone, Aurora PostgreSQL(pgvector)도 연동할 수 있습니다. 무엇보다 완벽한 AWS 통합이라는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 9번째 줄을 보면 Knowledge Base를 생성하는데, 임베딩 모델을 지정합니다.
AWS Titan 모델을 사용하면 추가 비용 없이 벡터를 생성할 수 있습니다. 이 부분이 핵심입니다.
19번째 줄에서는 저장소 타입을 선택합니다. OpenSearch Serverless 외에도 PINECONE, RDS 등을 선택할 수 있습니다.
38번째 줄에서 retrieve API를 호출하는데, 자연어 질문만 입력하면 자동으로 벡터 검색이 수행됩니다. 검색 결과에는 관련 문서와 유사도 점수가 포함됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 법무법인에서 AI 법률 상담 시스템을 개발한다고 가정해봅시다.
수천 개의 판례 문서가 있습니다. 이것을 S3에 업로드하고 Bedrock Knowledge Base를 연결합니다.
고객이 "부당해고로 소송하려면 어떻게 해야 하나요?"라고 물으면, 시스템은 자동으로 관련 판례를 찾고, Claude 모델이 그것을 참고하여 답변을 생성합니다. 코드 몇 줄로 전문가 수준의 AI 상담 시스템을 만들 수 있습니다.
여러 금융기관과 헬스케어 기업이 Bedrock Knowledge Base를 실제로 활용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 모든 문서를 하나의 Knowledge Base에 넣는 것입니다. 서로 관련 없는 주제의 문서가 섞이면 검색 정확도가 떨어집니다.
따라서 주제별로 분리하는 것이 좋습니다. 고객 지원용, 기술 문서용, 법률 문서용으로 각각 별도의 Knowledge Base를 만드세요.
또한 문서 업데이트 시 재동기화가 필요하다는 점도 기억해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
Bedrock Knowledge Base를 구축한 김개발 씨는 감탄했습니다. "RAG 시스템이 이렇게 쉽게 만들어지다니!" Bedrock Knowledge Base를 제대로 이해하면 복잡한 RAG 파이프라인 없이 AI 기반 검색 시스템을 빠르게 구축할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - S3 데이터 소스를 사용하면 문서 업데이트가 자동으로 동기화됩니다
- 여러 벡터 DB를 지원하므로 기존 인프라에 맞춰 선택할 수 있습니다
- CloudWatch로 검색 품질과 비용을 모니터링하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
vLLM 통합 완벽 가이드
대규모 언어 모델 추론을 획기적으로 가속화하는 vLLM의 설치부터 실전 서비스 구축까지 다룹니다. PagedAttention과 연속 배칭 기술로 GPU 메모리를 효율적으로 활용하는 방법을 배웁니다.
Web UI Demo 구축 완벽 가이드
Gradio를 활용하여 머신러닝 모델과 AI 서비스를 위한 웹 인터페이스를 구축하는 방법을 다룹니다. 코드 몇 줄만으로 전문적인 데모 페이지를 만들고 배포하는 과정을 초급자도 쉽게 따라할 수 있도록 설명합니다.
Sandboxing & Execution Control 완벽 가이드
AI 에이전트가 코드를 실행할 때 반드시 필요한 보안 기술인 샌드박싱과 실행 제어에 대해 알아봅니다. 격리된 환경에서 안전하게 코드를 실행하고, 악성 동작을 탐지하는 방법을 단계별로 설명합니다.
Voice Design then Clone 워크플로우 완벽 가이드
AI 음성 합성에서 일관된 캐릭터 음성을 만드는 Voice Design then Clone 워크플로우를 설명합니다. 참조 음성 생성부터 재사용 가능한 캐릭터 구축까지 실무 활용법을 다룹니다.
Tool Use 완벽 가이드 - Shell, Browser, DB 실전 활용
AI 에이전트가 외부 도구를 활용하여 셸 명령어 실행, 브라우저 자동화, 데이터베이스 접근 등을 수행하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 패턴과 베스트 프랙티스를 담았습니다.