데이터 에이전트에 DB 조회를 맡기기 전 챙겨야 할 4가지 안전장치
TuBrief 편집팀
2026년 7월 23일
0
컴퓨터/소프트웨어원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
B2B SaaS 기업에서 연차가 쌓일수록 Ad-hoc SQL 요청 처리에 치입니다. 현업 부서의 단순 데이터 추출 요청 때문에 본업인 인프라 고도화나 데이터 모델링은 계속 후순위로 밀리곤 합니다. Text-to-SQL 에이전트를 도입하면 해결될 것처럼 보이지만, 생성형 AI를 프로덕션 DB에 직접 붙이는 건 또 다른 재앙의 시작입니다. 보안 사고나 환각으로 인한 서비스 장애 위험을 감수하면서까지 그냥 넘겨줄 수는 없으니까요.
결국 핵심은 소프트웨어 프롬프트 몇 줄에 의존하는 게 아니라, DB와 미들웨어 단에서 물리적으로 위험을 차단하는 구조를 만드는 데 있습니다.
에이전트에게 DB 읽기 권한을 통째로 넘기면 프롬프트 주입 공격이나 환각으로 인한 DML 실행 위험에 노출됩니다. 읽기 전용 계정 설정부터 제대로 건드려야 합니다.
psycopg3 드라이버를 쓴다면 연결 설정에서 conn.set_read_only(True)를 명시하고, 세션 레벨에서 default_transaction_read_only를 활성화하세요. 데이터베이스 엔진 차원에서 모든 쓰기 시도를 거부하게 만드는 게 가장 확실합니다.
민감 정보(PII) 유출을 막으려면 데이터베이스 내 접근 스키마를 분리해야 합니다.
postgresql_anonymizer 확장 모듈을 설치합니다.SECURITY LABEL FOR anon ON ROLE agent_readonly IS 'MASKED'; 명령으로 에이전트 계정에 마스킹 라벨을 지정합니다.analytics_views)를 만들고, 원천 테이블의 이메일이나 전화번호에 anon.random_phone() 같은 마스킹 함수를 적용한 뷰(View)만 노출합니다.statement_timeout은 10000(10초), idle_in_transaction_session_timeout은 30000(30초), lock_timeout은 5000(5초)으로 잡는 것을 권장합니다.이렇게 격리 환경을 짜두면 보안 사고 위험을 차단하면서 Ad-hoc SQL 요청 처리에 들어가던 엔지니어링 시간을 매주 15시간 이상 줄일 수 있습니다.
아무리 SELECT 쿼리만 실행한다고 해도, AI가 작성한 쿼리가 Full Scan을 일으키거나 카테시안 곱(Cartesian Product)을 만들어내면 DB 전체가 기절합니다. DB에 쿼리가 전달되기 전 파이썬 미들웨어 단에서 구문 분석과 비용 평가를 먼저 거쳐야 합니다.
sqlglot 라이브러리의 sqlglot.parse_one() 함수로 LLM이 생성한 쿼리를 AST(추상 구문 트리) 구조로 바꿉니다. 기본 구문 오류부터 걸러내는 단계입니다.walk()를 실행해 exp.Delete, exp.Drop, exp.Update, exp.Create 같은 금지 노드가 포함되어 있는지 체크합니다. 감지되는 즉시 실행을 차단합니다.psycopg3 드라이버로 EXPLAIN (FORMAT JSON)을 먼저 돌립니다. 반환된 Total Cost가 임계치(예: 10000.0)를 넘어가거나, 10만 건 이상 테이블에 대한 Seq Scan이 보이면 실행을 거부하도록 설정합니다.이런 안전장치를 구문 분석과 비용 평가 순서로 배치하면 잘못된 쿼리로 인한 인프라 장애나 지표 오류를 사전에 차단할 수 있습니다.
dbt 마이그레이션이나 신규 컬럼 추가로 스키마가 바겼는데 LLM 프롬프트에 구버전 정보가 남아있으면 에이전트는 존재하지 않는 컬럼을 찾으며 UndefinedColumn 에러를 뿜어냅니다. dbt가 컴파일될 때 생기는 target/manifest.json을 단일 진실 공급원(Single Source of Truth)으로 활용하세요.
manifest.json 파일의 nodes 항목 중 resource_type이 model인 객체만 뽑아내는 파이썬 스크립트를 작성합니다.prompts/context/schema_context.md)로 추출합니다.main 브랜치에 models/ 디렉토리 변경 사항이 깃 푸시될 때 dbt compile과 파이썬 스크립트가 자동 실행되도록 만듭니다. 생성된 Markdown 파일은 stefanzweifel/git-auto-commit-action을 이용해 프롬프트 저장소로 자동 커밋되게 구성합니다.스키마가 바뀔 때마다 사람이 일일이 프롬프트를 수정할 필요가 없고, 쿼리 컴파일 실패로 인한 에이전트 먹통 현상도 원천 봉쇄할 수 있습니다.
SQL이 에러 없이 완주했다고 해서 비즈니스 로직까지 맞는 건 아닙니다. pandas 기반의 데이터 품질 검증과 PostgreSQL의 SQLSTATE 에러 메세지를 결합한 재시도 루프가 필요합니다.
pandas.DataFrame으로 받은 뒤 df.empty 여부를 체크합니다. 주요 PK/FK 컬럼의 Null 비율이 50%를 넘어서면 잘못된 LEFT JOIN이 일어난 것으로 판단하고 차단합니다.df[col] - mean) / std)를 계산해 4.0을 초과하는 기형적 이상치가 잡히면 DataQualityValidationError를 던집니다.psycopg.Error가 터지면 즉시 db_connection.rollback()을 실행합니다. 이후 발생한 PostgreSQL 오류 코드(예: SQLSTATE[42703])와 검증 실패 사유를 Reflection Prompt로 묶어 LLM에 다시 던져줍니다.다만 무한 루프로 인한 토큰 낭비를 막으려면 최대 재시도 횟수(MAX_RETRIES = 3)를 반드시 코드 상에 명시해야 합니다. 오류 메시지를 프롬프트에 재주입해 자율 수정하게 만들면 단순 1회차 실행 대비 쿼리 정확도가 확연히 올라갑니다.