Skip to main content

1. 한국어 RAG의 과제

한국어 RAG의 구조적 어려움

한국어 RAG는 영어 RAG와 근본적으로 다른 문제를 해결해야 합니다. 이는 한국어의 언어학적 특성 에서 비롯됩니다. 1. 교착어 (Agglutinative Language) 특성 한국어는 어근에 조사, 어미, 접사가 결합하여 하나의 단어를 형성합니다. 영어가 단어 순서(어순)로 문법적 관계를 표현하는 것과 달리, 한국어는 접사의 결합 으로 표현합니다. 이로 인해 동일한 의미의 단어가 수십 가지 형태로 변화합니다.
"데이터브릭스" (원형)
→ "데이터브릭스가" (주격), "데이터브릭스를" (목적격)
→ "데이터브릭스에서" (처소격), "데이터브릭스의" (관형격)
→ "데이터브릭스로" (도구격), "데이터브릭스와" (공동격)
→ 영어: "Databricks" 하나의 형태로 모든 문법적 관계 표현
2. 띄어쓰기 불규칙성 한국어는 띄어쓰기 규칙이 복잡하고, 실제 문서에서 띄어쓰기 오류가 빈번합니다. “데이터 분석”과 “데이터분석”이 혼재하는 경우가 많아, 공백 기반 토큰화에 의존하면 검색 품질이 저하됩니다. 3. 한영 혼용 텍스트 한국어 기술 문서에는 영어 용어가 빈번하게 등장합니다. “Databricks 워크스페이스에서 Delta Lake 테이블을 생성합니다”처럼 한국어와 영어가 한 문장에 혼재 합니다. 단일 언어 모델로는 양쪽 모두를 잘 처리하기 어렵습니다. 4. 상대적으로 적은 학습 데이터 대부분의 임베딩 모델과 LLM은 영어 데이터로 주로 학습됩니다. 한국어 데이터의 비중은 전체 학습 데이터의 1~3%에 불과한 경우가 많아, 한국어에 대한 의미 표현 능력이 영어보다 떨어질 수 있습니다.

이 문제들이 RAG에 미치는 실제 영향

위 특성들이 결합되면, 영어 기준으로 설계된 RAG 파이프라인은 한국어에서 심각한 성능 저하를 겪습니다:
  • BM25 키워드 검색 실패: 조사가 붙은 채로 토큰화되어 “데이터브릭스에서” ≠ “데이터브릭스를”로 처리됨
  • 토큰 비용 급증: 일반 토크나이저(tiktoken, SentencePiece)로 한국어를 처리하면 영어 대비 2~3배 많은 토큰 소비
  • 임베딩 품질 저하: 한국어 학습 데이터 부족으로 의미 벡터의 정밀도가 떨어질 수 있음
이 문제들의 해결책은 다음 섹션에서 다루는 형태소 분석 에서 시작됩니다.
주의 한국어 RAG에서 가장 흔한 실수는 영어 기준 파이프라인을 그대로 적용하는 것입니다. 특히 BM25 기반 키워드 검색은 형태소 분석 없이는 한국어에서 제대로 작동하지 않습니다.

2. Kiwi 한국어 형태소 분석기

형태소 분석이란? — 한국어 RAG의 핵심 전처리

형태소(Morpheme) 는 의미를 가진 최소 언어 단위입니다. 영어에서는 단어 사이의 공백(space)이 곧 의미 단위의 경계이지만, 한국어는 하나의 어절(띄어쓰기 단위) 안에 여러 형태소가 결합되어 있습니다. 형태소 분석은 이 어절을 의미 단위로 분해하는 작업입니다.
영어: "I   love   Databricks"   → 공백으로 나누면 3개 단어, 각각이 의미 단위
한국어: "데이터브릭스에서"         → 1개 어절이지만, 2개 형태소
       → "데이터브릭스" (고유명사, 의미 핵심) + "에서" (조사, 문법 기능)
형태소 분석이 앞서 언급한 문제를 어떻게 해결하는가? 섹션 1에서 설명한 교착어 특성 — “데이터브릭스에서”, “데이터브릭스를”, “데이터브릭스의”가 모두 다른 토큰으로 처리되는 문제 — 의 해결책이 바로 형태소 분석입니다. 핵심 아이디어는 간단합니다: 어절을 형태소로 분해한 뒤, 의미를 담당하는 형태소(명사, 동사 등)만 추출하고 문법 기능만 하는 형태소(조사, 어미)는 버리는 것 입니다.
형태소 분석 + 의미 형태소 추출:
  "데이터브릭스에서" → [데이터브릭스, 에서] → "데이터브릭스" ✓
  "데이터브릭스를"   → [데이터브릭스, 를]   → "데이터브릭스" ✓
  "데이터브릭스의"   → [데이터브릭스, 의]   → "데이터브릭스" ✓
  → 조사가 달라도 동일한 검색 토큰으로 통일!
