이제 실제 "검색"으로 들어간다. 첫 기법은 키워드 검색(keyword search)이다. 수십 년간 데이터베이스와 검색엔진을 지탱해 온 방식이고, 그 단순함과 효과 덕분에 현대 RAG에서도 핵심 구성요소로 남아 있다. 이번 편은 키워드 검색의 표준 baseline인 TF-IDF까지, 점수를 매기는 논리를 한 단계씩 쌓아 올린다.
1. 키워드 검색의 기본 아이디어
키워드 검색은 문서가 프롬프트와 공통 단어를 얼마나 공유하는지로 문서를 검색한다. 즉 "프롬프트의 단어를 많이 포함한 문서일수록 관련성이 높을 것"이라는 단순한 가정이다.

2. Bag of Words
프롬프트와 각 문서는 모두 bag of words(단어 주머니)로 취급된다. 단어의 순서는 완전히 무시하고, 어떤 단어가 얼마나 자주 나오는지만 센다. 예를 들어 "making pizza without a pizza oven"에는 pizza가 2번, making·without·a·oven이 각각 1번 들어 있다.

3. Sparse Vector와 Term-Document Matrix
이 단어 빈도는 벡터(vector)에 저장된다. 벡터에는 시스템 vocabulary의 단어마다 한 자리가 있으므로 자리 수가 수만 개에 이를 수 있고, 대부분의 자리는 0이다. 그래서 이를 sparse vector(희소 벡터)라 부른다.
검색을 준비하려면 문서마다 sparse vector를 하나씩 만들어 격자로 배열한다. 이것이 term-document matrix다. 각 열은 문서, 각 행은 단어다. 이 구조는 inverted index(역색인)라고도 불린다 — 보통은 "문서 → 그 안의 단어"로 생각하지만, 여기서는 "단어 → 그 단어를 포함한 모든 문서"로 거꾸로 찾기 때문이다. 이 색인은 검색 전에 미리 한 번 만들어 두고, 프롬프트가 들어오면 프롬프트의 sparse vector만 빠르게 생성하면 된다.

4. 점수 매기기 ① — 단순 점수와 빈도
이제 문서에 점수를 매긴다. 프롬프트의 각 단어를 keyword라 부른다. 가장 단순한 방법은 문서가 keyword를 포함하면 1점을 주는 것이다. 색인에서 keyword의 행을 찾아, 그 keyword를 한 번이라도 포함한 문서마다 1점씩 부여한다. keyword가 5개면 최고점은 5점이다.
하지만 단순 점수는 keyword가 여러 번 나오는지를 반영하지 못한다. 여러 번 나온다면 더 관련성이 높을 텐데 말이다. 그래서 등장할 때마다 점수를 올리는 방식(빈도 기반, term frequency)으로 바꾼다 — 색인에서 각 keyword 행의 값(등장 횟수)을 그대로 점수로 더한다.

5. 점수 매기기 ② — 문서 길이 정규화
빈도를 쓰면 새 문제가 생긴다 — 긴 문서는 단지 길어서 keyword를 여러 번 포함할 수 있다. 이를 보정하려면 각 문서의 점수를 그 문서의 총 단어 수로 나눈다.

이 정규화된 점수는, keyword가 전체 텍스트에서 더 큰 비중을 차지하는 문서에 보상하고, 단순히 길어서 keyword가 많이 든 문서의 비중을 낮춘다.

6. 모든 단어를 똑같이 취급하면 안됨
여기까지도 꽤 좋지만, 한 가지 맹점이 있다 — 모든 keyword에 똑같이 점수를 준다는 것이다. the 같은 흔한 filler 단어든, pizza처럼 존재 자체가 관련성을 훨씬 잘 나타내는 드문 단어든 동일하게 취급한다. 이를 보정하려면 단어에 가중치를 줘야 한다. 그 척도가 IDF(inverse document frequency, 역문서빈도)다.

7. IDF 계산 — 드문 단어에 보상
먼저 각 단어의 document frequency(DF)를 구한다. 그 단어가 등장하는 문서 수를 전체 문서 수로 나눈 값이다. 예를 들어 문서가 100개인데 pizza가 5개 문서에 나오면 DF = 5/100 = 0.05, the가 100개 모두에 나오면 DF = 100/100 = 1.0이다.

우리는 드문 단어에 보상하고 싶으므로 이 분수를 뒤집는다(invert). 그러면 pizza의 IDF = 1/0.05 = 20, the의 IDF = 1/1.0 = 1이 된다. 그런데 이렇게 하면 드문 단어의 가중치가 과도하게 커진다. 그래서 보통 IDF에 로그(log)를 취한다. 드문 단어는 여전히 큰 가중치를 갖지만 그 정도가 완화된다.

8. TF-IDF 최종 점수
이제 색인의 각 행 값에 그 단어의 IDF를 곱해 색인을 갱신하면, TF-IDF matrix가 만들어진다. 점수 계산은 이전과 똑같다 — 프롬프트의 각 keyword 행을 따라가며 각 문서에 그 행의 TF-IDF 값을 더한다.

결과적으로 가장 높은 점수를 받는 문서는 keyword를 자주 쓰면서, 특히 knowledge base 전체에서 드문 keyword를 많이 포함한 문서가 된다. 앞의 예에서 pizza·oven 같은 드문 단어를 담은 문서가 a·without 같은 흔한 단어를 담은 문서보다 훨씬 높은 점수를 받는다.


다음 글에서는 TF-IDF를 실전용으로 다듬은 BM25를 본다 — 빈도 포화(saturation)와 문서 길이 정규화를 조절 가능한 파라미터로 개선한 방식이다.
'AI > RAG' 카테고리의 다른 글
| Semantic Search & Embedding (0) | 2026.07.02 |
|---|---|
| BM25 (키워드 검색) (0) | 2026.07.02 |
| Metadata Filtering(메타데이터 필터링) (0) | 2026.07.02 |
| Retriever의 구조 (0) | 2026.07.02 |
| LLM의 동작 방식, 환각 발생 원인 (1) | 2026.07.02 |
