사용자가 자연어 질의를 입력한 뒤 최종 답변을 받을 때까지 각 컴포넌트가 어떤 순서로 동작하는지 정리한 글입니다. 이 글은 시리즈의 첫 글입니다. 각 구성 요소를 왜 그렇게 선택했는지, 실험 과정에서 무엇이 달라졌는지는 이어지는 글에서 다룹니다.

단일 NL2SQL의 한계와 라우팅 구조

NL2SQL을 실운영 환경에 처음 적용하면 같은 문제를 반복해서 만납니다. DDL만으로는 T_CUST_MST 같은 약어 테이블이 무슨 의미인지, “순매출"이 어떤 산식인지 LLM이 파악·추론하지 못합니다. 공개 벤치마크가 아무리 올라가도 실제 엔터프라이즈 환경에서는 정확도가 절반 이하라는 보고가 꾸준히 나옵니다. 같은 종류의 오답은 데이터셋을 바꿔도 사라지지 않습니다.

그렇다고 단일 SQL 경로만 두면 또 다른 문제가 생깁니다. 용어 정의를 묻는 질문, 비정형 문서에서 답을 찾는 질문은 처리할 수 없습니다. 그래서 DataNexus는 두 축으로 분리했습니다. LLM에 들어가기 전에 비즈니스 맥락을 명시화하는 온톨로지 주입과, 질문 유형에 따라 답을 가져오는 경로를 분리하는 라우팅 구조입니다.

일반적인 RAG 구조와의 차이점을 표로 정리하면 다음과 같습니다.

일반 RAGDataNexus
Grounding프롬프트 단계 주입온톨로지 단계 (Glossary 용어 + DDL + 관계)
RoutingLLM 단발 분기term_type 분기 + Supervisor 충돌 조정
RetrievalVector 위주Graph + SQL + Vector (+ Web, Phase 2+)
Validation사후 검토Schema Enforcer 사전 차단

전체 처리 워크플로우

flowchart TD
    Q["자연어 질문"]
    Q --> CTX["컨텍스트 조립<br/>Glossary·DDL·HoT 규칙 주입"]
    CTX --> R{"Router Agent<br/>term_type 분류"}
    R -->|"metric"| N["NL2SQL 엔진<br/>NL → SQL"]
    R -->|"concept · relation"| G["Graph DBA<br/>Cypher 템플릿 + LLM Fallback"]
    R -->|"비정형 문서"| V["GraphRAG 엔진<br/>문서 + Knowledge Graph"]
    R -.->|"외부 정보 (Phase 2+)"| W["Web Agent"]
    N --> SE["Schema Enforcer<br/>스키마 검증 · RLS 강제"]
    G --> SE
    SE --> EXEC["DB 실행"]
    V --> SUP
    W -.-> SUP
    EXEC --> SUP["Supervisor<br/>HoT 우선순위로 충돌 조정"]
    SUP --> ANS["결과 반환"]
    ANS -.피드백.-> FEED["NL2SQL 자가 학습 루프"]

기존 다이어그램과 다른 부분이 네 군데입니다. 라우터 앞단에 컨텍스트 조립 단계를 명시했고 실행 전 Schema Enforcer를 거치게 했습니다. 여러 소스 결과가 충돌하면 Supervisor가 Hierarchy of Truth(HoT) 우선순위로 정리합니다. Web Agent는 Phase 2+에서 추가하는 외부 정보 경로라 점선으로 따로 뒀습니다.

4개 레이어로 본 컴포넌트

Knowledge Layer (지식 정의)

컴포넌트역할선택 근거
비즈니스 용어 카탈로그비즈니스 용어와 4개 관계 유형(IsA / HasA / Values / RelatedTo) 정의SKOS 표준 호환으로 외부 온톨로지 Import/Export 확보
그래프 DB용어 간 관계 그래프 저장Neo4j 호환 + Multi-DB 격리. GPL-3.0 라이선스 리스크 때문에 Apache AGE로 전환 예정
CQ ValidatorCompetency Question 기반 온톨로지 품질 검증FCQ/RCQ/VCQ/MpCQ 18문항 매트릭스로 동기화 전 환각 위험 사전 검증

