Text-to-SQL 에이전트만으로 신뢰할 수 있는 데이터 에이전트를 만들 수 있을까?

Text-to-SQL 에이전트만으로 신뢰할 수 있는 데이터 에이전트를 만들 수 있을까?
Photo by Vincent van Zalinge / Unsplash

자연어로 질문하면 SQL을 생성하고, 실행한 뒤, 결과를 요약해 주는 데이터 에이전트는 이제 꽤 익숙한 패턴이 되었습니다. 저도 데이터 에이전트를 설계한다고 하면 가장 먼저 text-to-SQL 구조를 떠올렸습니다. 사용자의 질문을 받고, 관련 schema를 찾고, 필요한 테이블과 컬럼을 고른 뒤 SQL을 생성합니다. 이후 SQL을 실행하고, 결과를 다시 자연어로 설명하는 방식입니다.

흐름을 단순화하면 다음과 같습니다.

사용자 질문
→ schema retrieval
→ table / column selection
→ SQL generation
→ SQL execution
→ result summarization

이 접근은 직관적이고 강력합니다. 데이터베이스에 접근할 수 있다면 사용자는 거의 모든 질문을 자연어로 던져볼 수 있고, 에이전트는 그 질문을 SQL로 바꿔 실제 데이터를 조회할 수 있습니다.

문제는 실제 업무 데이터에 붙이는 순간부터 드러납니다. SQL이 실행됐다고 해서 답이 맞는 것은 아니기 때문입니다. 특히 “매출”, “활성 고객”, “전환율”, “순매출”, “리텐션”처럼 조직 안에서 합의된 의미가 필요한 비즈니스 지표를 다룰 때는 이 문제가 더 뚜렷해집니다. 이때 어려운 지점은 SQL 문법 자체가 아니라, 그 숫자가 조직 안에서 어떤 의미로 정의되어 있는지입니다.

text-to-SQL이 흔들리는 지점

예를 들어 사용자가 이렇게 묻는다고 해보겠습니다.

지난 분기 지역별 순매출을 보여줘.

text-to-SQL 에이전트는 대략 다음과 같은 SQL을 생성할 수 있습니다.

SELECT
  c.region,
  SUM(o.amount - o.refund_amount - o.tax_amount) AS net_revenue
FROM orders o
JOIN customers c
  ON o.customer_id = c.customer_id
WHERE o.status = 'paid'
  AND o.order_date >= ...
GROUP BY c.region;

겉으로 보기에는 그럴듯합니다. 실행도 될 수 있고, 결과도 숫자로 잘 반환될 수 있습니다. 하지만 이 쿼리 안에는 여러 개의 숨은 의사결정이 들어 있습니다.

amount는 gross revenue인가, net revenue인가?
환불은 제외해야 하는가?
세금은 제외해야 하는가?
기준일은 order_date인가, payment_date인가?
고객의 region은 주문 당시 주소인가, 현재 주소인가?
조인 과정에서 중복 집계가 생기지는 않는가?

이 질문들은 SQL 문법 문제가 아닙니다. 비즈니스 의미 해석의 문제입니다. LLM이 raw schema만 보고 매번 이런 결정을 추론하게 만들면, SQL은 실행되지만 숫자는 틀릴 수 있습니다. 오히려 이 경우가 더 위험합니다. 에러가 나는 SQL은 바로 고칠 수 있지만, 그럴듯하게 실행된 SQL이 만든 숫자는 그대로 보고서나 의사결정에 사용될 가능성이 있기 때문입니다.

BIRD benchmark도 이 문제를 잘 보여줍니다. BIRD는 95개 데이터베이스, 12,751개 text-to-SQL pair, 37개 전문 도메인을 포함한 대규모 benchmark입니다. 이 benchmark는 dirty database contents, external knowledge, SQL efficiency처럼 실제 환경에 가까운 문제를 강조합니다. 당시 ChatGPT의 execution accuracy는 40.08%였고, human result 92.96%와는 큰 차이가 있었습니다.

