하늘의 오케스트라 기술 노트
← 에세이
기술 노트 · Tech Note

드론 군집의 의미층은
어떻게 작동하는가

좌표 너머의 세계 — 데이터 타입이 온톨로지와 어떻게 연결되고, TypeDB가 무엇을 통합하며, 시나리오와 룰이 어떻게 자동 합성되는가.

SYSTEM ESSENCE · 본질은 검색-행동 자동 루프 화려한 단어들을 다 걷어내면 — 지식 그래프 위에서 도는 4단계 무한 루프 ① SEARCH 패턴 매칭 어느 룰의 WHEN과 매칭되는 사실 있나? + 타입 계층 자동 추론 ② MATCH 매칭된 룰 조건 충족된 룰 한 개 또는 여러 개 ③ FIRE THEN 자동 실행 매칭된 룰의 행동을 시스템이 자동 실행 ★ 액션 트리거 ④ NEW FACT 새 사실 생성 KG에 등록 → 다음 검색의 입력이 됨 자동 루프 · 사람 개입 없음 검색 엔진 + 룰 트리거 + 자동 루프 = "온톨로지 기반 자율 시스템"이라는 화려한 이름의 진짜 정체

본질 · 우리 시스템 = 검색(패턴 매칭) → 매칭(룰 발견) → 발화(THEN 실행) → 새 사실(KG 갱신) → 다시 검색의 무한 루프. 온톨로지는 이 검색의 *깊이(계층 추론)*를, 룰은 검색의 *행동(트리거)*을 담당. 아래 세 다이어그램은 이 루프의 각 부분을 줌인한 것.

DRONE SWARM · 다양한 출처·기관·제조사 PERCEPTION · 지각층 (통계적 추론 / 신경망) 카메라 픽셀 → AI 분류기 → { label: "person", confidence: 0.87 } ★ insert · 한 줄 SYMBOLIC LAYER · 통합 데이터베이스 (TypeDB류) ① TYPE · ONTOLOGY 분류 계층 + 공유 어휘 Person ⊂ LivingBeing ⊂ ProtectedEntity ② FACT · INSTANCE 매 순간 갱신되는 사실 det_2387 a Person @(37.1, 127.4) ③ RULE · 선언적 if-then 자동 발화 (포워드 체이닝) IF Person AND inDanger → SearchTarget ④ FUNCTION · SCENARIO 절차 + 시나리오 골격 Stage1 → Stage2 → Stage3 (룰 조합으로 자동 합성) REASONER · 자동 추론 엔진 (네 조각을 한 그릇에서) 자동 합성 · 결정 DECISION · 모든 드론에 표준 메시지 송신 "detection_2387 a SearchTarget @(37.1, 127.4)"

구조 줌인 · 루프가 어디서 도는가 · 위: 통계적 지각 (신경망) · 가운데: 통합 데이터베이스 (타입·사실·룰·시나리오 + 추론기) · 아래: 결정의 표준화된 송신

PREDICTIVE TRIGGER → ROUTING → NEW ENVIRONMENT ① FEATURES + PREDICTIVE MODEL · 수치 층 입력: 기온·습도·풍속·식생 건조도·강수 이력·과거 발화 패턴 ... score = w₁·temp + w₂·(100-humidity) + w₃·wind + w₄·dryness + ... SCORE: 84.6 ② THRESHOLD GATE · 임계치 분기 score < 60 SAFE · no-op 60 ≤ score < 80 ALERT · log only ★ score ≥ 80 · TRIGGER 기호 층으로 라우팅 ★ ROUTE · insert into Symbolic DB RiskAssessment(level=Critical, score=84.6) ③ RULE ROUTER · 모든 룰의 패턴 매칭 새 사실 하나가 들어옴 → 엔진이 모든 룰의 WHEN 절과 동시 매칭 R-PREV-01 ✓ 매칭 → 발화 R-PREV-02 ✗ stage 없음 R-PREV-03 ✗ stage 없음 R-PREV-06 ✗ scenario 없음 ... 23 rules ✗ 조건 미충족 ★ DERIVED FACT · 자동 도출 PreventionScenario(stage=Stage1_Survey, status=Active) ④ NEW DATASET ENVIRONMENT · 새 데이터셋 환경 형성 BEFORE TRIGGER active scenarios: 0 matchable rules: 23 stage rules: dormant (조건 불충족) AFTER TRIGGER active scenarios: 1 ★ matchable rules: 28 (+5 신규) stage rules: ★ LIVE (R-PREV-02·03·06...) "트리거 한 번 = 새로운 룰 풀이 깨어남" — 적실한 판단은 트리거 자체가 아니라 트리거 이후 새 환경에서 일어난다

① SEARCH 줌인 · 루프의 첫 단계는 어떻게 시작되나 · 예측 임계치(80) 초과 → 트리거 → 새 사실 insert → 룰 라우터가 모든 룰과 패턴 매칭 → 매칭된 룰 발화 → 새 사실 도출 → 그 결과 *이전엔 매칭 안 되던 stage-specific 룰들이 활성화* (휴면 → LIVE). 이게 "새 데이터셋 환경"의 본질 — 단순히 사실 하나 추가가 아니라 *룰의 매칭 가능 영역 자체가 확장됨*.

