검색은 완벽했는데 답은 왜 틀리나 — 생성단 사실 일치성 3층 방어

← 전체 목차 · 이전: RAG 시스템의 프롬프트 인젝션은 어떻게 막나 · 다음: RAG 효과는 어떻게 정량 평가하는가

사후(A/S) 상담 RAG가 "정품 보증"을 물은 고객에게 이렇게 답했다: 정품 1년 → 2년, 핵심 부품 3년 → 1년, 개봉 후 무이유 환불 불가 → 개봉해도 영향 없음. 세 조항 전부 오답이었고, 방향도 제각각이었다(늘어남/줄어듦/반전). 고객은 이 답을 들고 오프라인 매장에 가서 보증을 신청했다가 거절당했고, 결국 소비자보호원에 신고했다.

사후 조사 결과가 이 문제의 핵심이다: 검색이 리콜한 문서 조각은 100% 정확했고 질문을 완전히 커버했다. 문제는 순전히 생성 단계에서 터졌다.

상태
검색100% 정확, 최신 공식 문서를 리콜
생성검색 내용을 엄격히 따르지 않고, 낡은 학습 기억을 섞고 없는 조항을 새로 지어냄

"리콜이 맞으면 생성도 맞는다"는 가정이 여기서 정면으로 깨진다. RAG가 가장 위험해지는 지점은 바로 이곳이다 — 모델이 완전히 헛소리하면 사용자가 의심이라도 하지만, RAG의 오답은 "공식 문서를 근거로 했다"는 신뢰의 외피를 두르고 나온다. 그래서 사용자는 의심 없이 그 답을 들고 행동에 옮긴다.

4대 병근 — 왜 정확한 검색이 틀린 답으로 이어지나

#병근메커니즘
1다중 조각 혼합 접합여러 조각이 분류·필터링 없이 한꺼번에 들어가면, 모델이 각 조각의 적용 범위를 구분하지 못하고 서로 다른 시나리오의 내용을 무작위로 이어 붙인다
2조각에 섞인 잉여 정보무관한 부기·중복 서술·유사 지식점을 모델이 선별 없이 통째로 흡수해 핵심 질문에서 벗어난다
3생성 제약의 부재Prompt가 검색 내용을 강제로 근거로 삼게 하지 않으면, 모델은 "매끄럽고 완결된 답"을 우선시해 사전학습 지식으로 빈틈을 메운다
4어의 매칭 착오조각이 벡터 공간에서 "유사"하다고 판정되어 검색에는 성공했지만, 실제로는 질문과 다른 업무 시나리오를 다룬다 — 명중 자체가 가짜다

병근 4가 가장 발견하기 어렵다. 앞의 세 병근은 "조각은 맞는데 처리를 못 했다"는 가정 위에 서 있지만, 병근 4는 "명중"이라는 전제 자체가 거짓일 수 있음을 짚는다.

3층 방어 구조

검색 결과

  ├─[1층] 데이터·조각 구조화       ─ 병근 1, 2 대응
  │        지식베이스 조각을 업무 시나리오·지식점별로 통일 구조화
  │        각 조각에 적용 범위 라벨을 붙여 이종 시나리오의 접합을 차단

  ├─[2층] 업무 분급 + 강제 생성 규약  ─ 병근 3 대응
  │        고합규 시나리오(사후(A/S) 정책·요금 기준·법적 고지)
  │          → "오직 상하문 기반 생성" 강제, 모델 내장 지식 사용 금지
  │        일반 상담 시나리오(사용법·기능 설명)
  │          → 상식 보충 허용, 결론 강제 바인딩 없음

  └─[3층] 생성 후 사실 검증 + 아키텍처 제약  ─ 병근 3, 4 대응
           사실 함의 검증 ─ 출력을 검색 조각과 의미 매칭, 근거 없는 표현은 표시 후 제거·재생성 촉발
           강제 출처 추적 ─ 핵심 결론마다 출처 문서 바인딩, 출처 없으면 최종 답변에 미등장
           고위험 이차 재생성 ─ 검증 실패 시 프롬프트 조정 후 재생성, 재실패하면 사람에게 이관
           검색 증강 제약 디코딩 ─ 생성 단계에서 출력 분포 자체를 제한해 근거 없는 토큰 확률을 낮춤
           이중 경로 검증 아키텍처 ─ 생성 모델(초안) + 전용 검증 모델(원문 일치 대조), 검증 통과 후에만 반환
           강제 엄격 모드 스위치 ─ 대목·사후(A/S) 성수기·정책 갱신기에 개시, 원문 100% 일치 강제, 자유 재서술 금지

셋의 관계: 1층은 재료를 정리하고, 2층은 조리 규칙을 정하며, 3층은 완성된 요리를 출고 전에 검사하고 필요하면 되돌린다. 셋 중 하나만으로는 부족하다 — 사전 제약(2층)만 있으면 모델이 "안 지켜도 걸리지 않는" 요행을 노릴 수 있고, 사후 검증(3층)만 있으면 재생성이 반복되며 지연과 비용이 폭증한다.

진단: 어디가 문제인지 어떻게 가려내나

분층 로그(검색층 / 재정렬층 / 생성층)를 독립적으로 남긴다

  검색 조각 원문을 그대로 꺼내 사용자 질문을 커버하는지 대조
    ├─ 커버 안 됨 → 검색·재정렬 문제, 여기서 멈춘다
    └─ 커버함    → 문제는 생성단에 있다, embedding·청킹을 만지지 말 것