이 처리는 BM25 키워드 검색뿐 아니라 하이브리드 검색 전체의 품질을 높입니다. BM25 쪽의 품질이 떨어지면 앙상블 가중치를 아무리 조정해도 최종 검색 성능이 제한되기 때문입니다. 형태소 분석의 동작 원리: 형태소 분석기는 단순한 규칙 기반이 아닌 확률 모델 을 사용하여 어절을 분해합니다:
  1. 사전 탐색: 내장 사전에서 가능한 형태소 조합 후보를 탐색합니다. 예를 들어 “구축했습니다”는 “구축+했+습니다”로도, “구+축했+습니다”로도 분해할 수 있습니다.
  2. 확률 모델 적용: 여러 후보 중 가장 자연스러운 조합 을 통계적으로 선택합니다. 대규모 한국어 코퍼스에서 학습된 확률 분포를 기반으로, “구축+했+습니다”가 훨씬 자연스러운 분해임을 판단합니다.
  3. 미등록어 처리: 사전에 없는 신조어(예: “데이터브릭스”, “레이크하우스”)도 주변 문맥과 문자 패턴을 기반으로 품사를 추정합니다. 이 능력이 기술 문서 처리에서 특히 중요합니다.
다음은 실제 분석 과정의 예시입니다:
입력: "데이터브릭스에서 머신러닝 파이프라인을 구축했습니다"

분석 결과:
  데이터브릭스 (NNP, 고유명사) — 의미 핵심 ✓
  에서       (JKB, 부사격 조사) — 문법 기능, 검색에 불필요
  머신러닝    (NNG, 일반명사) — 의미 핵심 ✓
  파이프라인   (NNG, 일반명사) — 의미 핵심 ✓
  을         (JKO, 목적격 조사) — 문법 기능, 검색에 불필요
  구축       (NNG, 일반명사) — 의미 핵심 ✓
  했         (XSA, 과거 시제 접사) — 문법 기능, 검색에 불필요
  습니다      (EF, 종결 어미) — 문법 기능, 검색에 불필요

→ 검색용 토큰: ["데이터브릭스", "머신러닝", "파이프라인", "구축"]
RAG에서는 명사(NNG, NNP), 동사 어근(VV), 형용사 어근(VA), 외국어(SL) 만 추출하여 검색에 사용합니다. 조사, 어미 등 문법 기능 형태소를 제거함으로써 핵심 의미만으로 매칭 할 수 있게 됩니다.

Kiwi란?

Kiwi 는 C++ 기반의 고속 한국어 형태소 분석기입니다. 다른 한국어 형태소 분석기(KoNLPy의 Mecab, Komoran 등)와 비교했을 때 정확도와 속도 모두 뛰어나며, 특히 신조어와 미등록어 처리에 강합니다. Python 바인딩(kiwipiepy)을 통해 쉽게 사용할 수 있습니다.
형태소 분석기속도정확도설치 편의성미등록어 처리
Kiwi매우 빠름 (C++)높음pip install 한 줄통계 기반 추정
Mecab (KoNLPy)빠름 (C)높음시스템 의존성 복잡사전 추가 필요
Komoran (KoNLPy)보통 (Java)보통JVM 필요사전 추가 필요
Okt (KoNLPy)느림 (Java)보통JVM 필요제한적
Kiwi를 권장하는 이유는 Databricks 환경과의 호환성 때문이기도 합니다. 순수 Python 패키지로 설치되므로 클러스터에 별도 시스템 라이브러리를 설치할 필요가 없고, UDF로 감싸 대규모 배치 처리에도 사용할 수 있습니다.

설치

pip install kiwipiepy

기본 사용법

from kiwipiepy import Kiwi

kiwi = Kiwi()

# 형태소 분석
result = kiwi.tokenize("Databricks에서 RAG 파이프라인을 구축합니다")
for token in result:
    print(f"{token.form}\t{token.tag}\t{token.start}-{token.end}")
# Databricks  NNP    0-11
# 에서         JKB    11-13
# RAG          SL     14-17
# 파이프라인    NNG    18-23
# 을           JKO    23-24
# 구축         NNG    25-27
# 합니다       XSV+EF 27-30

주요 품사 태그

태그의미예시
NNG일반명사파이프라인, 구축, 데이터
NNP고유명사Databricks, Unity Catalog
VV동사구축하다, 배포하다
VA형용사빠르다, 정확하다
SL외국어RAG, LLM, API
JK*조사에서, 을, 의
E*어미합니다, 했습니다