Skip to content

RAG 다음은 시멘틱 레이어라는데, 고객한테 뭘 만들어 줘야 하나 ​

요즘 고객 미팅에 들어가면 "시멘틱 레이어", "온톨로지", "컨텍스트 레이어" 같은 단어가 자주 들린다. Microsoft는 Fabric IQ를, Google은 Looker 시멘틱 레이어를, Snowflake와 Databricks는 각자 시멘틱 뷰와 메트릭 뷰를 밀고 있다. 다들 "AI 에이전트가 우리 회사 데이터를 제대로 이해하게 해 준다"고 말한다.

우리 팀은 고객을 만나 컨설팅을 하고 프로토타입까지 만들어 주는 팀이고, 나는 거기서 개발을 맡고 있다. 그러니 결국 내가 궁금한 건 하나다. 이걸 고객 환경에 실제로 어떻게 만들어 주느냐.

그래서 AI한테 한참 물어봤다. 답변 자체는 꽤 괜찮았는데, 순서가 뒤죽박죽이고 "그래서 내일 뭘 하면 되는데?"에 대한 답이 부족했다. 이 글은 그 답변을 뼈대로 삼아 순서를 다시 잡고, 공식 문서와 자료를 확인하면서 구현 관점의 내용을 보탠 학습 노트다.

미리 밝혀 두면, 여기 나오는 모든 플랫폼을 직접 다 써 본 건 아니다. 플랫폼 기능과 출시 상태는 2026년 10월 초 기준으로 찾아본 자료를 바탕으로 정리했고, 이 분야는 몇 달 단위로 바뀐다. 고객 앞에서 쓰기 전에 한 번 더 확인하는 게 좋다.

문서 더미에서 나온 근거와 엔터티 관계·계산 규칙을 거친 결과가 AI 에이전트의 답변으로 모이는 개념 그림
문서에서 맥락을 찾고, 정의된 관계와 규칙으로 숫자와 판단의 근거를 보탠다.

먼저, RAG는 뭐가 부족했나 ​

대부분의 사내 RAG는 이렇게 돈다.

질문 → 관련 문서 검색 → 문서를 LLM에 전달 → 답변

예를 들어 협회 고객의 상담 Agent 프로젝트에서 누군가 이렇게 묻는다고 해 보자.

이 프로젝트에서 위험한 이슈 알려줘

RAG는 이슈 문서, 주간보고, 회의록을 뒤져서 '지연', '오류', 'SLA', '긴급' 같은 단어가 들어간 문단을 찾고, 그걸 요약해서 답한다. 문서를 찾고 요약하는 일이다. 그리고 이 방식은 몇 가지 질문 앞에서 확실히 무너진다.

첫째, "위험하다"의 뜻을 모른다. 예를 들어 우리 팀에서 고위험 이슈는 "긴급 등급이면서, SLA를 넘겼거나 3일 이상 아무도 손을 안 댄 것"인데, 그 정의는 어떤 문서에도 문장으로 적혀 있지 않다. 사람 머릿속에 있다.

둘째, 계산을 못 한다. "가장 문제가 많은 회원사는?"이라는 질문에 답하려면 회원사별로 상담건을 세고, 미해결을 거르고, 긴급을 다시 세야 한다. "회원사 A 문제 많음"이라는 문서는 없다. 검색할 대상이 아예 없는 거다.

셋째, 말이 애매하면 답도 애매하다. 회의록에 "일정이 좀 늦어지고 있습니다"라고 적혀 있으면 RAG는 "A 프로젝트가 늦어지고 있는 것으로 보입니다"라고 답한다. 얼마나? 왜? 진짜로? 아무것도 모른다.

솔직히 나도 처음엔 "프롬프트에 정의 몇 줄 넣고, 청킹 좀 잘 하면 되는 거 아냐?" 싶었다. 정의 몇 개까진 그걸로 버틴다. 그런데 정의가 수십 개가 되고, 그 정의가 숫자 계산과 테이블 조인을 요구하기 시작하면 프롬프트로는 감당이 안 된다. RAG 쪽 오해는 예전 글에서도 다뤘으니 같이 보면 좋다.

시멘틱 레이어, 컨텍스트 레이어, 온톨로지 — 다 같은 말인가 ​

벤더마다 이름이 달라서 처음엔 엄청 헷갈렸다. 내 나름대로 정리하면 이렇다. 이건 좀 의견이 갈릴 수 있다.

  • 시멘틱 레이어(Semantic layer): 원래는 BI 쪽 용어다. "매출 = 주문금액 합계 − 반품금액" 같은 지표 정의를 한 곳에 모아 두고, 대시보드든 SQL이든 같은 숫자가 나오게 하는 층. LookML, dbt Semantic Layer, Power BI 시멘틱 모델이 여기 속한다. 요즘은 이걸 LLM이 읽게 해서 Text-to-SQL 정확도를 올리는 용도로 다시 팔리고 있다.
  • 온톨로지(Ontology): 지표보다 한 단계 넓다. "회원사", "상담건", "담당자" 같은 업무 개체(엔터티)와 그 사이 관계, 그리고 규칙과 액션까지 정의한다. Palantir가 오래전부터 이 단어를 핵심으로 써 왔고, Microsoft Fabric IQ도 이 단어를 쓴다.
  • 컨텍스트 레이어(Context layer): 마케팅 용어에 가깝다고 본다. AI가 답할 때 참고하는 조직의 맥락 전체 — 데이터 의미, 문서 지식, 업무 관계, 권한 — 를 묶어서 부르는 말이다.

실무적으로는 이렇게 기억하면 충분했다. 시멘틱 레이어는 "숫자의 뜻", 온톨로지는 "업무의 구조", 컨텍스트 레이어는 "그걸 AI한테 먹이는 통로 전체".

이름이 뭐든 안에 들어가는 재료는 거의 같다. 엔터티, 관계, 용어사전, 규칙. 바로 다음 섹션에서 이 네 가지가 질문 하나를 처리할 때 각각 어디서 쓰이는지 따라가 본다. 벤더 제품을 볼 때도 "이 제품은 네 가지 중 무엇을 어디에 정의하게 하나"로 보면 훨씬 덜 헷갈린다.

동작 방식: 질문이 들어오면 무슨 일이 일어나나 ​

흐름만 놓고 보면 이렇게 바뀐다.

[RAG]           질문 → 문서 검색 → 답변
[컨텍스트 레이어] 질문 → 엔터티 식별 → 관계 탐색 → 규칙 적용 → 답변 생성

그런데 이 화살표만 보면 솔직히 와닿지 않는다. 처음 보면 대개 "엔터티 식별이 뭔데? AI가 알아서 하는 거야?"에서 막힌다. 그래서 여기서는 순서를 바꿔서, AI가 미리 갖고 있어야 하는 재료부터 보고, 작은 예시 데이터 하나로 질문 세 개를 끝까지 따라가 본다.

미리 준비해 두는 재료 네 가지 ​

컨텍스트 레이어 방식의 AI는 질문을 받기 전에 이미 네 가지를 들고 있다. 이건 AI가 알아서 만드는 게 아니라 우리가 만들어서 넣어 주는 것이다. 구현 순서는 뒤의 직접 구현할 때의 순서에서 다루고, 여기선 "이런 게 있다" 정도만 잡고 가자.

