본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 15:05

LLM 토큰 비용 최적화: 품질 저하 없이 API 비용 절감하기

요약

벡터 검색의 핵심 원리와 효과적인 RAG 시스템 구축을 위한 가이드를 제공합니다. 임베딩의 특성, 유사도 측정 방식, ANN 알고리즘 및 벡터 데이터베이스 선택법을 다룹니다.

핵심 포인트

  • 임베딩은 의미론적 유사성을 나타내는 밀집 수치 벡터임
  • 유사도 측정 방식과 ANN 알고리즘이 검색 품질과 속도에 결정적임
  • 효과적인 RAG를 위해 임베딩 모델과 벡터 DB의 적절한 선택이 필요함

전통적인 검색은 키워드를 매칭합니다. 사용자는 자신이 찾고자 하는 문서에 포함된 정확한 단어를 알고 있어야 합니다. 벡터 검색 (Vector search)은 의미를 매칭합니다. 사용자가 자연어로 무엇을 찾고 있는지 설명하면, 시스템은 키워드가 다르더라도 의미론적으로 유사한 콘텐츠를 찾아냅니다. 예를 들어 "자동차 문제"라고 검색하면 "자동차 수리"나 "엔진 문제"에 관한 문서를 찾아줍니다.

벡터 검색은 현대적인 의미론적 검색 (Semantic search), 추천 시스템, 그리고 LLM을 위한 검색 증강 생성 (RAG)의 핵심 동력입니다. 이는 텍스트, 이미지 또는 기타 콘텐츠를 의미론적 의미를 포착하는 고차원 벡터 (Embeddings, 임베딩)로 변환합니다. 그런 다음 대규모 환경에서 근사 최근접 이웃 (Approximate Nearest Neighbors, ANN)을 효율적으로 찾는 특수 알고리즘을 사용하여 쿼리 벡터와 가장 유사한 벡터를 검색합니다.

저는 지식 베이스, 제품 카탈로그, 콘텐츠 추천을 위한 벡터 검색 시스템을 구축해 왔습니다. 저는 임베딩 모델의 선택이 품질에 극적인 영향을 미친다는 점, 유사도 측정 방식 (Similarity metric)의 선택이 결과에 영향을 미친다는 점, 그리고 근사 최근접 이웃 (ANN) 알고리즘이 수백만 개의 문서 규모에서도 검색을 가능하게 한다는 점을 배웠습니다. 이 가이드는 효과적인 패턴들을 다룹니다: 임베딩과 그 특성 이해하기, 유사도 측정 방식과 각각의 사용 시점, 벡터 검색을 실용적으로 만드는 ANN 알고리즘, 벡터 데이터베이스 선택, 그리고 완전한 의미론적 검색 파이프라인 구축하기입니다.

임베딩 (Embeddings) 이해하기

임베딩이란 무엇인가

임베딩은 의미론적 의미를 나타내는 밀집 수치 벡터 (Dense numerical vectors)입니다. 유사한 항목은 유사한 벡터를 가집니다.

Text: "The quick brown fox"
Embedding: [0.12, -0.45, 0.89, ..., 0.34]  # 384 ~ 1536 차원

...

좋은 임베딩의 특성

의미론적 유사성 (Semantic similarity): 유사한 의미 = 벡터 공간 내에서 가까운 거리

선형 관계 (Linear relationships): 유추 (Analogy)가 벡터 산술로 작동함

king - man + woman ≈ queen
Paris - France + Italy ≈ Rome

밀집 표현 (Dense representation): 모든 차원이 값을 가짐 (희소한 원-핫 인코딩 (One-hot encoding)과 대조됨)

Text embeddings visualization showing similar phrases clustering together in vector space
(https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgk0m76aepujxh9nkev3d.jpg)
유사한 의미는 고차원 공간에서 서로 군집을 이루는 벡터를 생성합니다.

임베딩 모델 (Embedding Models)

모델 (Model)차원 (Dimensions)용도 (Best For)제공업체 (Provider)
text-embedding-3-small1536범용 (General purpose)OpenAI
...

선택 기준 (Selection criteria):

  • 품질 (Quality): 귀하의 특정 데이터에 대한 벤치마크 (Benchmark)
  • 비용 (Cost): API 비용 또는 자체 호스팅 (Self-hosted)을 위한 컴퓨팅 비용
  • 차원 (Dimensions): 차원이 높을수록 더 정확하지만 더 많은 저장 공간 필요
  • 지연 시간 (Latency): 모델 추론 (Inference) 시간

임베딩 생성하기 (Generating Embeddings)

# OpenAI
from openai import OpenAI

...
# 오픈 소스 (Open source) (sentence-transformers)
from sentence_transformers import SentenceTransformer

