온톨로지란 무엇인가: 실제 프로젝트의 설계·구축·검증·운영 가이드

온톨로지는 ‘세상의 모든 것을 거대한 그래프로 그리는 기술’이 아닙니다. 특정 업무에서 무엇을 같은 개념으로 볼지, 개념끼리 어떻게 연결되는지, 그 관계를 시스템이 어떤 의미로 해석할지를 합의하는 의미 모델입니다. 잘 설계하면 서로 다른 팀의 데이터가 같은 질문에 일관되게 답할 수 있습니다. 반대로 질문과 운영 책임 없이 용어만 늘리면 관리하기 어려운 사전이 됩니다.

이 글은 가상의 서비스 카탈로그를 끝까지 만드는 흐름으로 설명합니다. 목표 질문은 “어떤 서비스가 어떤 주제를 다루고, 어느 팀이 책임지는가?”입니다. 예제 주소 https://example.org/는 설명용이므로 실제 프로젝트에서는 조직이 관리하는 도메인으로 바꿔야 합니다.

먼저 구분할 것: 분류표, 데이터베이스 스키마, 온톨로지

도구주로 답하는 질문예시
분류표·택소노미무엇이 무엇의 하위 항목인가?지원 주제 → 계정 → 로그인
데이터베이스 스키마무엇을 어떤 형식으로 저장하는가?services.owner_team_id
온톨로지개념과 관계가 무엇을 뜻하는가?서비스는 팀이 담당하고 주제를 다룬다

온톨로지는 데이터베이스를 대체하지 않습니다. 기존 DB·CSV·API의 데이터를 같은 의미 체계로 연결하는 계약에 가깝습니다. 단순 탐색 메뉴만 필요하다면 분류표나 SKOS로 충분할 수 있습니다. 여러 출처의 개체와 관계를 재사용·추론·질의해야 할 때 온톨로지의 비용이 정당화됩니다.

핵심 구성요소를 한 장으로 보기

RDF는 정보를 주어–술어–목적어의 세 요소(트리플)로 표현합니다. 도움말 센터 → 담당 팀 → 고객경험팀처럼 대상과 관계를 연결합니다. 대상은 IRI라는 식별자로, 이름·날짜 같은 값은 리터럴로 표현할 수 있습니다. OWL 2는 그 위에서 클래스·속성·논리적 관계를 정의하고 추론할 수 있게 합니다.

사람, 작품, 날짜가 방향성 있는 관계로 연결된 W3C RDF 그래프 예제

W3C의 RDF 입문서 예제. 노드는 대상이나 값, 화살표는 관계를 나타낸다. (출처: W3C RDF 1.1 Primer)

실무에서는 다음 네 역할을 분리해 생각하면 쉽습니다.

층역할이 글의 결과물
RDF/Turtle데이터를 그래프로 표현·교환data.ttl
RDFS/OWL개념과 관계의 의미 정의ontology.ttl
SHACL들어온 데이터가 업무 규칙을 만족하는지 검사shapes.ttl
SPARQL그래프에서 필요한 답을 조회queries/services.sparql

여기서 중요한 차이가 있습니다. OWL은 보통 열린 세계 가정을 따르므로 기록에 담당 팀이 없다고 곧바로 “담당 팀이 없다”라고 단정하지 않습니다. “모든 서비스에는 담당 팀이 정확히 하나 있어야 한다”는 입력 품질 요구는 SHACL의 sh:minCount·sh:maxCount로 검사합니다. OWL의 rdfs:domain·rdfs:range도 검증 오류 메시지라기보다 추론에 쓰이는 의미 선언입니다. 이 구분을 놓치면 모델은 그럴듯한데 불완전한 데이터가 계속 유입됩니다. (W3C OWL 2 Primer, W3C SHACL)

1단계: 질문과 범위를 먼저 고정한다

첫 회의에서 클래스 이름을 만들기보다 역량 질문(competency questions) 세 개를 적습니다.

  1. 계정 관련 서비스를 모두 찾을 수 있는가?
  2. 각 서비스의 책임 팀을 알 수 있는가?
  3. 책임 팀이 없는 서비스가 반입될 때 발견할 수 있는가?