① 엔터티 정의 — 이 업무에 어떤 "것"들이 있는가. 회원사, 상담건, 이슈, 담당자, 부서 같은 것들이다. 각각 어느 테이블에 있고 무엇으로 구분하는지(키)까지 적는다.

② 관계 정의 — 그 "것"들이 서로 어떻게 이어지는가. "회원사가 상담건을 요청한다", "이슈는 담당자에게 배정된다"처럼. 데이터 관점에선 어떤 컬럼으로 조인하는지가 된다.

③ 용어사전(Business Glossary) — 사람이 쓰는 말을 데이터의 값으로 바꾸는 번역표다. 이게 처음 들으면 제일 낯선데, 생각보다 단순하다.

사람이 하는 말            데이터에서의 의미
──────────────────────   ─────────────────────────────
"답변품질 문제"            issue.type = 'QA_QUALITY'
"긴급", "급건", "P1"       issue.priority = 'P1'
"해결 안 된", "계속되는"    issue.status <> 'CLOSED_APPROVED'
"지난주"                  기준일이 속한 주의 직전 월~일
"담당 부서"               이슈 → 담당자 → 부서 를 따라간 부서

데이터베이스에는 QA_QUALITY라고 저장되어 있는데 사용자는 "답변품질 문제", "답변이 이상한 거", "품질 이슈"라고 말한다. 이 간극을 메우는 게 용어사전이다. RAG가 자주 헛다리를 짚는 이유도 대부분 여기 있다. 단어는 찾았는데 그 단어가 데이터에서 무엇인지를 모른다.

④ 규칙 — "위험하다", "지연됐다"처럼 판단이 들어가는 말을 계산 가능한 조건으로 적은 것이다. 용어사전과 비슷해 보이는데, 용어사전이 "이 말은 이 값"이라는 1:1 번역이라면 규칙은 여러 조건을 조합한 판정식이다.

고위험 이슈 = 긴급 등급 AND 미해결 AND (SLA 초과 OR 마지막 조치 후 3일 이상)

예시 데이터 ​

이제 이 재료가 실제로 어떻게 쓰이는지 보려면 데이터가 있어야 한다. 기준일은 2026년 9월 29일(월)로 잡는다. 그러면 "지난주"는 9/22(월) ~ 9/28(일)이다.

[부서]
D-1  AI서비스팀
D-2  상담운영팀

[담당자]
P-1  김OO  → D-1
P-2  이OO  → D-2
P-3  박OO  → D-1

[회원사]
M-01 한빛정밀   (별칭: 한빛, 한빛정밀㈜)
M-02 대성식품   (별칭: 대성)
M-03 미래소재

[이슈]
ID     유형        등급  SLA초과  마지막조치  상태    담당  생성일  관련 회원사
I-881  답변품질    P1    Y        9/24       미해결   P-1   9/22   M-01
I-882  답변품질    P2    N        9/28       미해결   P-1   9/23   M-02
I-883  응답지연    P1    N        9/28       미해결   P-2   9/25   M-01
I-884  답변품질    P1    N        9/24       미해결   P-3   9/24   M-03
I-885  로그인오류  P1    Y        9/27       완료     P-2   9/21   M-01

다섯 건밖에 안 되지만, 질문 세 개를 따라가 보기엔 충분하다.

질문 1 — "지난주부터 답변품질 문제가 계속되고 있는데, 담당 부서는 어디야?" ​

엔터티 식별. 질문을 조각내서 각 조각이 무엇을 가리키는지 정한다. 여기서 용어사전이 쓰인다.

"답변품질 문제"   → 이슈(Issue), 조건 type = 'QA_QUALITY'      ← 용어사전
"계속되고 있는"   → 조건 status <> 'CLOSED_APPROVED'          ← 용어사전
"지난주부터"      → 조건 생성일 >= 9/22                        ← 용어사전(시간 표현)
"담당 부서"       → 부서(Department), 이슈에서 따라가야 함      ← 관계 정의

이 단계는 LLM이 한다. 다만 LLM이 아무 컬럼명이나 상상해서 붙이는 게 아니라, 용어사전에 있는 항목 중에서 고르게 한다. "답변품질 문제"가 용어사전에 없으면? 그때는 추측하지 말고 "답변품질 문제가 '답변 정확도' 이슈를 말씀하시는 건가요?"처럼 되묻게 하는 게 맞다고 본다. 여기서 아무거나 골라 버리면 뒤 단계가 아무리 정확해도 답이 틀린다.

관계 탐색. 이슈에서 부서까지는 바로 이어져 있지 않다. 관계 정의를 보면 이슈 → 담당자 → 부서, 두 번 건너가야 한다.

I-881 → P-1 김OO → D-1 AI서비스팀
I-882 → P-1 김OO → D-1 AI서비스팀
I-884 → P-3 박OO → D-1 AI서비스팀
(I-883은 유형이 응답지연이라 제외, I-885는 완료라 제외)

이 단계는 시스템이 한다. 관계 정의에 조인 조건이 적혀 있으니, 실제로는 이런 SQL로 바뀐다.

sql
SELECT d.name AS dept, COUNT(*) AS issue_count
FROM issue i
JOIN person p ON i.assignee_id = p.person_id
JOIN dept   d ON p.dept_id     = d.dept_id
WHERE i.type = 'QA_QUALITY'
  AND i.status <> 'CLOSED_APPROVED'
  AND i.created_at >= DATE '2026-09-22'
GROUP BY d.name;

이렇게 엔터티 두 개 이상을 건너가는 걸 멀티홉(multi-hop)이라고 부른다. 거창한 이름인데 하는 일은 조인이다.

답변. "AI서비스팀입니다. 9/22 이후 생성된 미해결 답변품질 이슈 3건(I-881, I-882, I-884)이 모두 AI서비스팀 소속 담당자(김OO 2건, 박OO 1건)에게 배정되어 있습니다."

RAG였다면? 회의록에서 "답변품질"이 나온 문단을 찾고, 그 근처에 부서 이름이 언급됐으면 그걸 답했을 거다. 언급이 없으면 모른다고 하거나, 더 나쁘게는 그럴듯한 부서를 지어냈을 거다.

질문 2 — "가장 문제가 많은 회원사는?" ​

이 질문은 일부러 골랐다. "문제가 많다"는 말이 애매하기 때문이다. 이슈 수? 미해결 수? 긴급 수? 사람마다 다르게 이해한다.

여기서 선택지는 두 가지다. 팀이 미리 "문제 많은 회원사 = 미해결 이슈 수 기준, 동점이면 긴급 수"라고 규칙으로 정해 두거나, 정해진 게 없으면 AI가 기준을 밝히고 답하게 하는 것. 나는 POC에선 후자로 시작해서, 자주 나오는 질문이면 전자로 굳히는 쪽을 권한다.

관계 탐색은 이번엔 회원사에서 출발한다.

회원사 → 이슈(미해결만)
M-01 한빛정밀  : I-881(P1), I-883(P1)   → 미해결 2건, 긴급 2건
M-02 대성식품  : I-882(P2)              → 미해결 1건, 긴급 0건
M-03 미래소재  : I-884(P1)              → 미해결 1건, 긴급 1건
(I-885는 완료라 제외)