Routing Layer (질의 분류와 동기화)

컴포넌트역할비고
Router Agentterm_type을 보고 NL2SQL / Graph DBA / GraphRAG / Web 중 어디로 보낼지 결정metric → SQL / concept → Graph / 비정형 → Vector / 외부 → Web(Phase 2+)
Sync HubGlossary 변경을 NL2SQL 학습 데이터 / RAG Store / 그래프에 자동 반영동기화 실패 시 staleness 감지 후 담당자 검수 큐로 이관

Execution Layer (실행)

컴포넌트역할선택 근거
NL2SQL 엔진자연어 → SQL 변환, 자가 학습 루프User-Aware 설계, Row-level Security 지원
Graph DBA계층/추이적 폐쇄/집계 같은 그래프 질의DETERMINISTIC 질의는 Cypher 템플릿으로 처리해 LLM 호출 비용 없음, 템플릿 매칭 실패 시 LLM Fallback
GraphRAG 엔진비정형 문서 검색 (벡터 + 지식 그래프)MinerU 기반 문서 파싱, 하이브리드 검색
Web Agent (Phase 2+)외부 산업·규제 정보 보강사내 데이터로 해결되지 않을 때만 활성화

Verification Layer (검증과 충돌 조정)

컴포넌트역할비고
Schema EnforcerSQL/Cypher 실행 전 스키마 정합성 검증, 미등록 용어 차단RLS 필터 강제 주입
Supervisor (HoT)여러 소스 결과 충돌 시 우선순위 적용Ontology > Structured > Vector > Web 4단계

Dashboard Promotion: Pull 구조를 Push로 전환

여기까지가 자연어 질의 한 건의 처리 워크플로우입니다. 그런데 같은 질문을 매주 반복하는 KPI라면 매번 Chat에서 묻는 게 비효율적입니다. 그래서 Dashboard Promotion 경로를 따로 둡니다.

flowchart LR
    CHAT["Chat 탐색<br/>Pull"] -.동일 질의 3회 이상.-> DETECT["반복 패턴 감지"]
    DETECT --> PROMO["Dashboard Promotion<br/>SQL 파라미터화 + JWT RLS 토큰"]
    PROMO --> DASH["정기 KPI 대시보드<br/>Push"]
    GLOSS["Glossary 변경"] -.Lineage Drift 감지.-> DASH

탐색 단계에서 자주 반복되는 질의는 자동으로 정적 대시보드로 승격합니다. 승격된 SQL과 Glossary 사이에는 Lineage가 걸려 있어서 용어 정의가 바뀌면 대시보드가 STALE 상태로 표시되고 자동 재동기화 큐로 들어갑니다. 운영자가 일일이 확인하지 않아도 용어 정의 변경이 운영 보고에 자동으로 반영됩니다.

정리하면, DataNexus는 두 축으로 움직입니다. NL2SQL 정확도 향상과 반복 질의의 Push 승격입니다.

핵심 설계 원칙

컨텍스트는 Static First, Dynamic Last 구조로 고정합니다. 온톨로지와 DDL, HoT 규칙은 시스템 프롬프트의 고정된 prefix 블록에 두고 사용자 질문만 동적으로 붙입니다. Anthropic의 prefix caching이 이 구조에서 캐시 적중률을 높입니다.

사후 보정보다 사전 검증 이 비용이 덜 듭니다. SQL이 LLM에서 나온 직후 Schema Enforcer가 한 번 거릅니다. 잘못된 쿼리를 DB에서 실행한 뒤 빈 결과를 받는 것보다, 실행 전에 막고 다시 시도하는 게 운영 부담이 적습니다.

충돌은 LLM에 묻지 않고 우선순위 표 로 처리합니다. 같은 “이탈률"인데 마케팅 12%, CRM 8%로 나오는 일은 흔합니다. 산식이 다를 뿐 둘 다 오답은 아닙니다. 매번 모델에게 “둘 중 뭐가 맞아?“를 묻기 시작하면 답이 일관되지 않습니다. HoT 우선순위를 먼저 정하고 그 기준을 적용합니다.