IF-CLAUSE CASCADE · 룰의 WHEN/THEN 연쇄가 시나리오를 만든다 PHASE A · 트리거 한 사실 → 첫 룰의 WHEN과 매칭 → 첫 발화 TRIGGER FACT RiskAssessment { level: Critical region: Gangwon-A } 매칭 R-PREV-01 ★ 발화 WHEN (조건): $a isa RiskAssessment $a.level = Critical NOT EXISTS active Scenario THEN (행동): insert PreventionScenario { stage: Stage1_Survey, status: Active } 새 사실 도출 ★ NEW FACT (THEN의 결과) PreventionScenario { stage: Stage1_Survey } 이 새 사실이 또 다른 룰의 WHEN과 매칭... PHASE B · 새 사실이 추가 룰들의 WHEN과 매칭됨 (병렬 평가) R-PREV-02 WHEN: stage = Stage1 surveyResult = "clean" 상태: 대기 (외부 입력 필요) R-PREV-03 WHEN: stage = Stage1 surveyResult = "hotspot" 상태: 대기 (외부 입력 필요) R-PREV-06 ★ WHEN: scenario active availableDrones < 3 즉시 발화 → THEN: invoke RequestSupport(...) ★ ANOTHER NEW FACT SupportRequest(neighbor) RESULT · 트리거 후 0.3초 안에 자동으로 일어난 일 시나리오 시작 (R-01) + 인근 지원 요청 (R-06) + Stage1 룰 풀 활성화 (R-02·03 대기) + 자원 매칭

②③④ MATCH·FIRE·NEW FACT 줌인 · 루프의 한 사이클이 자세히 어떻게 돌아가나 · 룰은 WHEN(조건) + THEN(행동)의 두 부분. 트리거 사실이 어느 룰의 WHEN과 매칭되면 그 룰의 THEN이 실행되어 *새 사실*이 도출되고, 그 새 사실이 다시 다른 룰의 WHEN과 매칭됨. 이 발화 연쇄의 누적이 곧 "시나리오"다 — 사람이 시나리오를 적는 게 아니라 룰들이 모여 시나리오를 만들어낸다.

11 SECTIONS · 약 35분 소요 · 본문 에세이의 기술 동반본
읽기 시작

01개요와 핵심 명제#

드론 군집의 진짜 진화는 좌표 공유에서 의미 공유로 옮겨가는 것이다. 그 의미 공유를 실제로 작동시키는 기술 스택이 바로 — 온톨로지 + 룰 엔진 + 통합 데이터베이스 의 결합이다.

본문 에세이가 "왜 의미 공유가 필요한가"의 이야기를 다뤘다면, 이 노트는 그 의미 공유가 *기술적으로* 어떻게 작동하는가의 디테일을 다룬다. 한 번 읽고 잡힐 내용은 아니다. 섹션을 오가며 여러 번 읽기를 권한다.

이 문서가 답하는 질문

  • 온톨로지가 정확히 무엇이고, 드론과 어떻게 연결되는가
  • 기존 데이터 구조(JSON 스키마, RDB)로는 왜 안 되는가
  • TypeDB 같은 새 도구는 무엇이 본질적으로 다른가
  • 시나리오와 함수가 데이터베이스에 어떻게 들어가는가
  • 트리거가 어떻게 판단을 내리고, 그게 진짜 "추론"인가
  • 실제 시스템 한 사이클은 어떻게 세팅되고 어떻게 굴러가는가

이 문서가 다루지 않는 것

  • RDF/OWL의 상세한 문법, SPARQL 쿼리
  • 머신러닝 모델 학습법
  • 드론 비행 제어 알고리즘 자체 (PID, MPC 등)

02언제 필요한가#

TL;DR

온톨로지는 "드론에 필요한 기술"이 아니라 "여러 드론·시스템이 같이 일하기 위한 공용 인프라"다. 혼자 일하는 드론에는 영원히 안 필요하다. 합쳐서 일해야 하는 드론이 늘어나는 만큼 점점 필요해진다.

안 필요한 경우 (현재 대다수)

  • 평창 1,218대 드론쇼 — 전부 인텔 쇼팅스타. 같은 회사가 만들고 같은 컴퓨터가 조종.
  • 단일 기업 드론 라이트쇼 — DJI 5대를 한 사람이 조종.
  • 농약 살포 드론 한 대 — 자기 논 한 바퀴 돌고 끝.

이 경우들은 자기 회사 안에서만 통하는 데이터 타입으로 충분하다. 옆 드론도 같은 회사 제품이라 같은 단어를 쓰니까.

필요해지는 3가지 상황

(1) 다른 회사 드론들이 같은 하늘에 뜰 때 — UAM

도심 항공교통이 본격화되면 DJI 배송, 삼성 순찰, 응급 의료 드론이 같은 골목 하늘을 난다. 서로를 충돌 회피 대상으로 인식해야 하는데, 회사마다 단어가 다르면 합의가 안 된다. 비행 차선의 의미 합의가 필요해진다.

(2) 다른 기관이 같은 임무에 드론을 보낼 때

소방청 + 군 + 지자체 + 민간 구조단의 드론이 산불 현장에 모인다. 데이터가 중간에서 끊어지지 않으려면 단어와 의미의 표준이 필요하다. 사람이 매번 데이터를 옮겨치는 건 한 번이면 모를까 매 재난마다 못 한다.