답변은 "미해결 이슈 기준으로 한빛정밀이 2건(모두 긴급)으로 가장 많습니다"가 된다. 실제 운영 데이터라면 "회원사 A: 상담 45건 → 미해결 12건 → 긴급 5건" 같은 식으로 숫자가 커지겠지만 원리는 같다.

RAG에게 이 질문이 어려운 이유가 여기서 보인다. "한빛정밀이 문제가 제일 많다"는 문서는 어디에도 없다. 그 사실은 세어 봐야만 나온다.

질문 3 — "위험한 이슈 알려줘" ​

이번엔 규칙이 나설 차례다. 사용자는 "위험한"이라고만 했지만, 용어사전에서 "위험한 이슈"는 규칙 high_risk_issue로 연결되어 있다.

고위험 이슈 = 긴급(P1) AND 미해결 AND (SLA 초과 OR 마지막 조치 후 3일 이상)

규칙 적용은 다섯 건을 하나씩 판정하는 일이다.

ID     긴급  미해결  SLA초과  미조치일수  판정
I-881  ✔     ✔      ✔        5일        ✔ 고위험 (SLA 초과)
I-882  ✘     ✔      ✘        1일        ✘ (긴급 아님)
I-883  ✔     ✔      ✘        1일        ✘ (SLA 이내, 최근 조치함)
I-884  ✔     ✔      ✘        5일        ✔ 고위험 (5일째 미조치)
I-885  ✔     ✘      ✔        -          ✘ (이미 완료)

여기서 중요한 건 I-883이다. 긴급이고 미해결이라 단어만 보면 위험해 보이는데, 어제 조치가 있었고 SLA도 안 넘었다. RAG는 이걸 걸러내지 못한다. 규칙은 걸러낸다. 그리고 판정마다 이유가 같이 나온다.

답변 생성 — LLM은 마지막에 "설명"만 한다 ​

마지막 단계에서 LLM이 받는 건 문서 덩어리가 아니라 이미 계산이 끝난 결과다.

json
{
  "rule": "high_risk_issue",
  "as_of": "2026-09-29 06:00",
  "results": [
    { "issue_id": "I-881", "assignee": "김OO", "dept": "AI서비스팀",
      "reason": "긴급 등급이며 SLA 초과, 5일째 미조치" },
    { "issue_id": "I-884", "assignee": "박OO", "dept": "AI서비스팀",
      "reason": "긴급 등급이며 5일째 미조치" }
  ]
}

LLM은 이걸 사람 말로 풀어 주면 된다. "9/29 06:00 기준 고위험 이슈는 2건입니다. I-881은 SLA를 넘겼고 5일째 조치가 없습니다(담당 김OO). I-884는 5일째 조치가 없습니다(담당 박OO). 둘 다 AI서비스팀입니다." 여기에 문서 검색을 곁들이면 "I-881은 9/25 회의에서 모델 교체 후 재검토하기로 한 건입니다" 같은 맥락도 붙일 수 있다.

정리하면 각 단계를 누가 맡는지가 핵심이다.

엔터티 식별   LLM   (단, 용어사전 안에서 고르게 한다)
관계 탐색     시스템 (관계 정의 → 조인)
규칙 적용     시스템 (규칙 → SQL 뷰)
답변 생성     LLM   (계산 결과 + 문서 근거를 사람 말로)

LLM은 앞과 뒤, 말을 해석하고 말을 만드는 데만 쓴다. 가운데 계산은 시스템이 한다.

같은 질문, 다른 답 ​

마지막으로 "진행이 늦어지는 프로젝트 알려줘"를 두 방식으로 나란히 놓아 보면 차이가 더 선명하다.

[일반 RAG]
검색 결과: 회의록 "일정이 좀 늦어지고 있습니다"
답변: A 프로젝트가 늦어지고 있는 것으로 보입니다.

[컨텍스트 레이어]
엔터티: 프로젝트 A (예정일 9/20, 기준일 9/29, 완료율 60%)
규칙:   예정일 경과 AND 완료율 < 100% → 지연 프로젝트
답변:   A 프로젝트는 예정일을 9일 넘겼고 완료율 60%라 지연 상태입니다.

차이가 보이는가? 앞의 답은 "그런 것 같다"이고, 뒤의 답은 "이래서 그렇다"다. 그리고 회의록에 아무 말이 없던 프로젝트 B가 사실 더 늦어지고 있었다면, RAG는 B를 아예 모르고 컨텍스트 레이어는 B도 잡아낸다.

정리하면서 가장 크게 와닿은 것

규칙 계산을 LLM에게 맡기면 안 된다. "날짜 비교해서 9일 초과면 지연이라고 판단해"라고 프롬프트로 시키면 대부분은 맞겠지만, 날짜 계산이나 집계에서 가끔 틀리는 게 LLM이다. 규칙은 SQL 뷰나 코드로 미리 계산해 두고, LLM은 "어떤 규칙을 호출할지 고르고, 결과를 설명하는" 역할만 하게 하는 게 훨씬 안정적이다. 벤더들이 하나같이 '검증된 지표 정의'를 강조하는 것도 같은 이유라고 본다. 시멘틱 레이어의 진짜 가치는 결정적(deterministic)인 계산을 LLM 바깥으로 빼 주는 데 있다고 본다.

CSP별로 뭘 팔고 있나 ​

이제 벤더 이야기. 같은 문제를 각자 다른 쪽에서 풀고 있다는 게 재밌다.

Microsoft: IQ 패밀리 ​

Microsoft는 아예 "Microsoft IQ"라는 브랜드로 묶었다. Learn 문서는 이걸 Microsoft 스택의 "엔터프라이즈 인텔리전스 레이어"라고 부른다. 지능지수 얘기가 아니라, 에이전트에게 조직의 맥락을 공급하는 층이라는 뜻으로 이해하면 된다.

  • Fabric IQ: 이번 글의 주인공. Fabric(OneLake) 위의 기업 데이터에 비즈니스 의미를 입힌다. 핵심 아이템은 온톨로지(Ontology)와 Power BI 시멘틱 모델 두 개이고, 여기에 관계 탐색용 Graph, 자연어 질의용 Data Agent, 실시간 데이터를 감시하다 조치를 제안하는 Operations Agent, 그리고 계획·예측용 Planning이 같은 워크로드로 묶여 있다.
  • Work IQ: Microsoft 365 쪽. 메일, 일정, 파일, 사람, 채팅, 사이트 데이터를 에이전트가 쓸 수 있게 해 준다. 2026년 6월 16일 API가 GA됐고, 수백 개의 세부 기능을 MCP 도구 10개로 묶어 제공한다. A2A와 REST로도 붙일 수 있다. Microsoft 365 Copilot 라이선스와 별개로 Copilot Credits 기반 종량제라는 점도 견적 때 알아 둘 만하다.
  • Foundry IQ: Azure AI Search 기반의 지식 베이스. 정책 문서, 매뉴얼 같은 비정형 지식을 검색해 준다. 복잡한 질문을 하위 질의로 쪼개 병렬로 검색하고 재순위화한다. 사실상 "잘 만든 엔터프라이즈 RAG"라고 이해했다. 다만 문서 단위 권한은 원천 시스템이 그걸 지원할 때만 적용된다고 하니, "권한을 알아서 지켜 준다"고 고객에게 단정하면 안 된다.
  • Web IQ: 웹 정보. 2026년 6월에 발표된 Bing 기반 그라운딩 API로, 웹 페이지 전체가 아니라 출처를 붙인 문단 단위 근거를 에이전트에게 돌려준다. 발표 시점엔 일부 고객 대상 제한 접근(limited access)이었다.

