Contents
see List왜 RAG 품질은 모델보다 검색 설계에서 먼저 흔들리는가
RAG는 거대 언어 모델에 사내 문서, 매뉴얼, 정책, 상품 정보 같은 외부 지식을 붙여 답변하게 만드는 구조입니다. 하지만 실제 운영에서는 모델을 바꾸기 전에 검색 단계가 먼저 병목이 됩니다. 질문과 관련 없는 문단이 들어오면 좋은 모델도 그럴듯한 오답을 만들고, 필요한 근거가 빠지면 답변은 공손하지만 실무에는 쓸 수 없습니다. 따라서 RAG 품질 개선은 프롬프트 튜닝보다 문서 분할, 메타데이터, 검색 쿼리, 재랭킹, 근거 검증 순서로 점검하는 것이 안정적입니다.
이 문서는 이미 벡터 검색을 붙였지만 답변 품질이 들쭉날쭉한 팀을 위한 실전 가이드입니다. 특정 벡터 DB나 모델에 묶이지 않고, 사내 지식 검색형 챗봇, 고객지원 자동응답, 업무 매뉴얼 검색, 계약서 질의응답 시스템에 공통으로 적용할 수 있는 설계 기준을 정리합니다.
1. 청킹은 글자 수가 아니라 의미 단위로 나눈다
가장 흔한 실수는 문서를 500자 또는 1000자 단위로 기계적으로 자르는 것입니다. 이렇게 하면 표 제목과 표 내용이 갈라지거나, 절차의 조건과 실행 단계가 분리되어 검색 결과가 불완전해집니다. 청킹의 기준은 길이가 아니라 답변 가능한 의미 단위입니다. 한 chunk 안에는 질문에 답할 수 있는 주어, 조건, 결론, 예외가 함께 있어야 합니다.
- 정책 문서는 조항, 예외, 적용 대상을 같은 chunk에 둡니다.
- 개발 문서는 설정 목적, 코드 예제, 주의사항을 같은 chunk에 둡니다.
- FAQ는 질문과 답변을 절대 분리하지 않습니다.
- 표 문서는 컬럼 의미와 행 데이터를 함께 보존합니다.
- 긴 문서는 제목 계층을 메타데이터로 남기고 본문은 너무 잘게 쪼개지 않습니다.
운영 기준으로는 한국어 일반 문서의 경우 700자에서 1400자 사이를 먼저 테스트하고, overlap은 100자에서 200자 정도로 시작하는 것이 무난합니다. 다만 API 명세, 에러 코드표, 가격 정책처럼 구조가 뚜렷한 문서는 길이보다 항목 단위 분할을 우선해야 합니다.
2. 메타데이터는 필터링과 설명 가능성을 위해 남긴다
벡터 검색은 의미 유사도를 잘 찾지만, 날짜, 권한, 부서, 제품군, 문서 상태 같은 운영 조건은 별도 메타데이터로 관리해야 합니다. 예를 들어 폐기된 매뉴얼과 최신 매뉴얼이 동시에 검색되면 모델은 둘 중 하나를 임의로 선택할 수 있습니다. 고객용 문서와 내부용 문서가 섞여도 보안 문제가 생깁니다. 따라서 임베딩을 저장할 때 본문만 넣지 말고 검색 제한에 필요한 속성을 함께 저장해야 합니다.
const chunk = {
id: 'kb-2026-05-29-001-03',
text: '비밀번호 재설정 링크는 발송 후 30분 동안만 유효합니다...',
metadata: {
source: 'help-center',
product: 'admin-console',
audience: 'customer',
status: 'published',
version: '2026-05',
section: '계정 보안 > 비밀번호 재설정',
updatedAt: '2026-05-29',
url: 'https://example.com/docs/account/password-reset'
}
};
메타데이터는 나중에 출처 표시에도 쓰입니다. 답변 하단에 문서명, 섹션, 갱신일을 함께 보여주면 사용자는 답변을 검증할 수 있고, 운영자는 잘못 검색된 chunk를 추적할 수 있습니다. RAG 시스템에서 신뢰도는 모델의 말투보다 근거를 되짚을 수 있는 구조에서 나옵니다.
3. 검색은 벡터 하나로 끝내지 말고 하이브리드로 설계한다
벡터 검색은 의미가 비슷한 문서를 찾는 데 강하지만 제품 코드, 에러 번호, API 경로, 법 조항, 클래스명처럼 정확한 문자열이 중요한 질문에는 약할 수 있습니다. 반대로 키워드 검색만 쓰면 표현이 다른 질문을 놓칩니다. 그래서 실무형 RAG는 벡터 검색과 키워드 검색을 함께 수행하고, 두 결과를 합친 뒤 재랭킹하는 방식이 안정적입니다.
- 에러 코드, 주문번호, API 엔드포인트가 포함된 질문은 키워드 점수 비중을 높입니다.
- 사용자가 증상을 자연어로 설명하면 벡터 점수 비중을 높입니다.
- 최신 문서가 중요한 업무는 updatedAt 또는 version 점수를 추가합니다.
- 권한이 다른 문서는 검색 단계에서 미리 제외합니다.
async function retrieve(question, user) {
const filters = {
status: 'published',
audience: user.role === 'employee' ? ['internal', 'customer'] : ['customer'],
product: user.currentProduct
};
const vectorHits = await vectorStore.search(question, { topK: 30, filters });
const keywordHits = await keywordIndex.search(question, { topK: 30, filters });
const merged = mergeById(vectorHits, keywordHits);
return rerank(question, merged, {
topK: 6,
boostRecent: true,
requireSource: true
});
}
초기에는 topK를 너무 작게 잡지 않는 것이 좋습니다. 3개만 검색해 바로 모델에 넣으면 좋은 후보가 빠질 가능성이 큽니다. 20개에서 50개 정도를 넓게 가져온 뒤 재랭킹으로 5개 안팎을 고르는 구성이 장애 분석과 품질 개선에 유리합니다.
4. 재랭킹은 답변 직전의 품질 게이트다
재랭킹은 검색 후보 중 질문에 정말 도움이 되는 문서를 다시 정렬하는 단계입니다. 단순 유사도 점수만 사용하면 제목은 비슷하지만 세부 조건이 다른 문서가 상위에 올라올 수 있습니다. 재랭킹 단계에서는 질문, 후보 본문, 메타데이터를 함께 보고 실제 답변 가능성을 평가해야 합니다.
운영에서는 재랭킹 결과에 최소 점수 기준을 두는 것이 중요합니다. 적절한 근거가 없으면 모델에게 억지로 답하게 하지 말고, 관련 문서를 찾지 못했다고 말하게 해야 합니다. 특히 계약, 장애 대응, 보안 정책, 비용 안내처럼 오답 비용이 큰 업무에서는 낮은 점수의 근거로 답변을 생성하지 않는 편이 낫습니다.
const MIN_RERANK_SCORE = 0.62;
function buildAnswerContext(rerankedHits) {
const selected = rerankedHits.filter(hit => hit.score >= MIN_RERANK_SCORE).slice(0, 5);
if (selected.length === 0) {
return {
mode: 'no_context',
instruction: '근거 문서를 찾지 못했으므로 추측하지 말고 확인 요청을 안내한다.'
};
}
return {
mode: 'grounded_answer',
contexts: selected.map(hit => ({
text: hit.text,
source: hit.metadata.section,
updatedAt: hit.metadata.updatedAt
}))
};
}
5. 답변 생성 프롬프트에는 금지 규칙을 명확히 넣는다
RAG 프롬프트는 화려할 필요가 없습니다. 핵심은 근거 밖 추측 금지, 출처 표시, 불확실성 처리, 최신성 우선순위입니다. 모델에게 모든 것을 해결하라고 맡기지 말고, 검색 결과를 사용하는 방식과 실패 시 행동을 분명히 지정해야 합니다.
const systemPrompt = [
'너는 사내 기술 문서 기반 답변 도우미다.',
'1. 제공된 context에 있는 내용만 근거로 답한다.',
'2. context에 없는 내용은 추측하지 않는다.',
'3. 서로 충돌하는 문서가 있으면 updatedAt이 최신인 문서를 우선한다.',
'4. 답변 끝에 사용한 문서의 section과 updatedAt을 표시한다.',
'5. 근거가 부족하면 현재 문서 기준으로는 확인할 수 없다고 답한다.'
].join('
');
이 규칙은 간단하지만 운영 효과가 큽니다. 사용자는 근거를 확인할 수 있고, 운영자는 잘못된 답변이 검색 문제인지 문서 문제인지 프롬프트 문제인지 나눠서 볼 수 있습니다.
6. 운영 지표는 답변 만족도가 아니라 검색 실패부터 본다
RAG 품질을 개선하려면 로그를 남겨야 합니다. 최소한 질문, 검색된 chunk id, 재랭킹 점수, 최종 사용된 근거, 답변 성공 여부, 사용자의 피드백을 저장해야 합니다. 단순히 답변 텍스트만 저장하면 왜 틀렸는지 알 수 없습니다. 운영 초반에는 모델 답변을 평가하기보다 검색 후보가 적절했는지부터 보는 것이 빠릅니다.
- 정답 문서가 검색 후보에 없으면 청킹, 인덱싱, 필터 조건을 점검합니다.
- 정답 문서가 후보에는 있지만 선택되지 않으면 재랭킹 기준을 점검합니다.
- 정답 문서가 선택됐는데 답변이 틀리면 프롬프트와 생성 모델을 점검합니다.
- 문서 자체가 없으면 지식베이스 운영 프로세스를 개선합니다.
마무리 체크리스트
RAG는 모델을 붙였다고 끝나는 기능이 아니라, 검색 품질을 지속적으로 관리하는 운영 시스템입니다. 실무 적용 전에는 다음 항목을 확인하는 것이 좋습니다. 문서는 의미 단위로 나뉘었는가, 검색 필터에 필요한 메타데이터가 있는가, 벡터와 키워드 검색을 함께 쓰는가, 재랭킹 최소 점수와 근거 없음 처리가 있는가, 답변에 출처와 갱신일이 표시되는가, 검색 후보와 최종 근거 로그가 남는가. 이 여섯 가지가 갖춰지면 모델 교체 없이도 RAG 답변 품질을 크게 안정화할 수 있습니다.