Text-to-SQL의 성능을 끌어올린 기술 RAG
기존의 Text-to-SQL 모델은 LLM(Large Language Model)의 한계를 보완하기 위해 다양한 시도를 해왔습니다. 특히 구조화된 데이터에 대한 쿼리를 자연어로 생성하려면, LLM에게 충분한 문맥 정보를 주는 것이 매우 중요했습니다.
과거에는 이러한 문맥 정보를 제공하기 위해 전체 메타데이터를 프롬프트에 직접 삽입해 LLM에게 전달하는 방식이 주로 사용되었습니다. 하지만 이 방식은 토큰의 한계로 인해 정보 손실이 생기거나, 불필요한 데이터까지 함께 전달되어 오히려 정확도를 떨어뜨리는 문제가 있었습니다.
이러한 한계를 극복하기 위해 새롭게 도입된 기술이 바로 RAG(Retrieval Augmented Generation)입니다. RAG를 활용하는 현재 모델은 메타데이터를 벡터 데이터베이스(Vector DB)에 저장하고, 사용자의 질문에 맞는 정보만을 검색해 프롬프트에 삽입합니다. 덕분에 불필요한 정보는 줄이고, 꼭 필요한 정보만을 LLM에게 전달할 수 있게 되었습니다. 뿐만 아니라, 사전 구축된 질문-쿼리 샘플을 활용해, 실제 질문과 유사한 예제를 함께 제공함으로써 LLM이 더욱 정확하고 현실성 있는 쿼리를 생성할 수 있도록 돕고 있습니다.


더 높은 성능을 위한 고민
이전에는 LLM의 성능과 정교한 프롬프팅 기술이 Text-to-SQL 모델의 성능을 좌우했다면, 지금은 상황이 많이 달라졌습니다.
Text-to-SQL 모델이 실제 환경에서 안정적으로 작동하려면, 단순히 LLM을 잘 쓰는 것만으로는 부족합니다. 이제는 질문에 맞는 정보를 얼마나 정확하게 찾아내고, 그 정보를 어떻게 전달하느냐가 전체 성능에 결정적인 영향을 미치게 되었죠.
HEARTCOUNT ABI도 RAG를 도입하면서 자연스럽게 이런 고민을 하게 되었습니다.
“어떻게 하면 사용자의 질문과 더 유사한 정보를
더 정밀하게 찾아낼 수 있을까?”
이 문제를 해결하기 위해 우리가 집중한 핵심 요소는 다음의 두 가지입니다:
- 임베딩 모델(Embedding Model)
- 검색 알고리즘(Retrieval Algorithm)
이 두 요소는 RAG의 핵심을 구성하며, 정보 검색의 정확도에 직접적인 영향을 미칩니다.
HEARTCOUNT ABI가 이 두 요소를 어떤 기준으로 선택했는지, 그리고 실제로 진행한 테스트 결과에 대한 내용을 이어서 자세히 소개해드리겠습니다.
임베딩 모델(Embedding Model)의 역할
임베딩 모델(Embedding Model)이 뭔가요?
임베딩 모델은 텍스트 데이터를 수치화된 벡터로 변환하여 기계가 이해하고 처리할 수 있도록 하는 핵심 기술입니다. 이 과정에서 단어나 문장의 의미가 수치화된 형태로 변환되며, 결과적으로 의미적으로 유사한 텍스트는 벡터 공간상에서 서로 가까운 위치에 놓이게 됩니다. 이는 벡터 기반 검색에서 “비슷한 질문”, “비슷한 구조의 쿼리”를 찾아내는 데 결정적인 역할을 하며, Text-to-SQL 시스템에서 질문과 관련된 메타데이터나 예시 쿼리를 정확히 찾아내는 기반이 됩니다.

Open AI의 최신 임베딩 모델 text-embedding-3-large
HEARTCOUNT ABI의 Text-to-SQL 2.0에서는 OpenAI에서 2024년 1월에 출시한 최신 임베딩 모델인 text-embedding-3-large를 채택했습니다. 이 모델은 최대 3,072차원의 임베딩을 생성하며, 기존에 널리 사용되던 text-embedding-ada-002 대비 의미적 표현력과 유사도 판단 정확도에서 큰 향상을 보였습니다.
OpenAI의 발표에 따르면, text-embedding-3-large는
- 다국어 검색 벤치마크인 MIRACL에서 평균 점수를 31.4% → 54.9%,
- 영어 기반 임베딩 성능을 측정하는 MTEB에서는 61.0% → 64.6%로 끌어올리는 성과를 보였습니다.
이는 단순 수치 향상을 넘어서, 실질적인 의미 기반 유사도 검색의 품질 향상을 의미합니다.