정리하면 Fabric IQ는 비즈니스 엔터티와 데이터의 의미, Foundry IQ는 정책과 문서 지식, Work IQ는 사람이 일하는 맥락, Web IQ는 바깥 세상 정보다. 이걸 겹쳐 쓰라는 게 Microsoft의 그림이다.

앞에서 본 재료 네 가지에 대입하면 이렇다. Learn 문서 기준으로 온톨로지는 엔터티 타입, 속성, 관계, 규칙, 지표를 정의하고 이를 실제 데이터에 바인딩한다. 처음부터 만들 수도 있지만, 이미 운영 중인 Power BI 시멘틱 모델에서 생성하면 계산 열과 DAX 측정값이 지표로 같이 넘어온다. 온톨로지 에이전트에게 자연어로 초안을 만들게 하거나, RDF/OWL 같은 표준 형식에서 가져오는 것도 된다. 온톨로지가 생기면 거기서 그래프 모델을 생성할 수 있고, Data Agent가 온톨로지를 근거로 질문에 답한다. 문서 근거가 필요하면 Foundry IQ를 붙이는 구성이다.

여기서 하나 짚을 게 있다. Fabric IQ 온톨로지의 규칙은 "자연어로 비즈니스 로직을 적는" 방식이라고 문서에 나온다. 앞에서 내가 "규칙은 SQL로 계산해 두라"고 한 것과는 결이 다르다. 숫자 계산은 DAX 측정값(정의된 계산)으로 가져오고, 판단 로직은 자연어 규칙으로 두는 설계로 이해했는데, 자연어 규칙이 실행 시점에 얼마나 결정적으로 평가되는지는 문서만으로는 확인하지 못했다. POC에서 꼭 검증해 볼 지점이다.

출시 상태는 좀 복잡하다. Build 2026에서 Fabric IQ의 GA가 발표됐지만, 2026년 10월 초 기준 Learn 문서에는 IQ 워크로드와 그 중심인 온톨로지가 여전히 프리뷰로 표기되어 있다. Build 당시 Azure 블로그도 온톨로지는 "앞으로 몇 달 안에 GA 예정"이라고 했다. 헤드라인의 "GA"만 보고 고객에게 운영 수준이라고 말하면 곤란하다.

데이터 위치도 짚어야 한다. Fabric IQ의 모든 아이템은 OneLake 위에서 동작한다. 다만 외부 데이터를 꼭 복사해 와야 하는 건 아니고, OneLake 바로 가기(shortcut)나 미러링으로 원천을 그대로 참조할 수 있다고 한다. 그래도 고객 데이터를 OneLake에서 보이게 만드는 작업 자체는 필요하니, 견적 낼 때 그 범위를 꼭 확인해야 한다.

Google Cloud: Looker 시멘틱 레이어 + Gemini ​

Google은 원래 갖고 있던 무기를 꺼냈다. Looker의 LookML은 10년 넘게 쓰인 시멘틱 레이어다. 지표, 차원, 조인 경로를 코드로 정의한다.

  • Conversational Analytics in Looker: Gemini가 LookML 모델을 근거로 자연어 질의에 답한다. LLM이 SQL을 맨땅에서 짜는 게 아니라 LookML에 정의된 지표와 조인만 쓰도록 묶어 두는 방식이다.
  • Gemini Enterprise 연동: Looker에서 만든 대화형 에이전트를 A2A(Agent-to-Agent) 프로토콜로 Gemini Enterprise에 게시할 수 있게 됐다. 업무용 AI 비서에서 Looker 지표를 바로 묻는 그림이다.
  • Next '26에서 대시보드 에이전트, 에이전트 기반 시멘틱 모델링(LookML을 AI가 같이 짜 주는 것) 등이 추가로 발표됐다.
  • 데이터 카탈로그 쪽은 Dataplex Universal Catalog의 비즈니스 용어집(glossary, 2025년 6월 GA)이 용어사전 역할을 한다. 용어에 동의어와 관련 용어를 달고, 테이블이나 컬럼에 연결할 수 있다.

Microsoft처럼 "온톨로지"라는 단어를 전면에 내세우진 않는다. 내 느낌으론 Google은 "검증된 지표 정의"에 더 무게를 둔다. 관계 그래프 쪽은 상대적으로 약하다.

AWS: 조립형 ​

AWS는 늘 그렇듯 단일 제품보다 부품을 준다.

  • Amazon Quick Suite: 2025년 10월 9일 QuickSight가 에이전트형 워크스페이스로 확장되면서 Quick Suite가 됐다. 기존 BI 기능은 그 안의 "Quick Sight"라는 구성 요소로 남았고, 이후 이름이 "Amazon Quick"으로 더 짧아졌다는 정리도 있다. 여기서 시멘틱 레이어 역할을 하는 게 Topics다. 필드에 동의어, 단위, 설명을 달고, 여러 데이터셋 간 관계를 정의해서 자연어 질의가 런타임 조인을 할 수 있게 한다. 최근에는 기존 Topics를 "시멘틱 데이터셋"으로 옮기라는 가이드도 나왔다.
  • Bedrock Knowledge Bases 정형 데이터 지원: Redshift 같은 정형 저장소에 대해 관리형 NL2SQL을 제공한다. 데이터를 옮기지 않고 자연어로 조회한다.
  • GraphRAG: Bedrock Knowledge Bases가 Neptune Analytics와 엮어서 그래프 기반 검색을 지원한다(2025년 3월 GA). 다만 이건 문서에서 엔터티와 관계를 자동 추출해 검색 품질을 올리는 쪽이라, 우리가 직접 정의하는 온톨로지와는 성격이 다르다.
  • 파트너 조합: AWS 블로그에 Stardog의 시멘틱 레이어를 Aurora와 Redshift 위에 얹고, Bedrock AgentCore 위의 Strands 에이전트가 그걸 질의하는 예제가 있다. 온톨로지를 제대로 하고 싶으면 파트너를 쓰라는 메시지로 읽혔다.

비교 한눈에 보기 ​

구분MicrosoftGoogle CloudAWS
핵심 제품Fabric IQ (+ Work IQ, Foundry IQ)Looker (LookML) + GeminiQuick Suite Topics, Bedrock KB
강점온톨로지·그래프·액션까지 한 묶음, M365 맥락검증된 지표 정의, 성숙한 시멘틱 모델부품 선택 자유, 기존 AWS 데이터 그대로
약점OneLake 기반(바로 가기·미러링 작업 필요), 온톨로지는 아직 프리뷰관계 그래프·온톨로지는 전면에 없음직접 조립해야 할 게 많음
이럴 때고객이 이미 M365 + Power BI 중심고객이 이미 Looker/BigQuery 사용고객 데이터가 Redshift/Aurora에 있음

CSP가 아닌 쪽: 데이터 플랫폼과 SaaS ​

사실 이 판에서 더 빠르게 움직이는 건 데이터 플랫폼 회사들이다.

