콘텐츠로 이동

시맨틱 레이어의 개념과 용도

11/10(화)

한 줄 요약: 시맨틱 레이어는 원본 표 위에 "이 열은 무슨 뜻이고, 이 지표는 이렇게 센다"를 한 곳에 정의해 둔 층이다. 요즘은 특히 LLM이 SQL을 직접 쓰지 않고 정의된 것 중에서 고르게 해서 틀린 답을 막는 데 쓴다.

📍 만난 상황

  • 2026-11-10 — 남은 할 일을 정리하던 중이었다. 직전에 할 일 목록 표를 받았는데, 그중 use_llm 범주 정규화가 있었다(17:20). "이건 무슨 작업이고, 왜 시맨틱 레이어 이야기가 나오나?"라고 물었다. hub-dev에 시맨틱 레이어 기능이 있고 범주 정규화가 그 준비라는 설명을 들었다. 그러자 "하지만 이 대시보드는 에이전트를 안 쓰는데?"라고 되물었다. 결론은 시맨틱 레이어 자체는 이 대시보드에 꼭 필요하지 않다였다. → 그날 일지

🧩 쉽게 말하면

식당의 메뉴판과 같다. 손님이 주방 창고에 들어가 재료를 마음대로 섞으면, 맛이 이상해도 손님은 모른다. 메뉴판은 "김치찌개 = 이 재료, 이 양, 이 방법"을 미리 정해 두고, 손님은 고르기만 한다. "얼큰한 거요"라고 하면 직원이 김치찌개로 알아듣는다. 메뉴판이 없으면 같은 "김치찌개"를 사람마다 다르게 끓이고, 누가 틀렸는지도 알기 어렵다.

📖 제대로 알기

정의

  • 시맨틱 레이어(semantic layer: 의미 계층)는 물리적인 표·열과, 사람이 쓰는 업무 용어 사이에 놓인 정의 모음이다.
  • "매출", "공사 건수", "공사 종류" 같은 말을 어느 표의 어느 열로, 어떻게 계산하는지 한 번만 정해 둔다.
  • 원래는 BI 도구(Business Intelligence: 대시보드·보고서 도구) 쪽에서 나온 개념이다. Looker의 LookML, dbt Semantic Layer, Cube 같은 제품이 있다.

구성 요소

요소 뜻 예
차원(dimension) 거르거나 묶는 기준 열 구, 월, 공사 종류
지표(metric) 세거나 더하는 계산식 공사 건수 = count()
필터 이름 붙인 조건 "누수 공사" = 종류가 상수도
조인 표끼리 잇는 규칙 공사 표 ↔ 지역 코드 표
값 사전 정식값 + 라벨 + 동의어 WATER = 상수도 = "수도관"

hub-dev의 시맨틱 레이어

  • 그날 hub-dev 매니저 API에서 확인한 구성은 이렇다.
  • 시맨틱 테이블(/semantic/tables): 열(라벨, 동의어, 거르기·묶기 가능 여부), 지표, 이름 붙인 필터, 조인.
  • 사전(/semantic/dictionaries): 열 값의 정식값·라벨·동의어.
  • 온톨로지(ontology: 개체 사이 관계 정의)와 템플릿(검증된 질의 틀).
  • 설계 결정 기록(ADR)에 목적이 적혀 있다.
  • ADR-0119 (Text-to-Semantic-Layer): LLM은 SQL을 직접 쓰지 않고, 정의된 지표·열·필터 중에서 고르기만 한다.
  • ADR-0125 (값 정합): 사람이 입력한 값(오타·동의어)을 사전의 정식값에 맞춘다. 값 추측은 금지이고, 애매하면 답하지 않는다.

⚙️ 어떻게 동작하나

flowchart LR
  Q["사람의 질문"] --> L["LLM"]
  L -->|"지표·필터 고르기"| S["시맨틱 레이어<br/>정의·사전"]
  S -->|"정해진 규칙으로<br/>SQL 생성"| D[("데이터 표")]
  D --> A["답"]
