SAP를 위한 Text-to-SQL 에이전트를 구축했습니다. 왜 모든 것을 처음부터 다시 생각해야 했는지에 대하여
요약
SAP의 복잡한 데이터 구조를 정확히 쿼리하기 위해 시맨틱 레이어를 활용한 Text-to-SQL 에이전트 구축 사례를 소개합니다. LLM이 스키마를 임의로 생성하지 않고, 정의된 시맨틱 레이어에 매핑하는 '컴파일러' 역할을 수행하도록 설계하여 환각 현상을 방지합니다.
핵심 포인트
- LLM을 스키마 발명가가 아닌 시맨틱 레이어 매핑용 컴파일러로 활용
- YAML 기반의 시맨틱 레이어를 통해 단일 진실 공급원(SSOT) 확보
- 메달리온 모델(Bronze/Silver/Gold)을 적용한 데이터 구조화
- 추측 대신 명확한 매핑을 통해 SQL 생성의 재현성과 결정론적 결과 보장
관리되는 (governed) SQL, 메달리온 (medallion) 시맨틱 레이어 (semantic layer), 그리고 세 가지 쿼리 엔진이 어떻게 환각된 컬럼 이름 없이 기업 데이터를 실제로 쿼리 가능하게 만드는지에 대하여.
대부분의 Text-to-SQL 데모는 실제 기업 데이터에 적용해 보기 전까지는 훌륭해 보입니다. "지난 분기 매출 기준 상위 10개 자재는 무엇이었나요?"라고 물으면, 모델은 자신 있게 ORDERS와 PRODUCTS를 조인(join)하는 쿼리를 반환합니다. 하지만 이 테이블들은 귀하의 SAP 시스템에 존재하지 않는 테이블입니다. 또는 실제 컬럼이 VBAK.NETWR 안에 숨겨져 있음에도 불구하고 revenue라는 이름의 컬럼을 만들어내기도 합니다. VBAK.NETWR은 SAP 컨설턴트로 수년간 근무해야만 그 의미를 알 수 있는 필드입니다.
이것이 바로 우리가 Onibex ASK — Agentic Semantic Knowledge(에이전트 기반 시맨틱 지식)를 통해 해결하고자 했던 문제입니다. 이는 자연어를 SAP 데이터에 대한 관리되는 (governed) SQL로 변환하는 오픈 플랫폼입니다. 이 문장에서 "관리되는 (governed)"라는 단어는 매우 중요한 역할을 하며, 그것이 정확히 무엇을 의미하는지, 그리고 왜 모든 것을 바꾸는지 파헤쳐 볼 가치가 있습니다.
LLM은 발명가가 아니라 컴파일러 (Compiler)가 되어야 합니다
대부분의 Text-to-SQL 시스템은 LLM에 데이터베이스 스키마 (schema)를 제공하고 "알아서 파악하라"고 요청합니다. 이는 이름이 명확한 몇 개의 테이블로 구성된 단순한 스키마의 경우 놀라울 정도로 잘 작동합니다. 하지만 SAP HANA 스키마는 단순하지 않습니다. 실제 S/4HANA 시스템에는 수천 개의 테이블, 암호 같은 4자리 필드 이름, 그리고 가독성이 아닌 성능을 위해 설계된 조인 (join) 조건이 있을 수 있습니다.
우리의 접근 방식은 다릅니다. LLM은 구조를 절대 발명하지 않습니다. LLM은 오직 비즈니스 용어를 큐레이션된 시맨틱 레이어 (semantic layer)에 매핑 (mapping)할 뿐입니다.
우리가 데이터 프로덕트 (Data Products)라고 부르는 YAML 파일 세트인 시맨틱 레이어 (semantic layer)는 단일 진실 공급원 (single source of truth)입니다. 모든 쿼리의 모든 필드는 이를 연결하는 정확한 조인 술어 (join predicate)와 함께 실제 테이블의 실제 컬럼으로 역추적되어야 합니다. LLM은 컴파일러 (compiler)입니다. 자연어 질문을 받아 레이어에서 일치하는 비즈니스 용어를 찾아보고, 해당 해결된 매핑 (mapping)만을 사용하여 SQL을 생성합니다. 만약 용어가 레이어에 없다면, 에이전트는 추측하는 대신 명확한 설명을 요청합니다.
사용자가 “자재별 매출이 어떻게 되나요?”라고 질문하면, ASK는 synonyms (동의어) 필드를 통해 “revenue” (매출)를 VBAK.NETWR에 매핑합니다. 또한 Data Product (데이터 제품)가 정의한 내용을 바탕으로 VBAK에서 VBAP로의 조인 (join) 관계를 알고 있습니다. 에이전트는 그 외의 다른 테이블은 전혀 건드리지 않습니다. 생성된 SQL은 재현 가능하고, 감사 가능하며, 결정론적 (deterministic)입니다. 이는 LLM (대규모 언어 모델)이 유난히 똑똑해서가 아니라, 엄격한 가드레일 (guardrails) 안에서 작동하기 때문입니다.
SAP에 적용된 메달리온 모델 (Medallion Model)
다른 모든 요소가 제대로 작동하게 만든 구조적 결정 중 하나는 시맨틱 레이어 (semantic layer)에 Bronze / Silver / Gold 메달리온 모델 (medallion model)을 채택한 것입니다.
Bronze는 가공되지 않은 SAP 테이블입니다. 컬럼 (column)과 기본 키 (primary key)만 존재하며, 조인 로직 (join logic)은 없습니다. VBAK (판매 오더 헤더), VBAP (판매 오더 아이템), MARA (자재 마스터) 등이 이에 해당합니다. 이러한 테이블들은 ASK가 물리적 스키마 (physical schema)를 이해할 수 있도록 존재합니다.
Silver는 비즈니스 로직 (business logic)이 살아있는 단계입니다. Silver 엔티티 (entity)는 여러 Bronze 테이블을 하나의 일관된 비즈니스 개념으로 조인하며, 해당 개념에 대한 완전한 조인 토폴로지 (join topology)를 소유하고, 필드 역할(측정값 (measure), 차원 (dimension), 식별자 (identifier), 타임스탬프 (timestamp))을 정의합니다. Silver 레이어는 에이전트의 폴백 (fallback) 역할을 합니다. 만약 Gold 엔티티가 질문을 커버하지 못할 경우, ASK는 Silver를 통해 문제를 해결하고 조인을 계산합니다.
Gold는 비정규화된 분석 (denormalized analytics) 데이터입니다. 에이전트가 단 한 번의 스캔으로 쿼리할 수 있도록 미리 조인되고 미리 집계된 엔티티입니다. 질문에 필요한 정확한 지표 (metrics)와 차원 (dimensions)을 Gold 엔티티가 모두 포함하고 있다면, ASK는 Gold만 사용하여 답변합니다. 조인이 필요 없고, 플래닝 오버헤드 (planning overhead)가 없으며, 지연 시간 (latency)이 최소화됩니다.
질문: “1분기 순가치 기준 상위 10개 자재” │ ▼ Gold 엔티티가 이를 커버하는가?
├─ 예 → Gold 테이블에 대해 단일 쿼리 수행
└─ 아니오 → Silver 엔티티를 통해 해결 (VBAK + VBAP 조인)
이러한 Gold 우선 해결 방식 덕분에 대규모 환경에서도 쿼리 지연 시간을 합리적인 수준으로 유지할 수 있습니다. 잘 모델링된 Gold 엔티티는 비즈니스 사용자들이 실제로 던지는 질문의 80%를 커버합니다. Silver는 나머지 롱테일 (long tail) 질문들을 처리합니다.
서로 다른 트레이드오프 (Tradeoffs)를 위한 세 가지 엔진
우리가 가장 오랫동안 씨름했던 질문 중 하나는 다음과 같았습니다: 에이전트가 쿼리당 어느 정도의 계획 (planning)을 세워야 하는가? 더 많은 계획은 더 나은 SQL을 의미하지만, 이는 더 많은 LLM 호출, 더 높은 지연 시간 (latency), 그리고 더 많은 비용을 의미하기도 합니다. 우리는 결국 사용자와 관리자가 이러한 트레이드오프 (tradeoff)를 명시적으로 선택할 수 있도록 세 가지 엔진을 출시했습니다.
Flash
1 LLM 호출 · ~15초 · 낮은 비용
스키마를 자유 텍스트 청크 (free-text chunks)로 검색하고 단 한 번의 시도 (single shot)로 SQL을 작성합니다. 의미론적 계획 (semantic plan), 조인 검증 (join verification), 범위 확인 (scope check)이 없습니다. 빠르고 저렴하며, 탐색적 질문 (exploratory questions)에 적합합니다. 재현성이 가장 낮습니다: 동일한 질문을 두 번 물었을 때 약간 다른 SQL이 생성될 수 있습니다.
Precise
3 LLM 호출 · ~60초 · 높은 신뢰도
의미론적 계획 IR (Semantic Plan IR)을 추출하고, Medallion 재순위화 (re-ranking)를 포함한 하이브리드 kNN+BM25 검색을 실행하며, Dijkstra 알고리즘으로 조인을 계획하고, SQL을 생성한 다음, 허용된 테이블 세트와 대조하여 감사 (audit)합니다. 범위를 벗어날 경우 한 번 재시도합니다. 완전히 결정론적인 (deterministic) 데이터 제품 (Data Product) 선택을 보장합니다. 컴플라이언스 (compliance), 감사 추적 (audit trails), 또는 Flash가 실패할 때 사용하십시오.
Smart
2 LLM 호출 · ~40초 · 기본값
LLM에 압축된 카탈로그를 보여주고 관련 데이터 제품을 선택하게 합니다. 즉, 선택은 모델 주도적 (model-driven)입니다. 하지만 선택 후의 조인 계획 (join planning)은 Precise와 동일한 Dijkstra 그래프를 사용합니다. 일상적인 운영 환경에서의 사용을 위해 속도와 정확도의 균형을 맞췄습니다.
이 설계의 핵심 통찰은 결정론성 (determinism)을 어디에 배치하느냐가 중요하다는 점입니다. Precise는 데이터 제품의 선택을 결정론적으로 만듭니다. Smart는 조인 계획을 결정론적으로 만듭니다. Flash는 이 두 가지 모두를 모델에 맡깁니다. 감사 가능성 (auditability)이 필요한 사용자는 Precise를, 처리량 (throughput)이 필요한 사용자는 Smart를, 속도가 필요한 사용자는 Flash를 사용합니다.
질문이 모호할 때는 어떤 일이 발생하나요?
실제 기업 데이터에는 어휘 문제 (vocabulary problems)가 존재합니다. "Sales"는 SD 모듈에서는 VBAK를 의미할 수 있지만, 조달 관점의 MM 모듈에서는 EKKO를 의미할 수 있습니다. "Revenue"는 사용자가 재무(Finance) 부서에 있는지 영업(Sales) 부서에 있는지에 따라 총매출 (gross) 또는 순매출 (net)을 의미할 수 있습니다.
ASK는 OpenSearch의 의미론적 사전 인덱스 (semantic dictionary index)를 기반으로 한 3단계 모호성 해소 (disambiguation) 시스템을 통해 이를 처리합니다.
Level 1: 용어가 정확히 하나의 엔티티 (entity)에 매핑되는 경우, 에이전트가 자동으로 해결합니다. 중단 없이 진행됩니다.
Level 2: 용어가 서로 다른 SAP 모듈에 걸쳐 여러 엔티티에 매핑되는 경우, 에이전트는 “SD 판매 주문(sales order)을 의미하나요, 아니면 MM 구매 주문(purchasing order)을 의미하나요?”와 같은 모호성 해소 (disambiguation) 메시지를 표시하고 대기합니다. 추측하지 않습니다.
Level 3: 용어에 매핑이 전혀 없는 경우, 에이전트는 사용자를 Agentic Trainer로 안내하는 명확한 메시지를 반환합니다. 해결책을 환각 (hallucinate) 하지 않습니다.
시맨틱 사전 (semantic dictionary)은 관리자가 ASK Configuration App을 통해 관리합니다. 이 앱은 React SPA (Single Page Application)로, 모듈별로 표준 필드 레이블 (canonical field labels), SAP 컬럼 매핑 (column mappings), 유의어 (synonyms), 문맥 힌트 (context clues), 모호성 해소 힌트 (disambiguation hints)를 등록할 수 있으며, 이 모든 정보는 하이브리드 검색 (hybrid retrieval)을 위해 OpenSearch에 인덱싱됩니다.
Artifacts (아티팩트)
아티팩트 (artifact)는 자연어로부터 완전히 생성된 완성된 비즈니스 문서 — 판매 보고서, 경영 요약서 (executive brief), 데이터 테이블 팩 등 — 를 의미합니다. 사용자는 이름, 대상 및 목적, 포함할 데이터, 형식을 다루는 4단계 대화형 마법사 (conversational wizard)를 통해 필요한 내용을 설명합니다. 에이전트는 여러 개의 SQL 쿼리를 계획 및 실행하고, 결과로부터 구조화된 서사 (narrative)를 작성하며, 데이터 테이블이 포함된 서식화된 문서를 반환합니다.
출력물은 Excel 파일로 다운로드할 수 있습니다. 이 파일은 서사가 담긴 Report 시트, 각 쿼리 결과당 하나의 Data 시트, 그리고 SQL 시트로 구성된 워크북이며, 서버 측 Excel 의존성 없이 브라우저 내에서 완전히 조립됩니다.
이것이 “단순히 보고서를 생성하는 것”과 다른 점은, 문서 내의 데이터가 다른 모든 쿼리와 동일한 시맨틱 레이어 (semantic layer)의 통제를 받는다는 것입니다. 경영 요약서의 품목별 매출 (revenue-by-material) 테이블은 채팅 답변에서 사용된 것과 동일한 VBAK.NETWR 컬럼을 사용합니다. 동기화를 유지하기 위한 별도의 리포팅 레이어 (reporting layer)가 필요 없습니다.
What We Learned (우리가 배운 점)
01. 스키마 품질이 곧 제품이다
ASK는 데이터를 설명하는 데이터 제품 (Data Products)만큼만 성능을 발휘합니다. 추가하는 모든 유의어, 사전에 포함된 모든 모호성 해소 힌트, 조인 조건 (join condition)에 대한 모든 비즈니스 언어 설명 — 이 모든 것이 답변의 품질을 직접적으로 향상시킵니다. 엔지니어링은 인프라일 뿐이며, 시맨틱 레이어 (semantic layer)가 곧 제품입니다.
02. 결정론 (Determinism)은 제약이 아니라 기능입니다
우리는 조인 계획 (join planning)을 결정론적으로 만들기로 했습니다. 즉, LLM이 조인을 선택하게 하는 대신 그래프 상에서 다익스트라 (Dijkstra) 알고리즘을 사용했습니다. 이는 우리 사용자들이 감사인 (auditors)에게 답변을 설명해야 했기 때문입니다. "모델이 선택했습니다"라는 답변보다는 "에이전트가 관계 그래프에서 이 두 엔티티 사이의 최단 경로이기 때문에 이 조인을 선택했습니다"라는 답변이 훨씬 더 방어하기 쉽습니다.
03. 세 개의 엔진은 과잉 엔지니어링이 아닙니다
Flash와 Precise는 진정으로 다른 사용 사례 (use cases)를 지원하며, 단일 엔진으로는 두 가지를 모두 잘 처리할 수 없습니다. Smart는 80%의 사례를 처리하는 기본값으로 등장했습니다. 명시적인 모드를 갖추는 것은 사용자에게 디버깅 도구도 제공합니다. 만약 Smart가 실패하면 Precise를 시도하고, Precise가 너무 느리면 Flash를 시도하면 됩니다. 모드 선택기는 설정 옵션인 동시에 진단적 어포던스 (diagnostic affordance) 역할을 합니다.
04. 거버넌스 (Governance)에는 격식이 필요합니다
설계 당시에는 개발(dev)에서 운영(prod)으로의 승격 (promotion) 흐름이 오버헤드처럼 느껴졌습니다. 하지만 실제로 사용자들은 이것이 가장 가치 있는 기능 중 하나라고 말해주었습니다. 잘못된 필드 설명은 개발 쿼리를 망가뜨릴 수 있지만, 월요일 아침에 CEO가 조회하는 운영 데이터를 조용히 망가뜨릴 수는 없기 때문입니다.
Agentic Semantic Knowledge를 시도해 보세요
시맨틱 레이어 명세, 플랫폼 코드, 그리고 전체 매뉴얼은 GitHub에 공개되어 있습니다. SAP 데이터, 또는 복잡한 스키마를 가진 기업용 데이터를 다루고 있다면, 이 플랫폼을 사용하든 그렇지 않든 Bronze/Silver/Gold 모델과 거버넌스가 적용된 SQL 접근 방식을 이해할 가치가 있습니다. GitHub에서 확인하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기