Snowflake — Semantic Views + Cortex Analyst. 시멘틱 뷰는 Snowflake의 네이티브 객체다. 논리 테이블, 관계, 팩트, 차원, 지표, 동의어, 그리고 검증된 예시 쿼리(verified queries)를 담는다. Cortex Analyst가 이걸 읽고 자연어 질의를 처리하고, Snowflake Intelligence가 그 위에서 에이전트 UI를 제공한다. 시멘틱 뷰는 CREATE SEMANTIC VIEW SQL로 만들 수도 있고, YAML 스펙으로 작성해 변환하거나 기존 뷰를 YAML로 내보낼 수도 있다. 이 YAML 스펙이 공개되어 있어서 구조를 공부하기에 좋다. 나는 시멘틱 레이어에 뭐가 들어가야 하는지 감 잡을 때 이 스펙을 제일 많이 참고했다.

Databricks — Unity Catalog Metric Views + Genie. YAML로 차원과 측정값을 정의하는 메트릭 뷰를 Unity Catalog에 등록하면, SQL·대시보드·AI/BI Genie가 같은 정의를 쓴다. 스타·스노우플레이크 스키마의 멀티홉 조인도 지원한다.

Palantir — Ontology. 이 분야의 원조 격이다. 객체, 링크, 액션을 정의하고 AIP의 에이전트가 그 위에서 동작한다. 비싸고 무겁지만, 고객이 "온톨로지"라는 말을 꺼낼 때 머릿속에 있는 그림은 대개 이거다.

독립 시멘틱 레이어.

  • dbt Semantic Layer(MetricFlow): dbt를 이미 쓰는 고객이면 가장 자연스럽다. 지표를 코드로 버전 관리한다.
  • Cube: 오픈소스 기반이라 프로토타입에 가볍게 쓰기 좋다. API로 지표를 노출한다.
  • AtScale: 대기업 BI 쪽에서 오래 쓰인 시멘틱 레이어.
  • Stardog 등 지식 그래프 계열: 관계와 추론이 중요할 때.

표준화 움직임. 2025년 9월 Snowflake가 주도해 Salesforce, dbt Labs, BlackRock, RelationalAI 등과 함께 시작한 OSI(Open Semantic Interchange)가 있다. 지표, 차원, 관계 같은 시멘틱 정의를 YAML 형식으로 벤더 간에 주고받자는 취지다. 2026년 1월에 v0.1 스펙이 나왔고, Apache 재단으로 옮겨 가는 중이라고 한다. 아직 초기라 실무 영향은 지켜봐야 할 것 같다. 참여사 목록에 Microsoft, Google, AWS가 없다는 점도 눈여겨볼 만하다. 다만 고객에게 "한 벤더에 정의를 다 박아 두면 나중에 못 옮긴다"는 리스크를 설명할 때 꺼낼 만한 근거는 된다.

그래서 고객한테 뭘 추천하나 ​

내 기준은 단순하다. 고객 데이터가 이미 있는 곳을 따라간다.

  • M365 + Power BI를 쓰는 고객 → Fabric IQ부터 검토
  • BigQuery/Looker 고객 → LookML + Conversational Analytics
  • Snowflake 고객 → Semantic Views + Cortex Analyst
  • Databricks 고객 → Metric Views + Genie
  • 데이터가 흩어져 있고 어디에도 정착 안 한 고객 → 플랫폼을 고르기 전에 아래의 "플랫폼 없는 프로토타입"으로 가치부터 증명

마지막 케이스가 생각보다 많다. 그리고 그런 고객한테 처음부터 Fabric 전환을 제안하면 POC가 데이터 이관 프로젝트로 변해 버린다. 이건 꽤 확신한다.

우리가 직접 구현할 때의 순서 ​

AI가 처음 준 답변은 "엔터티 정의 → 관계 → 데이터 매핑 → 용어사전 → 규칙 → Agent 연결 → 그래프" 순서였다. 틀린 건 아닌데, 나는 맨 앞에 하나를 추가하고 맨 뒤에 하나를 더 붙였다. 질문 수집과 평가다.

0. 질문 수집        ← 추가
1. 엔터티 정의
2. 관계 정의
3. 데이터 매핑
4. 용어사전
5. 규칙/KPI
6. Agent 연결
7. 그래프 (필요할 때만)
8. 평가            ← 추가

그리고 목표는 작게 잡는다. 많은 조직이 "우리 회사 온톨로지를 만들자"로 시작한다. 그러면 6개월 동안 엔터티 정의 회의만 하다 끝난다. 대신 "우리 팀 업무를 AI가 이해하게 만들자"로 시작하는 게 맞다.

0단계. 질문부터 모은다 ​

엔터티부터 정의하면 끝이 없다. "고객"을 정의하다 보면 "고객 등급", "고객 유형", "잠재 고객"이 줄줄이 나온다. 범위를 자르는 기준이 없기 때문이다.

그래서 질문을 먼저 모은다. 고객 현업 담당자에게 "이 AI한테 실제로 묻고 싶은 질문 20~30개"를 받는다. 이게 이후 모든 단계의 범위 기준이자, 마지막 평가 세트(골든 셋)가 된다.

- 이번 주 가장 위험한 이슈는?
- 담당자별 미해결 이슈는 몇 건이야?
- 회원사 A의 최근 상담 이력과 관련 프로젝트 현황 알려줘
- 지난주 대비 증가한 상담 유형은?
- 이 이슈는 누가 처리해야 해?

질문을 받을 때 "정답은 지금 어떻게 구하세요?"도 같이 물어본다. "엑셀 두 개 열어서 VLOOKUP 합니다" 같은 답이 나오면 그게 바로 관계와 규칙의 힌트다.

1단계. 엔터티 정의 — 질문 속 명사를 뽑는다 ​

모은 질문에서 명사를 뽑으면 엔터티 후보가 나온다. 위 질문들이면 이슈, 담당자, 회원사, 상담건, 프로젝트, 상담 유형 정도다.

엔터티마다 최소한 이것만 적는다.

  • 이름과 한 줄 정의
  • 식별자(무엇으로 하나를 구분하는가)
  • 핵심 속성 3~7개 — 질문에 실제로 쓰이는 것만

예를 들어 이슈 엔터티라면 이 정도다.

엔터티: 이슈(Issue)
정의:   프로젝트 수행 중 발생해 조치가 필요한 문제 또는 요청
키:     issue_id (Jira 이슈 키, 예: AGT-881)
속성:   유형, 등급, 상태, SLA 초과 여부, 마지막 조치일, 생성일

여기서 자주 헷갈리는 게 "이건 엔터티인가, 속성인가"다. 위 목록의 "상담 유형"이 그렇다. 내가 쓰는 기준은 이렇다. 그 자체에 대해 질문이 들어오고 자기만의 속성이 있으면 엔터티, 다른 엔터티를 분류하거나 거르는 데만 쓰이면 속성이다. "상담 유형별 건수"처럼 거르는 데만 쓰이면 상담건의 속성으로 충분하다. "상담 유형마다 담당 부서와 SLA가 다르다"면 그때 엔터티로 올린다.

처음엔 4~6개면 충분하다. 우리 팀 업무 기준이면 프로젝트, 이슈, 담당자, 작업(Task). 상담 Agent 고객이라면 회원사, 상담건, 담당자, 사업 정도. FAQ, 매뉴얼, 정책 문서 같은 건 엔터티로 모델링하기보다 Foundry IQ 같은 문서 검색 쪽으로 넘기는 게 낫다고 본다. 모든 걸 온톨로지에 넣으려 하지 말자.