질문마다 필요한 데이터 출처와 책임자를 붙입니다. 예를 들어 서비스 목록은 CMS, 팀 목록은 조직 시스템, 주제 목록은 지원팀의 관리 어휘에서 올 수 있습니다. 처음에는 수십 개 클래스보다 Service, Team, Topic 세 개와 실제 샘플 10~20건이 낫습니다. 프로젝트 범위 밖의 개념은 만들지 말고, 같은 말을 다른 팀이 다르게 쓰는 경우 정의와 예외를 기록합니다.

2단계: 저장소와 식별자 규칙을 만든다

프로젝트를 다음처럼 나누면 모델, 실제 데이터, 품질 규칙, 질의를 각각 검토할 수 있습니다.

ontology-project/
├── ontology.ttl           # 개념과 관계
├── shapes.ttl             # 반입 데이터의 품질 규칙
├── data.ttl               # 작은 테스트 데이터
├── mappings/              # DB·CSV·API → RDF 변환 규칙
├── queries/
│   └── services.sparql    # 역량 질문을 검증하는 질의
└── docs/                  # 용어 정의·소유자·변경 기록

클래스·속성의 IRI(…/ontology/Service)와 개별 레코드의 IRI(…/id/help-center)를 구분하세요. 화면에 보이는 이름이 바뀌어도 식별자는 가능한 유지하고, IRI를 재사용해 전혀 다른 대상을 가리키지 않도록 합니다. 이 예시의 주소는 발행된 실제 온톨로지가 아닙니다. 운영에서는 조직 소유의 안정적인 HTTPS 주소와 접근 가능한 문서를 준비합니다. (W3C RDF Concepts — IRI와 변경)

3단계: 작은 모델과 실제 데이터를 작성한다

아래는 ontology.ttl의 최소 모델입니다. ownedBy와 addressesTopic은 리터럴 값이 아니라 다른 개체를 가리키는 관계입니다.

@prefix ex: <https://example.org/ontology/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

ex:Service a owl:Class .
ex:Team a owl:Class .
ex:Topic a owl:Class .

ex:ownedBy a owl:ObjectProperty ;
  rdfs:domain ex:Service ; rdfs:range ex:Team .
ex:addressesTopic a owl:ObjectProperty ;
  rdfs:domain ex:Service ; rdfs:range ex:Topic .

data.ttl에는 테스트용 인스턴스를 넣습니다. rdfs:label은 사람이 읽을 이름이며, @ko는 언어 태그입니다.

@prefix ex: <https://example.org/ontology/> .
@prefix id: <https://example.org/id/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

id:help-center a ex:Service ;
  rdfs:label "도움말 센터"@ko ;
  ex:ownedBy id:cx-team ;
  ex:addressesTopic id:account .
id:cx-team a ex:Team ; rdfs:label "고객경험팀"@ko .
id:account a ex:Topic ; rdfs:label "계정"@ko .

Protégé Desktop는 OWL 모델의 클래스·속성을 시각적으로 편집하는 도구입니다. 팀 단위 협업에는 WebProtégé도 선택할 수 있습니다. 두 도구 모두 모델 편집용이고, 운영 데이터 저장소·반입 검증·서비스 API의 전부를 대신하지는 않습니다.

Protégé의 클래스 계층과 속성 패널을 보여 주는 편집 화면

Stanford Protégé 공식 위키의 이전 버전 편집 화면. 클래스 계층과 속성 편집 영역이 분리되는 방식을 보여 주며, 현재 UI는 다를 수 있다. (출처: Protégé Getting Started)

4단계: SHACL로 반입 조건을 검증한다

shapes.ttl에는 서비스마다 한국어 또는 다른 언어의 이름 리터럴이 하나 이상 있고, 담당 팀은 정확히 하나이며 Team 유형이어야 한다는 규칙을 둡니다. 아래 예제는 이름의 존재와 리터럴 여부만 검사합니다. 특정 언어 태그까지 강제하려면 규칙을 추가해야 합니다.