(3) 드론 데이터가 다른 분석 시스템으로 흘러갈 때

디지털 트윈, 스마트시티 플랫폼, 감시 시스템 같은 받는 쪽 시스템은 어떤 회사 드론인지 신경 안 쓴다. 그저 "사람 몇 명, 차량 몇 대"를 알고 싶다. 받는 쪽이 모든 드론 회사 어휘를 외울 수 없으므로 표준 사전이 필요하다.

현재 위치 대부분의 드론 현장은 아직 온톨로지 없이 굴러간다. 사람이 중간에서 옮겨치거나, 회사간 1:1 변환 코드를 매번 짠다. 비효율적이지만 돌아가긴 한다. 변곡점은 위 3가지 상황이 동시에 일어나기 시작하는 지금이고, 군사·재난·공공안전 분야가 먼저 도착해 있다.

03데이터 타입과 온톨로지의 연결#

TL;DR

"내가 부르는 이름"을 "남들도 알아듣는 이름"으로 바꿔주는 변환표 한 장 — 그게 전부다.

데이터 흐름 5단계

01
센서
카메라 픽셀, 열화상 36.5°C, GPS (37.123, 127.456) — 그저 raw 숫자.
02
분류기
드론 안의 작은 AI가 라벨 생성 — {label:"person", confidence:0.87}
03 ★
매핑 — 핵심 접합부
분류기의 "person"을 온톨로지의 :Person으로 변환. 인스턴스가 생성되는 순간 의미층에 등록됨.
04
추론
계층 자동 상속(:Person ⊂ :LivingBeing ⊂ :ProtectedEntity) + 룰 발화로 :SearchTarget 도출.
05
송신
옆 드론에 표준 ID로 한 줄 전송 — "detection_2387 a :SearchTarget @(37.1, 127.4)"

↓ 같은 흐름의 자세한 데이터 모양

[1] 센서     카메라 픽셀, 열화상 36.5°C, GPS (37.123, 127.456)
                        ↓
[2] 분류기   드론 안의 작은 AI가 라벨 생성
              { label: "person", confidence: 0.87, bbox: [x,y,w,h] }
                        ↓
[3] 매핑     분류기의 "person" 라벨을 온톨로지의 :Person으로 바꿈
              인스턴스 생성:

                detection_2387:
                  type:        :Person
                  location:    (37.123, 127.456)
                  confidence:  0.87
                  detectedBy:  :Drone_07
                  detectedAt:  2026-05-07T14:23:01Z
                        ↓
[4] 추론     :Person ⊂ :LivingBeing ⊂ :ProtectedEntity
              규칙: Person AND inDisasterArea AND ¬conscious
                    → :SearchTarget
              → 같은 인스턴스가 SearchTarget으로도 자동 분류됨
                        ↓
[5] 송신     옆 드론에게 단 한 줄 (사전 ID로):
              "detection_2387 a :SearchTarget @(37.123, 127.456)"

핵심은 [3] 매핑

드론에는 Person이라는 자기만의 클래스가 있다 (그냥 프로그래밍 데이터 타입). 온톨로지에도 :Person이라는 개념이 있다 (산업 공유 사전). 이 둘을 연결하는 한 줄짜리 선언이 드론 소프트웨어 어딘가에 박혀 있다:

// 드론 소프트웨어 어딘가
register(drone.classes["person"], ontology[":Person"])

이게 다다. 드론이 자기 데이터 타입의 인스턴스를 만들 때마다, 그 인스턴스가 동시에 온톨로지의 인스턴스로도 등록된다.

가장 직관적인 비유 — 온톨로지는 회사 간 공유 타입 시스템

프로그래밍온톨로지
class Person { ... }:Person (RDF 클래스)
필드 location: GPS속성 :hasLocation
class Survivor extends Person:Survivor rdfs:subClassOf :Person
instanceof Person 체크추론기가 자동 판정
내부 타입 체크회사를 넘어 작동하는 타입 체크

한 회사 안에서만 통하는 타입 시스템 = 그냥 데이터 타입.
여러 회사가 합의해서 공유하면 = 온톨로지.

04기존 데이터 구조의 한계#

TL;DR

80%는 기존 데이터 구조(JSON 스키마, REST, gRPC)로 풀린다. 온톨로지가 풀어주는 건 나머지 20%이고, 그 20%가 언제 필요해지는지가 핵심이다.

기존 도구로 충분한 것

  • 메시지 모양 통일 — 드론은 항상 {class, lat, lon} 형식으로 보낸다.
  • 공유 어휘 — 회사들이 모여서 단어 목록 합의.
  • 버전 관리 — 새 항목 추가되면 스키마 버전 올리고 모두 업데이트.

산불 현장 5대 드론도, 처음부터 같은 JSON 스키마로 합의했다면 온톨로지 없이 풀린다. 실제로 많은 현장이 이렇다.

기존 구조가 막히는 4가지 순간

(1) 단어가 다른데 사후에 합쳐야 할 때