또한 이 모델은 임베딩 차원을 줄인 설정(256차원 등)에서도 ada-002 대비 더 우수한 성능을 보여주는 것이 특징입니다. 실제로 OpenAI는 text-embedding-3 계열 모델의 구조적 효율성과 일반화 성능이 뛰어나, 다양한 애플리케이션에 적절한 임베딩 사이즈를 선택해 사용할 수 있도록 설계했다고 밝혔습니다.

HEARTCOUNT ABI Text-to-SQL 2.0에 적용된 text-embedding-3-large 모델
text-embedding-3-large은 기본적으로 최대 3,072차원의 임베딩을 지원하지만, HEARTCOUNT ABI의 Text-to-SQL 2.0에서는 성능과 효율성의 균형을 고려해 768차원으로 설정하였습니다. 차원을 줄였음에도 불구하고, 이 모델은 기존의 text-embedding-ada-002보다 뛰어난 표현력과 유사도 판단 성능을 보여줍니다.
실제로 유사도 검색 성능이 향상되었는지를 확인하기 위해 Spider Dataset의 일부를 활용한 테스트를 진행했습니다. 영어, 한국어, 일본어로 구성된 질문-쿼리 쌍을 미리 벡터 DB에 저장한 뒤, text-embedding-3-large (768D) 모델을 기반으로 각 언어별 60개의 질문에 대해 검색 정확도를 측정하였습니다. 결과는 다음과 같습니다.

‘3-large’ 모델의 차원을 768차원으로 줄였음에도 1,536차원의 ‘ada-002’ 모델보다 모든 언어에서 더 높은 성능을 보였습니다.
이처럼 다국어 환경에서도 높은 검색 정확도와 순위 기반 정답률(MRR)을 달성한 것은 임베딩 모델의 품질이 전반적인 시스템 성능에 직결될 수 있습니다. 유사한 질문을 정확히 찾아낼수록, LLM에 제공되는 예시의 품질이 높아지고, 이는 곧 더 정밀한 쿼리 생성을 가능하게 만들기 때문입니다.
한-영, 한-일 다국어 질문의 TTS 성능 측정
이번에는 실제 사용 환경처럼 질문과 저장된 언어가 서로 다른 경우에도 검색 성능이 유지되는지 궁금했습니다. 그래서 한국어로 질문하고 영어 또는 일본어 질문만 저장된 Milvus에서 유사 질문을 검색해 테스트해보았습니다.
입력 언어 | 저장 언어 | Top-1 Accuracy | Recall@5 | MRR | Top-5 내 미검색 수 |
---|---|---|---|---|---|
한국어 | 영어 | 83.33% | 91.67% | 0.8839 | 5 |
한국어 | 일본어 | 90.00% | 93.33% | 0.9272 | 4 |
다른 언어로 저장되어 있더라도 높은 정확도로 유사한 샘플을 찾아내는 것을 확인할 수 있습니다. 여기서 주목할 점은 질문을 모든 언어로 번역하여 별도로 저장하지 않아도, 하나의 언어로 구성된 질문-쿼리 예시만으로도 사용자의 다국어 질문에 대해 적절한 유사 질문을 찾아내고 정확한 SQL을 생성하는 데 활용할 수 있다는 것입니다. 임베딩 모델의 다국어 일반화 능력 덕분에 훨씬 적은 노력으로 다양한 언어 환경을 지원할 수 있으며, 사용자는 자연스럽게 자신의 언어로 질문하면서도 정확하고 일관된 응답을 받을 수 있습니다.