Can LLM Already Serve as A Database Interface? A BIg Bench for Large-Scale Database Grounded Text-to-SQLs
Text-to-SQL parsing, which aims at converting natural language instructions into executable SQLs, has gained increasing attention in recent years. In particular, Codex and ChatGPT have shown impressive results in this task. However, most of the prevalent benchmarks, i.e., Spider, and WikiSQL, focus on database schema with few rows of database contents leaving the gap between academic study and real-world applications. To mitigate this gap, we present Bird, a big benchmark for large-scale database grounded in text-to-SQL tasks, containing 12,751 pairs of text-to-SQL data and 95 databases with a total size of 33.4 GB, spanning 37 professional domains. Our emphasis on database values highlights the new challenges of dirty database contents, external knowledge between NL questions and database contents, and SQL efficiency, particularly in the context of massive databases. To solve these problems, text-to-SQL models must feature database value comprehension in addition to semantic parsing. The experimental results demonstrate the significance of database values in generating accurate text-to-SQLs for big databases. Furthermore, even the most effective text-to-SQL models, i.e. ChatGPT, only achieves 40.08% in execution accuracy, which is still far from the human result of 92.96%, proving that challenges still stand. Besides, we also provide an efficiency analysis to offer insights into generating text-to-efficient-SQLs that are beneficial to industries. We believe that BIRD will contribute to advancing real-world applications of text-to-SQL research. The leaderboard and source code are available: https://bird-bench.github.io/.

Spider 2.0은 enterprise text-to-SQL의 난이도를 더 직접적으로 다룹니다. 632개 real-world workflow problem을 포함하고, BigQuery와 Snowflake 같은 환경, 1,000개 이상 column을 가진 데이터, metadata, dialect documentation, project-level codebase 탐색까지 평가합니다. 이 benchmark에서는 o1-preview 기반 code agent가 21.3%만 해결했다는 결과도 보고했습니다.

Spider 2.0: Evaluating Language Models on Real-World Enterprise Text-to-SQL Workflows
Real-world enterprise text-to-SQL workflows often involve complex cloud or local data across various database systems, multiple SQL queries in various dialects, and diverse operations from data transformation to analytics. We introduce Spider 2.0, an evaluation framework comprising 632 real-world text-to-SQL workflow problems derived from enterprise-level database use cases. The databases in Spider 2.0 are sourced from real data applications, often containing over 1,000 columns and stored in local or cloud database systems such as BigQuery and Snowflake. We show that solving problems in Spider 2.0 frequently requires understanding and searching through database metadata, dialect documentation, and even project-level codebases. This challenge calls for models to interact with complex SQL workflow environments, process extremely long contexts, perform intricate reasoning, and generate multiple SQL queries with diverse operations, often exceeding 100 lines, which goes far beyond traditional text-to-SQL challenges. Our evaluations indicate that based on o1-preview, our code agent framework successfully solves only 21.3% of the tasks, compared with 91.2% on Spider 1.0 and 73.0% on BIRD. Our results on Spider 2.0 show that while language models have demonstrated remarkable performance in code generation -- especially in prior text-to-SQL benchmarks -- they require significant improvement in order to achieve adequate performance for real-world enterprise usage. Progress on Spider 2.0 represents crucial steps towards developing intelligent, autonomous, code agents for real-world enterprise settings. Our code, baseline models, and data are available at https://spider2-sql.github.io

요지는 단순합니다.

LLM은 SQL을 점점 더 잘 쓰고 있지만, enterprise analytics에서는 SQL 작성 능력만으로 충분하지 않습니다.

실제 업무 분석에서는 “SQL을 만들 수 있는가”보다 “조직이 신뢰하는 정의에 맞는 숫자를 만들 수 있는가”가 더 중요합니다.

dbt Semantic Layer가 제안하는 접근