JSON 스키마는 "필드 이름이 다르면 다른 거다." DJI는 "person", 삼성은 "human"이라 이미 코드에 박아놓고 5년 운영했다. 둘을 사후에 합치려면 한쪽이 코드 다 뜯거나, 매번 변환 서비스를 새로 짜야 한다.

온톨로지는 person sameAs human 한 줄을 사전에 추가하면 끝난다. 양쪽 코드는 그대로 둔다.

(2) 받는 쪽이 모든 규칙을 미리 알고 있어야 할 때

JSON 스키마로는 메시지 *모양*만 정의된다. "person 발견 → 충돌 회피 1등급 격상 → 본부 즉시 보고 → 옆 드론 모드 전환" 같은 *행동 규칙*은 받는 드론마다 자기 코드에 박아야 한다. 100대면 100번 박는다. 규칙이 바뀌면 100번 다시 배포한다.

온톨로지는 그 규칙을 사전 안에 한 번만 적는다. 모든 드론이 그 사전 한 권만 읽으면 끝.

(3) 새 개념이 계속 추가되는데 기존을 깨고 싶지 않을 때

JSON 스키마에 새 항목을 추가하면 — 받는 쪽이 그걸 모르면 보통 에러를 뱉거나 무시한다. 온톨로지는 새 개념을 *기존 개념의 하위 종류*로 추가한다. "휴머노이드 로봇은 사람의 한 하위 종류"라고 적으면, 휴머노이드를 모르는 옛날 드론도 그걸 그냥 "사람"으로 받아들여서 처리한다.

(4) 데이터 위에서 자동 추론을 돌리고 싶을 때

"지난 1시간 동안 발견된 모든 *생명체*를 보여줘" 같은 질문. JSON 스키마로는 "사람·개·사슴·휴머노이드는 다 생명체"라는 분류를 받는 쪽 코드에 짜 넣어야 한다. 온톨로지는 그 분류 자체가 사전에 들어 있어 추론기가 알아서 끌어온다.

실무 풍경 단순 협업(회사 5~6개, 단어 30개 수준)은 JSON 스키마로 충분. 중간 복잡도는 JSON + 매핑 테이블 + 변환 서비스로 굴러감. 고복잡도(회사 수십 개, 단어 수백 개, 자동 추론 필요)에서 진짜 온톨로지가 비용 회수.

05TypeDB의 통합 접근#

TL;DR

전통적으로 데이터 + 의미 + 추론이 세 시스템에 따로 살았다. TypeDB류는 셋을 한 시스템에 묶는다. 함수까지 들어가면 비즈니스 로직이라는 네 번째 조각도 흡수한다.

기존 방식 — 시스템 3개로 쪼개진 그림

[1] 데이터베이스 (PostgreSQL, MySQL ...)
       사실 저장: "Drone-7이 (37.1,127.4)에서 사람 봤다 14:23"
       그냥 줄과 칸. 의미는 모름.

[2] 온톨로지 파일 (OWL/RDF)
       의미 정의: "사람 ⊂ 생명체 ⊂ 보호대상"
       별도 파일.

[3] 추론기 (Pellet, HermiT)
       위 둘을 읽어 추론하는 별도 프로그램.

이 분리가 만드는 세 가지 비용

  • 유지보수 지옥 — DB 스키마 바꾸면 온톨로지·추론 규칙도 따라 바꿔야. 셋이 어긋나면 시스템이 거짓말.
  • 속도 문제 — 추론마다 DB→추론기→DB 왕복. 실시간 드론 판단에는 너무 느림.
  • 두 종족 개발자 필요 — DB 팀과 온톨로지 팀이 따로. 의사소통 비용 큼.

새 방식 — 셋을 하나로

[하나의 시스템]
  스키마(테이블 정의) = 온톨로지
  데이터 저장 시 자동으로 의미·계층까지 같이 알려짐
  추론기가 DB 안에 박혀 있음 (왕복 없음)
  함수(비즈니스 로직)도 DB 안에 박을 수 있음

드론 한 장면으로 차이

기존 방식

드론7 사람 발견 → DB에 {type:"person",...} 저장 → 무전 송출 → 옆 드론은 자기 코드의 if문 체인 발화 if(type=="person") { 회피1등급(); 보고(); ... } → 새 규칙 추가 시 모든 드론 다시 빌드/배포.

합쳐진 방식

드론7 사람 발견 → DB에 사람 인스턴스 저장 → 시스템이 즉시 자동 분류(생명체·보호대상·구조대상자 후보) → 옆 드론은 DB에 질의 "보호대상 우선 1등급 객체 다 줘" → 새 규칙 추가 시 DB 안 룰 한 줄 수정.

정직한 노트 TypeDB는 OWL/RDF가 아니라 자체 타입 이론(PERA)을 쓴다. 무거운 OWL 추론은 못 한다. 진짜 무거운 추론이 필요하면 Stardog, GraphDB 같은 OWL 트리플 스토어가 따로 있다. TypeDB는 "타입이 풍부한 그래프 DB + 가벼운 추론기"의 중간 지점이라 보는 게 정확하다. 만능 아님. 단순 도메인엔 PostgreSQL이 여전히 더 빠르고 싸다.

06시나리오와 함수의 실체#

TL;DR

