[SQL RAG] LangChain과 LangGraph를 활용한 지능형 데이터베이스 질의 에이전트 구축(쿼리문 RAG)

2026. 4. 2. 10:14·개념 정리 step2/AI Agent

데이터 분석이나 서비스 운영 과정에서 데이터베이스에 직접 쿼리를 날려 정보를 확인해야 하는 경우가 빈번하다. 하지만 SQL 문법에 익숙하지 않은 사용자나, 복잡한 스키마를 가진 데이터베이스의 경우 매번 쿼리를 작성하는 것이 번거로울 수 있다. 이를 해결하기 위해 거대 언어 모델(LLM)이 자연어를 SQL로 변환하고 실행 결과까지 해석해 주는 SQL RAG(Retrieval-Augmented Generation) 시스템을 구축해 보았다.

 

본 포스팅에서는 SQLite를 활용해 환경을 구성하고, LangChain과 LangGraph를 이용하여 스스로 판단하고 오류를 수정하며 답변하는 에이전트 구축 과정을 상세히 기록한다.


1. SQLite의 특징과 활용

본 프로젝트의 데이터베이스로 채택한 SQLite는 서버가 필요 없는 독립적인 관계형 데이터베이스 관리 시스템(RDBMS)이다.

  • 경량성 및 독립성: 별도의 서버 프로세스를 가동할 필요 없이, 하나의 파일(.db) 형태로 데이터베이스가 관리된다. 따라서 설치 과정이 극도로 단순하며 복사만으로도 전체 데이터를 이전할 수 있다.
  • 표준 SQL 지원: ANSI-SQL 표준을 폭넓게 지원하므로 트랜잭션 처리, 인덱싱, 뷰, 트리거 등 현대적인 DBMS가 갖추어야 할 기능을 대부분 제공한다.
  • 적합한 유즈케이스: 동시 접속자가 매우 많은 대규모 서비스보다는 모바일 애플리케이션의 로컬 저장소, 프로토타입 개발, 그리고 이번 프로젝트와 같은 데이터 분석 실습용으로 최적의 선택이다.

2. 환경 구성 및 데이터 준비

실습을 위해 샘플 데이터베이스인 Chinook.db를 다운로드한다. 이 데이터베이스는 앨범, 아티스트, 송장(Invoice) 등 음악 상점 운영에 필요한 다양한 테이블을 포함하고 있어 SQL RAG 테스트에 적합하다.

import requests
from langchain_community.utilities import SQLDatabase

# 1. 샘플 DB 다운로드
url = "https://storage.googleapis.com/benchmarks-artifacts/chinook/Chinook.db"
response = requests.get(url)

if response.status_code == 200:
    with open("Chinook.db", "wb") as file:
        file.write(response.content)
    print("Chinook.db 다운로드 완료")

# 2. LangChain SQLDatabase 연동
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
print(f"사용 가능 테이블: {db.get_usable_table_names()}")

LangChain의 SQLDatabase 클래스는 LLM이 데이터베이스와 상호작용할 수 있도록 스키마 정보를 추출하고 쿼리를 실행하는 인터페이스를 제공한다.


3. Agentic Workflow의 필요성

단순히 질문을 던져 SQL만 생성하는 방식은 한계가 명확하다. LLM이 존재하지 않는 컬럼명을 생성하거나 문법 오류를 범할 수 있기 때문이다. 이를 보완하기 위해 Agentic Workflow가 필요하다.

에이전트는 다음과 같은 '추론과 행동(Reasoning and Acting)' 과정을 반복한다.

  1. 테이블 목록 확인: 질문과 관련된 테이블이 무엇인지 파악한다.
  2. 스키마 조회: 선택한 테이블의 상세 구조(컬럼, 타입, 관계)를 확인한다.
  3. 쿼리 생성 및 실행: 정보를 바탕으로 SQL을 작성하고 실행한다.
  4. 오류 수정: 실행 결과 에러가 발생하면 에러 메시지를 바탕으로 쿼리를 수정한다.
  5. 최종 답변: 결과 데이터를 바탕으로 사용자의 언어로 답변한다.

4. LangGraph를 이용한 정교한 에이전트 설계

LangGraph를 사용하면 각 단계를 노드(Node)로 정의하고, 조건에 따라 흐름을 제어하는 엣지(Edge)를 구성하여 복잡한 로직을 구조화할 수 있다.

4-1 주요 노드 구성

  • chatbot (list_tables): 사용자의 첫 질문을 받아 데이터베이스 내에 어떤 테이블들이 있는지 탐색하는 도구를 호출한다.
  • call_get_schema: 질문과 연관성이 높은 테이블들의 스키마(CREATE TABLE 문 등)를 LLM이 학습하도록 전달한다.
  • generate_query: 스키마 정보를 바탕으로 구문 오류가 없는 SQL 쿼리를 생성한다. 이때 LLM에게 결과 제한(Limit)과 불필요한 컬럼 배제를 지시하는 시스템 프롬프트를 주입한다.
  • check_query: 생성된 쿼리를 정규표현식으로 정제(Sanitize)한 뒤 실제 DB에서 실행한다.
  • answer: DB로부터 반환된 원시 데이터(Raw data)를 자연어 답변으로 변환한다.