LLM은 SQL을 쓰지 않는다. 고른 항목을 시맨틱 레이어가 검증된 규칙으로 SQL로 바꾼다.

  1. 사람이 "강남구 상수도 누수 공사 몇 건이야?"라고 묻는다.
  2. LLM이 질문을 정의된 항목으로 옮긴다. 지표 = 공사 건수, 필터 = 구:강남구, 공사 종류:상수도.
  3. "상수도 누수"라는 말은 값 사전의 동의어로 정식값 WATER에 맞춘다. 사전에 없으면 추측하지 않고 되묻거나 답하지 않는다.
  4. 시맨틱 레이어가 정해진 조인·계산식으로 SQL을 만든다.
  5. 실행 결과를 돌려준다.

왜 이렇게 설계하나: LLM이 SQL을 직접 쓰면 문법은 맞는데 뜻이 틀리는 일이 생긴다. 조인을 잘못하거나 "건수"를 다르게 센다. 그래도 숫자는 그럴듯하게 나와서 조용히 틀린다. 고르기만 하게 하면 틀릴 수 있는 범위가 확 줄어든다.

🧪 예시

  • 예시 1 · 일상에 빗대어: 메뉴판에 찌개가 3개(김치·된장·순두부) 있다. 손님 10명이 "얼큰한 거", "김치 들어간 찌개", "김치찌개 주세요"라고 각자 말한다. 직원이 메뉴판 동의어로 10명 모두 "김치찌개"로 받는다. 주방은 정해진 방법 하나로 끓인다. "매운 생선 요리요"처럼 메뉴판에 없는 주문은 비슷한 걸 멋대로 내지 않는다. "그건 없습니다"라고 말한다. 이게 "추측 금지"다.

  • 예시 2 · 실제로는: 도로굴착 공사 데이터를 시맨틱 레이어에 올린다고 하자(개념을 보여 주는 단순화한 형식).

    table: norm_road_dig            # ① 원본 표
    dimensions:
      - name: work_type             # ② 거르기 기준
        column: category_std
        label: 공사 종류
        filterable: true
    metrics:
      - name: dig_count             # ③ 지표
        label: 공사 건수
        expr: count()
    dictionary: work_type           # ④ 값 사전
      - { value: WATER, label: 상수도, synonyms: [상수도 누수, 수도관] }
    
    ① 실제 데이터가 있는 표다. ② "공사 종류"로 거를 수 있다고 정의한다. 열은 표준 범주 열(category_std)이다. ③ "공사 건수"는 행 수를 센다고 정해 둔다. 누가 물어도 같은 식이다. ④ "상수도 누수"라고 말해도 WATER로 맞춘다.

LLM은 다음처럼 고른 결과만 낸다. SQL은 시스템이 만든다.

{ "metric": "dig_count",
  "filters": { "sgg": "강남구", "work_type": "WATER" } }
여기서 ②가 왜 중요한지 보인다. 지금 category는 "상수도긴급누수복구공사", "상수도 긴급 누수복구 공사"처럼 문장이고, 고유값이 53,361개다. 이대로면 work_type에 올릴 유한한 값 목록이 없다. 그래서 범주 정규화가 시맨틱 레이어의 준비 작업으로 나온 것이다.

⚖️ 비교 · 흔한 오해

개념 담는 것 주로 누가 쓰나
시맨틱 레이어 열의 뜻, 지표 계산식, 값 사전 LLM 에이전트, 여러 BI 도구
메타데이터 카탈로그 데이터셋이 어디 있고 어떤 모양인지 앱 서버(예: 대시보드 PG의 app.dataset)
DB 뷰(VIEW) 미리 저장해 둔 SQL 한 개 SQL을 쓰는 사람·앱
데이터 사전 문서 열 설명 글 사람
  • 헷갈렸던 점: "범주 정규화를 하려면 시맨틱 레이어가 필요한가?" 아니다. 순서가 반대다. 범주 정규화는 시맨틱 레이어의 재료를 만드는 일이다. 재료는 시맨틱 레이어 없이도 따로 쓸모가 있다. → 범주형 데이터 정규화
  • 왜 그렇게 생각하기 쉬운가: 할 일 목록에서 "use_llm 범주 정규화"와 "시맨틱 레이어"가 한 묶음으로 설명됐다. 게다가 둘 다 "의미를 정리한다"는 말로 설명돼서 한 덩어리처럼 들린다.
  • 대시보드에 꼭 필요하지 않은 이유: 대시보드는 사람이 화면의 정해진 선택지(기간, 지역, 데이터셋)를 고른다. SQL은 서버가 정해진 틀(plan.ts)로 만든다. 이미 "고르기만 하게" 되어 있다. 자연어 질문을 받는 LLM이 없으니, 이를 막을 층도 필요 없다.
  • 오해: "시맨틱 레이어 = LLM 기술". 원래는 BI에서 "매출 정의를 팀마다 다르게 쓰는 문제"를 풀려고 나왔다. LLM은 최근에 생긴 큰 용도일 뿐이다.

