합성 데이터(Synthetic Data) 생성으로 RAG 성능 극복하기
원천 데이터 부족으로 겪었던 성능 한계, 그리고 QA 합성 데이터로 이를 해결한 과정에 대한 기록.
실무에서 에이전트의 채팅 기능을 증강시키기 위해 급히 RAG 파이프라인을 고도화해야했다. 이미 Weaviate에 내장된 BM25 + Vector 하이브리드 검색과 **리랭크(Re-ranking)**를 적용했고, 나아가 Graph RAG 구조까지 아키텍처 레벨에 올려둔 상태였지만, 성능이 나오지 않았다. 이유는 물론 아키텍처가 아니라 ‘데이터’ 그 자체에 있었고, 도메인 데이터 부족 사태를 극복이 관건이었다.
화려한 아키텍처와 빈�## 해결책: 합성 데이터(Synthetic Data) 생성#
설계 대비 부족한 지식 베이스를 물리적으로 늘리는 데에는 한계가 있었다. 실무자가 일일이 도메인 지식을 타이핑해서 QA 데이터를 만들 수는 없는 노릇이니까.
그래서 방향을 틀었다. **AI 서비스(LLM)를 활용해 원본 문서들로부터 가상의 질문-응답(QA) 쌍을 대량으로 생성(Synthetic Data Generation)**하기로 한 것이다. 업계에서는 이를 RAG Data Augmentation 혹은 Doc2QA 방식이라고도 부른다고 한다.
작업 흐름은 다음과 같았다.
- 청크 주입 및 프롬프팅: 원본 문서 청크를 강력한 LLM에 밀어 넣고, “이 텍스트를 바탕으로 사용자가 채팅 에이전트에게 물어볼 법한 다양한 질문 3~5개와 그 정답을 생성해 줘”라고 지시했다.
- 다양성 확보: 단순 팩트 확인뿐만 아니라, 비교, 요약, 추론을 요구하는 형태 등 유저의 예상 질의 패턴을 다양화하여 QA 쌍을 뽑아냈다.
- 적재: 이렇게 생성된 수많은 QA 쌍을 다시 벡터 DB(Weaviate)에 적재했다.
이 QA 쌍들이 벡터 DB에 들어가자, 에이전트의 채팅 응답 품질이 눈에 띄게 개선되었다.
가장 큰 변화는 하이브리드 검색 엔진이 드디어 제 역할을 하기 시작했다는 점이다. 사용자가 채팅창에 질문을 던지면, Weaviate는 서술형 원본 문서가 아닌 우리가 미리 생성해둔 **‘가상의 질문(Q)‘**들과 먼저 강하게 매칭되었다. 질문은 질문끼리 문장 구조나 쓰이는 어휘(키워드)가 비슷하기 때문에, BM25와 Vector 양쪽 모두에서 검색 정확도가 극적으로 올라간 것이다.
더 나아가서: 스터디 차원에서 기록해 두는 RAG 고도화 기법들#
앞으로 RAG 파이프라인의 검색 성능을 한 단계 더 끌어올리기 위해 스터디 차원에서 살펴볼 만한 기법을 몇가지 추가로 정리해 둔다.
1. 쿼리 최적화 (Query Routing & Multi-Query): 질문을 영리하게 던지기#
단순히 사용자의 질문을 곧바로 검색 엔진에 던지는 것을 넘어, 검색 이전에 질문 자체를 시스템이 이해하기 쉽도록 가공하는 방법론이다.
- Query Routing (라우팅): 사용자의 질문 의도를 사전에 분류한다. 예를 들어 사내 규정 관련 질문은 ‘HR 컬렉션’으로, 기술 스택 질문은 ‘Tech 컬렉션’으로 분기시켜 검색 범위를 좁히고 노이즈를 줄여 정확도를 높인다.
- Multi-Query (다중 쿼리 확장): 사용자가 모호하거나 복합적인 질문을 던졌을 때, LLM을 거쳐 이 질문을 3~5개의 다각도 질문(예: 장단점, 비교 분석 등)으로 파생시킨다. 각각의 질문으로 검색을 수행한 뒤 반환된 여러 결과들의 순위를 융합(Reciprocal Rank Fusion)하여 최종 문서를 도출하는 방식이다. 사용자의 개떡같은 질문도 찰떡같이 찾아낼 수 있게 해준다.
2. 에이전틱 RAG (Agentic RAG): 다단계 추론과 자가 수정#
단순 ‘검색(Retrieve) -> 생성(Generate)‘의 단방향 파이프라인 구조를 벗어나, 주도성을 가진 에이전트가 스스로 검색 과정을 제어하게 만드는 고차원적인 구조다.
- 다중 검색 (Multi-step Retrieval): 복잡한 질문에 대해 에이전트가 먼저 “A 정책을 찾아야겠군” 하고 1차 검색을 수행한다. 결과를 읽고 나서 “A와 비교하려면 B 정책도 알아야 하네. B도 검색하자”라고 스스로 판단하여 순차적으로 정보를 긁어모은다.
- 자가 평가 (Self-Correction): 검색해 온 문서가 질문에 대답하기에 퀄리티가 부족하다고 판단되면, 억지로 답변(환각)을 지어내는 대신 “이 문서로는 답할 수 없다”고 판단하고 검색 키워드를 스스로 수정하여 다시 검색을 시도한다. (주로 LangGraph 등의 프레임워크 활용)
3. 도메인 특화 미세조정 (Fine-Tuning): 데이터의 잠재력 극대화#
고품질의 합성 QA 데이터를 대량으로 확보했다면, 이를 단순 DB 적재용으로만 쓰기엔 아깝다. 이 데이터를 활용해 인공지능 모델 자체의 체급을 올릴 수 있다.
- 임베딩 모델 미세조정: 범용 임베딩 모델(예: OpenAI, BGE-m3)이 사내의 전문 용어나 줄임말을 잘 이해하지 못할 때, 확보한 QA 쌍을 학습시켜 텍스트를 벡터로 변환하는 의미 파악 능력 자체를 도메인에 완벽히 맞춘다.
- 생성 LLM 미세조정: 프롬프트 엔지니어링만으로는 꽉 잡기 힘든 고유의 어투, 응답 포맷팅, 세밀한 뉘앙스를 맞추기 위해 파라미터 수가 적은 오픈소스 LLM을 우리의 QA 데이터셋으로 파인튜닝한다. 검색 결과를 바탕으로 가장 ‘우리 회사 봇다운’ 대답을 생성하는 전용 두뇌를 만드는 작업이다.� 채팅창에 질문을 던지면, 서술형 원본 문서가 아닌 우리가 미리 생성해둔 **‘가상의 질문(Q)‘**들과 먼저 강하게 매칭된다. 질문끼리는 문장 구조나 쓰이는 어휘(키워드)가 비슷하기 때문에, BM25와 Vector 양쪽 모두에서 검색 정확도가 극적으로 올라갔다. 하이브리드 검색 엔진이 드디어 제 역할을 하기 시작한 것이다.
2. 쿼리 최적화 (Query Routing & Multi-Query): 질문을 영리하게 던지기#
단순히 사용자의 질문을 곧바로 검색 엔진에 던지는 것을 넘어, 검색 이전에 질문 자체를 시스템이 이해하기 쉽도록 가공하는 방법론이다.
- Query Routing (라우팅): 사용자의 질문 의도를 사전에 분류한다. 예를 들어 사내 규정 관련 질문은 ‘HR 컬렉션’으로, 기술 스택 질문은 ‘Tech 컬렉션’으로 분기시켜 검색 범위를 좁히고 노이즈를 줄여 정확도를 높인다.
- Multi-Query (다중 쿼리 확장): 사용자가 모호하거나 복합적인 질문을 던졌을 때, LLM을 거쳐 이 질문을 3~5개의 다각도 질문(예: 장단점, 비교 분석 등)으로 파생시킨다. 각각의 질문으로 검색을 수행한 뒤 반환된 여러 결과들의 순위를 융합(Reciprocal Rank Fusion)하여 최종 문서를 도출하는 방식이다. 사용자의 개떡같은 질문도 찰떡같이 찾아낼 수 있게 해준다.
3. 에이전틱 RAG (Agentic RAG): 다단계 추론과 자가 수정#
단순 ‘검색(Retrieve) -> 생성(Generate)‘의 단방향 파이프라인 구조를 벗어나, 주도성을 가진 에이전트가 스스로 검색 과정을 제어하게 만드는 고차원적인 구조다.
- 다중 검색 (Multi-step Retrieval): 복잡한 질문에 대해 에이전트가 먼저 “A 정책을 찾아야겠군” 하고 1차 검색을 수행한다. 결과를 읽고 나서 “A와 비교하려면 B 정책도 알아야 하네. B도 검색하자”라고 스스로 판단하여 순차적으로 정보를 긁어모은다.
- 자가 평가 (Self-Correction): 검색해 온 문서가 질문에 대답하기에 퀄리티가 부족하다고 판단되면, 억지로 답변(환각)을 지어내는 대신 “이 문서로는 답할 수 없다”고 판단하고 검색 키워드를 스스로 수정하여 다시 검색을 시도한다. (주로 LangGraph 등의 프레임워크 활용)
4. 도메인 특화 미세조정 (Fine-Tuning): 데이터의 잠재력 극대화#
앞서 1번 방법론을 통해 고품질의 합성 QA 데이터를 대량으로 확보했다면, 이를 단순 DB 적재용으로만 쓰기엔 아깝다. 이 데이터를 활용해 인공지능 모델 자체의 체급을 올릴 수 있다.
- 임베딩 모델 미세조정: 범용 임베딩 모델(예: OpenAI, BGE-m3)이 사내의 전문 용어나 줄임말을 잘 이해하지 못할 때, 확보한 QA 쌍을 학습시켜 텍스트를 벡터로 변환하는 의미 파악 능력 자체를 도메인에 완벽히 맞춘다.
- 생성 LLM 미세조정: 프롬프트 엔지니어링만으로는 꽉 잡기 힘든 고유의 어투, 응답 포맷팅, 세밀한 뉘앙스를 맞추기 위해 파라미터 수가 적은 오픈소스 LLM을 우리의 QA 데이터셋으로 파인튜닝한다. 검색 결과를 바탕으로 가장 ‘우리 회사 봇다운’ 대답을 생성하는 전용 두뇌를 만드는 작업이다.
검색의 본질은 결국 ‘데이터’#
이번 경험을 통해 아무리 Graph RAG 같은 고도화된 오케스트레이션 레이어가 있고, 하이브리드 검색과 리랭킹 파이프라인이 촘촘하게 짜여 있더라도 **“타겟 데이터의 형태가 사용자의 멘탈 모델(질문 형식)과 동떨어져 있으면 시스템은 흔들린다”**는 뼈저린 교훈을 얻었다.
합성 데이터(Synthetic Data) 생성은 단순히 데이터의 양을 늘리는 것을 넘어, 데이터의 형태를 검색에 최적화된 모양으로 성형해 주는 필수적인 과정이었다.
앞으로는 이 합성 QA 데이터들을 바탕으로 자체 임베딩 모델을 파인튜닝(Fine-tuning)하거나, 질문의 난이도나 성격에 따라 쿼리를 분기하는 라우팅(Query Routing) 방식도 고민해 볼 수 있을 것 같다.