데이터베이스 안에 들어가는 건 "함수" 하나가 아니다. 타입 + 룰 + 함수의 묶음이고, 그 묶음에서 시나리오가 *발현*된다. 시나리오를 일일이 박으면 경우의 수 폭발로 망한다.

오해 — 시나리오를 일일이 박는다고?

"드론 5대 + 사람 1명 + 낮 + 여름 + 강풍" / "드론 4대 + 사람 2명 + 밤 + 겨울 + 비" ... 이런 식으로 박으면 경우의 수가 수천·수만으로 폭발. 새 변수 하나 추가되면 또 곱하기. 6개월 안에 유지보수 불가능.

실제 패턴 — 작은 룰들의 *조합*에서 시나리오가 *발현*

// 산불 대응 — 각 룰은 독립적, 짧음

R1: 발화 가능 열 이상 현상 감지됨 → Mode = FireResponseMode
R2: SearchTarget 발견 → 가장 가까운 드론에게 접근 지시
R3: 드론 배터리 < 20% → 임무 해제, 복귀
R4: 야간이면 → 모든 드론 열화상 모드 활성화
R5: 강풍이면 → 비행 고도 +20m, 안전 마진 +5m
R6: 가용 드론 수 < 3 → 정찰 범위 축소, 핵심 영역 우선
R7: 어떤 임무든 30분 진척 없음 → 인근 지원 자동 호출
... (수십 개)

새벽 3시 강풍에 드론 4대로 산불 대응 시작 → R1·R4·R5·R6이 *동시에* 트리거 → "야간·강풍·소수 드론용 산불 대응" 시나리오가 *자동 합성*된다. 도중에 사람 발견 → R2 추가 → 시나리오 *자동 확장*. 배터리 부족 → R3 → 시나리오 *자동 재구성*.

룰은 30개인데 만들 수 있는 시나리오는 수만 개다.

룰끼리는 어떻게 연결되는가

명시적 연결은 거의 없다. 룰들이 서로를 트리거하는 통로는 공유 어휘(온톨로지) + 공유 상태(DB의 사실)다. R1이 트리거되면 Mode = FireResponseMode가 DB에 적힌다. R6은 그 모드를 읽는다. R6은 R1을 직접 가리키지 않는다 — 같은 데이터 위에 살고 있을 뿐.

예외 — 명시적 시나리오 골격이 필요할 때

순서가 본질적인 절차는 골격으로 명시한다.

SCENARIO: 구조작전
  단계: [접근, 확인, 보고, 응급조치, 후송]
  단계 간 전이 조건: ...

// 각 단계 안은 다시 작은 룰들의 조합에 맡김

위는 골격, 아래는 발현 — 두 층으로 나뉜다. 대부분의 시나리오는 발현되고, 순서가 본질적인 소수만 명시된다.

실무 패턴 정리

  1. 공유 어휘(온톨로지) — 단어들의 정의와 관계
  2. 작은 룰들 — 수십~수백 개의 독립적 if-then
  3. 명시적 시나리오 골격 — 순서가 본질적인 소수 절차
  4. 추론 엔진 — 위 셋을 사실 위에서 자동 합성

사람이 미리 적어두는 건 [1][2]가 95%, [3]은 5% 미만. 적어두는 게 아니라 만들어낼 수 있게 해두는 것 — 이게 지식 기반 시스템의 본질이다. 사실 사람의 언어도 똑같이 작동한다(단어 + 문법 + 상황 → 새 문장 합성).

07트리거와 추론의 작동 원리#

TL;DR

판단은 if-else 조건문이 아니라 포워드 체이닝으로 일어난다. 새 사실이 들어오면 패턴 매칭으로 룰이 자동 발화하고, 그 결과 또 새 사실이 도출되며 연쇄된다. 이건 기호적 추론의 일종이며, 신경망 추론과는 다른 가치(설명·보장·감사)를 가진다.

포워드 체이닝 — 트리거가 판단을 내리는 메커니즘

  1. 새 사실이 들어옴. 예: Drone-7이 (37.1, 127.4)에서 person을 봤다.
  2. 룰 엔진이 패턴 매칭을 돈다. "지금 이 새 사실 때문에 조건이 충족되는 룰이 있나?"
  3. 조건 충족된 룰 → 새 사실 도출. 예: Person AND inDisasterArea AND consciousness=impaired → SearchTarget이 충족 → "그 person은 사실 SearchTarget이다."
  4. 그 새 사실이 또 다른 룰을 트리거. 예: SearchTarget 발견 → 인근 드론을 RescueMode로 전환.
  5. 더 트리거될 룰이 없을 때까지 연쇄.

if-else와 결정적으로 다른 점 — 선언적 vs 명령적

코드 if문 (명령적)

"이 조건이 오면 이걸 해라" — 호출 순서를 프로그래머가 짠다. 새 규칙 추가 시 호출 흐름을 다시 손봐야 함.

룰 (선언적)

"이게 참이면 저것도 참이다" — 사실관계만 선언. 호출 순서는 엔진이 알아서. 새 룰을 끼워넣어도 기존 흐름은 안 깨짐.

두 가지 추론 — "이게 진짜 추론인가" 논쟁의 답

부류본질예시
기호적 추론형식 규칙으로부터의 연역TypeDB, Prolog, OWL 추론기
통계적 추론확률 분포로부터의 추정신경망, 베이지안 모델