🛠️ 실무에서는

  • 필요한 경우
  • 사람이 자연어로 묻는 에이전트·챗봇이 데이터에 붙는다.
  • 여러 도구(대시보드, 보고서, 노트북)가 같은 지표를 같은 식으로 계산해야 한다.
  • "건수", "피해액" 같은 정의가 팀마다 달라서 숫자가 안 맞는 일이 생긴다.
  • 필요 없는 경우
  • 화면이 정해진 필터만 주고, SQL을 서버가 틀로 만든다(지금 대시보드).
  • 지표가 몇 개뿐이고 쓰는 곳이 한 군데다.
  • 판단 질문 하나: "이게 없으면 어떤 질문에 답을 못 하나?" 답이 "에이전트 질문"뿐이면 에이전트가 생길 때 하면 된다.
  • 올릴 때 체크리스트
  • 거르기 열의 값이 유한한 범주인가? 문장·코드 그대로면 먼저 정규화한다.
  • 지표 계산식에 이름과 설명이 있는가?
  • 사전에 없는 값을 받았을 때 추측하지 않고 멈추는가?

❓ 자주 묻는 질문

  • Q. 대시보드에도 나중에 "말로 묻기" 기능을 넣으면? A. 그때는 hub-dev의 시맨틱 레이어를 쓰는 게 낫다. 대시보드가 따로 만들 필요는 없다.
  • Q. 시맨틱 레이어가 있으면 LLM이 절대 안 틀리나? A. 아니다. 고르는 걸 잘못할 수 있다. 다만 SQL을 직접 쓸 때보다 틀릴 범위가 좁고, 틀려도 무엇을 골랐는지 보여서 찾기 쉽다.
  • Q. 대시보드 PG의 메타데이터와 무엇이 다른가? A. PG 메타데이터는 "이 데이터셋은 어느 표에 있고 위치 단위가 무엇인가"다. 시맨틱 레이어는 "이 열의 이 값이 무슨 뜻인가"까지 담는다.

🔭 더 깊이 보기

  • Text-to-SQL은 어디서 주로 틀리나? — 시맨틱 레이어를 쓰는 이유를 실패 사례로 이해할 수 있다.
  • 값 사전의 동의어는 누가 어떻게 관리하나? — 사전이 낡으면 "애매해서 답 못 함"이 늘어난다. 운영의 핵심이다.
  • dbt 같은 도구는 지표 정의를 코드로 어떻게 관리하나? — 정의를 버전 관리하는 방법을 배운다.
  • 관련 주제: 범주형 데이터 정규화 · 메타데이터 카탈로그 기반 조회 · BFF Backend For Frontend 패턴

📚 참고 자료

  • LookML 소개 (Google Cloud Looker 문서, 한국어판) — 차원·측정값을 한 곳에 정의하는 대표적인 시맨틱 레이어 · 링크
  • dbt Semantic Layer (dbt 공식 문서, 영문) — 지표를 코드로 정의하고 여러 도구가 같이 쓰는 방식 · 문서
  • Cube 문서 (Cube 공식 문서, 영문) — 차원·지표 모델과 API로 시맨틱 레이어를 제공하는 예 · 문서

🗓️ 이력

  • 2026-11-10: use_llm 범주 정규화가 무엇이고 왜 시맨틱 레이어가 나오는지 물음. 에이전트가 없으면 필요 없다는 결론 → 일지

🕸️ 연결된 주제