dbt Semantic Layer는 text-to-SQL을 더 잘하게 만드는 장치라기보다, LLM이 SQL 전체를 직접 작성해야 하는 부담을 줄이는 접근에 가깝습니다.

핵심은 dbt project 안에 metric, dimension, entity 같은 비즈니스 의미를 미리 정의해 두는 것입니다. 이렇게 해두면 LLM은 SQL 전체를 생성할 필요가 없습니다. 대신 사용자 질문에 맞는 metric과 dimension을 선택하고, 실제 SQL 생성은 MetricFlow가 처리합니다.

MetricFlow는 YAML 파일을 바탕으로 semantic graph를 구성합니다. 그리고 이 graph 안에서 semantic model과 metric의 관계를 해석해 SQL을 생성합니다.

About MetricFlow | dbt Developer Hub
Learn more about MetricFlow and its key concepts

흐름은 다음처럼 바뀝니다.

사용자 질문
→ 사용 가능한 metric 조회
→ dimension / entity 조회
→ metric + dimension + filter 선택
→ Semantic Layer query 실행
→ 결과 요약

앞의 질문을 다시 보겠습니다.

지난 분기 지역별 순매출을 보여줘.

text-to-SQL 방식에서는 LLM이 SQL 전체를 만들어야 합니다. 반면 Semantic Layer 방식에서는 LLM이 다음과 같은 요청을 구성하는 쪽에 가깝습니다.

{
  "metrics": ["net_revenue"],
  "group_by": ["customer__region", "metric_time__quarter"],
  "where": "metric_time = previous_quarter"
}

그다음 MetricFlow가 이미 정의된 metric, dimension, entity 관계를 바탕으로 SQL을 생성합니다.

Semantic models | dbt Developer Hub
Semantic models are YAML abstractions on top of a dbt model, connected via joining keys as edges

이 차이를 간단히 정리하면 다음과 같습니다.

text-to-SQL:
자연어 → SQL 전체 생성

Semantic Layer:
자연어 → metric / dimension / filter 선택

LLM이 해야 할 일이 줄어들수록, 틀릴 수 있는 공간도 줄어듭니다. 이 점이 Semantic Layer의 핵심 가치입니다.

검증된 metric interface를 호출하게 만들기

Semantic Layer를 이해하는 가장 쉬운 방식은 API처럼 보는 것입니다.

text-to-SQL은 LLM에게 이런 작업을 맡깁니다.

이 데이터베이스를 보고 정답 SQL을 직접 작성해줘.

반면 Semantic Layer는 이렇게 말하는 방식입니다.

이미 정의된 metric API가 있으니, 사용자 질문에 맞는 metric과 dimension을 골라 호출해줘.

이 구조는 function calling과도 비슷합니다. LLM에게 자유롭게 텍스트를 생성하게 하는 것보다, 정해진 tool schema 안에서 argument를 채우게 하는 쪽이 더 안정적인 경우가 많습니다. Semantic Layer도 마찬가지입니다. SQL이라는 자유도 높은 출력을 직접 만들게 하기보다, 사전에 정의된 metric interface를 호출하게 만듭니다.

예를 들어 net_revenue가 이미 다음처럼 정의되어 있다고 가정해보겠습니다.

metrics:
  - name: net_revenue
    description: "Paid orders only, excluding refunds and taxes"
    type: simple
    type_params:
      measure: net_revenue_amount

이 경우 LLM은 “순매출이 정확히 무엇을 의미하는가”를 매번 추론할 필요가 없습니다. 사용자 질문이 net_revenue metric에 해당하는지 판단하고, 필요한 dimension과 filter를 선택하면 됩니다.

정확도 차이는 여기서 만들어집니다. 더 강한 모델을 고르는 일도 중요하지만, production analytics agent에서는 모델이 매번 추론해야 하는 범위를 줄이는 일이 더 중요해질 수 있습니다.

benchmark 결과는 무엇을 보여주나

dbt는 2026년에 Semantic Layer와 text-to-SQL을 비교한 benchmark update를 공개했습니다.