2단계. 관계 정의 — 질문 속 동사를 뽑는다 ​

"회원사가 요청한 상담건", "이슈를 담당하는 사람" 처럼 질문 속 연결어가 관계가 된다.

From관계To카디널리티
회원사요청한다상담건1 : N
상담건발생시킨다이슈1 : N
이슈배정된다담당자N : 1
담당자소속된다부서N : 1
프로젝트포함한다이슈1 : N

AI가 처음 준 표에는 카디널리티와 방향이 없었는데, 구현할 땐 이게 꼭 필요하다. 1:N인지 N:M인지에 따라 조인 방식과 집계 결과가 달라진다. 대표적인 게 팬아웃(fan-out)이다. 프로젝트(1)에 이슈(N)를 조인하면 프로젝트 행이 이슈 수만큼 복제되는데, 그 상태로 프로젝트 예산을 합산하면 예산이 이슈 수만큼 부풀어 오른다. N:M 관계를 중간 테이블 없이 1:N처럼 다루면 같은 일이 양쪽에서 일어난다. 에러 없이 그럴듯한 숫자가 나오니 집계 버그 중 제일 찾기 어려운 유형이다. 카디널리티를 적어 두는 이유가 이거다.

3단계. 데이터 매핑 — 각 엔터티가 어느 시스템에 있나 ​

1, 2단계가 "무엇이 있는가"였다면 3단계는 "그게 실제로 어디에 있는가"다. 엔터티마다 원천 시스템, 키, 갱신 주기를 적는 매핑 시트를 만든다.

엔터티      원천 시스템          키                갱신 주기
─────────   ─────────────────   ────────────────  ─────────
회원사      CRM (회원사 마스터)   사업자등록번호      일 1회
상담건      상담 DB              상담번호           실시간
이슈        Jira                이슈 키 (AGT-881)  15분
담당자      인사 DB / Azure AD   사번 / 이메일      일 1회
주간보고    SharePoint 문서       (문서, 키 없음)     주 1회
회의 내용   Teams 회의록          (문서, 키 없음)     회의 후

키가 없는 것(주간보고, 회의록)은 엔터티가 아니라 문서 검색 대상으로 분류된다는 것도 이 시트를 그리면서 자연스럽게 정리된다. 갱신 주기는 나중에 답변에 "몇 시 기준"을 붙일 때 그대로 쓴다.

Microsoft 스택이라면 대략 이렇게 나뉜다. 메일·Teams·회의록은 Work IQ, 상담 DB·요구사항·이슈 같은 정형 데이터는 Fabric IQ, 운영 매뉴얼·정책 문서는 Foundry IQ.

이 단계에서 시간이 제일 많이 깨진다. 기술 문제가 아니라 키 문제다. Jira의 담당자는 이메일로, 상담 DB의 담당자는 사번으로, CRM의 담당자는 이름 문자열로 들어 있다. 이 셋을 같은 사람으로 묶는 매핑 테이블이 없으면 관계 탐색이 전부 끊긴다.

person_id  사번     이메일              CRM 표기
P-1        201734   kim@example.com    김OO 책임
P-2        198812   lee@example.com    이OO(상담운영)

이름 문자열 매칭은 동명이인과 표기 차이("김OO 책임" vs "김OO") 때문에 결국 사람이 한 번은 검수해야 한다. 고객 미팅 초반에 "시스템 간에 같은 사람/같은 회원사를 어떻게 식별하세요?"를 꼭 물어봐야 한다. 답이 "음..."이면 일정을 늘려 잡는다.

4단계. 용어사전 — 말의 뜻을 고정한다 ​

앞의 동작 방식에서 본 "사람 말 → 데이터 값 번역표"를 실제로 만드는 단계다. 실제 컨텍스트 레이어는 여기서 시작된다고 봐도 된다. RAG가 실패하는 원인의 상당수가 단어 의미를 모르는 것이기 때문이다.

1단계의 엔터티 정의와 뭐가 다르냐고 물을 수 있다. 엔터티 정의는 "이슈라는 게 있고 이런 속성이 있다"는 구조 설명이고, 용어사전은 "사람들이 이슈를 뭐라고 부르고, '긴급'이라는 말은 어떤 값인가"라는 말의 설명이다. 엔터티 정의는 개발자가 읽고, 용어사전은 LLM과 현업이 읽는다고 생각하면 편하다.

용어사전에 들어가는 말은 대략 다섯 종류다.

  • 엔터티를 부르는 말: 회원사, 회원기업, 가입사
  • 특정 값을 가리키는 말: 긴급, P1, 답변품질 문제
  • 상태를 가리키는 말: 완료, 미해결, 보류
  • 시간 표현: 지난주, 이번 달, 분기 (이 회사의 "주"는 월요일 시작인가?)
  • 판단이 들어가는 말: 위험한, 지연된, 문제 많은 → 5단계 규칙으로 연결

모으는 방법은 두 갈래다. 0단계에서 받은 질문에 나온 표현을 전부 뽑고, 원천 시스템의 코드 테이블(우선순위 코드, 상태 코드)을 거꾸로 훑어 각 코드를 현업이 뭐라고 부르는지 묻는다. 둘을 합치면 POC 규모에선 50~100개 안팎이 나올 거라고 예상한다.

yaml
- term: 회원사
  definition: 협회 상담 서비스의 대상 기업. 가입 상태가 '정상'인 기업만 해당
  synonyms: [회원기업, 회원 업체, 가입사]
  not_to_confuse: [거래처, 파트너사]   # 비슷하지만 다른 개념
  source: CRM.member.status = 'ACTIVE'

- term: 긴급
  definition: SLA 1일 이하인 상담건/이슈
  synonyms: [급건, P1, 최우선]
  source: issue.priority = 'P1'

- term: 완료
  definition: 요청자가 종료를 승인한 상태. 담당자가 '처리'만 한 것은 완료가 아님
  source: issue.status = 'CLOSED_APPROVED'

여기서 노하우 두 가지.

동의어(synonyms)를 최대한 많이 넣는다. 사용자는 "P1"이라고도 하고 "급건"이라고도 한다. Snowflake 시멘틱 뷰나 Quick Suite Topics가 동의어 필드를 따로 두는 데는 이유가 있다.

헷갈리기 쉬운 것(not_to_confuse)을 적는다. "완료"처럼 팀마다 뜻이 다른 단어가 꼭 있다. 이걸 정리하다 보면 고객 내부에서도 정의가 합의 안 되어 있다는 걸 발견하게 되는데, 사실 이게 컨설팅 관점에선 꽤 큰 산출물이다.

그리고 source를 꼭 채운다. 정의만 있고 데이터의 어느 값인지가 비어 있으면, LLM은 그 말을 이해는 하는데 조회는 못 한다. 실행 시점에 질문에 나온 표현을 용어사전에서 찾아 source 조건으로 바꾸는 것, 그게 엔터티 식별의 실체다. 앞에서 본 질문 1이 정확히 이 과정이었다.

5단계. 규칙과 KPI — 계산 가능한 형태로 ​

규칙은 반드시 쿼리로 바꿀 수 있어야 한다. SQL로 못 쓰는 규칙은 아직 규칙이 아니라 의견이다.

