데이터 엔지니어링을 하는 AI 에이전트 — Text-to-SQL을 넘어 파이프라인까지
데이터 엔지니어가 매일 반복하는 SQL 작성·파이프라인 디버깅·품질 검증·카탈로그 정리를 AI 에이전트에게 위임하는 방법. Trino·Iceberg·PySpark 위에서 도는 데이터 엔지니어링 에이전트의 아키텍처, 자기수정 루프, 그리고 프로덕션 가드레일을 다룹니다.
데이터 엔지니어의 하루를 들여다보면, 의외로 많은 시간이 반복 가능한 일에 쓰입니다. 새 테이블의 스키마를 훑어보고 적당한 조인을 찾아 SQL을 쓰고, 파이프라인이 깨지면 스택 트레이스를 읽어 고치고, 적재된 데이터에 NULL이 얼마나 끼었는지 품질을 확인하고, 카탈로그에 설명을 채워 넣는 일들 말이죠. 하나하나는 어렵지 않지만, 묶어 놓으면 하루가 사라집니다.
이 일들에는 공통점이 있습니다. 목표가 분명하고, 도구가 정해져 있고, 결과를 검증할 수 있다는 것. 바로 AI 에이전트가 잘하는 종류의 일입니다. 이 글은 "챗봇에게 SQL을 물어본다"를 넘어서, 데이터 플랫폼 위에서 스스로 계획하고·쿼리를 실행하고·실패를 고치는 데이터 엔지니어링 에이전트를 어떻게 설계하는지 다룹니다.
이 글에서 배우는 것
- 데이터 엔지니어링 에이전트가 Text-to-SQL 챗봇과 근본적으로 무엇이 다른지
- 에이전트가 카탈로그·쿼리 엔진·스토리지에 닿는 아키텍처
- 에이전트가 잘하는 네 가지 일: Text-to-SQL, 파이프라인 작성, 품질 검증, 카탈로그
- 쿼리가 실패했을 때 에러를 읽고 스스로 고치는 자기수정 루프
- 프로덕션에 올리기 전에 반드시 깔아야 할 가드레일
에이전트 자체의 개념(ReAct, Plan-and-Execute, Tool Use, 메모리)이 낯설다면 AI Agent 완전 가이드를 먼저 훑고 오면 이 글이 훨씬 수월합니다. 도구 호출(Function Calling)과 MCP가 처음이라면 AI Agent · MCP · A2A 입문 가이드도 함께 보세요.
1. 챗봇과 무엇이 다른가 — "물어보는 것" vs "해내는 것"
"Text-to-SQL"이라는 말은 익숙합니다. 자연어를 넣으면 SQL을 뱉어주는 것. 하지만 그건 에이전트의 첫 한 스텝일 뿐입니다. 진짜 데이터 엔지니어링은 SQL을 쓰는 것이 아니라, 그 쿼리가 맞는 답을 내는 것까지를 책임지는 일이거든요.
차이를 그림으로 보겠습니다.
핵심은 루프가 닫혀 있느냐입니다. 챗봇은 SQL을 던지고 끝나므로, 컬럼명을 환각하거나 조인을 잘못 걸어도 사람이 발견하기 전까지는 알 수 없습니다. 에이전트는 직접 실행해 보고, 에러가 나면 그 에러 메시지를 다시 읽어 고치고, 결과가 이상하면(예: 행이 0개) 가설을 바꿔 다시 시도합니다. 이 관찰 → 수정 사이클이 챗봇과 에이전트를 가르는 결정적 차이입니다.
| 구분 | Text-to-SQL 챗봇 | 데이터 엔지니어링 에이전트 |
|---|---|---|
| 출력 | SQL 문자열 | 검증된 결과 / 적용된 변경 |
| 실행 | 사람이 함 | 에이전트가 함(가드레일 하에) |
| 실패 처리 | 사람이 디버깅 | 에러 읽고 자기수정 |
| 스키마 인지 | 프롬프트에 통째로 넣음 | 필요한 만큼 검색(agentic) |
| 범위 | 단발 쿼리 | 파이프라인·품질·카탈로그까지 |
2. 아키텍처 — 에이전트가 데이터 플랫폼에 닿는 법
에이전트의 능력은 결국 어떤 도구를 쥐여주느냐로 결정됩니다. 데이터 엔지니어링 에이전트에게 필요한 도구는 사람 엔지니어가 쓰는 것과 정확히 같습니다. 메타데이터를 찾을 카탈로그, 쿼리를 던질 엔진, 데이터가 사는 스토리지, 그리고 변환을 돌릴 실행 환경입니다.
여기서 중요한 설계 원칙 하나. 에이전트는 데이터에 직접 손대지 않습니다. 항상 도구라는 좁은 통로를 통해서만 플랫폼에 닿습니다. 이게 왜 중요하냐면, 그 통로마다 권한·감사·한도를 거는 단 하나의 지점이 되기 때문입니다(§5에서 다룹니다). 자사 Argus 카탈로그 에이전트도 정확히 이 철학 — AI 코드를 API 서버에 끼워 넣지 않고 독립 에이전트로 떼어내, 도구를 통해서만 카탈로그에 닿게 하는 — 위에 서 있습니다. 도구를 OpenAI 스키마로 등록하고 실행 함수와 묶는 구체적인 방법은 Argus 에이전트의 도구·Function Calling 편에 코드 수준으로 정리돼 있습니다.
3. 에이전트가 잘하는 네 가지 일
3-1. Text-to-SQL — 스키마를 "검색"하는 에이전트
순진한 Text-to-SQL은 데이터베이스의 모든 스키마를 프롬프트에 통째로 밀어 넣습니다. 테이블이 수백 개인 레이크하우스에서는 컨텍스트 윈도우가 터지고, 비용이 폭발하고, LLM이 엉뚱한 테이블을 고를 확률만 높아집니다.
에이전트는 다르게 접근합니다. 필요한 스키마만 그때그때 검색하죠 — 이게 바로 "Agentic RAG"입니다. 정적 RAG가 한 번 검색해서 한 번 답하는 거라면, 에이전트는 검색을 도구로 들고 스스로 반복합니다.
스키마를 의미 기반으로 검색하려면 테이블·컬럼 설명을 임베딩해 둬야 합니다. 이 부분은 임베딩 모델 가이드와 벡터 데이터베이스 비교, 그리고 검색 파이프라인 전반은 RAG 완전 가이드가 토대가 됩니다. Trino 위에서 도는 에이전트라면 방언과 패턴을 알아야 하니 Trino SQL 패턴과 Trino 페더레이션 실전도 에이전트의 "교과서"로 함께 물려주면 좋습니다.
3-2. 파이프라인 작성·수정 — PySpark를 쓰는 에이전트
조회를 넘어 변환으로 가면 무대는 PySpark입니다. 에이전트에게 "원천 주문 테이블에서 일별 매출 집계 테이블을 만들어줘" 같은 목표를 주면, 스키마를 확인하고 변환 코드를 작성한 뒤 테스트와 함께 제출합니다.
# 에이전트가 생성한 변환 — 항상 테스트를 함께 낸다
from pyspark.sql import functions as F
def build_daily_sales(orders):
return (
orders
.filter(F.col("status") == "PAID")
.withColumn("order_date", F.to_date("created_at"))
.groupBy("order_date")
.agg(F.sum("amount").alias("gross_sales"),
F.countDistinct("customer_id").alias("buyers"))
)여기서 에이전트가 사람보다 잘 잊지 않는 게 하나 있습니다. 테스트를 같이 쓴다는 것. 변환 로직을 검증 가능한 단위로 쪼개 테스트하는 패턴은 PySpark 테스트 가이드에 정리돼 있고, 에이전트에게도 이 규율을 그대로 요구해야 합니다. 코드를 잘 쓰는 에이전트(SWE 에이전트)의 설계 원리가 궁금하면 명세 우선 접근을 다룬 왜 Spec-Driven Development인가 시리즈가 좋은 참고가 됩니다.
3-3. 데이터 품질 검증 — 룰을 생성하고 실행하는 에이전트
데이터가 적재됐다고 끝이 아닙니다. NULL 비율, 유니크 제약, 값 범위 — 품질 규칙을 통과해야 비로소 신뢰할 수 있죠. 에이전트는 스키마와 샘플을 보고 적절한 품질 규칙을 제안하고, 이를 Deequ 같은 도구로 실행해 결과를 가져옵니다.
규칙 자체를 어떻게 정의하고 실행하는지는 PySpark 데이터 품질(Deequ)에 구체적으로 나옵니다. 에이전트의 역할은 규칙 엔진을 대체하는 게 아니라, 규칙을 빠르게 만들어내고 실패를 해석하는 보조에 있습니다.
3-4. 카탈로그·메타데이터 — 이미 우리가 만든 영역
테이블 설명, 컬럼 주석, PII 태깅, 비즈니스 용어 매핑. 이 지루하지만 중요한 일이야말로 에이전트의 첫 번째 킬러 유스케이스입니다. 그리고 이건 이론이 아니라 우리가 이미 만들어 운영하는 영역이죠.
- 아키텍처(배치·폴링 데몬·어시스턴트의 3가지 실행 모드): 표준 라이브러리만으로 만든 데이터 카탈로그 AI 에이전트
- LLM 레이어(OpenAI 호환·로컬 모델): Argus 에이전트의 모델/LLM 편
- 거버넌스(AI가 생성하되 사람이 승인·PII 안전장치): AI가 카탈로그를 거버넌스한다
특히 마지막 거버넌스 편은 다음 §5에서 이야기할 가드레일의 살아있는 사례라서, 데이터 엔지니어링 에이전트를 진지하게 고려한다면 꼭 읽어볼 만합니다.
4. 자기수정 루프 — 실패를 연료로 쓰는 법
에이전트가 챗봇을 이기는 지점은 실패를 다루는 방식입니다. 사람이라면 컬럼명을 틀렸을 때 에러를 읽고 카탈로그를 다시 확인하죠. 에이전트도 똑같이 합니다.
이 루프에는 반드시 상한이 있어야 합니다. 무한히 재시도하면 비용이 폭발하고, 같은 실수를 반복하며 도는 "루프 지옥"에 빠지거든요. 보통 ① 최대 재시도 횟수(예: 3회), ② 토큰/비용 예산, ③ "직전과 동일한 쿼리면 중단" 같은 정체 감지를 함께 겁니다. 이 한도를 어떻게 관측하고 끊을지는 운영 영역이라, 곧 이어질 **운영 3부작 1편(AgentOps 관측성)**에서 자세히 다룹니다.
5. 가드레일 — 프로덕션의 진짜 90%
데모를 만드는 데는 하루면 되지만, 프로덕션에 올리는 일의 9할은 에이전트가 사고 치지 못하게 막는 것입니다. 자율성과 안전성은 트레이드오프이고, 그 사이를 메우는 게 가드레일입니다.
실전에서 거의 항상 채택하는 가드레일은 다음과 같습니다.
- 기본은 읽기 전용(read-only by default). 쓰기·DDL·삭제는 별도 승인 경로로만.
- 사람이 고리에(Human-in-the-loop). 되돌리기 어려운 작업은 제안까지만 하고 사람이 적용. Argus의
suggest/apply분리가 정확히 이 패턴입니다 — 거버넌스 편 참고. - 항상 dry-run 먼저.
EXPLAIN으로 플랜과 스캔량을 보고, 한도를 넘으면 실행 전에 차단. - 행 수·타임아웃·비용 한도. 폭주 쿼리가 클러스터를 잡아먹지 못하게. Trino 리소스 그룹과 결이 맞습니다.
- 권한은 위임받은 사용자 토큰으로. 에이전트가 admin 권한을 상시 들고 있으면 안 됩니다. serve 모드가 사용자 토큰을 위임받아 그 사람 권한으로만 동작하는 Argus 설계가 좋은 본보기입니다.
- 모든 도구 호출은 감사 로그로. 무엇을·왜·어떤 결과로 했는지 추적 가능해야 합니다.
이 가드레일들이 "있으면 좋은" 게 아니라 없으면 프로덕션 금지 수준이라는 점을, 한 번 사고를 겪어본 팀은 다 압니다.
6. 프로덕션의 함정 — 데모와 현실의 거리
마지막으로, 실제로 올려보면 만나는 함정들을 정리합니다.
- 스키마 환각. 그럴듯한데 존재하지 않는 컬럼을 자신만만하게 씁니다. → 스키마를 프롬프트로 주입하지 말고 도구로 검색하게 하고,
EXPLAIN으로 항상 검증. - 비용 폭발. 자기수정 루프 한 번에 LLM 호출 + Trino 풀스캔이 몇 번씩 돕니다. → 토큰/스캔 예산과 재시도 상한을 강제.
- 조용히 틀린 조인. 에러는 안 나는데 결과가 틀립니다(카티전 곱, 잘못된 키). → 결과 행 수·분포에 대한 자기 점검(sanity check) 단계를 루프에 넣기.
- 거버넌스 우회. 에이전트가 RLS·마스킹을 건너뛰고 원천을 직접 읽으면 데이터 사고. → 항상 위임된 권한으로, 카탈로그의 정책을 경유.
- 관측 불가. 에이전트가 무슨 생각으로 그 쿼리를 던졌는지 안 보이면 디버깅이 불가능. → 트레이싱은 선택이 아니라 필수.
마지막 두 가지 — 거버넌스와 관측 — 는 너무 중요해서 이어지는 운영 3부작으로 따로 뺐습니다.
마치며 — 그리고 운영 3부작 예고
데이터 엔지니어링 에이전트는 "사람을 대체하는 마법"이 아니라, 반복 가능하고 검증 가능한 일을 도구를 통해 닫힌 루프로 처리하는 잘 설계된 시스템입니다. Text-to-SQL은 그 첫 스텝일 뿐이고, 진짜 가치는 실패를 스스로 고치고, 품질을 검증하고, 가드레일 안에서 안전하게 도는 데서 나옵니다.
좋은 데모를 만드는 것과 프로덕션에서 믿고 맡기는 것 사이엔 큰 강이 있습니다. 그 강을 건너는 세 개의 다리 — 관측·평가·보안 — 을 이어지는 운영 3부작에서 하나씩 놓겠습니다.
- 1편 · AgentOps: 에이전트 관측성과 트레이싱 — 에이전트가 무슨 생각으로 그 도구를 호출했는지, 토큰과 비용은 얼마였는지, 실패를 어떻게 재현하는지.
- 2편 · 에이전트 평가 — 정답이 하나가 아닐 때 — 태스크 성공률·트라젝토리 평가·회귀 테스트, 그리고 LLM-as-judge의 함정.
- 3편 · 에이전트 보안 — 프롬프트 인젝션 그 너머 — 도구 권한 최소화, 샌드박싱, confused deputy, MCP 신뢰 경계.
한 문장으로: 에이전트의 가치는 "SQL을 생성하는 것"이 아니라 "검증된 결과를 책임지는 것"에 있고, 그 책임을 떠받치는 건 닫힌 루프와 가드레일이다.