이 한 단계가 없으면 "회신이 틀렸다"는 신호 하나로 검색 파라미터부터 대규모 모델까지 순서대로 다 건드려보는 비효율에 빠진다.

핵심 통찰

  1. RAG에서 가장 위험한 실패는 "근거 있는 오답"이다 — 순수 생성 모델이 헛소리하면 사용자가 의심하지만, RAG의 오답은 "공식 문서에서 나왔다"는 맥락을 걸치고 있어 오히려 신뢰도가 높다. 오답의 파괴력은 얼마나 터무니없는가가 아니라 얼마나 그럴듯한가에 비례한다.
  2. 검색 지표와 생성 충실도는 서로 다른 것을 잰다 — 리콜율·관련성 같은 검색 지표가 100%여도 생성 결과의 사실 일치성은 별개로 측정해야 한다. 이 둘을 하나의 "정확률"로 뭉뚱그리면 사고는 지표에 잡히지 않는 사각지대에서 터진다.
  3. 모델의 목적함수는 "충실"이 아니라 "매끄러운 완결"이다 — 검색 내용이 답을 완전히 뒷받침하지 못할 때 모델은 잔결로 남느니 사전학습 지식으로 채운다. 그래서 "모델 내장 지식 사용 금지"는 반드시 명시적 Prompt 조항으로 써야지, "상하문을 참고하라"는 권유로는 지켜지지 않는다.
  4. 숫자를 바꾸는 오류보다 "없는 조항을 새로 만드는" 오류가 더 위험하다 — 개봉 후 무이유 환불이 "불가"에서 "영향 없음"으로 뒤집힌 사례처럼, 원문에 없는 반대 방향 결론은 단순 수치 비교로는 절대 잡히지 않는다. 검증은 문자열·숫자 대조가 아니라 어의 층위의 함의 판정이어야 한다.
  5. 방어는 반드시 등급별로 차등 적용해야 한다 — 엄격 모드는 답변을 딱딱하게 만드는 대가가 있다. 모든 질문에 걸면 일반 상담 경험이 나빠지고, 아무 데도 안 걸면 고합규 사고가 재발한다. "말이 틀리면 클레임으로 이어지는가"를 기준으로 방어 강도를 나눠야 비용 대비 효과가 맞는다.
  6. 사전 제약과 사후 검증은 서로를 대체하지 못한다 — 제약 디코딩은 생성률을 낮추지만 완전히 막지는 못하고, 사실 검증은 새는 것을 잡아내지만 재생성 비용을 태운다. 둘을 겹쳐야 비로소 "발생률을 낮추고 + 유출률을 낮추는" 이중 방어가 완성된다.
  7. 자동화할 수 있는 방안만이 진짜 방안이다, 단 인간 종착점은 남겨둬야 한다 — "모든 답을 사람이 검수한다"는 규모가 안 나오는 가짜 해법이다. 옳은 구조는 자동 검증 → 자동 재생성 → 재시도까지 실패한 것만 사람에게 넘기는 것이다.
  8. 근본 원인 진단은 검색과 생성을 먼저 갈라야 한다 — "리콜 조각이 질문을 커버하는가"를 가장 먼저 확인하면, 커버하는데도 틀렸다는 결과가 나왔을 때 embedding 교체나 청킹 재설계 같은 헛수고를 원천 차단한다.

엔지니어링 실전 Tips

  • "모델 내장 지식 사용 금지"는 요청이 아니라 하드 제약으로 쓸 것: 프롬프트에 애매하게 "상하문을 참고해서 답하라"고 쓰면 모델은 지킬 수도 안 지킬 수도 있다. 명시적 금지 조항 + 사후 검증으로 이중 잠금해야 한다.
  • 사실 검증은 문자열·숫자 대조가 아니라 어의 함의 판정으로: 숫자 뒤바뀜, 방향 반전(불가→영향없음), 없는 조항 신설을 모두 잡으려면 검증 자체가 언어모델 수준의 의미 이해를 갖춰야 한다.
  • 출처 추적은 문장 단위가 아니라 결론 단위로 바인딩할 것: 답변 전체에 참고 링크 하나만 붙이면 부족하다. 조항이 세 개면 출처도 세 개 독립적으로 바인딩해야 오답 조항이 정답 조항에 묻어 나가지 못한다.
  • 엄격 모드는 시간 창으로 켜고 끌 것: 대목·사후(A/S) 성수기·정책 갱신기처럼 오답의 후폭풍이 큰 구간에만 걸고, 평시에는 정상 유연성을 유지한다.
  • 재시도 횟수와 사람 이관 임계값을 명시적으로 정할 것: "재시도해도 통과 못 하면 사람에게"를 코드로 못 박아야 무한 재시도나 무책임 통과를 막을 수 있다.
  • 분층 로그 없이 사고를 복기하지 말 것: 검색층·재정렬층·생성층을 분리해 남기지 않으면 "어디서 틀렸나"는 영원히 추측으로 남는다.
  • 더 파고들 방향: 사실 함의 검증 모델 자체의 선택(경량 NLI 모델 vs LLM-as-judge)과 지연·비용 비교, 제약 디코딩의 구현 방식(logit bias vs 문법 제약 디코딩), 업무 분급 규칙의 자동화(문서 태그·지식베이스 파티션에 따라 고합규 여부를 자동 판정), 이 문서와 RAG21 프롬프트 인젝션 방어의 접점 — 둘 다 "생성이 검색 내용을 벗어나는" 것을 막지만 공격자가 유발하는가 모델이 스스로 유발하는가로 나뉜다.