검색 알고리즘(Retrieval Algorithm)의 중요성
쿼리 생성 성능에 결정적인 영향을 미치는 검색 알고리즘
벡터로 변환된 텍스트들을 비교하는 방식은 RAG 기반 Text-to-SQL 시스템의 성능에 결정적인 영향을 미칩니다. 동일한 임베딩 모델을 사용하더라도, 어떤 유사도 계산 알고리즘을 적용하느냐에 따라 검색 품질이 달라질 수 있기 때문입니다.
RAG 기반의 Text-to-SQL 시스템에서는 사용자의 질문과 의미적으로 가장 가까운 정보(예: 샘플 쿼리, 테이블 설명 등)를 정확하게 찾아내는 것이 핵심입니다. 이를 위해 중요한 요소 중 하나는 임베딩된 벡터들 간의 유사도를 어떤 기준으로 비교하느냐입니다.
자연어 기반 시스템에서는 동일한 의도를 가진 질문이라도 표현 방식이 매우 다양하기 때문에, 문장의 길이나 구조에 상관없이 의미 중심으로 유사도를 판단할 수 있는 기준이 필요합니다. 이와 같은 맥락에서, 코사인 유사도(Cosine Similarity)는 문장 간 의미적 유사성을 잘 반영할 수 있는 방식으로, 자연어 기반 검색 시스템에서 널리 활용되고 있는 방법 중 하나입니다.
코사인 유사도 vs 다른 검색 알고리즘
알고리즘 | 비교 방식 | 장점 | 단점 |
---|---|---|---|
코사인 유사도 | 벡터의 방향 (각도) | 의미 중심 유사도 비교에 탁월 | 절대적 거리(크기)는 고려하지 않음 |
유클리드 거리 | 벡터 간 직선 거리 | 직관적인 거리 계산 | 길이나 표현 방식에 민감 |
내적(Dot Product) | 방향 + 크기 | 계산 속도 빠름, 일부 추천 시스템에 유용 | 벡터 크기에 민감, 정규화 필요 |
코사인 유사도는 두 벡터 간의 방향성을 기준으로 유사도를 측정합니다. 즉, 두 벡터가 얼마나 비슷한 방향을 가리키고 있는지를 비교하는 방식입니다. 이때 중요한 것은 벡터의 크기(길이)가 아니라, 그 벡터들이 어느 방향을 향하고 있는지입니다.

왜 방향이 중요한가요?
자연어 질문은 표현 방식에 따라 구조가 다를 수밖에 없습니다. “서울의 날씨는?”과 “오늘 서울의 날씨는 어떤가요?“는 단어 수도 다르고, 문장의 구조도 완전히 다르지만 의미적으로는 거의 동일합니다.
따라서 유클리드 거리처럼 벡터의 절대적인 위치나 크기를 기준으로 거리를 계산할 경우, 문장의 표현 방식이나 복잡성에 따라 벡터 간 거리가 멀어질 수 있게 됩니다. 이로 인해 실제로 의미는 유사하지만 거리 기반 기준에서는 유사하지 않다고 판단되는 오류가 발생할 수 있습니다.
반면 코사인 유사도는 벡터를 정규화한 뒤 방향만 비교하기 때문에, 문장의 길이나 단어 수에는 영향을 받지 않고 의미 기반으로 유사도를 정확히 파악할 수 있습니다.
결국, 벡터의 길이가 아닌 방향을 비교하는 코사인 유사도는, 문장은 달라도 의미가 같은 자연어의 특성을 가장 잘 반영하는 알고리즘입니다.
Text-to-SQL 시스템에서 코사인 유사도는 정확한 정보 검색과 고품질 쿼리 생성에 중요한 역할을 하며, 전체 모델 성능의 중요한 축을 담당하고 있습니다.
우리 TTS가 달라졌어요.
이전의 Text-to-SQL 모델도 단순한 질문에는 꽤 괜찮은 성능을 보였습니다. 하지만 실제 환경에서 자주 등장하는 복잡한 조건이나 다중 테이블 조인이 필요한 질문 등에서는 아쉬운 점이 분명히 있었습니다.
이는 LLM이 참조할 수 있는 정보가 제한적이었기 때문입니다. 모든 메타데이터를 프롬프트에 넣는 방식으로는, 모델이 질문의 의도를 충분히 파악하고 정교한 쿼리를 생성하기 어려웠습니다.
그러나 RAG를 도입한 현재 모델에서는, 질문에 맞는 정보만 선별적으로 제공할 수 있게 되면서 복잡한 질문에 대해서도 훨씬 더 높은 정확도를 보여주고 있습니다. 최적의 임베딩 모델과 검색 알고리즘을 기반으로 할 뿐만 아니라, 더 나은 성능을 위해 다양한 방식으로 모델을 세밀하게 튜닝하고 최적화해왔습니다.

수치로도 성능 향상이 확인되지만, 좀 더 직관적으로 이해할 수 있도록 동일한 데이터와 동일한 질문에 대한 결과 차이를 예시로 보여드리겠습니다.
Text-to-SQL 성능 비교
Hallucination 문제
질문1 : “각 지역마다 주문이 가장 많았던 고객의 이름과 주문 건수를 알려주세요.”
이전 모델(LLM 단독)은 실제 데이터 구조를 충분히 이해하지 못해 잘못된 조인이나 조건이 포함되는 경우가 많았습니다. 설명만 보면 그럴듯해 보이지만, 실제로 쿼리를 실행해보면 기대에 못 미치는 결과가 나오는 경우가 많았습니다.

현재 모델(RAG 적용)에서는 세 개의 테이블 간 관계를 정확히 파악하고, 필요한 정보만 조인하여 정확한 쿼리를 생성했습니다. 주문이 가장 많은 고객이 여러명인 경우에도 모두 확인이 가능하도록 쿼리를 생성했네요!

