RAG 검색 품질을 높이는 법, 청크·하이브리드 검색·필터를 따로 조정하기
AI · LLM · 검색 설계
AI를 활용하여 생성한 이미지입니다.
RAG가 엉뚱한 문서를 가져올 때 청크 크기만 바꾸면 원인을 놓치기 쉽습니다. 검색 결과는 문서를 어떻게 나눴는지, 키워드가 맞는지, 임베딩 벡터가 가까운지, 메타데이터 필터가 너무 좁지 않은지, 몇 개를 반환하고 어떤 순서로 다시 정렬하는지가 함께 결정합니다. 한 질의에서 좋아진 설정이 다른 질의에서는 잡음을 늘릴 수 있으므로, 증상별로 조정 항목을 나눠야 합니다.[1][2]
먼저 검색 실패의 종류를 구분하세요
| 증상 | 먼저 볼 항목 | 피해야 할 반응 |
|---|---|---|
| 정답 문장이 중간에서 잘림 | 청크 경계와 겹침 | 모든 청크를 무조건 크게 만들기 |
| 비슷한 문서가 너무 많이 나옴 | 메타데이터 필터·top 수 | 임베딩 모델부터 교체하기 |
| 제품 코드·오류 번호를 못 찾음 | 키워드 검색과 하이브리드 방식 | 벡터 검색만 고집하기 |
| 관련 없는 결과도 항상 반환됨 | 점수 임계값·빈 결과 처리 | k만 계속 늘리기 |
| 정답은 있지만 답변에 반영되지 않음 | 재순위·컨텍스트 조합·생성 단계 | 검색 성공으로 간주하기 |
이 표에서 중요한 점은 검색 결과에 정답 문서가 포함되는 것과 최종 답변이 정답을 사용하는 것이 다른 품질 문제라는 사실입니다. 검색 단계와 생성 단계를 분리해 기록해야 어느 부분을 고칠지 결정할 수 있어요.
청크는 검색의 단위입니다
OpenAI Retrieval 문서는 파일을 벡터 스토어에 넣으면 청크화·임베딩·인덱싱을 거쳐 검색할 수 있다고 설명하고, 고정 청크 전략의 예로 최대 1,200토큰과 200토큰 겹침을 제시합니다.[1] 이 수치를 모든 문서에 그대로 적용하라는 뜻은 아닙니다. 제품 설명서, 회의록, 코드, 표, 규정처럼 경계가 중요한 자료는 제목과 조항, 표의 행이 분리되지 않도록 의미 단위로 나누는 편이 낫습니다.
청크가 너무 작으면 질문에 필요한 조건과 결론이 서로 다른 조각으로 갈라집니다. 반대로 너무 크면 한 조각에 주제가 여러 개 섞여 유사도 점수가 흐려지고, 생성 모델에 불필요한 내용이 많이 전달됩니다. 겹침은 문장 경계가 끊기는 문제를 줄이는 장치이지, 나쁜 분할을 대신하는 만능 해결책은 아니에요.
문서 유형별 분할 기준
- 매뉴얼: 기능 제목, 사전 조건, 단계, 예외를 한 흐름으로 유지합니다.
- 규정·계약: 조항 번호와 적용 범위를 함께 보존합니다.
- 코드: 함수나 클래스 단위로 나누고 파일 경로와 언어를 메타데이터로 남깁니다.
- 표: 열 제목과 행의 의미가 분리되지 않게 텍스트로 변환합니다.
- 긴 글: 제목 계층과 문단 경계를 이용하되, 답변에 필요한 정의와 제한 조건이 같이 남는지 확인합니다.
벡터와 키워드를 함께 쓰는 이유
벡터 검색은 표현이 달라도 의미가 비슷한 내용을 찾는 데 유리합니다. 반면 제품 코드, 오류 번호, 버전 문자열, 법 조항처럼 정확한 문자열이 중요한 질의는 키워드 검색이 더 직접적일 수 있어요.[1][3] Azure AI Search 문서는 키워드 검색과 벡터 검색을 한 요청에서 수행하는 하이브리드 검색과 결과를 RRF 방식으로 합치는 흐름을 설명합니다.[2][3]
자연어로 “로그인이 계속 실패하는 이유”를 묻는 질문은 벡터 검색의 도움을 받을 수 있지만, “ERR-4017”처럼 고유한 문자열을 입력한 질문은 정확한 일치가 중요합니다. 날짜·부서·제품 버전 조건까지 붙으면 하이브리드 검색과 메타데이터 필터를 함께 고려해야 합니다. 검색 방식을 하나로 고정하기보다 실제 질의 유형을 분류해 기본 경로를 정하세요.
필터는 검색 전에 적용하되, 너무 좁히지 마세요
제품, 버전, 지역, 공개 상태, 작성 부서 같은 속성을 문서에 저장하면 후보 범위를 줄일 수 있습니다. OpenAI Retrieval 문서는 파일 속성에 조건을 걸어 날짜나 지역 같은 범위로 검색하는 방법을 설명합니다.[1] 공개 문서만 답변에 쓰려는 경우처럼 반드시 지켜야 할 조건은 검색 결과를 받은 뒤 프롬프트로 부탁하기보다 필터로 제한하는 편이 예측 가능합니다.
제품 = "A"
버전 >= "4.2"
공개상태 = "public"
다만 필터를 여러 개 겹치면 정답 문서가 후보에서 빠져 0건이 될 수 있습니다. 필터 적용 전·후 결과 수를 로그에 남기고, 0건이면 제품→버전→공개 상태처럼 조건을 하나씩 풀어 보는 진단 경로를 마련하세요. 필터를 완화할 때 비공개 문서가 답변에 섞이지 않도록, 검색용 완화와 답변용 접근 권한 검사를 분리해야 합니다.
k, 임계값, 재순위를 따로 조절하세요
벡터 검색은 가장 가까운 결과를 k개 채워 반환할 수 있습니다. 유사도가 낮아도 k가 채워지면 관련 없는 문서가 답변 컨텍스트에 들어갈 수 있어요. Azure 문서도 순수 벡터 질의에서 점수 임계값으로 약한 결과를 제외할 수 있다고 설명합니다.[2] 따라서 k를 5에서 20으로 늘리는 것이 근거를 늘리는 선택이라고 단정할 수 없습니다.
- 대표 질의 20~50개를 만들고 정답 문서 ID와 정답 청크를 표시합니다.
- 청크 변경 전후에 정답 문서가 top-k 안에 들어오는지 비교합니다.
- 정답은 들어왔지만 순위가 낮으면 하이브리드 검색이나 재순위를 검토합니다.
- 정답이 없는데도 결과가 늘 채워지면 점수 임계값과 빈 결과 응답을 조정합니다.
- 최종 답변에 인용할 문장과 제한 조건이 한 컨텍스트에 함께 있는지 확인합니다.
재순위 모델을 넣는 경우에도 후보를 넓히는 것과 답변에 전달할 최종 문서를 고르는 것을 구분하세요. 후보를 많이 가져온 뒤 재순위하는 구조는 도움이 될 수 있지만, 필터가 잘못됐거나 원문이 오래됐다는 문제를 해결하지는 않습니다.
평가 질의와 운영 로그를 먼저 만드세요
검색 품질을 판단하려면 “그럴듯해 보인다”는 인상 대신 반복 가능한 질의 집합이 필요합니다. 실제 사용자가 묻는 자연어 질문, 제품 코드가 포함된 질문, 버전과 날짜가 포함된 질문, 정답이 없는 질문을 섞으세요. 각 질의에 기대하는 문서와 허용 가능한 빈 결과를 표시하면 설정 변경 전후를 비교할 수 있습니다.
운영에서는 질의 원문, 적용 필터, 검색 방식, k와 임계값, 반환된 문서 ID와 점수, 최종 답변에 사용한 문서를 남기세요. 개인정보가 포함될 수 있는 서비스라면 원문 대신 마스킹한 질의 ID를 기록하는 방식도 검토해야 합니다. 검색 결과가 맞아도 생성 모델이 인용하지 않았다면 검색과 생성 로그를 함께 비교해야 합니다.
예외 상황을 설계에 넣기
- 버전 충돌: 최신 문서와 이전 문서가 모두 검색되면 버전 필터와 문서의 유효 기간을 확인합니다.
- 0건 검색: 억지로 답을 만들지 말고 조건이 너무 좁은지와 실제 미등록 질문인지 구분합니다.
- 동일 문서 중복: 같은 원문에서 나온 청크가 결과를 독점하면 문서별 최대 개수나 다양성 규칙을 둡니다.
- 권한 변경: 인덱스 생성 시점의 공개 상태와 현재 사용자의 접근 권한을 다시 확인합니다.
- 업데이트 문서: 재인덱싱 시 기존 청크가 남아 새 문서와 함께 검색되지 않는지 확인합니다.
자주 묻는 질문
청크를 크게 만들면 정확도가 올라가나요?
항상 그렇지는 않습니다. 필요한 조건과 결론이 함께 남는 크기를 찾되, 주제가 섞여 유사도가 흐려지지 않는지 평가 질의로 비교해야 합니다.
k를 크게 하면 정답을 놓치지 않나요?
정답이 후보에 들어올 가능성은 달라질 수 있지만 잡음과 컨텍스트 비용도 늘어납니다. k와 점수 임계값, 재순위를 별도로 검토하세요.[2]
필터와 키워드 검색 중 무엇을 먼저 적용하나요?
권한과 공개 상태처럼 반드시 지켜야 할 조건은 먼저 필터링하고, 제품명이나 오류 번호처럼 정확한 문자열은 키워드 경로를 함께 두는 방식이 실무적입니다. 0건일 때 완화 규칙도 미리 정의하세요.
RAG 전체 흐름은 RAG란 무엇인가? AI가 내 문서에서 답을 찾는 방식에서, 임베딩의 역할은 AI 임베딩이란? 문장을 숫자로 바꿔 검색하는 이유에서 이어서 확인할 수 있습니다.
[…] 검색 파이프라인을 조정한다면 RAG 검색 튜닝 글도 함께 참고할 수 있습니다. 검색 결과를 prefix 앞쪽에 고정하는 방식은 […]