KPI와 규칙은 비슷한 듯 다르다. KPI는 숫자를 내고("이번 주 평균 처리일 = 2.4일"), 규칙은 대상을 골라낸다("이 이슈는 고위험이다"). 둘 다 정의해 두면 "평균 처리일이 지난주보다 늘었는데, 고위험 이슈 때문인가?" 같은 질문도 받을 수 있다. POC에선 규칙 2~3개, KPI 2~3개면 충분하다.

현업이 말로 준 정의를 규칙으로 옮길 때는 애매한 단어를 하나씩 숫자로 바꾸는 작업이 필요하다. "오래 방치된"은 며칠인가? "방치"의 기준은 생성일인가, 마지막 조치일인가? "조치"에 댓글도 포함되나? 이 질문들의 답이 그대로 SQL의 조건이 된다.

sql
-- 고위험 이슈: 긴급 AND 미해결 AND (SLA 초과 OR 3일 이상 미조치)
CREATE VIEW v_high_risk_issue AS
SELECT
  i.issue_id,
  i.title,
  i.project_id,
  i.assignee_id,
  i.priority,
  CURRENT_DATE - i.last_action_date AS days_without_action,
  '긴급 등급이며 '
    || CASE WHEN i.sla_breached THEN 'SLA 초과, ' ELSE '' END
    || (CURRENT_DATE - i.last_action_date) || '일째 미조치' AS reason
FROM issue i
WHERE i.priority = 'P1'
  AND i.status <> 'CLOSED_APPROVED'
  AND (i.sla_breached OR CURRENT_DATE - i.last_action_date >= 3);

-- 지연 프로젝트: 예정일 경과 AND 완료율 < 100%
CREATE VIEW v_delayed_project AS
SELECT
  p.project_id,
  p.name,
  p.due_date,
  p.progress_rate,
  CURRENT_DATE - p.due_date AS days_overdue
FROM project p
WHERE p.due_date < CURRENT_DATE
  AND p.progress_rate < 100;

reason 컬럼을 같이 만들어 두는 게 작은 팁이다. LLM이 "왜 고위험인지"를 설명할 때 이 문자열을 근거로 쓰면 지어내는 일이 줄어든다.

규칙마다 오너(누가 이 정의를 책임지는가)도 적어 두자. 나중에 "3일이 아니라 2일이어야 하는데요?"라는 요청이 반드시 온다.

6단계. Agent에 연결 — LLM에게 도구를 준다 ​

여기서부터 RAG와 확실히 달라진다. LLM에게 "문서 검색" 도구 하나만 주는 게 아니라, 시멘틱 레이어를 다루는 도구들을 준다.

json
[
  {
    "name": "find_entity",
    "description": "이름/별칭으로 엔터티를 찾는다. 예: '협회 프로젝트' → project_id",
    "parameters": { "entity_type": "project|issue|member|person", "keyword": "string" }
  },
  {
    "name": "traverse",
    "description": "엔터티에서 관계를 따라 연결된 엔터티를 조회한다",
    "parameters": { "from_type": "string", "from_id": "string", "relation": "string", "filters": "object" }
  },
  {
    "name": "evaluate_rule",
    "description": "정의된 비즈니스 규칙을 실행한다. 가능한 규칙: high_risk_issue, delayed_project",
    "parameters": { "rule": "string", "scope": "object" }
  },
  {
    "name": "search_documents",
    "description": "정책 문서, 매뉴얼, 회의록에서 근거 문단을 찾는다",
    "parameters": { "query": "string" }
  }
]

도구를 이렇게 나누는 이유가 있다. LLM에게 "SQL을 직접 짜라"고 하는 방식(자유 Text-to-SQL)도 가능하지만, 그러면 LLM이 조인 경로와 규칙 조건을 매번 새로 상상하게 된다. 도구로 나눠 두면 LLM은 "어떤 엔터티에서, 어떤 관계를 따라, 어떤 규칙을 쓸지"만 고르고, 실제 SQL은 YAML의 관계 정의와 규칙 뷰를 보고 시스템이 만든다. 자유도는 줄지만 틀릴 자리도 같이 줄어든다. 정해진 도구로 안 되는 질문이 자주 나오면, 그때 규칙 뷰 위에서만 도는 제한된 Text-to-SQL을 추가하는 순서가 안전하다고 본다.

그러면 "이 프로젝트에서 위험한 이슈 알려줘"는 이렇게 처리된다.

find_entity(project, "협회 Agent")        → project_id = P-102
evaluate_rule(high_risk_issue, {project_id: P-102})
                                         → 이슈 2건 + reason
traverse(issue, I-881, "assigned_to")    → 담당자 김OO
search_documents("I-881 관련 회의")       → 9/25 회의록 문단
→ 답변: 고위험 이슈 2건, 근거, 담당자, 관련 회의 내용

포인트는 RAG를 버리는 게 아니라는 점이다. 숫자와 판단은 시멘틱 레이어에서, 맥락과 서술은 문서 검색에서 가져와서 섞는다. 내가 보기엔 이 조합이 가장 현실적이다.

시스템 프롬프트에는 용어사전 전체를 넣지 말고, 엔터티 목록과 규칙 목록, 그리고 지켜야 할 원칙만 짧게 넣는다.

너는 프로젝트 이슈 현황을 답하는 에이전트다.
엔터티: project, issue, person, dept, member
규칙: high_risk_issue(고위험 이슈), delayed_project(지연 프로젝트)
- 숫자와 판정은 반드시 도구 결과만 근거로 말한다. 직접 계산하지 않는다.
- 질문의 표현이 용어사전에 없으면 추측하지 말고 되묻는다.
- 답변 첫 줄에 데이터 기준 시각을 밝힌다.

용어 상세는 find_entity가 필요할 때 조회하게 하자. 용어가 100개를 넘어가면 프롬프트에 다 넣는 방식은 금방 한계가 온다. 이 부분은 컨텍스트 엔지니어링 글과도 이어진다.

7단계. 그래프 — 정말 필요할 때만 ​

Fabric IQ의 핵심 기능 중 하나가 Graph다. 엔터티 연결을 따라 다단계 추론을 한다.

회원사 A → 상담건 #125 → 담당자 김OO → 프로젝트 "Agent 고도화" → 이슈 "SLA 지연"

이런 연결이 있으면 "회원사 A의 최근 이슈와 관련 프로젝트 현황 알려줘" 같은 질문에 답할 수 있다.

그런데 내 생각엔 POC 단계에서 그래프 DB까지 갈 일은 드물다. 홉이 2~3단계면 관계형 DB의 조인으로 충분하다. 그래프가 빛나는 건 홉 수가 가변적이거나("이 협력사 장애가 영향을 주는 모든 프로젝트"), 경로 자체가 궁금할 때다. 그 전까진 조인으로 버티고, 질문 목록에 그런 유형이 늘어나면 그때 그래프를 꺼내자. 그래프 RAG와의 차이는 RAG vs Graph RAG에 따로 정리해 뒀다.

8단계. 평가 — 0단계 질문으로 채점한다 ​

0단계에서 모은 질문 20~30개에 정답을 붙여 골든 셋을 만든다. 한 줄은 이런 모양이다.

yaml
- question: 이번 주 가장 위험한 이슈는?
  as_of: 2026-09-29
  expected: [I-881, I-884]
  must_mention: [SLA 초과, 미조치]   # 근거로 꼭 나와야 하는 말
  type: rule                        # lookup / traverse / rule / document

