본 문서는 "방대한 한국어 지식에서 사용자의 질문에 근거 있는 답을 검색·생성한다"는 과제를 해결하는 과정을 담았습니다.
기업·서비스가 보유한 지식의 대부분은 뉴스·매뉴얼·위키·FAQ 등 방대한 문서 코퍼스에 흩어져 있다. 사용자는 이 지식을 구조나 키워드가 아니라 자연어 질문으로 꺼내 쓰고 싶어 한다. 그러나 LLM에게 질문만 던지면 (a) 학습에 없던 지식은 지어내고(환각), (b) 출처가 없어 검증이 불가능하며, (c) 최신·도메인 지식을 반영하지 못한다. 이를 해결하려면 질문에 대해 관련 문서를 검색해 근거로 붙이고(RAG), 그 근거 위에서 답을 생성해야 한다. 그런데 실제 현장에서는 사용자 질문이 모호하거나 구어체라 검색이 빗나가고, 리트리버가 언어·도메인에 정합되지 않으면 엉뚱한 문서를 상위로 올리며, LLM이 검색된 문서를 무시하고 지어내거나 반대로 과도하게 기권한다. 요구사항은 "질문을 이해해 알맞은 문서를 찾고, 그 근거만으로 출처를 밝혀 답하라"이다.
- 초기 접근 방법: "RAG = 질문으로 top-k 문서를 검색해 그대로 이어 붙여 LLM에 넣기"(naive concat). → 그러나 구어체·모호 질문은 검색 자체가 빗나가고, 사전학습 임베딩은 대상 언어·도메인에 정합되지 않아 정답 문서를 상위로 올리지 못한다. 검색이 틀리면 생성은 근거 없는 답을 만든다. 또 문서를 단순 concat하면 LLM이 근거를 무시하고 지어내거나 인용을 남기지 않는다. naive concat은 "질문을 이해하고, 알맞은 근거를 찾아, 그 위에서만 답하라"에 답하지 못한다.
- 현재 접근 방법: RAG 질의응답의 핵심은 "검색 품질이 생성 품질의 상한"이라는 점이다. 이를 AI 문제로 옮기면 세 하위 문제로 분해된다.
- 모호·구어 질문을 검색친화 질의로 바꾸는 질의 재작성 → query rewriting
- 정답 문서를 상위로 올리도록 리트리버를 대상 도메인에 정합시키는 리트리버 파인튜닝 → dense retrieval + contrastive finetuning
- 검색된 문서만 근거로, 출처를 인용해 답하고 근거가 없으면 정직하게 대응하는 근거 기반 생성 → grounded generation + citation / abstention
Retrieval-Augmented Question Answering (RAG QA) — 한국어 질문이 주어지면 (질의 재작성 → 문서 검색 → 근거 기반 한국어 답변 + 문서 인용)으로 이어지는 파이프라인.
- 하위 태스크: Query Rewriting + Dense Retrieval(+ contrastive finetuning) + Grounded Generation(+
[문서 n]인용, 근거 부재 대응) - 최종 산출물: 질문별 (재작성 질의, 검색 근거 문서, 인용이 달린 한국어 답변) → 문서 기반 챗봇 / 지식 검색 어시스턴트 / 사내 QA의 코어로 직결
- 단순 LLM은 근거·출처가 없어 신뢰할 수 없고, naive concat RAG는 검색 품질에 발목이 잡힌다. RAG QA는 이를 검증 가능한(인용 있는) 지식 응답으로 바꾼다.
- 응용 맥락: 문서 기반 챗봇, 사내 지식 검색, 고객지원 자동응답, LLM 출력의 사실성·출처 보강 레이어.
- 확장성: 데이터셋(뉴스·법률·의료)만 바꿔 재사용 가능하고, 대화 메모리(6절 참고)를 붙이면 멀티턴 개인화 대화로 확장된다.
- Dense Retrieval: DPR·Sentence-Transformers 계열이 질의/문서를 같은 벡터 공간에 임베딩해 코사인 유사도로 검색. e5·bge·ko-sroberta 등 다국어·한국어 임베딩이 강한 표준.
- 대조학습(Contrastive): (query, 정답문서) 쌍을 가깝게, 배치 내 나머지를 멀게 미는 in-batch negative(MultipleNegativesRankingLoss). 적은 라벨로 리트리버를 도메인에 정합시키는 대표 기법.
- RAG: Lewis et al.의 RAG, FiD 등 검색 결과를 생성 조건으로 결합하는 프레임. 검색 품질이 생성 상한을 결정.
- Query Rewriting / Expansion: 모호·구어 질문을 검색친화 질의로 바꾸는 LLM 재작성·HyDE·확장 기법. 검색 recall을 끌어올림.
- Grounded Generation / Faithfulness: 인용 강제, 근거 부재 시 기권(abstention), 환각 억제 등 근거 충실도 향상 연구.
- 평가: BEIR 스타일 랭킹 평가(Recall/MRR/nDCG/Hit@k)로 검색 품질을 생성과 분리해 측정.
- Primary baseline: 사전학습 임베딩 + Chroma(cosine) 검색 + GPT-4o-mini 근거 프롬프트 생성
- 사전학습 임베딩(예:
BAAI/bge-m3)으로 코퍼스를 색인하고, 원 질문 그대로 top-k 검색 - 검색 문서를 프롬프트에 넣어 GPT-4o-mini(API)로 한국어 답변 생성 — 질의 재작성·파인튜닝 없음
- 실행:
python -m rag.cli ask "질문"
- 사전학습 임베딩(예:
- 선정 이유: (a) 재현이 쉬워 공정한 비교 기준이 되며, (b) 우리가 개선하려는 지점(구어·모호 질문의 검색 미스, 도메인 미정합 리트리버, 근거 무시·환각)이 구조적으로 드러난다.
- (참고용 하한 baseline) 검색 없이 LLM 단독 응답 — RAG의 근거·출처 효과와 필요성을 대비하는 용도.
Query-rewritten · Finetuned-retriever · Grounded-prompted RAG — baseline 파이프라인을 유지하면서 세 지점을 개선해 결합한다.
- 질의 재작성: LLM으로 모호·구어 질문을 핵심 개체·키워드 중심의 검색친화 질의로 재작성한 뒤 검색에 사용.
- 리트리버 파인튜닝: (query, 정답문서) 쌍을 in-batch negative 대조학습(MultipleNegativesRankingLoss)으로 학습해 대상 도메인·언어에 정합. 파인튜닝 전/후를 같은 평가셋으로 비교한다.
- 근거 기반 프롬프팅: 참고 문서만을 기반으로 답하도록 고정하고
[문서 n]인용을 강제하며, 근거가 부재하면 '제공된 문서에서 찾을 수 없습니다'로만 기권하게 한다.
| 구분 | Baseline | Proposed (Rewrite + Finetune + Grounded) |
|---|---|---|
| 질의 처리 | 원 질문 그대로 검색 | LLM 질의 재작성 후 검색 |
| 리트리버 | 사전학습 임베딩 고정 | (query, 정답) 대조학습 파인튜닝 |
| 근거 사용 | 문서 단순 concat, 인용 없음 | [문서 n] 인용 강제 |
| 근거 부재 대응 | 자유 생성(환각 위험) | 기권 고정('제공된 문서에서 찾을 수 없습니다') |
| 평가 | 생성 결과만 정성 | 검색(Recall/MRR/nDCG/Hit) + 생성 분리 평가 |
- 사용 데이터셋: Ko-miracl (
taeminlee/Ko-miracl, 한국어, BEIR 스타일)queries(_id,text) +qrels(query-id,corpus-id,score>0=정답) +corpus(_id,title,text), train / dev split- 생성 임베딩
BAAI/bge-m3, 리트리버 파인튜닝 베이스jhgan/ko-sroberta-multitask, 생성 LLMgpt-4o-mini(API)
- 데이터 특성
- 코퍼스가 대규모(약 149만 청크)라 전량 색인 불가 → 정답 문서 + 네거티브 풀만 스트리밍 수집
- qrels의 관계 분포가 long-tail, 질의당 정답은 소수이고 대부분 문서는 비정답(NA)
- 질문이 실제 검색 질의라 모호·구어체가 섞여 있어 질의 재작성의 이득이 드러남
- 전처리
- 코퍼스를 스트리밍하며 정답 문서 +
neg_pool_size만큼의 네거티브만 수집(전량 로드 회피) - 코사인 공간을 위해 임베딩 정규화, e5 계열 대비 query/passage prefix 지원,
max_seq_len절단 - 리트리버 학습용 (query, 정답문서) 쌍 구성(score>0만), in-batch negative로 대조학습
- 검색 결과는
score = 1 - distance(클수록 유사) 계약으로 통일해 생성부에 전달
- 코퍼스를 스트리밍하며 정답 문서 +
- H1. LLM 질의 재작성이 모호·구어 질문의 검색 Recall / nDCG를 높일 것이다.
- H2. (query, 정답) 대조학습 파인튜닝이 리트리버를 도메인에 정합시켜 Recall@k · MRR을 파인튜닝 전 대비 개선할 것이다.
- H3. 근거 기반 인용 프롬프트가 환각을 줄이고, 근거 부재 시 기권을 고정하면 (기권율 ↔ 유용성) 트레이드오프가 드러날 것이다. 검증은 같은 평가셋을 정답 문서 포함/제외 두 조건으로 돌려 양방향(과잉 기권 ↔ 환각)으로 측정한다.
- E1. Baseline(사전학습 임베딩 + 원 질문 + 근거 프롬프트) 재현 및 성능 측정
- E2. 리트리버 파인튜닝 전/후 비교 — 동일 평가셋 (
python -m rag.cli compare) - E3. 질의 재작성 유무 비교 (검색 품질 변화)
- E4. Ablation — 프롬프트 전략(
A_baseline지시만 vsB_fewshot예시 주입,prompts.py), 인용 강제 유무, top_k 변화의 효과 분리 - E5. 정성 분석 — 검색 미스 · 환각 · 부적절한 기권 사례 집중 검토
- 원 질문 vs 재작성 질의 (검색 품질)
- 파인튜닝 전 vs 후 (Recall / MRR / nDCG / Hit@k) — 주 비교
- 프롬프트
A_baselinevsB_fewshot(기권율 · 인용 정확성 · 환각) - 정답 문서 포함 vs 제외 인덱스 (과잉 기권 ↔ 환각 트레이드오프)
- top_k 별 검색·생성 성능
- 평가셋
- dev 정답(score>0) 쿼리 전수 213개를 검색·생성 평가에 동일하게 고정 사용
- train split은 평가에 쓰지 않는다 — 리트리버 파인튜닝 학습에 쓰이므로 평가에 섞으면 데이터 누수
- 같은 213개를 두 조건으로 실행 — 정답 문서 포함 인덱스(answerable) / 정답 문서 제외 인덱스(무근거) → 환각율·기권 적절성을 양방향으로 측정
- 코퍼스 밖 질문(OOD)은 라벨이 우리 추정이라 정량 집계에서 제외하고 정성 예시로만 보고
- 평가셋 구성 시 질문 길이 분포(
evaluation/check_evalset_dist.py)와 카테고리 분포(evaluation/check_evalset_topics.py) 두 축의 치우침을 점검 (카테고리는 DB의doc_type수급) - 검색 평가와 파인튜닝 전/후 비교는 같은 규모(약 20만 청크)의 인덱스에서 측정 — 인덱스가 작으면 정답 찾기가 쉬워져 절대 수치가 부풀려지고 파인튜닝 개선폭이 천장에 눌린다
- 지표 설계
- 검색: Recall@k, MRR@k, nDCG@k, Hit@k (
rag/metrics.py, k = 1 / 5 / 10) — 주 지표, 생성과 분리 측정 - 생성 (규칙 기반·결정적): 인용 정확성(
[문서 n]의 범위 유효성), 환각율, 기권 적절성 (rag/gen_metrics.py) — 판정 LLM 없이 재현 가능 - 생성 (의미 지표, RAGAS): faithfulness / answer_relevancy — 판정기는 생성 모델(
gpt-4o-mini)보다 상위 모델을 temperature=0으로 고정 사용.context_precision은 RAGAS가 정답 '문장'(ground truth)을 요구하는데 Ko-miracl에는 정답 '문서'만 있어 제외 - 파인튜닝 전/후는 개선폭(Δ, 개선%)을 함께 보고
- 검색: Recall@k, MRR@k, nDCG@k, Hit@k (
- 지표 검증 방법
- 타당성: 검색 지표(nDCG/MRR) 개선이 실제 생성 답변의 근거 품질 향상과 정렬되는지 대조
- 신뢰성: 파인튜닝 전/후 비교는 학습 seed를 바꾼 3회의 평균 ± 표준편차로 보고한다(매 회 새로 학습하므로 실제 변동이 발생). 반면 생성은 1회로 충분 — 생성이 API + temperature=0 이라 같은 입력에 같은 답이 나와 반복해도 표준편차가 0에 수렴하고, 판정 API 비용만 배로 든다. 질의 재작성·RAGAS 판정도 모두 temperature=0으로 결정적이며, 파인튜닝 전/후는 동일 평가셋 고정
- 사람 평가: 팀 결정으로 제외 — 생성 평가는 자동(규칙 기반 + LLM 판정)으로만 수행
- 한계: 판정기와 생성기가 다른 모델이라 자기 채점(순환) 편향은 없으나 둘 다 OpenAI 계열이라 완전 독립은 아님 → 규칙 기반 지표와 교차 확인. 또 RAGAS
faithfulness는 "주어진 문서에 충실한가"만 보므로 검색이 헛다리를 짚어도 그 문서에 충실하면 점수가 높다 — 환각율을 대체하지 못하며, 정답 문서를 제외한 무근거 조건이 그 역할을 담당 - sanity check: 인용된
[문서 n]이 실제 검색 근거에 존재하는지, 근거 부재 시 strict가 기권하는지 점검
| 일자 | 수행 내용 | 산출물 |
|---|---|---|
| 7/20 | 팀 구성 및 주제 선정 (Knowledge RAG QA / Ko-miracl) | 주제 확정 |
| 7/21 | 데이터 분석(Ko-miracl 구조·통계), baseline 후보 탐색 | 데이터 분석 노트북 |
| 7/22 | 연구 계획 확정, 전처리·평가 파이프라인 설계 | 연구 계획서, 스켈레톤 코드 |
| 7/23 | Baseline(사전학습 임베딩 + 근거 프롬프트) 재현 및 1차 성능 측정 | 1차 성능(Recall/MRR/nDCG/Hit) |
| 7/24 - 7/25 | 리트리버 파인튜닝 전/후 비교, 질의 재작성·프롬프트 전략 실험 | compare 결과, 생성 로그, 학습 곡선 |
| 7/26 | Ablation·정성 분석, 파이프라인 패키지화(rag/), 발표자료 작성 |
Ablation 표, 통합 파이프라인, PPT |
| 7/27 | 결과 정리 및 최종 발표 | 최종 발표 |
현재 파이프라인은 질문 하나에 대한 단발성 RAG QA다. 이를 멀티턴 대화로 확장하되, 이전 대화를 단순 history concat으로 이어 붙이는 방식은 컨텍스트 길이·비용이 폭증하고 오래된 잡음까지 함께 끌고 들어가는 문제가 있다. 대신 요약 기반 memory / selective memory를 설계한다.
- Redis (단기 메모리): 세션별 최근 대화 턴·상태를 TTL과 함께 캐시. 빠른 read/write로 진행 중 대화의 즉시 컨텍스트를 담당.
- PostgreSQL (장기 메모리): 대화 요약·사용자 선호/제약을 영속 저장. 세션이 끝나도 남는 장기 지식 레이어.
- 요약 기반 / selective 회수: 전체 히스토리를 붙이는 대신 (a) LLM으로 과거 대화를 요약해 압축 저장하거나, (b) 현재 질문과 관련성 높은 과거 턴만 선택적으로 회수해 컨텍스트에 주입. 검색 단계에서 문서 코퍼스와 대화 메모리를 하나의 근거 소스로 결합한다.
- 기대 효과: 동일한 질문이라도 이전 대화 맥락(앞서 밝힌 선호·제약·화제)에 따라 다른 답변이 나오도록 설계 — 개인화된 멀티턴 응답, 컨텍스트 길이·비용 절감, 장기 일관성 확보.