이 실험은 ACME Insurance benchmark 기반 11개 질문을 여러 모델에서 반복 실행했고, 다음 네 가지 방식을 비교했습니다.

text-to-SQL
minimal Semantic Layer
modeled Semantic Layer
modeled data 위의 text-to-SQL

dbt는 text-to-SQL 방식에 전체 schema를 context로 넣었다는 caveat도 함께 명시했습니다.

Semantic Layer vs. Text-to-SQL: 2026 Benchmark Update | dbt Developer Blog
With 2026’s best models, the dbt Semantic Layer hits near-100% accuracy for covered queries. Here’s what changed and what didn’t in our updated benchmark.

dbt가 공개한 주요 결과는 다음과 같습니다.

모델방식정확도
Claude Sonnet 4.6Text-to-SQL90.0%
Claude Sonnet 4.6Semantic Layer98.2%
GPT-5.3 CodexText-to-SQL84.1%
GPT-5.3 CodexSemantic Layer100.0%

dbt는 Semantic Layer scope 안에 있는 질문에서는 정확도가 100%에 가깝거나 100%에 도달했다고 설명합니다. 또한 deterministic query generation 덕분에 LLM이 미묘하게 틀린 결과를 만들 가능성을 줄일 수 있다고 봅니다.

물론 이 결과를 그대로 일반화해서는 안 됩니다. dbt가 수행한 vendor benchmark이고, 질문 수도 제한적입니다. 또한 Semantic Layer가 커버하는 범위 안에서 평가했다는 점도 함께 봐야 합니다.

그럼에도 결론은 참고할 만합니다.

정확도가 중요한 KPI 질문에는 Semantic Layer를 우선 사용하고, ad hoc 분석에는 text-to-SQL을 함께 쓰는 구조가 더 안전합니다.

dbt도 비슷한 방향을 권장합니다. board data, auditor, OKR, KPI, weekly report처럼 정확도가 중요한 질문에는 Semantic Layer를 연결하고, one-off 질문이나 prototyping에는 Semantic Layer를 먼저 확인한 뒤 필요하면 text-to-SQL로 fallback하는 방식입니다.

Knowledge Graph benchmark가 주는 비슷한 메시지

이 관점은 dbt Semantic Layer에만 해당하는 이야기는 아닙니다.

data.world 연구진의 Knowledge Graph benchmark에서는 enterprise SQL database에 대해 GPT-4 zero-shot text-to-SQL을 사용했을 때 정확도가 약 16%였고, 같은 데이터베이스를 Knowledge Graph representation으로 질의했을 때 약 54%로 증가했다고 보고했습니다.

https://data.world/mstatic/assets/pdf/kg_llm_accuracy_benchmark_11132023_public.pdf

이 실험은 dbt Semantic Layer 자체를 테스트한 것은 아닙니다. 하지만 메시지는 유사합니다.

raw schema만 제공하는 것보다, business semantics가 구조화된 중간 layer를 제공하는 쪽이 LLM 기반 질의 정확도에 유리할 수 있습니다.

결국 중요한 것은 LLM에게 어떤 모델을 쓰느냐만이 아닙니다. 어떤 context와 interface를 제공하느냐가 데이터 에이전트의 정확도와 신뢰성을 크게 좌우합니다.

Semantic Layer의 한계

Semantic Layer는 강력하지만, 모든 질문에 답할 수 있는 구조는 아닙니다. 모델링된 metric과 dimension 안에서만 안정적으로 동작합니다.

예를 들어 net_revenue는 정의되어 있지만 refund_reason별 분석이 semantic model에 없다면, Semantic Layer만으로는 답하지 못할 수 있습니다. 필요한 entity 관계가 정의되어 있지 않으면 query가 실패할 수도 있습니다.

하지만 이 실패 방식 자체가 중요합니다.

text-to-SQL의 실패는 종종 다음 형태로 나타납니다.