...

임베딩을 로컬에서 실행할지 또는 API를 통해 실행할지 평가하는 팀에게는 비용과 지연 시간 사이의 트레이드오프 (Tradeoff)가 중요합니다. 저희의 로컬 AI 실행 가이드 (guide to locally run AI)는 자체 호스팅이 관리형 임베딩 API를 사용하는 것보다 언제 비용을 절감할 수 있는지 상세히 설명합니다.

유사도 측정 지표 (Similarity Metrics)

코사인 유사도 (Cosine Similarity)

크기 (Magnitude)를 무시하고 벡터 사이의 각도를 측정합니다.

import numpy as np

def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
...

사용 시점:

  • 텍스트 임베딩 (대부분의 모델이 정규화 (Normalized)됨)
  • 크기보다 방향이 더 중요한 경우
  • 가장 일반적인 기본 선택지

유클리드 거리 (Euclidean Distance)

벡터 사이의 직선 거리입니다.

def euclidean_distance(a: np.ndarray, b: np.ndarray) -> float:
    return np.linalg.norm(a - b)

...

사용 시점:

  • 크기가 중요한 경우
  • 컴퓨터 비전 (Computer vision) 임베딩
  • 벡터가 정규화 (Normalized)되지 않은 경우

내적 (Dot Product)

요소별 곱의 단순 합계입니다.

def dot_product(a: np.ndarray, b: np.ndarray) -> float:
    return np.dot(a, b)

사용 시점:

  • 벡터가 정규화되었을 때 (코사인 유사도와 동일)
  • 빠른 계산
  • 일부 벡터 데이터베이스 (Vector Databases)에서 이를 최적화함

지표 선택 가이드 (Metric Selection Guide)

지표 (Metric)사용 시점범위
코사인 (Cosine)텍스트 검색, 정규화된 벡터[-1, 1]
...

근사 최근접 이웃 (Approximate Nearest Neighbor, ANN) 알고리즘

ANN을 사용하는 이유

고차원 데이터에서 정확한 최근접 이웃 검색 (Exact nearest neighbor search)은 $O(n)$의 복잡도를 가집니다. 백만 단위의 문서 규모에서는 속도가 너무 느립니다.

ANN 알고리즘은 약간의 정확도 손실을 대가로 엄청난 속도 향상 (1000배 이상)을 제공합니다.

Approximate Nearest Neighbor algorithm visualization showing hierarchical graph search

ANN 알고리즘은 모든 항목을 스캔하지 않고도 가장 유사한 벡터로 직접 찾아 들어가는 계층적 그래프 (Hierarchical graphs)를 구축합니다.

HNSW (Hierarchical Navigable Small World)

그래프 기반 알고리즘입니다. 프로덕션 환경에서 가장 대중적으로 사용됩니다.

구축 과정:
1. 계층적 그래프 구조에 포인트 삽입
2. 각 계층은 근접 그래프 (Proximity graph)임
...

특징:

  • 높은 재현율 (Recall, 일반적으로 >95%)
  • 빠른 쿼리 (밀리초 단위)
  • 메모리 집약적 (그래프를 저장함)
  • 백만 단위 규모의 데이터셋에 적합

IVF (Inverted File Index)

클러스터링 (Clustering) 기반 접근 방식입니다.

구축 과정:
1. 벡터를 N개의 그룹 (보로노이 셀, Voronoi cells)으로 클러스터링
2. 클러스터 중심점 (Centroids) 저장
...

특징:

  • 조절 가능한 속도/정확도 트레이드오프 (Tradeoff)
  • 메모리 효율적
  • 십억 단위 규모의 데이터셋에 적합

LSH (Locality Sensitive Hashing)

해시 (Hash) 기반 접근 방식입니다.

구축 과정:
1. 여러 개의 해시 함수 생성
2. 유사한 벡터는 동일한 버킷 (Buckets)으로 해싱됨
...

특징:

  • 매우 빠름
  • HNSW보다 낮은 재현율 (Recall)
  • 재현율이 낮아도 괜찮은 매우 거대한 데이터셋에 적합

PQ (Product Quantization)

다른 인덱스와 결합하여 자주 사용되는 압축 기술입니다.

벡터 압축 방식:
1. 벡터를 하위 벡터 (Sub-vectors)로 분할
2. 각 하위 벡터를 코드북 (Codebook)으로 양자화 (Quantize)
...

벡터 데이터베이스 (Vector Databases)

Pinecone

Pinecone은 관리형 벡터 데이터베이스 (Managed Vector Database)입니다.

from pinecone import Pinecone, ServerlessSpec

pc = PineCone(api_key="your-api-key")
...

Weaviate