TypeDB의 룰 엔진이 하는 건 명백히 첫 번째 의미의 추론이다. 1960년대부터 "automated reasoning"이라는 학문이 정확히 이걸 다뤘다. 다만 신경망 추론과 비교하면 단순하다 — 학습 안 하고, 확률도 못 다루고, 결정론적이다. 하지만 그건 단점이 아니라 의도된 특성이다.

신경망 추론

유연하지만 설명 못 함, 보장 못 함, 감사 못 함.

기호적 추론

경직되지만 설명 가능, 보장 가능, 감사 가능.

드론 시스템의 분업 — 두 추론이 같이 일한다

[지각층 - 통계적 추론]
  카메라 픽셀 → 신경망 → "사람 (확률 0.87)"
  * 학습 기반, 적응적, 모호함 잘 다룸
  * 단점: 왜 그렇게 봤는지 못 설명

       ↓ "사람이다" 라는 단언만 넘어옴

[판단층 - 기호적 추론]  ← TypeDB가 이 층
  "사람이다" + 위치 + 임무 정보
  → 룰 엔진이 자동으로 SearchTarget 도출
  → 다른 룰이 RescueMode 전환 도출
  → ...
  * 결정론적, 설명 가능, 감사 가능
  * 단점: 사람이 룰을 미리 박아둬야 함

지각은 신경망에게, 판단은 룰 엔진에게. 이 분업이 지금 드론·자율차·로봇 분야의 정통 아키텍처가 되어가고 있다.

08온톨로지의 5가지 진짜 기여#

TL;DR

룰 기반 시스템은 1960년대부터 있었다. "룰 엔진의 일"과 "온톨로지의 일"을 분리해야 진짜 가치가 보인다. 온톨로지가 진짜로 추가하는 건 다음 다섯 가지에서뿐이다.

예: 분류 계층 자동 상속(서브섬션)

ProtectedEntity LivingBeing 룰: 회피 1등급 Person Survivor Pedestrian Humanoid "룰: 회피 1등급"이 LivingBeing에 한 번만 적혀도 아래 모든 하위 클래스에 자동 적용된다

상위에 한 번 적은 룰이 하위 모두에 자동 상속 — 이게 룰 엔진은 못 하고 온톨로지만 할 수 있는 것

#기여설명
1 분류 계층 룰 자동 확장 Person ⊂ LivingBeing이라 적어두면, "LivingBeing은 충돌회피 1등급" 룰 한 개가 자동으로 Person·Animal·Robot 모두에 적용됨. 흔히 서브섬션(subsumption)이라 부름.
2 어휘 간 동등성 선언 fire sameAs ignition source 같은 선언으로 다른 단어가 같은 개념임을 표현. 룰 엔진은 자동으로 못 함.
3 조직 경계 넘는 표준 어휘 DJI·삼성·육군이 같은 사전을 공유. 사회적·정치적 측면. 한 회사 내부 룰 엔진은 못 가짐.
4 열린 세계 가정 룰 엔진/DB는 "기록에 없으면 거짓"으로 처리. 온톨로지는 "기록에 없으면 모름"으로 처리. 정보가 항상 부분적인 드론 환경에서 결정적.
5 타입 자체에 대한 추론 "X는 Y의 하위 종류인가?" "이 두 타입은 동등한가?" 같은 *타입에 대한 질의*가 가능.
정직한 테스트 "이 다섯 중 하나라도 빼면 시스템이 다르게 동작하는가?" — 빼도 같으면 그건 온톨로지가 아니라 룰 엔진이다. 빼면 동작이 바뀌면 그제서야 온톨로지가 진짜로 일하고 있는 것.

업계의 부끄러운 진실: "온톨로지 기반"이라 마케팅하는 시스템의 상당수가 실제로는 위 다섯 중 어느 것도 안 쓰고 그냥 룰 엔진 + 클래스 다이어그램으로 굴러간다. 그러면 그건 잘 정리된 객체지향 코드이지 온톨로지가 아니다.

09실전 예제 — 산불 예방 시스템#

TL;DR

가중치는 수치 층에서 점수를 만들고, 임계치는 그 점수를 기호 사실로 변환하고, 그 사실이 들어오는 순간 미리 박아둔 룰들이 시나리오를 합성한다. 사람은 가중치·룰·시나리오 골격만 미리 박고, 작동은 엔진이 한다.

전체 아키텍처

[수치 층 - 통계적]            [기호 층 - 온톨로지/룰]

센서 데이터                          타입 정의 (Region, Risk, Scenario...)
   ↓                                + 룰들 (R-PREV-01 ~ R-PREV-N)
가중치 함수                          + 시나리오 골격 (Stage1~Stage4)
   ↓
위험 점수 (0~100)
   ↓
임계치 검사 ─────트리거────→  RiskAssessment(Critical) 사실 삽입
                                         ↓
                                   룰 R-PREV-01 발화
                                         ↓
                                   PreventionScenario 인스턴스 생성
                                         ↓
                                   단계별 룰들이 자동 연쇄

세팅 7단계

1단계 — 온톨로지에 타입 박기

Region          // 위험 평가 단위 영역
  속성: name, polygon, historicalFireFreq