SQL 실행 성공
결과 반환 성공
하지만 숫자가 틀림

Semantic Layer의 실패는 대개 더 명시적으로 드러납니다.

이 metric / dimension 조합은 지원되지 않음

실제 환경에서는 두 번째 실패가 더 안전한 경우가 많습니다. 특히 KPI, 감사 자료, 임원 보고, OKR dashboard처럼 틀린 숫자가 의사결정에 바로 영향을 주는 상황에서는 “답할 수 없다”고 말하는 시스템이 더 낫습니다.

틀린 숫자를 그럴듯하게 말하는 시스템은 가장 위험한 형태의 데이터 에이전트가 될 수 있습니다.

text-to-SQL Hybrid 접근

그렇다면 text-to-SQL을 버려야 할까요?

저는 hybrid 구조가 더 현실적이라고 봅니다. Semantic Layer는 신뢰 가능한 metric 질의에 강하고, text-to-SQL은 탐색적 분석이나 비정형 질문에 강합니다. 두 접근은 경쟁 관계라기보다 역할이 다릅니다.

구조는 다음처럼 설계할 수 있습니다.

사용자 질문
  ↓
Semantic Layer로 답 가능한가?
  ├─ 가능 → governed metric query
  └─ 불가능 → text-to-SQL fallback

조금 더 구체적으로는 다음 기준을 둘 수 있습니다.

1. KPI / metric / reporting 질문인가?
   → Semantic Layer 우선 사용

2. 관련 metric은 있지만 dimension이 부족한가?
   → semantic model 개선 후보로 기록

3. 완전히 ad hoc 분석인가?
   → mart model 대상으로 text-to-SQL fallback

4. fallback 질문이 반복되는가?
   → 새 dbt model 또는 metric으로 승격

이 구조의 핵심은 역할 분담입니다. Semantic Layer가 잘 맞는 질문과 text-to-SQL이 잘 맞는 질문을 나누는 것입니다.

질문 유형더 적합한 접근
“지난달 지역별 매출 보여줘”Semantic Layer
“이번 분기 활성 고객 수 추이 보여줘”Semantic Layer
“A/B 테스트 그룹별 전환율 비교해줘”Semantic Layer, 단 metric 정의 필요
“이 테이블에 어떤 데이터가 있는지 탐색해줘”text-to-SQL
“최근 생성된 raw event 중 특이한 패턴 찾아줘”text-to-SQL
“반복적으로 묻는 ad hoc 질문”처음엔 text-to-SQL, 이후 metric으로 승격

Semantic Layer로 모든 질문을 처리하려고 하면 유연성이 떨어집니다. 반대로 text-to-SQL로 모든 질문을 처리하려고 하면 신뢰성이 흔들립니다. 따라서 중요한 것은 하나를 선택하는 것이 아니라, 질문의 성격에 따라 어떤 경로로 처리할지 정하는 것입니다.

데이터 에이전트의 목표

text-to-SQL 에이전트를 만들다 보면 자연스럽게 다음 문제에 집중하게 됩니다.

  • schema retrieval을 어떻게 잘할 것인가
  • SQL generation prompt를 어떻게 개선할 것인가
  • 실행 에러를 어떻게 repair할 것인가
  • SQL dialect를 어떻게 맞출 것인가
  • join path를 어떻게 찾을 것인가

이 문제들은 여전히 중요합니다. 하지만 production analytics agent의 목표를 SQL 생성 자체로만 두면 부족합니다.

목표는 이쪽에 더 가깝습니다.

사용자가 신뢰할 수 있는 숫자를 일관되게 얻도록 하는 것.

이 관점에서 보면 Semantic Layer는 단순한 dbt 기능이 아닙니다. LLM 기반 데이터 에이전트의 출력 공간을 제한하고, metric governance를 에이전트에 연결하는 interface입니다.

데이터 에이전트 아키텍처는 다음처럼 바뀔 수 있습니다.

Before:
Natural Language → SQL → Result

