QL AI 데이터베이스 솔루션: 실제로 실행 가능한 Text-to-SQL 파이프라인 구축하기
요약
Text-to-SQL 파이프라인의 핵심 아키텍처인 스키마 조사, 프롬프트 구성, SQL 생성, 실행의 4단계를 설명합니다. SQLite를 활용해 실제 작동하는 파이프라인을 구축하고, Claude와 같은 외부 LLM을 유연하게 교체할 수 있는 플러그형 클라이언트 설계 방식을 제안합니다.
핵심 포인트
- Text-to-SQL의 4단계 핵심 아키텍처 분석
- 스키마 조사부터 실행까지의 전체 워크플로우 구현
- LLM 클라이언트를 인터페이스화하여 유연한 교체 가능 설계
- 실제 SQLite 데이터베이스를 활용한 검증된 파이프라인 구축
초록 (Abstract)
freeCodeCamp의 SQL 쿼리 추출기 튜토리얼부터 Hugging Face의 smolagents Text-to-SQL 예제, 그리고 Vanna.AI와 같은 프로덕션 프레임워크에 이르기까지, "데이터베이스와 대화하기" 도구들은 모두 동일한 핵심 아키텍처를 공유합니다: 스키마 (schema)를 설명하고, 자연어 질문과 해당 스키마를 LLM에 전달한 뒤, SQL을 받아 실행하여 결과를 반환하는 방식입니다. 이 글에서는 소규모 커피 구독 상점을 위한 실제 SQLite 데이터베이스를 대상으로 이 파이프라인을 처음부터 구축합니다. 또한 플러그형 LLM 클라이언트를 사용하여, 프로덕션 환경에서 Claude를 호출하든 API 키 없이 데모를 실행하든 동일한 코드 경로가 작동하도록 설계했습니다. 라이브 데이터베이스를 대상으로 네 가지 자연어 질문을 던졌으며, 단순한 예시용 코드 조각이 아닌 실제 검증된 SQL과 실제 결과 집합을 생성해냈습니다.
모든 "AI SQL" 도구 뒤에 숨겨진 아키텍처
벤더에 관계없이 모든 Text-to-SQL 시스템은 다음 네 단계를 따릅니다:
- 스키마 조사 (Schema introspection) — LLM은 본 적 없는 스키마를 추측할 수 없으므로, 데이터베이스에서 실제 테이블 및 컬럼 이름을 읽어옵니다.
- 프롬프트 구성 (Prompt construction) — 스키마 설명과 사용자의 질문을 하나의 지침으로 결합합니다.
- SQL 생성 (SQL generation) — LLM은 SQL 문자열(답변이 아닌 SQL 자체)을 반환합니다.
- 실행 (Execution) — 생성된 SQL을 실제 데이터베이스에서 실행하며, 그 결과 집합이 사용자에게 보여집니다.
Vanna.AI와 같은 프로덕션 도구들은 그 위에 검색 레이어 (retrieval layer)를 추가합니다. 이들은 DDL, 문서, 과거 쿼리를 학습하여 LLM이 매 호출마다 전체 스키마를 보는 대신 관련 예시를 볼 수 있게 합니다. 하지만 핵심적인 4단계 구조는 아래에서 구축할 내용과 동일합니다.
실제 사례: 커피 상점 데이터베이스
customers, products, orders, order_items라는 네 개의 테이블로 구성된 SQLite 데이터베이스입니다. 전체를 읽기에 충분히 작으면서도, 실제 조인 (join)과 집계 (aggregation)가 필요할 만큼 현실적입니다.
# schema.py
def describe_schema(db_path: str) -> str:
conn = sqlite3.connect(db_path)
...
실제 출력:
customers(id INTEGER, name TEXT, tier TEXT)
products(id INTEGER, name TEXT, price REAL)
orders(id INTEGER, customer_id INTEGER, created_at TEXT)
...
이것이 바로 LLM 프롬프트(prompt)에 삽입되는 바로 그 형태의 압축된 스키마(schema) 설명입니다.
플러그형 LLM 클라이언트 — API 비용 없이 파이프라인을 테스트할 수 있도록
흥미로운 엔지니어링 결정은 프롬프트가 아닙니다. 외부 의존성(dependency)을 모킹(mock)하는 것과 동일한 방식으로, LLM 호출을 인터페이스(interface) 뒤에 유지하는 것입니다:
# llm_client.py
class SQLClient(ABC):
@abstractmethod
...
AnthropicSQLClient가 실제 프로덕션(production) 경로입니다. 이 글의 데모를 누구나 API 키나 비용 없이 실행할 수 있도록 하기 위해, 두 번째 구현체인 LocalSQLClient는 호스팅된 모델 대신 스키마 기반 패턴 매칭(pattern matching)을 사용하여 정확히 동일한 인터페이스를 충족합니다. 두 구현체 모두 아래의 동일한 파이프라인(pipeline)에 연결됩니다. 데모에서 프로덕션으로 전환하는 것은 호출부(call site)에서 한 줄만 수정하면 됩니다.
파이프라인: 질문 입력, 실제 결과 출력
# ask.py
def ask(question: str, client: SQLClient, db_path: str = "store.db"):
schema = describe_schema(db_path)
...
실제 데이터베이스를 대상으로 네 가지 실제 질문을 실행합니다:
Q: How many gold customers do we have?
SQL: SELECT COUNT(*) FROM customers WHERE tier = 'gold'
Columns: ['COUNT(*)']
...
이 숫자들은 모두 시드 데이터(seed data)와 대조하여 수동으로 확인할 수 있습니다. 이것이 Text-to-SQL 시스템이 제대로 작동하는지 확인하는 실제 테스트 방법입니다. SQL이 그럴듯해 보이는지가 아니라, 올바른 행(rows)을 반환하는지가 핵심입니다.
다른 코드 경로와 마찬가지로 파이프라인 테스트하기
SQL 생성 단계가 인터페이스 뒤에 위치하기 때문에, 시스템의 나머지 부분은 실제 LLM을 건드리지 않고도 완전히 테스트할 수 있습니다:
def test_top_products_by_revenue():
sql, columns, rows = ask("What are the top 3 products by revenue?", client)
assert len(rows) == 3
...
실제 실행:
test_ask.py::test_gold_customer_count 통과 (PASSED)
test_ask.py::test_top_products_by_revenue 통과 (PASSED)
test_ask.py::test_orders_for_named_customer 통과 (PASSED)
...
마지막 테스트는 다른 테스트만큼이나 중요합니다. Text-to-SQL 시스템은 답변할 수 없는 질문에 대해 확신에 찬 오답 쿼리를 생성하는 대신, 정의된 동작(defined behavior)을 가져야 합니다.
프로덕션 시스템이 이 위에 추가하는 것들
위의 파이프라인은 완성된 제품이 아닌 최소한의 핵심(minimal core)임을 솔직하게 밝히고 있습니다. Vanna.AI, smolagents의 Text-to-SQL 예제, 그리고 아래에서 참조하는 freeCodeCamp 튜토리얼과 같은 도구들이 추가하는 기능은 다음과 같습니다:
- 검색 증강 프롬프팅 (Retrieval-augmented prompting) — 모든 프롬프트에 전체 스키마 (schema)를 집어넣는 대신, 질문과 관련된 테이블과 예시 쿼리만을 검색하여 가져옵니다. 이는 데이터베이스에 수백 개의 테이블이 있을 때 매우 중요합니다.
- 쿼리 검증 (Query validation) — LLM이 컬럼 (column) 이름을 환각 (hallucinate)할 수 있으므로, 실행 전 생성된 SQL이 읽기 전용(read-only)인지, 실제 테이블을 참조하고 있는지 확인합니다.
- 결과 설명 (Result explanation) — 원시 행(raw rows) 데이터를 다시 자연어 답변으로 변환하는 두 번째 LLM 호출 단계입니다.
- 대화 메모리 (Conversation memory) — "이제 골드 등급만 보여줘"와 같은 후속 질문이 이전 쿼리의 필터 (filter)를 참조할 수 있게 합니다.
결론
모든 "AI SQL" 제품의 핵심은 오후 한나절 만에 구축하고 검증할 수 있을 정도로 작습니다. 스키마를 조사하고, 이를 LLM에 프롬프트로 제공하며, 결과물을 실행하고, 실제 모델을 대신하는 가짜 모델로 전체 과정을 테스트하는 것입니다. 진정으로 어려운 부분 — 그리고 Vanna.AI와 같은 도구들이 복잡성을 감수하며 가치를 창출하는 부분 — 은 수백 개의 테이블과 모호한 질문에 대해 해당 핵심 기능을 신뢰할 수 있게 만드는 것입니다. 하지만 이 4단계의 골격(skeleton)을 먼저 이해하는 것이 그러한 프로덕션 도구들을 평가하거나 그 위에 구축하는 것을 가능하게 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기