WeatherSnapshot
  속성: temperature, humidity, windSpeed, rainfall24h, capturedAt

VegetationStatus
  속성: dryness(0-100), lastBurnYear, dominantSpecies

RiskAssessment
  속성: assessedRegion, computedScore, riskLevel, computedAt
  관계: basedOn → WeatherSnapshot, VegetationStatus

RiskLevel = enum { Safe, Caution, Alert, Critical }

PreventionScenario
  속성: triggeredBy → RiskAssessment, currentStage, startedAt
  관계: assignedAssets → DroneAsset[]

DroneAsset
  속성: type, status, batteryLevel, currentLocation
  타입계층: SurveillanceDrone ⊂ DroneAsset
            ThermalDrone ⊂ SurveillanceDrone
            DeliveryDrone ⊂ DroneAsset

하이라이트된 계층 정의가 온톨로지의 (1) 분류 계층 기여를 활용하는 지점이다. 룰을 SurveillanceDrone에 적용하면 자동으로 ThermalDrone에도 적용됨.

2단계 — 가중치 함수 박기 (수치 층)

function calculateRiskScore(region) -> double:
  w := latest WeatherSnapshot for region
  v := latest VegetationStatus for region

  base :=
    normalize(w.temperature, 0, 40)     * 0.20 +
    (100 - w.humidity)                   * 0.25 +
    normalize(w.windSpeed, 0, 30)        * 0.20 +
    v.dryness                            * 0.25 +
    region.historicalFireFreq            * 0.10

  // 최근 강수 보정
  if w.rainfall24h > 5: base := base * 0.5

  return clamp(base, 0, 100)

가중치는 소방청·기상청·산림청 도메인 전문가 합의값. 처음에는 합의로 시작, 점점 데이터로 재조정.

3단계 — 임계치 검사 (수치 → 기호 접합부)

function evaluateRegion(region):
  score := calculateRiskScore(region)

  level :=
    if score >= 80: Critical
    elif score >= 60: Alert
    elif score >= 40: Caution
    else:            Safe

  // ★ 핵심: 점수를 기호 사실로 변환해서 DB에 삽입
  insert RiskAssessment {
    assessedRegion: region,
    computedScore:  score,
    riskLevel:      level,
    computedAt:     now()
  }

이 단 한 줄(insert)이 두 층의 접합부다. 수치 층에서 만든 점수가 여기서 기호 사실로 변환되어 기호 층을 깨운다.

4단계 — 트리거 룰 박기

RULE R-PREV-01: Critical 위험에 시나리오가 없으면 시작
  WHEN
    $a isa RiskAssessment, $a.riskLevel = Critical
    NOT EXISTS $s isa PreventionScenario where
      $s.triggeredBy.assessedRegion = $a.assessedRegion
      AND $s.status = Active
  THEN
    insert PreventionScenario {
      triggeredBy:  $a,
      currentStage: "Stage1_Survey",
      startedAt:    now(),
      status:       Active
    }

새 RiskAssessment가 삽입되는 순간 엔진이 패턴 매칭으로 이 룰을 발화시킴. NOT EXISTS 절이 같은 영역에 시나리오 중복 생성을 막음.

5단계 — 시나리오 골격 박기

SCENARIO: ForestFirePrevention

  Stage1_Survey:
    필요 자원: SurveillanceDrone × 2
    행동:       위험 영역 격자 스캔
    완료 조건:  surveyResult ∈ {clean, hotspot_found}
    제한 시간:  30분

  Stage2_HotspotInvestigation:
    필요 자원: ThermalDrone × 1, SurveillanceDrone × 1
    행동:       의심 지점 정밀 열화상 확인
    완료 조건:  investigationResult ∈ {false_alarm, prefire, ignition}
    제한 시간:  15분

  Stage3_PreventiveAlert:
    행동:       본부 알림, 등산로 출입 통제 권고, 소방 헬기 대기 요청

  Stage4_HandoffToSuppression:
    행동:       FireResponseScenario로 시나리오 핸드오프

6단계 — 단계 전이 룰 (작은 룰들의 조합)

RULE R-PREV-02: Stage1 결과 깨끗 → 시나리오 정상 종료
  WHEN  $s.currentStage = "Stage1_Survey"
        $s.surveyResult = "clean"
  THEN  update $s.status = Closed_AllClear

RULE R-PREV-03: Stage1에서 hotspot 발견 → Stage2 전이
  WHEN  $s.currentStage = "Stage1_Survey"
        $s.surveyResult = "hotspot_found"
  THEN  update $s.currentStage = "Stage2_HotspotInvestigation"

RULE R-PREV-04: Stage2 prefire 판정 → Stage3
  WHEN  $s.currentStage = "Stage2_HotspotInvestigation"
        $s.investigationResult = "prefire"
  THEN  update $s.currentStage = "Stage3_PreventiveAlert"

RULE R-PREV-05: Stage2 실제 발화 → Stage4 핸드오프
  WHEN  $s.currentStage = "Stage2_HotspotInvestigation"
        $s.investigationResult = "ignition"
  THEN  update $s.currentStage = "Stage4_HandoffToSuppression"
        insert FireResponseScenario { handedOffFrom: $s, ... }