4-2 조건부 엣지와 자가 수정(Self-Correction) 로직

에이전트의 핵심은 실패를 인지하고 다시 시도하는 능력에 있다. should_correct 함수를 통해 실행 결과에 'Error' 문구가 포함되어 있다면 다시 generate_query 노드로 돌아가 쿼리를 재작성하도록 설계했다.

def should_correct(state):
    txt = state["messages"][-1].content
    if "Error:" in txt or "error" in txt.lower():
        # 오류 발생 시 쿼리 재생성 노드로 이동
        return "generate_query"
    else:
        # 정상 실행 시 답변 생성 노드로 이동
        return "answer"

5. 에이전트 실행 및 결과 확인

"2009년에 가장 많은 매출을 올린 영업 사원은 누구인가요?"라는 복잡한 질문을 던져 보았다. 이 질문은 Employee, Customer, Invoice 테이블 간의 조인(Join)과 연도 필터링, 그리고 집계(Aggregation)가 필요하다.

에이전트는 다음과 같은 흐름으로 작업을 수행했다.

  1. Employee, Invoice 등의 테이블 존재 여부 확인.
  2. 각 테이블의 컬럼명과 관계(FK) 파악을 위한 스키마 조회.
  3. strftime('%Y', InvoiceDate) = '2009' 조건을 포함한 SQL 생성.
  4. 쿼리 실행 후 매출액이 가장 높은 사원 이름 획득.
  5. 한국어로 최종 답변 제공.

6. 결론 및 고찰

LangGraph를 활용한 SQL RAG 구축은 단순히 모델의 성능에만 의존하는 것이 아니라, 시스템의 구조를 통해 정확도를 높이는 작업이다.

특히 쿼리 실행 중 발생하는 예외 상황을 에이전트 스스로 인지하고 수정하는 루프를 구성함으로써, 할루시네이션(Hallucination)을 대폭 줄일 수 있었다. 향후에는 쿼리 실행 전 보안 검사(DML 차단 등)를 더욱 강화하거나, 다국어 쿼리 최적화 기능을 추가하여 확장할 수 있을 것으로 판단된다.

데이터베이스라는 정형 데이터의 세계와 LLM이라는 비정형 데이터 처리 도구가 만났을 때, 진정한 데이터 민주화가 가능해짐을 이번 프로젝트를 통해 다시 한번 확인했다.

'개념 정리 step2 > AI Agent' 카테고리의 다른 글

[RAG 시스템 구축] 벡터 데이터베이스, 환경 여부 평가, 코드 설정 (2)  (0) 2026.04.01
[RAG 시스템 구축] 벡터 데이터베이스부터 앙상블 리트리버까지 (1)  (0) 2026.03.31
[LangGraph] LLM 도구 사용법 (Tool Calling & Agents) (5)  (0) 2026.03.23
[AI Agent] "Tool Calling Agent의 개념"과 "Tavily"를 활용한 웹 검색 챗봇 구현 (4)  (0) 2026.03.20
[LangGraph] 상태 업데이트 및 워크플로우 제어 (3)  (0) 2026.03.19
'개념 정리 step2/AI Agent' 카테고리의 다른 글
  • [RAG 시스템 구축] 벡터 데이터베이스, 환경 여부 평가, 코드 설정 (2)
  • [RAG 시스템 구축] 벡터 데이터베이스부터 앙상블 리트리버까지 (1)
  • [LangGraph] LLM 도구 사용법 (Tool Calling & Agents) (5)
  • [AI Agent] "Tool Calling Agent의 개념"과 "Tavily"를 활용한 웹 검색 챗봇 구현 (4)
고니3000원
고니3000원
공부 내용 정리, 자기발전 블로그 입니다. 기존 네이버 블로그에서 티스토리로 이전했습니다. https://blog.naver.com/pak1010pak
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (176)
      • 1. AI 논문 + 모델 분석 (19)
        • AI 논문 분석 (13)
        • AI 모델 분석 (6)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (25)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
      • 4. [팀] 프로젝트 및 공모전 (14)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
      • 5. [개인] 프로젝트 및 공모전 (0)
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (56)
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 네이버 곤이의 블로그(Naver->Tistory)
    • Github
  • 공지사항

  • 인기 글

  • 태그

    Attention Is All You Need
    프로젝트
    github
    transformer
    귀칼
    EfficientNet
    Grad-CAM
    자바스크립트
    Ai
    파이썬
    자료구조
    알고리즘
    Vision
    파인튜닝
    bottleneck
    pandas
    구현
    html
    paddleocr
    OCR
    논문 리뷰
    강화학습
    ViT
    공모전
    학습
    데이터분석
    강화 학습
    OCR학습
    Python
    javascript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[SQL RAG] LangChain과 LangGraph를 활용한 지능형 데이터베이스 질의 에이전트 구축(쿼리문 RAG)
상단으로

티스토리툴바