Weaviate는 관리형 옵션을 제공하는 오픈 소스 (Open-source) 벡터 데이터베이스입니다.

import weaviate

client = weaviate.Client("http://localhost:8080")
...

pgvector

pgvector는 기존 Postgres 데이터베이스에 벡터 유사도 검색 (Vector Similarity Search) 기능을 추가하는 PostgreSQL 확장 프로그램 (Extension)입니다.

-- 확장 프로그램 활성화
CREATE EXTENSION vector;

...
# SQLAlchemy와 함께 사용하기
from sqlalchemy import create_engine, Column, Integer, String
from pgvector.sqlalchemy import Vector
...

선택 가이드 (Selection Guide)

데이터베이스최적 용도배포 방식
Pinecone관리형, 쉬운 시작SaaS
...
Vector database comparison showing Pinecone, Weaviate, pgvector, Milvus, Chroma, and Qdrant
각 벡터 데이터베이스는 서로 다른 배포 모델과 규모 요구 사항에 최적화되어 있습니다.

시맨틱 검색 파이프라인 구축하기 (Building a Semantic Search Pipeline)

아키텍처 (Architecture)

Documents
    |
    v
...

청킹 전략 (Chunking Strategy)

def chunk_text(text: str, chunk_size: int = 500, overlap: int = 50) -> list[str]:
    """문맥 보존을 위해 오버랩 (Overlap)을 포함하여 텍스트를 청킹합니다"""
    chunks = []
...

하이브리드 검색 (Hybrid Search)

벡터 유사도 (Vector Similarity)와 키워드 매칭 (Keyword Matching)을 결합합니다.

def hybrid_search(query: str, vector_weight: float = 0.7) -> list[dict]:
    """BM25와 벡터 검색을 결합합니다"""

...

리랭킹 (Reranking)

초기 검색 (빠름, 근사치) → 리랭킹 (느림, 정확함).

def search_with_reranking(query: str) -> list[dict]:
    # 초기 검색 (ANN)
    query_embedding = get_embedding(query)
...

필터링 및 메타데이터 (Filtering and Metadata)

메타데이터 필터가 적용된 Pinecone

results = index.query(
vector=query_embedding,
...


## 성능 최적화 (Performance Optimization)

### 인덱스 튜닝 (Index Tuning)

HNSW 파라미터

index_params = {
"M": 16, # 레이어당 연결 수 (높을수록 정확도가 높아지지만 메모리 사용량 증가)
...


### 배치 작업 (Batch Operations)

배치 임베딩 (Batch embedding) (훨씬 빠름)

texts = [doc['content'] for doc in documents]
embeddings = model.encode(texts, batch_size=64)
...


### 캐싱 (Caching)

from functools import lru_cache

@lru_cache(maxsize=10000)
...


## 평가 (Evaluation)

### 지표 (Metrics)

def evaluate_search(queries: list[dict]) -> dict:
"""
queries: [{"query": str, "relevant_ids": [str]}]
...


## 흔히 발생하는 실수 (Common Pitfalls)

**실수 1: 잘못된 임베딩 모델 (Wrong Embedding Model)**

도메인 특화(domain-specific) 콘텐츠에 일반적인 임베딩을 사용하는 경우입니다. 도메인에 맞춰 튜닝된 모델을 사용하세요.

**실수 2: 부적절한 청킹 (Poor Chunking)**

의미적 일관성(semantic coherence)을 깨뜨리는 청크를 만드는 경우입니다. 오버랩(overlap)과 의미적 경계(semantic boundaries)를 사용하세요.

**실수 3: 메타데이터 필터링 미사용 (No Metadata Filtering)**

사용자가 필터링된 결과를 필요로 함에도 모든 문서를 대상으로 검색하는 경우입니다. 메타데이터를 인덱싱하세요.

**실수 4: 완전 일치 검색 무시 (Ignoring Exact Matches)**

사용자가 특정 ID나 이름을 검색할 때 벡터에만 의존하는 경우입니다. 하이브리드 검색 (hybrid search)을 사용하세요.

**실수 5: 잘못된 유사도 측정 방식 (Wrong Similarity Metric)**

정규화된 임베딩에 유클리드 거리 (Euclidean distance)를 사용하는 경우입니다. 텍스트에는 코사인 유사도 (cosine)를 사용하세요.

**실수 6: 품질 모니터링 미흡 (Not Monitoring Quality)**

측정 없이 시간이 지남에 따라 검색 품질이 저하되는 경우입니다. 정기적으로 평가하세요.

## 결론 (Conclusion)

벡터 검색은 대규모 환경에서 의미론적 이해를 가능하게 합니다. 임베딩을 선택할 때...

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0