임베딩과 벡터 검색: 의미를 숫자로 바꾸는 방법
텍스트를 벡터로 바꾸는 임베딩의 개념과 코사인 유사도로 의미가 비슷한 문서를 찾는 원리를 설명합니다. 키워드 검색과의 차이, 벡터 데이터베이스의 역할까지 다룹니다.

이 글의 목차
"강아지"와 "개"는 다른 글자지만 비슷한 뜻입니다. 반대로 "은행에서 돈을 찾다"의 은행과 "강 은행을 걷다"의 은행은 같은 글자지만 다른 뜻입니다. 컴퓨터가 이런 차이를 다루려면 글자를 그대로 비교해서는 안 되고, 의미를 나타내는 다른 표현이 필요합니다.
그 표현이 임베딩(embedding) 입니다. 텍스트를 수백에서 수천 개의 숫자로 이루어진 벡터로 바꾸되, 뜻이 비슷하면 벡터도 가깝도록 만든 것입니다. 이 성질 하나로 의미 기반 검색, 추천, 분류, 중복 제거 같은 일이 가능해집니다.
이 글에서는 임베딩이 무엇인지, 가까움을 어떻게 재는지, 키워드 검색과 무엇이 다른지, 그리고 실무에서 어떤 점을 조심해야 하는지를 정리합니다. RAG 파이프라인을 이해하는 데 필요한 기초이기도 합니다.
벡터 하나가 좌표 하나입니다
임베딩 벡터를 이해하는 가장 쉬운 방법은 좌표로 보는 것입니다. 지도 위의 한 점이 위도와 경도 두 숫자로 표현되듯, 임베딩은 어떤 공간 안의 한 점을 수백~수천 개의 숫자로 표현합니다.
이 공간에는 유용한 성질이 있습니다. 비슷한 뜻의 텍스트가 서로 가까운 곳에 모입니다. "강아지", "개", "반려견"은 한 구역에 모이고, "주식", "환율", "금리"는 다른 구역에 모입니다. 각 차원이 무엇을 뜻하는지는 사람이 지정하지 않았고 해석하기도 어렵지만, 거리 관계는 의미를 반영합니다.
이런 벡터는 어떻게 만들어질까요. 임베딩 모델은 "같은 문맥에 나타나는 표현은 비슷한 뜻"이라는 가정을 바탕으로 학습됩니다. 비슷한 쌍은 가깝게, 관련 없는 쌍은 멀게 배치하도록 반복 조정하면, 결과적으로 의미가 거리에 반영된 공간이 만들어집니다.
참고
트랜스포머 구조에서 다룬 토큰 임베딩과는 구분됩니다. 토큰 임베딩은 토큰 하나의 초기 벡터이고, 여기서 말하는 임베딩은 문장이나 문단 전체를 하나의 벡터로 요약한 것입니다.
가까움은 각도로 잽니다
두 벡터가 얼마나 비슷한지는 보통 코사인 유사도(cosine similarity) 로 측정합니다. 두 벡터가 이루는 각도를 보는 방식으로, 같은 방향이면 1, 직각이면 0, 반대 방향이면 -1이 됩니다.
거리가 아니라 각도를 쓰는 이유는 길이를 무시하기 위해서입니다. 텍스트가 길면 벡터의 크기가 커지는 경향이 있는데, 우리가 알고 싶은 것은 "분량이 비슷한가"가 아니라 "방향이 비슷한가", 즉 의미가 비슷한가입니다.
import numpy as np
def cosine_similarity(a, b):
a, b = np.asarray(a, dtype=float), np.asarray(b, dtype=float)
return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))
# 예시: 미리 정규화된 벡터라면 내적만으로 충분합니다
similarity = cosine_similarity([0.2, 0.9, 0.1], [0.3, 0.8, 0.2])많은 임베딩 모델이 길이가 1로 정규화된 벡터를 내놓습니다. 이 경우 코사인 유사도는 단순한 내적(dot product)과 같아져 계산이 빨라집니다.
주의할 점은 유사도 값 자체에 절대적 기준이 없다는 것입니다. 0.8이 "비슷함"을 뜻하는지는 모델마다 다릅니다. 어떤 모델은 관련 없는 문장끼리도 0.7이 나오고, 어떤 모델은 0.3이 나옵니다. 임계값을 정하려면 실제 데이터로 분포를 확인해야 합니다.
키워드 검색과 무엇이 다른가
기존 검색은 단어가 일치하는지를 봅니다. 벡터 검색은 의미가 가까운지를 봅니다. 둘은 잘하는 일이 다릅니다.
| 키워드 검색 | 벡터 검색 | |
|---|---|---|
| 찾는 기준 | 단어 일치 | 의미 근접 |
| "환불 어떻게 하나요" | '환불' 포함 문서 | '반품 절차', '결제 취소'도 함께 |
| 고유명사·제품 코드 | 정확히 찾음 | 놓치는 경우 있음 |
| 오타·동의어 | 취약 | 강함 |
| 결과 설명 | 쉬움(어느 단어가 맞았는지) | 어려움 |
벡터 검색의 강점은 표현이 달라도 찾아낸다는 것입니다. 사용자가 "돈 돌려받고 싶어요"라고 물어도 "환불 규정" 문서를 찾을 수 있습니다.
약점도 분명합니다. ERR-4021 같은 코드나 드문 고유명사는 임베딩 공간에서 잘 구분되지 않아 엉뚱한 결과가 나오기 쉽습니다. 또 "포함하지 않는 것"을 찾는 부정 조건이나 날짜 범위 같은 조건 필터링에 약합니다.
그래서 실무에서는 두 방식을 함께 쓰는 하이브리드 검색이 기본에 가깝습니다. 키워드 검색과 벡터 검색을 각각 수행한 뒤 결과를 합치는 방식입니다.
팁
제품 코드, 사번, 오류 코드처럼 정확히 일치해야 하는 값이 중요한 도메인이라면 벡터 검색만으로 시작하지 마세요. 키워드 검색을 기본으로 두고 벡터 검색을 보완재로 얹는 편이 안전합니다.
벡터 데이터베이스가 하는 일
문서가 수백 개라면 모든 벡터와 일일이 유사도를 계산해도 괜찮습니다. 하지만 수백만 개가 되면 그럴 수 없습니다. 질문 하나마다 수백만 번의 계산이 필요하기 때문입니다.
벡터 데이터베이스는 이 검색을 빠르게 만들어 줍니다. 핵심은 근사 최근접 이웃(ANN, Approximate Nearest Neighbor) 탐색입니다. 정확히 가장 가까운 것을 찾는 대신, 아주 가까운 것들을 훨씬 빠르게 찾는 방식입니다. 비슷한 벡터끼리 미리 묶어 두거나 계층 구조를 만들어, 후보를 크게 줄인 뒤 그 안에서만 비교합니다.
"근사"라는 말 그대로 정답을 놓칠 가능성이 있습니다. 속도와 정확도 사이에 조절 가능한 트레이드오프가 있고, 대부분의 용도에서는 약간의 손실이 문제가 되지 않습니다.
벡터 데이터베이스는 보통 다음도 함께 제공합니다.
- 메타데이터 필터링 — 날짜, 작성자, 문서 종류로 범위를 좁힌 뒤 검색
- 갱신과 삭제 — 원문이 바뀌면 해당 벡터를 교체
- 다중 인덱스 — 용도별로 컬렉션 분리
별도 제품을 쓸 수도 있고, 기존 관계형 데이터베이스나 검색 엔진의 벡터 확장 기능을 쓸 수도 있습니다. 데이터 규모가 크지 않다면 후자가 운영 부담이 적습니다.
실무에서 조심할 점
같은 모델로 만든 벡터끼리만 비교할 수 있습니다. 임베딩 공간은 모델마다 완전히 다릅니다. 모델 A로 만든 문서 벡터와 모델 B로 만든 질문 벡터를 비교하면 아무 의미 없는 결과가 나옵니다. 모델을 바꾸면 전체 문서를 다시 임베딩해야 합니다. 이 재색인 비용을 미리 고려해야 합니다.
긴 문서는 통째로 넣으면 안 됩니다. 문서 전체를 벡터 하나로 만들면 여러 주제가 평균되어 뭉개집니다. 적당한 크기로 잘라(청킹) 각각을 벡터로 만들어야 합니다. 청크가 너무 작으면 문맥이 끊기고, 너무 크면 의미가 흐려집니다. 문단이나 소제목 단위로 나누고 앞뒤를 조금 겹치게 하는 방식이 무난한 출발점입니다.
입력 길이 제한이 있습니다. 임베딩 모델마다 처리 가능한 최대 길이가 정해져 있고, 초과분은 조용히 잘리는 경우가 있습니다. 긴 텍스트를 넣고 뒷부분이 반영되지 않는 문제가 여기서 생깁니다.
대칭이 아닌 검색을 고려하세요. 짧은 질문으로 긴 문서를 찾는 상황에서는 질문과 문서의 형태가 많이 다릅니다. 일부 임베딩 모델은 질문용과 문서용 처리를 구분하도록 설계되어 있으므로, 사용하는 모델의 문서를 확인하는 편이 좋습니다.
언어를 확인하세요. 다국어를 지원하지 않는 모델에 한국어를 넣으면 품질이 크게 떨어집니다. 한국어 문서를 다룬다면 다국어 또는 한국어 지원이 명시된 모델을 선택해야 합니다.
검색 외의 쓰임
임베딩은 검색에만 쓰이지 않습니다.
- 중복·유사 문서 탐지 — 표현이 달라도 내용이 겹치는 문서를 찾습니다.
- 분류 — 미리 정의한 범주의 예시 벡터와 비교해 가장 가까운 범주로 분류합니다. 소량의 예시만으로도 동작해 학습 데이터가 적을 때 유용합니다.
- 군집화 — 문의 내용을 자동으로 묶어 자주 나오는 주제를 파악합니다.
- 추천 — 사용자가 본 항목과 가까운 항목을 제시합니다.
- 이상 탐지 — 기존 데이터와 지나치게 먼 입력을 걸러냅니다.
이런 작업에는 생성 모델보다 임베딩 모델이 훨씬 빠르고 저렴합니다. 분류나 유사도 판단을 매번 LLM에게 시키고 있다면 임베딩으로 대체할 수 있는지 검토해 볼 만합니다.
흔한 오해
"벡터 데이터베이스를 쓰면 검색이 정확해진다." 벡터 데이터베이스가 해결하는 것은 주로 속도와 규모입니다. 검색 결과의 품질은 임베딩 모델, 청크 크기, 하이브리드 구성 같은 앞 단계에서 대부분 결정됩니다.
"차원이 클수록 좋다." 차원이 크면 저장 공간과 계산 비용이 늘어납니다. 품질은 차원 수보다 모델이 어떤 데이터로 어떻게 학습됐는지에 더 크게 좌우되므로, 자기 데이터로 비교해 보는 것이 정확합니다.
"유사도가 높으면 답이 들어 있다." 유사도가 높다는 것은 주제가 비슷하다는 뜻일 뿐, 그 청크가 질문의 답을 담고 있다는 보장은 아닙니다. 같은 주제의 다른 조건을 다룬 문서가 높은 점수로 올라오는 경우가 흔합니다.
정리
- 임베딩은 텍스트를 벡터로 바꾸되 뜻이 비슷하면 가깝게 배치되도록 만든 표현입니다.
- 유사도는 보통 코사인 유사도로 재며, 값의 절대적 기준은 모델마다 다르므로 데이터로 확인해야 합니다.
- 벡터 검색은 표현이 달라도 찾아내지만 고유명사·코드에는 약해, 키워드 검색과 함께 쓰는 하이브리드가 안전합니다.
- 벡터 데이터베이스는 근사 최근접 탐색으로 대규모 검색을 빠르게 만들며, 약간의 정확도를 속도와 맞바꿉니다.
- 같은 모델로 만든 벡터끼리만 비교할 수 있고, 모델을 바꾸면 전체 재색인이 필요합니다.
- 긴 문서는 적절히 잘라서 임베딩해야 하며, 청크 크기가 검색 품질을 좌우합니다.
참고 자료
- Efficient Estimation of Word Representations in Vector Space — 단어 임베딩의 초기 연구
- Sentence-BERT — 문장 단위 임베딩과 유사도 비교
- Sentence Transformers 공식 문서 — 임베딩 모델 사용법