10 AI 탐정, SQL을 만나다
1950년대부터 본격적으로 컴퓨터가 도입되면서 CLI를 필두로 다양한 사용자 인터페이스(User Interface)가 적용되었다. 스티브 잡스의 애플사는 매킨토시 GUI에 이어 아이폰 모바일 인터페이스를 일반화시켰다면, 최근 챗GPT는 언어 사용자 인터페이스(LUI)를 통해 각 분야에 혁신을 예고하고 있다. 챗GPT(Vaswani 기타, 2017) 데이터 과학도 사용자 관점에서 보자. 기존 R, 파이썬, SQL, 엑셀 등 데이터 과학 구문을 머리속에 암기하고 있거나 구글이나 네이버를 통해 중요 키워드를 통해 문제를 해결해야 했었다. 하지만, 이제 챗GPT가 자연어를 이해하기 때문에 데이터 전처리, 통계 작업, 데이터 분석, 시각화, 모형개발 등 데이터 과학 전반에 변화는 필연적이다. (Wickham 기타, 2023) (Wickham 기타, 2019) (Gozalo-Brizuela & Garrido-Merchan, 2023)
하지만 이 강력한 AI 탐정을 그대로 믿어도 될까? 챗GPT(Wu 기타, 2023)를 “웹의 흐릿한 JPEG”(Chiang, 2023)에 비유하는 것처럼, AI는 방대한 데이터를 기반으로 그럴듯한 ’추측’을 내놓지만, 그 추측이 항상 진실은 아니다. 특히 1930년대 남극 탐사대의 미스터리처럼 복잡하고 미묘한 단서가 얽힌 사건에서는 더욱 그렇다.
이번 장에서는 우리 데이터 탐정팀에 합류한 새로운 파트너, AI와 함께 수수께끼를 풀어보겠다. 우리는 AI에게 질문을 던져 가설을 세우고, 그 가설을 다시 SQL이라는 가장 날카로운 검증 도구로 파헤쳐 볼 것이다. 이 과정을 통해 AI의 놀라운 능력과 명백한 한계를 동시에 목격하며, AI 시대의 데이터 탐정에게 가장 필요한 역량이 무엇인지 깨닫게 될 것이다.
10.1 AI 탐정 길들이기: 프롬프트 엔지니어링
AI 탐정은 매우 유능하지만, 우리가 원하는 답을 얻기 위해서는 그에게 사건 파일을 정확히 브리핑해야 한다. 이 브리핑 과정이 바로 프롬프트 엔지니어링(Prompt Engineering)이다. 프롬프트의 품질이 AI가 생성하는 SQL 쿼리의 품질을 결정하기 때문이다.
훌륭한 SQL 쿼리를 생성하는 프롬프트는 다음과 같은 핵심 요소들을 포함해야 한다.
역할 부여 (Persona): AI에게 “너는 최고의 SQL 전문가야(You are an expert in SQL)”라고 역할을 부여하면, AI는 그 역할에 맞는 지식과 스타일로 답변을 생성한다.
명확한 맥락 (Context): 가장 중요한 부분이다. AI가 어떤 데이터베이스를 보고 쿼리를 작성해야 하는지 알려줘야 한다. 바로
CREATE TABLE
구문으로 정의된 데이터베이스 스키마를 제공하는 것이다. 이것은 AI 탐정에게 사건 현장의 지도와 용의자 목록을 주는 것과 같다.구체적인 지시 (Instruction): “과학자들의 이름을 보여줘”와 같이 원하는 바를 명확하고 구체적으로 지시해야 한다. “설명은 빼고 SQL 쿼리만 보여줘(No explanation. Write only SQL query)”와 같이 결과의 형식까지 지정해주면 더욱 좋다.
제약 조건 (Constraints): “
JOIN
은 사용하지마” 또는 “AVG
함수를 사용해” 와 같이 특정 제약 조건을 추가하여 쿼리 생성 방식을 제어할 수 있다.
이 요소들을 조합하여, 우리는 AI 탐정이 우리의 의도에 맞는 정확한 SQL 쿼리를 생성하도록 유도할 수 있다. 이제 실제 사건에 이 원칙들을 적용해 보겠다.
10.2 최첨단 AI 탐정: 상용 LLM 활용법 (OpenAI GPT)
가장 먼저 만나볼 AI 탐정은 현존 최강의 추리력을 자랑하는 OpenAI의 GPT 모델이다. 먼저 가장 직관적인 챗GPT 웹 인터페이스를 통해 사건의 실마리를 찾아보겠다.
10.2.1 챗GPT 인터페이스로 추리 시작하기
우리의 첫 번째 임무는 간단하다. “탐사대에 참여한 과학자들의 이름을 화면에 출력하는 SQL 쿼리를 작성해줘.” 라는 요청이다. 앞서 배운 프롬프트 엔지니어링 원칙에 따라, 역할, 맥락(스키마), 지시사항을 모두 담아 AI에게 사건 파일을 전달한다.
You are an expert in SQL. The following table definitions have been provided to you. Please convert my query into an appropriate SQL statement.
CREATE TABLE Person(
ident text,
personal text,
family text
);
CREATE TABLE Site(
name text,
lat real,
long real
);
CREATE TABLE Visited(
ident integer,
site text,
dated text
);
CREATE TABLE Survey(
taken integer,
person text,
quant text,
reading real
);
Let's write an SQL query to display the names of scientists on the screen.
SELECT personal, family
FROM Person;
AI 탐정은 즉시 Person
테이블에서 personal
과 family
컬럼을 선택하는 정확한 SQL 쿼리를 제시한다. 매우 간단한 임무였지만, AI가 우리의 의도를 완벽하게 이해했음을 알 수 있다.
10.2.2 파이썬으로 AI 탐정 자동화하기
매번 웹 인터페이스에 접속하여 프롬프트를 복사-붙여넣기 하는 것은 번거롭다. 이제 파이썬과 OpenAI API를 사용하여 우리만의 자동화된 AI 탐정 시스템을 구축해 보겠다. 이를 통해 반복적인 작업을 자동화하고, 더 복잡한 분석 파이프라인을 만들 수 있다.
먼저, 필요한 라이브러리를 설치하고 API 키를 설정해야 한다. (자세한 설정 방법은 부록을 참고하라.)
다음은 자연어 질문을 SQL 쿼리로 번역하는 파이썬 코드다.
```{python}
#| eval: false
import os
from openai import OpenAI
# OpenAI 클라이언트 초기화
= OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
client
# 데이터베이스 스키마와 질문을 포함하는 프롬프트 작성
= """
sql_prompt You are an expert in SQL. The following table definitions have been provided to you. Please convert my query into an appropriate SQL statement.
CREATE TABLE Person(ident text, personal text, family text);
CREATE TABLE Site(name text, lat real, long real);
CREATE TABLE Visited(ident integer, site text, dated text);
CREATE TABLE Survey(taken integer, person text, quant text, reading real);
Question: display the names of scientists on the screen.
SQL Query:
"""
# OpenAI API 호출
= client.chat.completions.create(
response ="gpt-4",
model=[
messages"role": "user", "content": sql_prompt}
{
],=0
temperature
)
# 결과 출력
= response.choices[0].message.content
sql_query print(sql_query)
```
SELECT personal, family FROM Person;
코드를 실행하면 웹 인터페이스와 동일한, 정확한 SQL 쿼리를 얻을 수 있다. 이제 우리는 이 코드를 재사용하여 어떤 자연어 질문이든 SQL로 변환할 수 있는 강력한 도구를 갖게 되었다.
10.2.3 심화 추리: AI 탐정의 진짜 실력 테스트
이제 AI 탐정에게 더 어려운 임무를 맡겨보겠다. “각 탐사대원이 마지막으로 측정한 날짜와, 그날 측정한 방사능(rad) 수치를 알려줘.” 이 질문은 여러 테이블을 JOIN
하고, 각 대원별로 그룹화하여 가장 마지막 날짜를 찾아야 하는 복잡한 쿼리를 필요로 한다.
#| eval: false
# 더 복잡한 질문으로 프롬프트 업데이트
= """
advanced_sql_prompt You are an expert in SQL. The following table definitions have been provided to you. Please convert my query into an appropriate SQL statement.
CREATE TABLE Person(ident text, personal text, family text);
CREATE TABLE Site(name text, lat real, long real);
CREATE TABLE Visited(ident integer, site text, dated text);
CREATE TABLE Survey(taken integer, person text, quant text, reading real);
Question: For each scientist, find their last measurement date and the radiation reading on that date.
SQL Query:
"""
# OpenAI API 호출
= client.chat.completions.create(
response ="gpt-4",
model=[
messages"role": "user", "content": advanced_sql_prompt}
{
],=0
temperature
)
# 결과 출력
= response.choices[0].message.content
sql_query print(sql_query)
WITH LastVisit AS (
SELECT
s.person,MAX(v.dated) AS last_date
FROM Survey s
JOIN Visited v ON s.taken = v.ident
WHERE v.dated IS NOT NULL
GROUP BY s.person
)SELECT
p.personal,
p.family,
lv.last_date,AS radiation_reading
s_rad.reading FROM LastVisit lv
JOIN Person p ON lv.person = p.ident
JOIN Visited v ON lv.last_date = v.dated
JOIN Survey s_rad ON v.ident = s_rad.taken AND lv.person = s_rad.person
WHERE s_rad.quant = 'rad';
AI 탐정은 WITH
절(공통 테이블 표현식, CTE)을 사용하여 이 복잡한 문제를 단계별로 해결하는 매우 정교한 SQL 쿼리를 생성했다. 먼저 각 대원별 마지막 방문 날짜를 찾은 다음, 그 정보를 바탕으로 Person
, Visited
, Survey
테이블을 다시 조인하여 최종 결과를 도출한다.
이처럼 상용 LLM은 복잡한 SQL 작성에 매우 강력한 능력을 보여준다. 하지만 이 능력에는 비용이 따른다. API 호출은 유료이고, 특히 한국어는 토큰 처리 방식 때문에 영어보다 더 많은 비용이 발생할 수 있다. 또한 우리의 민감한 데이터를 외부 서버로 보내야 한다는 잠재적인 보안 문제도 있다.
그렇다면 비용 없이, 우리의 데이터를 안전하게 지키면서 AI 탐정의 능력을 활용할 방법은 없을까? 다음 섹션에서는 우리 컴퓨터에서 직접 실행할 수 있는 ’오픈소스 AI 탐정’에 대해 알아보겠다.
10.3 나만의 AI 탐정 만들기: 오픈소스 LLM
상용 LLM의 강력한 성능은 매력적이지만, 비용과 데이터 보안 문제는 우리 데이터 탐정에게 큰 고민거리다. 다행히 우리에게는 또 다른 선택지가 있다. 바로 오픈소스 LLM이다. 메타의 Llama 모델을 시작으로, 전 세계 개발자들이 함께 발전시키고 있는 오픈소스 LLM들은 이제 특정 분야에서 상용 모델에 버금가는 성능을 보여주며 우리에게 새로운 가능성을 열어주고 있다.
오픈소스 LLM의 가장 큰 장점은 다음과 같다.
- 비용: 무료다. 우리 자신의 컴퓨터에서 실행하므로 API 사용료 걱정 없이 마음껏 실험하고 사용할 수 있다.
- 데이터 보안: 모든 데이터가 우리 컴퓨터 안에서 처리된다. 민감한 정보가 외부로 유출될 걱정이 없다.
- 투명성과 유연성: 모델의 작동 방식을 직접 들여다보고, 필요하다면 우리에게 맞게 미세조정(fine-tuning)할 수도 있다.
물론, 강력한 GPU가 필요하고 초기 설정이 다소 복잡할 수 있다는 단점도 있다. 하지만 Ollama
와 같은 도구 덕분에 이제는 누구나 쉽게 자신만의 AI 탐정을 가질 수 있게 되었다.
10.3.1 Ollama로 로컬 AI 탐정 구축하기
Ollama
는 다양한 오픈소스 LLM을 우리 컴퓨터에서 쉽게 실행하고 관리할 수 있게 해주는 놀라운 도구다. 몇 가지 간단한 명령만으로 SQL 쿼리 생성에 특화된 AI 탐정을 우리 팀에 합류시킬 수 있다.
1단계: Ollama 설치
먼저 Ollama 웹사이트를 방문하여 자신의 운영체제에 맞는 프로그램을 다운로드하고 설치한다.
2단계: SQL 특화 모델 다운로드
터미널을 열고 다음 명령어를 입력하여 SQL 생성에 특화된 duckdb-nsql
모델을 다운로드한다. 이 모델은 DuckDB 데이터베이스의 SQL 문법에 특히 강점을 가지도록 훈련되었다.
ollama pull duckdb-nsql
3단계: 로컬 AI 탐정과 대화하기
이제 우리만의 AI 탐정과 대화를 시작할 시간이다. 터미널에서 다음 명령어를 실행한다.
ollama run duckdb-nsql
이제 우리는 상용 LLM을 사용했을 때와 동일한 프롬프트를 사용하여 SQL 쿼리를 요청할 수 있다. 놀랍게도, 앞서 OpenAI API를 호출했던 파이썬 코드를 거의 그대로 재사용할 수 있다. base_url
만 로컬 서버 주소로 변경해주면 된다.
#| eval: false
from openai import OpenAI
# 클라이언트를 로컬 Ollama 서버로 지정
= OpenAI(
client ='http://localhost:11434/v1',
base_url='ollama', # Ollama는 API 키가 필요 없음
api_key
)
# 프롬프트는 동일하게 사용
= """
sql_prompt You are an expert in SQL. The following table definitions have been provided to you. Please convert my query into an appropriate SQL statement.
CREATE TABLE Person(ident text, personal text, family text);
CREATE TABLE Site(name text, lat real, long real);
CREATE TABLE Visited(ident integer, site text, dated text);
CREATE TABLE Survey(taken integer, person text, quant text, reading real);
Question: display the names of scientists on the screen.
SQL Query:
"""
= client.chat.completions.create(
response ='duckdb-nsql', # 다운로드한 모델 이름
model=[
messages"role": "user", "content": sql_prompt}
{
]
)
print(response.choices[0].message.content)
SELECT T2.personal, T2.family FROM Person AS T2
보시다시피, 로컬에서 실행된 오픈소스 모델도 정확한 SQL 쿼리를 성공적으로 생성했다. 이제 우리는 비용과 보안 걱정 없이, 우리만의 AI 탐정과 함께 1930년대 남극의 미스터리를 계속해서 파헤칠 수 있게 되었다.
10.4 AI 탐정 성능 평가하기
우리는 이제 상용 AI 탐정(GPT-4)과 우리만의 오픈소스 AI 탐정(duckdb-nsql)을 모두 다룰 수 있게 되었다. 그렇다면 어떤 상황에서 어떤 탐정을 선택해야 할까? 이를 결정하려면 이들의 성능을 객관적으로 평가하는 방법을 알아야 한다.
Text-to-SQL 모델의 성능 평가는 빠르게 발전하는 분야다. 과거에는 WikiSQL처럼 간단한 쿼리를 평가하는 벤치마크가 사용되었지만, 오늘날의 AI 탐정들은 훨씬 더 복잡한 사건들을 해결해야 한다. 그래서 학계와 산업계는 더 현실적인 벤치마크들을 개발했다.
Spider: 여러 테이블을 조인하고 복잡한 조건을 다루는 쿼리가 포함된, 다양한 분야의 데이터베이스 138개를 아우르는 표준 벤치마크다. AI 탐정의 기본적인 추리력을 테스트하는 ’수능 시험’과 같다.
BIRD (BIg Bench for LaRge-scale Database Grounded Text-to-SQL Evaluation): 실제와 유사한 대용량 데이터베이스 환경에서 AI 탐정이 얼마나 효율적이고 정확한 SQL을 생성하는지 평가하는, ’실무 능력 평가’에 가깝다.
이러한 벤치마크에서 모델의 성능은 주로 실행 정확도(Execution Accuracy, EX)로 측정된다. 즉, AI가 생성한 SQL 쿼리를 실제로 데이터베이스에서 실행했을 때, 정답과 동일한 결과를 반환하는지를 평가하는 가장 확실한 방법이다.
2024년 현재, GPT-4o, Claude 3.5 Sonnet, IBM의 Granite Code Model과 같은 최신 상용 모델들이 이러한 벤치마크에서 최고의 성능을 보여주고 있다. 오픈소스 진영에서도 이들을 빠르게 따라잡고 있으며, 특정 작업에서는 이미 상용 모델을 능가하는 성능을 보여주기도 한다.
하지만 중요한 점은 리더보드의 순위가 절대적인 기준은 아니라는 것이다. 우리의 ‘1930년대 남극 탐사’ 데이터베이스처럼 특정 도메인에서는, 해당 분야에 특화된 오픈소스 모델이 거대한 범용 모델보다 더 나은 성능을 보일 수도 있다. 최고의 데이터 탐정은 여러 AI 도구의 장단점을 이해하고, 주어진 사건에 가장 적합한 도구를 선택하여 활용할 줄 알아야 한다.
💭 생각해볼 점
AI 탐정이라는 강력한 파트너가 생겼지만, 우리의 역할은 결코 줄어들지 않았다. 오히려 더 중요해졌다. AI는 놀라운 속도로 SQL 코드를 생성하지만, 그 코드가 담고 있는 논리와 맥락을 이해하고 최종적으로 검증하는 것은 오롯이 우리, 인간 탐정의 몫이기 때문이다.
AI가 제시한 복잡한 JOIN
과 WITH
구문을 보며 우리는 무엇을 느껴야 할까? 단순히 ’편리하다’에서 그쳐서는 안 된다. 우리는 그 쿼리를 해독하고, 더 나은 방법은 없는지 비판적으로 검토하며, AI의 실수를 잡아낼 수 있는 깊이 있는 SQL 지식을 갖추어야 한다. AI는 최고의 조수이지만, 사건 해결의 책임은 우리에게 있다.
오픈소스 LLM을 로컬 환경에 구축하는 경험은 우리에게 무엇을 말해줄까? 이는 우리가 더 이상 기술의 ’소비자’가 아니라, 우리에게 필요한 도구를 직접 만들고 통제하는 ’생산자’가 될 수 있음을 의미한다. 비용과 보안의 제약에서 벗어나, 우리만의 방식으로 미스터리를 해결할 힘을 갖게 된 것이다.
탐정으로서의 당신의 추리는 무엇인가? AI가 생성한 복잡한 쿼리가 1930년대 남극의 미스터리에 대해 어떤 새로운 단서를 제공할 수 있을까? 혹시 AI가 우리가 미처 생각지 못한 방식으로 테이블을 연결하여 숨겨진 관계를 밝혀낼 수도 있지 않을까?
이제 우리는 AI와 SQL이라는, 상상력과 분석력을 겸비한 최고의 탐정 도구를 모두 손에 쥐었다. 이 도구들을 가지고, 다음 장에서는 평범해 보이는 데이터 속에 숨겨진 놀라운 이야기들을 찾아 떠나보겠다. 우리가 마주할 첫 번째 현대의 사건 파일은 바로 스프레드시트다.