@prefix ex: <https://example.org/ontology/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

ex:ServiceShape a sh:NodeShape ;
  sh:targetClass ex:Service ;
  sh:property [ sh:path rdfs:label ;
                sh:minCount 1 ; sh:nodeKind sh:Literal ] ;
  sh:property [ sh:path ex:ownedBy ;
                sh:minCount 1 ; sh:maxCount 1 ;
                sh:class ex:Team ] .

Apache Jena 명령 도구를 설치한 뒤 프로젝트 폴더에서 다음을 실행합니다. Jena 버전에 맞는 Java 요구사항은 다운로드 페이지에서 확인하세요. data.ttl에서 ex:ownedBy 행을 지우고 다시 실행하면 누락 오류를 확인할 수 있습니다. 실제 반입 파이프라인에서는 이 검사를 통과한 데이터만 저장소로 보내야 합니다. (Jena SHACL 명령 문서)

shacl validate --shapes shapes.ttl --data data.ttl

5단계: Fuseki에 싣고 질문을 질의로 바꾼다

Apache Jena Fuseki는 RDF를 적재하고 SPARQL로 조회할 수 있는 서버입니다. 공식 빠른 시작 안내처럼 서버를 실행해 http://localhost:3030/에서 catalog라는 인메모리 데이터셋을 만들고 ontology.ttl과 data.ttl을 추가합니다. 인메모리는 학습용이므로 운영 저장에는 지속형 저장소와 백업이 필요합니다. 쿼리 화면에서 다음 queries/services.sparql을 실행합니다.

PREFIX ex: <https://example.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?serviceName ?teamName WHERE {
  ?service a ex:Service ;
           rdfs:label ?serviceName ;
           ex:ownedBy ?team .
  ?team rdfs:label ?teamName .
  FILTER(LANG(?serviceName) = "ko" && LANG(?teamName) = "ko")
}

예상 결과는 도움말 센터 — 고객경험팀 한 행입니다. ex:addressesTopic과 Topic의 이름을 추가하면 첫 번째 역량 질문도 조회할 수 있습니다. 이 단계에서 중요한 것은 그래프가 예쁜지가 아니라, 처음 적은 업무 질문에 질의 결과가 정확히 답하는지입니다. (W3C SPARQL 1.1 Query, Fuseki Quickstart)

실제 운영 구조: 파일이 아니라 파이프라인으로 본다

원천 시스템(DB·CSV·API)
  → 매핑/정규화 → RDF 데이터
  → SHACL 검증 → 트리플 저장소(Fuseki 등)
  → SPARQL/API → 검색·분석·서비스 화면
       ↑
  버전 관리되는 온톨로지·용어 정의·테스트 질의

운영 단계에서는 세 가지를 별도로 설계해야 합니다. 변경 관리는 용어의 소유자, 클래스·속성의 변경 승인, 이전 IRI와의 호환성을 정합니다. 데이터 계보는 각 트리플의 원천과 갱신 시각을 추적합니다. 배포 관리는 테스트 데이터 검증, 역량 질문 회귀 테스트, 접근 권한, 백업·복원 절차를 포함합니다. 추론기가 필요한 경우에만 별도 단계로 추가하고, 추론 결과와 원본 사실을 구별해 저장·제공하세요. RDF의 명명 그래프는 출처별 데이터를 구분하는 한 가지 수단이지만, 그 자체가 권한 관리나 계보 정책을 자동으로 완성해 주지는 않습니다. (W3C RDF Datasets)

처음부터 대규모 지식 그래프를 목표로 할 필요는 없습니다. 세 개의 업무 질문, 세 개의 핵심 클래스, 소량의 실제 샘플, 한 번의 검증과 한 개의 질의가 동작하면 이미 실용적인 출발점입니다. 그 후 새 데이터 출처와 질문이 생길 때 모델을 넓히는 편이 검증 가능하고 유지보수하기 쉽습니다.