type을 달아 두면 어떤 유형의 질문에서 강하고 약한지 나눠서 볼 수 있다. 정답은 고객 현업이 지금 방식(엑셀, 수작업)으로 구한 값을 쓴다. 우리가 만든 시스템으로 낸 값을 정답으로 쓰면 채점이 의미가 없다.

그리고 같은 질문을 두 번 돌린다.

  • 기존 RAG만으로
  • 시멘틱 레이어 + RAG로

비교 항목은 단순하게 잡는다.

  • 정답 여부 (숫자가 맞는가)
  • 근거 제시 여부 (어떤 규칙, 어떤 데이터로 판단했는가)
  • 같은 질문을 다시 했을 때 같은 답이 나오는가

고객 보고에선 이 비교표 한 장이 아키텍처 그림 열 장보다 설득력이 있을 거다. "그래서 뭐가 좋아진 건데요?"라는 질문은 반드시 나오고, 그때 말로만 설명하면 약하다.

플랫폼 없이 먼저 만들어 보는 프로토타입 ​

고객이 아직 플랫폼을 정하지 않았거나, 우리가 빨리 가치를 보여 줘야 할 때 쓰는 구성이다. 우리 팀이 POC에서 쓰기 가장 현실적인 형태라고 생각한다.

YAML 정의를 PostgreSQL 규칙 뷰와 도구 API로 구현하고, LLM Agent가 API의 계산 결과와 기존 RAG의 문서 근거를 함께 받아 답변하는 구조
YAML은 정의를 관리하고, SQL 뷰와 도구 API는 조회·계산을 맡는다. Agent는 기존 RAG의 문서 근거까지 합쳐 답한다.

온톨로지 YAML은 이 정도 모양이면 시작하기 충분하다.

yaml
entities:
  project:
    description: 고객사와 계약된 수행 프로젝트
    table: project
    key: project_id
    display: name
    aliases_column: aliases          # "협회 Agent", "상담봇 고도화" 등
  issue:
    description: 프로젝트 수행 중 발생한 문제 또는 요청
    table: issue
    key: issue_id
  person:
    description: 내부 담당자
    table: person
    key: person_id

relations:
  - name: has_issue
    from: project
    to: issue
    join: project.project_id = issue.project_id
    cardinality: one_to_many
  - name: assigned_to
    from: issue
    to: person
    join: issue.assignee_id = person.person_id
    cardinality: many_to_one

rules:
  high_risk_issue:
    description: 긴급 AND 미해결 AND (SLA 초과 OR 3일 이상 미조치)
    view: v_high_risk_issue
    owner: PMO
  delayed_project:
    description: 예정일 경과 AND 완료율 < 100%
    view: v_delayed_project
    owner: PMO

이렇게 해 두면 좋은 점이 하나 더 있다. 나중에 고객이 Fabric IQ든 Snowflake든 플랫폼을 정하면, 이 YAML이 그대로 이관 설계서가 된다. 엔터티·관계·규칙이라는 개념 자체는 어느 벤더나 같으니까. 실제로 Databricks 메트릭 뷰는 YAML로 정의하고, Snowflake 시멘틱 뷰도 YAML로 작성하거나 내보낼 수 있으며, OSI 표준도 YAML이다. 구조가 꽤 비슷해서 옮기는 부담이 생각보다 작다.

4주 POC를 한다면 ​

첫 POC 목표로 가장 현실적인 건 "주간보고 자동 생성 Agent"라고 본다. 데이터가 이미 있고(Jira, 회의록, 메일), 매주 사람이 손으로 하는 일이라 효과가 바로 보이고, 엔터티가 4개(프로젝트, 이슈, 담당자, 액션아이템)면 끝난다.

1주차 — 질문과 엔터티. 현업 인터뷰로 질문 20~30개를 수집하고 정답을 구하는 현재 방식을 기록한다. 엔터티 4개와 관계를 정의하고, 시스템 간 식별 키 매핑 현황을 조사한다. 이 주의 산출물은 질문 목록과 엔터티/관계 정의서.

2주차 — 데이터 연결. Jira, 회의록, 주간보고 원천을 PostgreSQL(또는 고객 플랫폼)에 적재한다. 담당자 키 매핑 테이블을 만든다. 2주차가 밀린다면 대부분 여기서 밀린다.

3주차 — 용어사전과 규칙. 고위험 이슈, 긴급도, 미해결, 배포완료 같은 용어를 정의하고, 규칙을 뷰로 구현한다. 현업과 한 번 리뷰 미팅을 꼭 잡는다. 정의가 틀리면 4주차 결과가 전부 틀린다.

4주차 — Agent와 평가. 도구 API를 만들고 Agent를 연결한다. 골든 셋으로 기존 RAG와 비교 평가하고, 주간보고 초안 자동 생성 데모를 준비한다.

이후 회원사, 상담건, 사업정보까지 확장하면 고객의 상담 Agent 고도화 방향과 자연스럽게 연결된다.

고객 앞에서 써먹을 만한 이야기들 ​

자료를 보고 POC를 구상하면서 정리한 생각들이다. 일부는 아직 가설에 가깝다.

  • 고객이 "온톨로지"라는 말을 먼저 꺼내면, 범위를 줄이는 대화부터 한다. "전사 온톨로지"는 POC 범위가 아니다.
  • 정의 합의가 기술보다 어렵다. "완료" 하나의 정의를 두고도 부서 간 회의가 열릴 수 있다. 일정에 반영해야 한다.
  • 권한을 잊지 말자. 시멘틱 레이어를 거치면 사용자가 원래 못 보던 데이터를 집계로 우회해서 보게 될 수 있다. 행 단위 권한(RLS)을 도구 API 레벨에서 걸어야 한다.
  • 데이터 신선도를 답변에 같이 보여 준다. "9/29 06:00 기준"이 붙어 있으면 숫자가 어제와 달라도 고객이 덜 놀란다.
  • 규칙의 오너가 정해지지 않으면 운영 단계에서 아무도 고치지 않는다.

아직 고민 중인 부분 ​

몇 가지는 정리가 안 됐다.

용어사전과 규칙을 누가, 어떤 도구로 유지보수하느냐. POC에선 우리가 YAML을 고치면 되지만, 고객에게 넘긴 뒤엔? 현업이 YAML을 고칠 리는 없다. 각 플랫폼의 UI 편집기가 결국 답일 수도 있는데, 그러면 처음 얘기한 벤더 종속 문제로 돌아온다.

LLM이 엔터티 식별을 얼마나 믿을 만하게 하느냐도 아직 모르겠다. "그 프로젝트", "저번에 말한 회원사" 같은 지시어가 나오면 꽤 자주 틀린다. 대화 이력에서 엔터티를 추적하는 별도 장치가 필요할 것 같은데, 아직 깔끔한 방법을 못 찾았다.

그리고 솔직히, 이게 정말 "RAG 다음"인지는 반반이다. 문서가 중심인 업무에선 여전히 RAG가 주인공이고, 시멘틱 레이어는 숫자와 판단이 필요한 질문에서만 빛난다. 둘 다 필요하다는, 좀 재미없는 결론이 맞을지도 모르겠다.

참고자료 ​

멸종 위기 개발자