Embedding
텍스트를 의미가 담긴 숫자 벡터로 바꿔 유사도를 계산할 수 있게 하는 기법
한 줄 정의
임베딩은 텍스트를 의미가 담긴 고정 길이의 숫자 벡터로 바꾸는 것이다.
왜 필요한가
컴퓨터는 문자열을 직접 비교할 수밖에 없다. 그래서 다음을 구분하지 못한다.
- “자동차 가격” 과 “차량 시세” — 글자는 다르지만 의미는 가깝다
- “사과를 먹었다” 와 “사과를 했다” — 글자는 비슷하지만 의미는 멀다
임베딩은 의미를 좌표로 바꾼다. 의미가 가까운 문장은 벡터 공간에서도 가깝게 놓인다. 그래서 의미 기반 검색이 가능해진다.
핵심 개념
| 용어 | 설명 |
|---|---|
| 차원(dimension) | 벡터의 길이. text-embedding-3-small은 1536 |
| 코사인 유사도 | 두 벡터가 이루는 각도로 유사도를 재는 방법 |
| 정규화 | 벡터 길이를 1로 맞춰 비교를 단순화하는 것 |
동작 구조
flowchart LR
T["중고차 매입 절차"] --> M[임베딩 모델]
M --> V["[0.021, -0.113, ...]"]
V --> S[(벡터 저장소)]
Q[질문] --> M2[임베딩 모델]
M2 --> C[유사도 계산]
S --> C
C --> R[가까운 문서]
같은 모델로 문서와 질문을 모두 벡터로 바꾼 뒤, 거리를 재서 가까운 것을 찾는다.
예제
세 문장을 임베딩했다고 하자.
| 문장 | 질문과의 유사도 |
|---|---|
| 중고차 매입 시 감가 기준 | 0.89 |
| 차량 시세 조회 방법 | 0.72 |
| 오늘 점심 메뉴 추천 | 0.11 |
질문이 “중고차 살 때 가격이 얼마나 깎이나?”였다면 첫 번째가 선택된다. 단어가 하나도 겹치지 않아도 의미로 찾아낸다.
코드
from openai import OpenAI
client = OpenAI()
response = client.embeddings.create(
model="text-embedding-3-small",
input="중고차 매입 절차",
)
vector = response.data[0].embedding
print(len(vector)) # 1536
코사인 유사도는 다음과 같이 정의된다.
장점
- 단어가 겹치지 않아도 의미로 검색된다
- 언어가 달라도 의미가 가까우면 찾아진다(다국어 모델)
- 한 번 계산해두면 재사용할 수 있다
단점
- 문서와 질문에 같은 모델을 써야 한다. 섞으면 결과가 무의미하다
- 모델을 바꾸면 전체를 다시 임베딩해야 한다
- 고유명사나 숫자처럼 정확히 일치해야 하는 검색에는 약하다
- 차원이 크면 저장 비용이 늘어난다
자주 발생하는 문제
| 증상 | 원인 | 해결 |
|---|---|---|
| 검색 결과가 엉망 | 문서와 질문의 임베딩 모델이 다름 | 같은 모델로 통일 |
| 특정 제품명을 못 찾음 | 의미 검색의 한계 | 키워드 검색과 함께 쓰는 하이브리드 검색 |
| 비용이 많이 나옴 | 매번 재계산 | 결과를 저장해두고 재사용 |
실제 프로젝트 적용
아직 없음.
관련 문서
참고 자료
- OpenAI Embeddings 문서 (2026-07-25 확인)