데이터 표현 불일치 문제
질문2 : “집을 소유한 사람들이 가장 많이 주문하는 카테고리는 뭐야?”
생성된 쿼리를 실행해보니 결과 데이터가 없습니다. 쿼리를 확인해보니 “집을 소유한 고객”을 확인하려는 시도는 했지만, 데이터 표현 방식에 대한 정보가 없어 잘못된 조건으로 필터링하고 있었던 것으로 보입니다. 민감한 정보가 아니라면, 이러한 값 표현 방식을 메타데이터에 미리 명시해 LLM이 참고할 수 있도록 해주는 것도 좋은 방법입니다.

값이 특정 범위나 조건으로 정해져 있는 경우, 메타데이터에 명시해주면 LLM이 더 정확한 쿼리를 생성하는 데 도움이 됩니다. 이번 사례에서는 ‘집을 소유한 사람’을 판단하는 기준이 “Y” 또는 “N”임을 메타데이터에 포함시켜, LLM이 이를 참고할 수 있도록 구성해보았습니다.

달라진 쿼리를 한번 확인해볼까요? 집을 소유하는지에 대한 여부를 확인하고 해단 고객들이 주문한 제품의 카테고리를 그룹화하여 잘 결과를 보여주고 있습니다.

질문 3: “캐나다에서 가장 많이 팔린 카테고리는 뭔가요?”
이번에도 생성된 쿼리를 실행해보니 결과 데이터가 없습니다. 같은 방법으로 메타데이터에 설명을 추가하여 해결할 수 있겠네요!

메타 데이터에 컬럼에 대한 설명을 추가한 모습입니다. 데이터에 표현되고 있는 국가명을 파악할 수 있도록 설명에 추가를 해주었습니다.

이전에는 사용자 질문에 사용된 ‘캐나다’라는 국가명을 그대로 사용했다면, 지금은 영어로 작성된 ‘Canada’라는 국가명을 잘 사용하고 있는 것을 확인할 수 있습니다.

질문 해석 오류
질문 4 : “20대 고객이 가장 많이 주문한 제품의 이름은 무엇인가요?”
이전 모델에서는 ‘20대’라는 범주형 조건을 수치로 정확히 해석하지 못하는 경우가 많았습니다. 이 질문에서는 나이를 기준으로 20~29세 범위 조건을 정확히 계산하는 쿼리를 구성하는 것이 관건입니다.

만약 연령대를 계산하는 쿼리가 미리 저장되어 있다면, LLM은 비슷한 질문을 검색해 해당 쿼리를 참고하고, 그 안에 사용된 계산 방식을 바탕으로 새로운 쿼리를 생성할 수 있습니다.

결과를 확인해보니 LLM이 유사 질문의 예시 쿼리를 참고하여 ‘20대 고객’ 조건을 적절히 반영한 것을 확인할 수 있습니다. 이처럼 자주 사용하는 테이블이나 비즈니스 로직을 이해하는 데 도움이 되는 질문-쿼리 쌍을 미리 저장해두면, LLM이 문맥을 더 잘 파악해 더 정확하고 높은 퀄리티의 쿼리를 생성할 수 있습니다.

마무리
HEARTCOUNT ABI의 Text-to-SQL 2.0은 단순한 LLM 기반의 쿼리 생성 모델을 넘어, 더 정확하고 현실적인 SQL 생성을 위한 구조로 진화했습니다.
복잡한 조건, 다중 테이블, 다양한 표현 방식에 대응하기 위해, 우리는 RAG 아키텍처와 고성능 임베딩 모델, 검색 알고리즘을 결합하고, 여기에 질문 전처리, 쿼리-샘플 구성 전략, 메타데이터 활용 방식 등 전체 파이프라인을 정밀하게 설계하여, 질문에 꼭 맞는 정보만 선별적으로 제공하고 모델이 참조할 수 있는 고품질 예시를 함께 전달할 수 있도록 최적화했습니다.
또한 질문과 쿼리 예시를 하나의 언어로만 저장해도, 다국어 질문에 대한 의미 기반 검색이 가능하며, 이를 기반으로 정확한 SQL 생성까지 연결된다는 점에서 효율적이고 확장 가능한 구조를 갖추게 되었습니다.
HEARTCOUNT ABI는 실사용 환경에 최적화된 Text-to-SQL 시스템을 목표로, 앞으로도 성능과 실용성 모두를 지속적으로 개선해 나갈 예정입니다.
HEARTCOUNT ABI는 한층 진화한 Text-to-SQL 기술로 신뢰도 높은 자동 SQL 생성을 지원합니다. 지금 도입 문의를 남기고, 실무자의 질문이 곧 분석이 되는 환경을 구축해보세요.