직접 만든 Text-to-SQL을 Genie로 바꾼 이유
처음 만든 챗봇은 질문과 관련된 스키마와 SQL 예시를 검색한 뒤 모델이 SQL을 생성하는 구조였습니다. 문서 질문은 RAG로 따로 처리했습니다.
직접 구현한 만큼 바꿀 수 있는 부분은 많았지만, 지표나 컬럼이 늘어날 때마다 스키마와 예시, 프롬프트도 손봐야 했습니다. 사용자가 새로운 질문을 하려면 엔지니어가 먼저 예시 SQL을 추가하는 일이 반복됐습니다.
5월에는 이 중 SQL 생성 경로를 Databricks Genie로 바꿨습니다. 챗봇 전체를 다시 만드는 대신 운영 부담이 컸던 부분을 교체한 작업입니다.
SQL 생성 부분을 Genie로 교체
질문 분류와 화면, 문서 검색, 다른 조회 경로는 유지했습니다. 데이터 질문일 때 기존 BI 프록시를 통해 Genie Space를 호출하도록 바꿨습니다.
프록시를 사용한 이유는 인증과 세션, 응답 형식을 클라이언트마다 다시 만들지 않기 위해서입니다. 대신 SQL 질문 경로도 프록시의 가용성에 의존하게 됩니다. 연결을 공통화하면서 어느 서비스의 장애에 영향을 받는지도 함께 봐야 했습니다.
Genie 전환 후 관리할 것
Genie로 바꿔도 도메인 설명과 예시가 필요 없는 것은 아닙니다. Space에 분석 대상 테이블과 설명, 업무 용어, 예시 SQL을 정리했습니다. 어떤 테이블을 우선할지와 분석 대상으로 삼지 않을 데이터도 설명했습니다.
| 직접 관리하던 부분 | 전환 후 관리 대상 |
|---|---|
| 스키마·예시 검색 인덱스 | Space의 테이블과 설명 |
| SQL 생성 프롬프트 | 질문 예시와 업무 용어 |
| 실행 연결과 세션 | 프록시 연결과 권한 전달 |
| 결과 확인 | 업무 질문의 SQL과 수치 비교 |
예시와 지시문은 답변을 유도하는 자료입니다. 데이터 접근을 막는 권한 설정을 대신하지는 않습니다. 프록시가 어떤 사용자 권한으로 요청하는지와 실제로 조회할 수 있는 범위는 별도로 확인해야 합니다.
프록시와 화면 사이의 응답 처리
SQL 질문은 자연어 문장을 조금씩 출력하는 경로와 동작이 다릅니다. 질문 접수, SQL 생성·실행 대기, 결과 수신, 실패를 구분하면 화면이 무엇을 기다리는지 표현하기 쉽습니다. 아래는 UI와 프록시 사이에서 사용할 수 있는 상태 예시입니다. Databricks API의 원본 상태명을 그대로 정의한 것은 아닙니다.
type DataAnswerState =
| { state: 'pending'; requestId: string }
| { state: 'ready'; columns: string[]; rows: unknown[][]; sql: string }
| { state: 'failed'; message: string };프록시는 제공자 응답을 해석하고 화면은 준비된 결과나 오류를 표시합니다. 기다리는 동안 같은 질문을 계속 새로 보내면 별도 대화나 실행이 늘어날 수 있어 기존 요청의 진행 상태와 새 요청을 구분해야 합니다. 후속 질문은 앞선 대화의 문맥을 유지할지도 정해야 합니다.
연결 시 필요한 인증과 대화·결과 API는 공식 API 문서 를 함께 확인합니다. 본문의 Space라는 표현은 당시 작업 기록의 용어를 유지했습니다. 공식 문서의 명칭과 제공 기능은 이후 변경될 수 있으므로 이 글은 현재 Genie의 전체 기능보다 당시 SQL 생성 방식을 바꾼 과정에 초점을 맞췄습니다.
업무 질문을 검증 항목으로 바꾸기
“최근 사용자 활동을 보여줘”처럼 넓은 질문에는 기간과 시간대, 중복 기준이 숨어 있습니다. 예시 SQL을 추가하기 전에 이 질문이 어떤 집계를 뜻하는지 정해야 했습니다.
다음은 가상의 감사 이벤트 테이블에서 월별 사용자를 세는 검증용 SQL입니다. 실제 업무 테이블이나 결과 수치는 아닙니다.
SELECT COUNT(DISTINCT user_id) AS active_users
FROM sample_audit_events
WHERE event_time >= '2026-09-01T00:00:00+09:00'
AND event_time < '2026-10-01T00:00:00+09:00'
AND event_name = 'login';같은 질문에 대해 테이블, 이벤트 필터, 조회 종료 시각, 사용자 식별자, 중복 기준이 맞는지 봅니다. 결과 숫자만 우연히 같아도 다른 필터를 사용했다면 다음 달에 달라질 수 있습니다. 한국어와 영어 질문도 같은 기준으로 해석하는지 비교합니다.
| 질문에서 정할 것 | 잘못 해석하면 생기는 차이 |
|---|---|
| 지난달 | 최근 30일과 달력 월의 차이 |
| 사용자 수 | 이벤트 건수와 고유 사용자 수의 차이 |
| 활동 | 어떤 이벤트를 포함하는지 |
| 조직별 비교 | 당시 조직과 현재 조직 조인의 차이 |
Genie로 옮기면서 줄인 것은 SQL 검색·생성 경로를 직접 유지하는 부분입니다. 업무 정의까지 자동으로 정해지는 것은 아니므로 이런 질문과 기준 쿼리를 Space 설명과 검증 자료로 남겼습니다.
질문별 결과 확인
자주 묻는 질문을 한국어와 영어로 정리하고 기준 쿼리와 비교했습니다. 생성된 SQL의 테이블과 조인, 결과 수치를 함께 봤습니다. 미리 계산된 지표가 없는 질문은 필요한 조인 예시를 보완했습니다.
Trusted 표시도 결과 검증을 생략할 근거로 사용하지 않았습니다. 등록한 쿼리나 함수에 기반한 답변이라는 점과 원본 데이터나 결과 수치가 올바른지는 다른 확인 항목입니다.
화면의 응답 처리도 맞춰야 했습니다. 기존 토큰 스트리밍과 새 SQL 응답을 같은 방식으로 다룰 수 없어 기다리는 동안의 표시와 결과 전달을 조정했습니다.
전환 후에도 질문 예시와 데이터 설명, 권한, 결과 확인은 남았습니다. 다만 SQL 생성을 위한 검색과 프롬프트를 직접 유지하는 부분을 줄이고, 기존 챗봇의 다른 기능은 계속 사용할 수 있었습니다.