RULE R-PREV-06: 자원 부족 → 인근 영역에 지원 요청
  WHEN  $s isa PreventionScenario
        available_drones($s.stage.requiredAssets) < required_count
  THEN  invoke RequestSupport($s, neighbor_regions($s.region))

7단계 — 한 사이클 슬로우모션

15:00:00  센서 갱신 → WeatherSnapshot, VegetationStatus 사실 삽입
          (기온 33도, 습도 22%, 풍속 18m/s, 식생 건조도 88, 강우 0)

15:00:05  evaluateRegion(강원-A) 실행
          → calculateRiskScore = 84.6RiskAssessment(Critical) 삽입

15:00:05  ★ 룰 엔진이 새 사실을 감지하고 R-PREV-01 발화
          → PreventionScenario(Stage1_Survey) 인스턴스 생성

15:00:06  Stage1 정의를 보고 자원 매칭 시도
          → 가용 SurveillanceDrone 2대 배정
          → 드론들에게 격자 스캔 임무 송신

15:23:42  드론 한 대가 의심 지점 보고
          → surveyResult = "hotspot_found" 사실 삽입
          → ★ R-PREV-03 발화 → currentStage = Stage2

15:23:43  Stage2 정의 보고 ThermalDrone 호출, 정밀 확인 시작

15:31:08  열화상 분석 결과 → investigationResult = "prefire"
          → ★ R-PREV-04 발화 → currentStage = Stage3
          → 본부 알림, 등산로 출입 통제 권고, 소방헬기 대기 요청

15:35:12  investigationResult 업데이트 = "ignition"
          → ★ R-PREV-05 발화 → Stage4 → FireResponseScenario 핸드오프
          → 산불 *예방* 시나리오에서 산불 *대응* 시나리오로 전환

전체 사이클에 사람이 한 번도 개입하지 않는다. 가중치도 룰도 시나리오 골격도 미리 박혔고, 시스템은 사실들을 받아 합성할 뿐이다.

10두 층 아키텍처 정리#

수치 층 · NUMERICAL
센서 입력 (날씨·식생·인적 활동)
가중치 함수
위험 점수 (0~100)
임계치 검사 (≥ 80?)
insert
★ 단 한 줄
숫자 → 기호
기호 층 · SYMBOLIC
RiskAssessment(Critical) 사실 삽입
룰 R-PREV-01 자동 발화
PreventionScenario 인스턴스 생성
단계별 룰 자동 연쇄
담당작동 방식
수치 층 위험 *측정* 가중치 함수가 점수 계산. 임계치로 잘라 사실로 변환.
기호 층 위험 *대응* 사실이 들어오면 룰 연쇄 발화. 시나리오 합성.
접합부 insert 한 줄 숫자 → 기호 변환의 단 한 지점.

이 분업의 우아함

  • 가중치를 ML 모델로 바꿀 때 — 수치 층만 갈아끼우면 끝. 기호 층은 한 줄도 안 건드림. "점수 → Critical 사실"이라는 인터페이스만 지키면 됨.
  • 시나리오를 바꿀 때 — 룰만 건드리고 가중치는 안 건드림.
  • 두 층이 분리되어 있어 각자 진화 가능. 신경망 분류기는 데이터 학습으로, 룰은 도메인 전문가 합의로 — 서로 다른 시계로 발전한다.

지각은 신경망에게, 판단은 룰 엔진에게. 둘이 한 줄(insert)로 연결될 때 시스템 전체가 살아난다.

11용어집#

온톨로지(Ontology)한 도메인의 개념과 관계를 형식화한 공유 사전. 단어들의 정의 + 단어 간 관계까지 함께 적힌 구조.
추론기(Reasoner)온톨로지를 읽고 새 사실을 도출하는 프로그램. Pellet, HermiT, FaCT++ 등.
포워드 체이닝(Forward chaining)새 사실 → 룰 매칭 → 새 사실 → ... 의 자동 연쇄. 트리거 메커니즘의 정통 방식.
룰 엔진선언적 if-then 규칙을 실행하는 시스템. Drools, CLIPS, Jess 등. 1960년대부터 존재.
서브섬션(Subsumption)상위 클래스의 룰이 하위 클래스에 자동 적용되는 것. 온톨로지의 핵심 기여 중 하나.
열린 세계 가정 (Open World Assumption)기록에 없으면 거짓이 아니라 "모름"으로 처리. 정보가 항상 부분적인 환경에서 결정적.
닫힌 세계 가정 (Closed World Assumption)기록에 없으면 거짓으로 처리. 일반적인 RDB와 룰 엔진의 기본 가정.
RDF / OWL / SPARQL웹 표준 기반 온톨로지 기술 스택. RDF는 데이터 모델, OWL은 온톨로지 언어, SPARQL은 질의 언어.
TypeDB타입 시스템 + 온톨로지 + 추론을 통합한 데이터베이스. OWL/RDF가 아닌 자체 타입 이론(PERA) 사용.
시나리오 골격순서가 본질적인 절차의 명시적 구조. 단계 전이가 의미를 가지는 경우에만 사용.
두 층 아키텍처지각층(통계적, 신경망)과 판단층(기호적, 룰 엔진)이 분업하는 현대 자율 시스템의 정통 구조.

— 끝 —

← 본문 에세이로 돌아가기