After:
Natural Language
→ Governed Metric Query if possible
→ SQL fallback if necessary
→ Recurring fallback questions become modeled metrics

이 구조에서는 에이전트가 무조건 SQL을 잘 쓰는 것보다, 어떤 질문을 governed metric query로 처리하고 어떤 질문을 fallback으로 넘길지 판단하는 능력이 더 중요해집니다.

작게 시작하기

처음부터 전사 Semantic Layer를 만들 필요는 없습니다. 오히려 그렇게 시작하면 실패할 가능성이 높습니다. 모든 지표와 차원을 한 번에 모델링하려고 하면 범위가 커지고, 실제 사용자의 질문과 멀어질 수 있습니다.

작게 시작하려면 다음 정도가 적당합니다.

핵심 metric 5~10개
실제 사용자 질문 30~50개
text-to-SQL baseline
Semantic Layer-first agent
동일 benchmark로 비교

평가할 때는 execution success만 보면 부족합니다. SQL이 실행됐다고 해서 답이 맞는 것은 아니기 때문입니다.

더 중요한 지표는 다음과 같습니다.

평가 항목의미
result accuracygold result와 일치하는가
silent failure rate실행은 됐지만 결과가 틀린 비율
repeatability같은 질문을 여러 번 했을 때 결과가 일관되는가
coverageSemantic Layer로 답 가능한 질문 비율
refusal quality답할 수 없는 질문에 적절히 거절하는가
traceability어떤 metric definition이 사용됐는지 추적 가능한가

특히 silent failure rate를 반드시 봐야 합니다.

text-to-SQL 에이전트는 발전할수록 더 그럴듯한 SQL을 만듭니다. 문제는 그 SQL이 틀렸을 때도 더 그럴듯해진다는 점입니다. 실행 실패보다 더 위험한 것은 조용한 실패입니다. 숫자는 반환됐고, 설명도 자연스럽지만, 실제 비즈니스 정의와는 어긋난 경우입니다.

Semantic Layer-first 구조는 이런 실패를 줄이는 데 도움이 될 수 있습니다. 적어도 metric으로 정의된 범위에서는 같은 질문에 대해 같은 정의를 사용하고, 지원하지 않는 질문은 지원하지 않는다고 드러낼 수 있기 때문입니다.

결론

text-to-SQL은 계속 중요합니다. ad hoc exploration이나 prototype 분석에서는 여전히 가장 유연한 접근입니다. 사용자가 미리 정의되지 않은 질문을 던지고, 데이터를 빠르게 탐색해야 하는 상황에서는 text-to-SQL이 강력한 도구가 됩니다.

다만 모든 자연어 데이터 질의를 text-to-SQL로 처리하려는 전략은 다시 검토할 필요가 있습니다. 특히 조직에서 공유되는 KPI, metric, reporting 질문이라면 LLM이 매번 SQL을 새로 생성하게 두는 방식은 위험할 수 있습니다.

dbt Semantic Layer의 가치는 LLM을 더 똑똑하게 만드는 데만 있지 않습니다. 더 중요한 가치는 LLM이 틀릴 수 있는 공간을 줄이는 데 있습니다. 조직이 합의한 metric 정의를 에이전트가 호출하게 만들고, 필요한 경우에만 text-to-SQL로 fallback하게 하면 데이터 에이전트의 신뢰성을 더 안정적으로 설계할 수 있습니다.

앞으로 데이터 에이전트를 설계한다면 저는 다음 구조를 우선 검토할 것 같습니다.

Semantic Layer first
→ governed answer
→ text-to-SQL fallback
→ 반복 질문은 metric으로 승격

자연어 데이터 질의의 목표가 SQL 생성 자동화라면 text-to-SQL만으로도 충분할 수 있습니다. 하지만 목표가 신뢰 가능한 숫자를 제공하는 것이라면, Semantic Layer는 데이터 에이전트 아키텍처에서 꽤 중요한 선택지가 됩니다.