PATOS v4.4 · 전라남도 화재 취약지역 분석 · 2026-05-01
jeonnam_sample.json → poc_jeonnam.py → poc_judgment.py → Claude Code
(22개 시군 데이터) (L1·L2·L3) (컨텍스트 조립) (AI 판단 L4)
↓
jeonnam_fire.html ← build_map_html.py ← judgment_result.json
(정적 SPA 출력) (HTML 빌더)
patos/ ├── poc_jeonnam.py # Layer 1+2+3: 온톨로지 스키마·취약도 산출·컨텍스트 조립 ├── poc_judgment.py # Layer 4 준비: 판단 프롬프트 생성 ├── build_map_html.py # 정적 HTML SPA 빌더 ├── jeonnam_fire.html # 최종 출력물 (서버 없이 브라우저에서 실행) ├── data/ │ ├── jeonnam_sample.json # 전라남도 22개 시군 샘플 데이터 │ └── jeonnam_enriched.json # GeoJSON + 취약도 병합 (Leaflet 지도용) └── judgment_prompt.txt # poc_judgment.py 실행 시 생성되는 Claude 요청 파일
| 컴포넌트 | 언어 | 책임 |
|---|---|---|
| poc_jeonnam.py | Python 3.11 | TypeQL 스키마 + 취약도 산출 + 컨텍스트 조립 (Layer 1·2·3) |
| poc_judgment.py | Python | 상위 N개 지역 컨텍스트 조립 → judgment_prompt.txt 생성 (Layer 4 준비) |
| build_map_html.py | Python | 모든 뷰 HTML 조립 → jeonnam_fire.html 단일 파일 생성 |
| jeonnam_sample.json | JSON | 전라남도 22개 시군 — 노후건물·출동시간·소방서·기상·인접정보 |
| jeonnam_fire.html | HTML/JS | Leaflet 지도 + 다중 뷰 패널 SPA — 서버 없이 로컬 실행 |
취약도 = 노후건물(0.30) × n_old
+ 출동시간(0.30) × n_resp
+ 화재밀도(0.15) × n_fire ← fire_count_5y / area_km2
+ 도서지역(0.15) × island_yn
+ 산림인접(0.10) × forest_yn
각 연속값은 min-max 정규화 → 22개 시군 상대 비교
결과: 신안군 0.751 · 완도군 0.711 · 진도군 0.703 순
| 영역 | 기술 | 버전 | 비고 |
|---|---|---|---|
| 스크립트 런타임 | Python 3.11 | 표준 라이브러리만 사용 (json, os, datetime) | |
| 온톨로지 (개념) | TypeQL 스키마 | Python 문자열 정의 — 실제 TypeDB 서버 미연결 | |
| AI 판단 엔진 | Claude Code | claude-sonnet-4-6, 터미널 직접 요청 | |
| 프론트엔드 | Vanilla JavaScript | ES2020+, 프레임워크 없음 | |
| CSS | Tailwind CSS CDN | 반응형 유틸리티 클래스 | |
| 지도 | Leaflet.js 1.9.4 | CartoDB Light 타일, GeoJSON 폴리곤 |
| 항목 | 현재 상태 | 서비스화 시 필요 |
|---|---|---|
| 데이터 | 공공데이터 기반 추정치 (POC) | 행정안전부·소방청 실시간 API 연동 |
| TypeDB 온톨로지 | Python 문자열 개념 설계 | 실제 TypeDB 서버 배포 + TypeQL 실행 |
| AI 판단 | 수동 프롬프트 붙여넣기 | Claude API 자동 호출 + 결과 저장 자동화 |
| 배포 | 정적 HTML (서버 불필요) | 클라우드 서버 + 실시간 데이터 파이프라인 |
시맨틱 (TypeDB 온톨로지) Layer 1
└─▶ 키네틱 (취약도·커버리지 산출) Layer 2
└─▶ 다이나믹 (컨텍스트 조립) Layer 3
└─▶ 판단 (Claude Code) Layer 4 ← NEW
└─▶ 대응 프로토콜 생성
판단 결과 (지역별): 위험_등급 CRITICAL|HIGH|MEDIUM|LOW 상황_요약 2~3문장 상황 분석 온톨로지_추론 발동된 TypeDB 규칙 목록 트리아지_결정 우선순위 근거 + 자원 배분 대응_프로토콜 즉시 조치 + 에스컬레이션 선제_경보_지역 인접 위험 지역 목록 추론_체인 규칙→컨텍스트→판단 설명 신뢰도 0.0 ~ 1.0
PATOS v4.4 · Data Architecture · 2026-04-24
┌──────────────────────────────────────────────────────────────┐
│ 데이터 소스 (POC 샘플) │
│ 건축물대장(국토부) 소방청 출동통계 기상청 API (추정) │
│ → old_building_ratio → avg_response_min → weather_current│
└──────────────────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ jeonnam_sample.json (22개 시군 통합) │
│ regions[] fire_stations[] adjacency[] weather_current{} │
└──────────────────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ poc_jeonnam.py (Layer 1·2·3) │
│ load_data() → calc_vulnerability() → build_fire_context() │
└────────────┬─────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────┐
│ poc_judgment.py → judgment_prompt.txt → Claude Code │
│ → judgment_result.json │
└──────────────────────────────┬───────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────┐
│ build_map_html.py → jeonnam_fire.html (정적 SPA) │
└──────────────────────────────────────────────────────────────┘
region
├─ region-id (string, @key)
├─ region-name (string)
├─ old-bldg-ratio (double)
├─ fire-count-5y (long)
├─ avg-response (double, 분)
├─ island-yn (boolean)
├─ forest-yn (boolean)
└─ vuln-score (double) ← 산출값
fire-station
├─ station-id (string, @key)
├─ station-name (string)
└─ truck-count (long)
fire-event
├─ event-id (string, @key)
├─ call-content (string)
└─ severity (string)
jurisdiction (station: fire-station) ↔ (area: region) adjacency (neighbor: region) ↔ (neighbor: region)
# 인접 지원 탐색 (TypeQL 규칙)
rule reachable-by-neighbor:
when { (station: $s, area: $a) isa jurisdiction;
(neighbor: $a, neighbor: $b) isa adjacency; }
then { (station: $s, area: $b) isa jurisdiction; };
# 판단 프롬프트에서 Claude Code가 적용하는 추론 규칙
rule physical-isolation-by-island:
도서지역($r, true) → 물리적 고립 위험 가중
rule coverage-gap:
avg-response($r) >= 20min AND truck-count($s) <= 2
→ 커버리지 갭 경보
rule forest-adjacency-risk:
forest-yn($r, true) AND wind-speed >= 6m/s
→ 확산 위험 가중
rule jurisdiction-conflict:
(station: $s1, area: $r) AND (station: $s2, area: $r) AND $s1 != $s2
→ 이중 관할 → 자원 분산 위험
| 자재 | 확산속도 | 열방출률 | 유독가스 | 플래시오버 | 구조붕괴계수 |
|---|---|---|---|---|---|
| 비닐하우스 | 15.0 m²/min | 8,500 kW | O (PVC) | 2.0분 | 0.60 |
| 샌드위치 패널 | 8.0 m²/min | 6,000 kW | O (HCN·CO) | 3.5분 | 0.70 |
| 경량 목구조 | 6.0 m²/min | 4,000 kW | X | 5.0분 | 0.80 |
| 슬레이트+조적 | 3.0 m²/min | 2,500 kW | O (석면) | 8.0분 | 0.85 |
| 조적조 | 1.5 m²/min | 1,500 kW | X | 12.0분 | 0.90 |
| 철근콘크리트 | 0.5 m²/min | 800 kW | X | 25.0분 | 0.95 |
fire_risk_index = 건조도(0~40) + 풍속(0~40) + 기온(0~20) 건조도 = max(0, (30 - humidity) / 30) × 40 풍속 = min(wind_ms / 15, 1.0) × 40 기온 = max(0, (temp_c - 10) / 25) × 20
| 데이터 | 신뢰도 | 갱신 주기 | 비고 |
|---|---|---|---|
| 노후건물비율 | 추정치 | POC 샘플 | 건축물대장(국토부) 실제 연동 시 정확도 향상 |
| 평균출동시간 | 추정치 | POC 샘플 | 소방청 출동통계 실제 연동 필요 |
| 기상 데이터 | 고정값 | 2026-05-01 기준 | 기상청 실시간 API 연동 시 자동 갱신 |
| 소방서 자원 | 추정치 | POC 샘플 | 소방청 공개 데이터 기반, 실제 운용 현황 반영 필요 |
[생성] [처리] [소비] [갱신]
jeonnam_sample.json → poc_jeonnam.py → jeonnam_fire.html 수동 업데이트
(취약도 산출·컨텍스트) (정적 SPA 뷰) (공공데이터 API
→ poc_judgment.py 연동 시 자동화)
↓
judgment_prompt.txt → Claude Code → judgment_result.json
poc_jeonnam.py
├─ Layer 1: TypeQL 스키마 정의
├─ Layer 2: calc_vulnerability() → ranked[]
└─ Layer 3: build_fire_context() → context JSON
↓
poc_judgment.py
├─ 상위 N개 지역 컨텍스트 조립
└─ judgment_prompt.txt 생성
↓
Claude Code 터미널 ← 판단 엔진
├─ TypeDB 추론 규칙 적용 검토
├─ 트리아지 결정 (우선순위·자원 배분)
├─ 대응 프로토콜 생성
└─ 에스컬레이션 여부 판단
↓
judgment_result.json → AI 판단 엔진 뷰
{
"generated_at": "2026-05-01T10:00:00+09:00",
"model": "claude-sonnet-4-6",
"pipeline": "시맨틱 → 키네틱 → 다이나믹 → 판단",
"count": 5,
"results": [
{
"region_id": "JN-22",
"region_name": "신안군",
"vuln_score": 0.751,
"context": { ... }, // Layer 3 조립 결과
"judgment": {
"상황_요약": "...",
"위험_등급": "CRITICAL",
"온톨로지_추론_발동": [ { "규칙명": "...", "판단_영향": "..." } ],
"트리아지_결정": { "우선순위_근거": "...", "자원_배분": "..." },
"대응_프로토콜": { "즉시_조치": "...", "에스컬레이션_여부": true },
"선제_경보_지역": ["목포시"],
"추론_체인": "TypeDB 규칙 → 컨텍스트 해석 → 판단...",
"신뢰도": 0.96
}
}
]
}
전라남도 화재 취약지역 예측에서 시작해, 온톨로지 기반 AI 판단 엔진을 만들기까지. 왜 이 방식을 선택했고, 무엇을 만들었으며, 무엇이 아직 부족한지를 솔직하게 써봤습니다.
전라남도는 대한민국에서 가장 독특한 지형 조건을 가진 지역 중 하나입니다. 22개 시군 가운데 신안군·완도군·진도군은 섬으로 이루어져 있거나 반도 끝에 위치해 있고, 고흥군·해남군·보성군 등은 산림과 직접 맞닿아 있습니다. 도시 기준으로 생각하면 평범해 보이는 조건들이 이 지역에서는 전혀 다른 의미를 가집니다.
화재가 발생하고 소방차가 도착하는 데 31분이 걸린다면 어떻게 될까요. 일반적인 목조 단독주택은 화재 발생 후 5~10분이면 전소에 가까워집니다. 아파트나 콘크리트 건물은 그보다 느리지만, 노후 건물이 밀집한 농촌 마을에서는 불씨가 옆 건물로 옮겨붙는 데 그리 오랜 시간이 걸리지 않습니다. 31분이라는 출동시간은 단순한 지연이 아니라, 초기 진압 가능성 자체가 사라진다는 의미입니다.
여기에 바람이 더해지면 상황은 더 나빠집니다. 전라남도는 해안과 인접해 있어 풍속이 강한 날이 많습니다. 산림 인접 지역에서 화재가 나고 풍속이 6~8m/s 이상이면, 불이 산으로 번지는 속도는 사람이 걸어서 피하기 어려운 수준이 됩니다.
신안군의 경우, 관할 소방서가 목포에 있습니다. 해상 이동이 포함되기 때문에 평균 출동시간이 31.5분입니다. 날씨가 나쁘거나 야간이면 그 시간은 더 늘어납니다. 이건 소방 인력의 문제가 아닙니다. 지리적 구조의 문제입니다.
우리가 이 문제를 선택한 이유는 여기에 있습니다. 잘 보이는 위험이 아니라, 구조 속에 숨어 있는 위험을 미리 발견하고 대비할 수 있다면 실질적인 피해를 줄일 수 있다는 판단이었습니다. 그리고 그 '구조 속 위험'을 찾으려면 숫자만으로는 부족하다는 것도 이미 알고 있었습니다.
가장 먼저 한 건 취약도 점수를 만드는 것이었습니다. 노후건물 비율, 출동시간, 화재 발생 이력, 도서지역 여부, 산림 인접 여부. 다섯 가지 지표에 가중치를 곱해서 0에서 1 사이의 숫자로 정렬했습니다.
취약도 = 0.30 × 노후건물비율
+ 0.30 × 평균출동시간(정규화)
+ 0.15 × 화재밀도(5년/km²)
+ 0.15 × 도서지역여부(0 or 1)
+ 0.10 × 산림인접여부(0 or 1)
결과: 신안군 0.751 · 완도군 0.711 · 진도군 0.703
고흥군 0.533 · 해남군 0.523
이 점수는 분명 유용합니다. 어느 지역이 상대적으로 더 위험한지는 잘 보여줍니다. 하지만 이 숫자를 들고 "그럼 신안군에 자원을 더 배치하면 되겠네"라고 결론을 내리기엔 결정적으로 빠진 정보가 있습니다.
진도군(취약도 0.703)의 관할 소방서는 해남소방서입니다. 그런데 해남소방서는 해남군(취약도 0.523)도 동시에 담당합니다. 두 지역에 화재가 동시에 발생하면 차량 3대를 나눠야 합니다. 이 이중 관할 구조는 취약도 숫자 어디에도 나타나지 않습니다.
신안군의 출동시간 31.5분과 고흥군의 19.8분을 단순 비교하면 신안군이 더 위험해 보입니다. 하지만 신안군은 섬입니다. 31.5분 안에는 해상 이동 시간이 포함되어 있고, 기상 악화 시 이 시간은 예측 불가능하게 늘어납니다. 19.8분짜리 육지 출동과 31.5분짜리 해상 출동은 질적으로 다른 문제입니다.
고흥군은 취약도가 0.533으로 상위 5개 중 가장 낮습니다. 하지만 여수시 소방서가 8.2분 거리에 있고 차량이 충분합니다. 반면 진도군은 가장 가까운 인접 시군인 해남군도 이미 취약한 상태입니다. 이 차이가 실질적인 대응 능력의 차이인데, 점수만으로는 보이지 않습니다.
통계 모델은 개별 지표를 잘 처리하지만 관계와 구조를 이해하지 못합니다. 소방서가 어디를 담당하는지, 섬이라는 물리적 고립이 어떤 의미인지, 인접 지역이 지원 가능한지 여부. 이런 것들은 숫자 하나로 표현되지 않는 맥락입니다. 이 맥락을 담는 방법이 필요했고, 그게 온톨로지였습니다.
온톨로지(Ontology)는 원래 철학에서 온 단어입니다. "존재하는 것들의 체계와 구조"를 다루는 학문이죠. 컴퓨터 과학에서는 이 개념을 빌려와서, 특정 도메인에서 무엇이 존재하고 그것들이 어떤 관계를 맺는지를 형식적으로 정의하는 방법으로 씁니다.
일반 데이터베이스와의 차이를 구체적으로 보면 이렇습니다.
온톨로지의 진짜 힘은 추론 규칙(Inference Rule)에 있습니다. 관계들을 정의해두면, 명시적으로 입력하지 않아도 시스템이 스스로 새로운 사실을 도출합니다.
규칙: 도서지역(island_district = true)이면 물리적 고립 상태로 분류
효과: 신안군·완도군·진도군이 자동으로 "고립 지역"으로 추론됨. 출동시간이 같은 육지 지역과 질적으로 다른 판단을 받게 됨
규칙: 하나의 소방서가 2개 이상 지역을 관할하면 자원 분산 위험으로 분류
효과: 해남소방서가 해남군과 진도군을 모두 관할한다는 관계에서 자동 발동. 진도군의 구조적 취약점이 드러남
규칙: 인접 지역의 소방서도 지원 가능 소방서로 자동 탐색
효과: 고흥군 화재 시 여수시 소방 자원이 8.2분 내 지원 가능하다는 정보가 자동 조립됨. 데이터에 직접 입력하지 않아도 관계에서 도출
이것이 데이터베이스와 온톨로지의 핵심 차이입니다. 데이터베이스는 우리가 넣은 것만 알고 있습니다. 온톨로지는 관계와 규칙을 통해 우리가 직접 입력하지 않은 것도 추론합니다.
그런데 이 온톨로지 개념을 실제 기업 운영에 적용하는 방식으로 재해석한 회사가 있습니다. 팔란티어입니다. 다음 챕터에서 팔란티어가 온톨로지를 어떻게 다르게 봤는지, 그리고 PATOS가 그 방식에서 무엇을 배웠는지를 살펴봅니다.
앞 챕터에서 온톨로지가 관계와 규칙을 통해 추론한다는 개념을 살펴봤습니다. 그런데 이 개념을 학술적 도구에 머물지 않고, 기업이 실시간으로 운영되는 살아있는 레이어로 만든 회사가 있습니다. 팔란티어(Palantir)입니다.
팔란티어는 2003년 설립된 미국의 데이터 분석 플랫폼 기업입니다. 처음에는 CIA 등 정보기관 수요로 시작했지만, 지금은 Foundry라는 제품을 통해 제조·금융·헬스케어 등 민간 기업에도 플랫폼을 제공합니다. 팔란티어를 이해하는 핵심 키워드가 바로 Ontology as Operating Layer, 즉 운영 레이어로서의 온톨로지입니다. PATOS는 이 구조에서 영감을 받아 설계됐습니다.
기존 온톨로지(OWL, RDF)는 세계를 정확히 기술하기 위한 도구였습니다. 팔란티어는 이걸 뒤집었습니다. 온톨로지를 지식 표현 도구가 아니라, 기업이 실시간으로 운영되는 살아있는 레이어로 만든 것입니다.
팔란티어 Foundry의 온톨로지는 세 개의 레이어로 구성됩니다.
Object Types, Properties, Link Types를 정의합니다. "제품"이 무엇인지, "설비"가 무엇인지, 둘이 어떤 관계인지를 정의하는 단계입니다. 조직 전체가 공유하는 공통 언어를 만드는 과정입니다.
→ PATOS에서는: region, fire-station 엔티티와 jurisdiction, adjacency 관계 정의가 이 레이어입니다.
실제 데이터를 연결하고 비즈니스 로직을 담습니다. Actions(행위 정의), Functions(로직 캡슐화), Pipeline Builder(데이터 파이프라인)가 여기 속합니다. 온톨로지가 살아서 움직이기 시작하는 레이어입니다.
→ PATOS에서는: 취약도 산출 엔진(calc_vulnerability)과 컨텍스트 조립기(build_fire_context)가 이 레이어입니다.
AI가 온톨로지 위에서 판단하고, 그 판단이 Action으로 실행됩니다. 팔란티어의 AIP Logic이 여기 해당합니다. AI는 raw 데이터가 아니라 의미가 정의된 객체와 관계를 보고 추론하며, 결과는 온톨로지 상태를 업데이트하는 Action으로 이어집니다.
→ PATOS에서는: Claude Code가 TypeDB 규칙이 포함된 컨텍스트를 받아 판단을 내리는 것이 이 레이어입니다. 단, Action 루프는 아직 없습니다.
팔란티어 구조에서 가장 중요한 점은, AI가 온톨로지 없이는 작동하지 않는다는 겁니다. AI가 볼 수 있는 세계는 온톨로지가 정의한 범위 안에 있습니다. 이게 AI를 신뢰할 수 있게 만드는 구조적 장치입니다. AI가 틀려도, 온톨로지 규칙의 범위 안에서만 틀립니다.
PATOS는 팔란티어와 동일한 3레이어 구조를 따르되, 팔란티어의 독점 플랫폼 대신 TypeDB + Python + Claude Code 조합으로 구현했습니다. 도구는 달라도 아키텍처 철학은 같습니다.
define
region sub entity,
owns region-id, owns region-name,
owns old-bldg-ratio, owns avg-response,
owns island-yn, owns forest-yn,
plays jurisdiction:area,
plays adjacency:neighbor;
fire-station sub entity,
owns station-id, owns truck-count,
plays jurisdiction:station;
jurisdiction sub relation,
relates station, relates area;
adjacency sub relation,
relates neighbor;
22개 시군을 region 엔티티로, 18개 소방서를 fire-station으로 정의합니다. jurisdiction(관할)과 adjacency(인접) 관계를 통해 구조적 맥락을 담습니다.
WEIGHTS = {
"old_building" : 0.30,
"response_time": 0.30,
"fire_density" : 0.15,
"island" : 0.15,
"forest" : 0.10,
}
# 상위 5개 지역 컨텍스트 조립
for region in ranked[:5]:
context = build_fire_context(region, data)
# 기상·소방 자원·인접 지원 가능성 자동 포함
5개 지표로 취약도를 산출하고, 상위 5개 지역의 컨텍스트를 조립합니다. 인접 지역 소방 자원 탐색(reachable-by-neighbor 규칙)도 이 단계에서 자동으로 처리됩니다.
# judgment_prompt.txt 구성 요소 1. TypeDB 추론 규칙 5개 (참조 컨텍스트) 2. 에스컬레이션 기준 (취약도 0.6↑ + 차량 2대↓ + 도서/산림) 3. 5개 지역 조립된 컨텍스트 (기상/자원/인접) # Claude Code → 판단 출력 → 위험등급 · 추론_체인 · 에스컬레이션_여부 → judgment_result.json 저장
TypeDB 규칙을 프롬프트에 포함시켜 Claude Code가 규칙 기반으로 판단하게 합니다. 어떤 규칙이 발동됐는지, 왜 이 등급인지가 판단 결과에 함께 기록됩니다.
세 레이어가 조립되면 파이프라인이 됩니다.
python poc_judgment.py를 실행하는 순간
데이터 로드 → 취약도 산출 → 컨텍스트 조립 → Claude Code 판단 요청의
전체 흐름이 한 번에 실행됩니다.
결과는 judgment_result.json에 저장되고, 이 대시보드의 AI 판단 엔진 메뉴에서 볼 수 있습니다.
많은 AI 서비스가 "AI가 분석합니다"라고 말합니다. 하지만 어떤 맥락에서, 어떤 규칙을 근거로, 왜 그런 결론을 냈는지는 블랙박스입니다. 소방 대응 같은 공공안전 분야에서 설명할 수 없는 판단은 신뢰받을 수 없습니다.
PATOS는 이 문제를 온톨로지 규칙의 명시적 포함으로 해결합니다. Claude Code가 받는 판단 프롬프트 안에는 TypeDB 추론 규칙 5개가 그대로 적혀 있습니다. AI는 그 규칙들을 참조해서 판단을 내리고, 어떤 규칙이 발동됐는지를 판단 결과 안에 반드시 기록합니다.
취약도만 봤다면 진도군(0.703)은 완도군(0.711)보다 낮은 순위입니다. 하지만 온톨로지 추론을 거치면 진도군이 구조적으로 더 복잡하고 위험한 상황임을 알 수 있습니다. 이중 관할 문제는 어떤 통계 지표로도 표현되지 않는 관계적 정보입니다. 온톨로지가 없었다면 AI는 이걸 알 방법이 없었습니다.
이것이 온톨로지 기반 AI 판단의 핵심입니다. AI가 잘 추론하는 게 목표가 아닙니다. AI가 맞는 것을 보고 추론하게 만드는 것이 목표입니다. 온톨로지는 AI한테 세계를 보여주는 방식입니다.
현재 PATOS POC를 구성하는 것들을 정직하게 나열하면 이렇습니다.
POC를 만들면서 가장 신경 쓴 것이 솔직함이었습니다. 파이프라인이 돌아갔다고 해서 그게 곧 검증이 되는 건 아닙니다. 이 시스템이 말할 수 없는 것들을 정확히 짚어두는 게 오히려 더 중요합니다.
jeonnam_sample.json에 있는 전라남도 22개 시군의 데이터는 실제 소방청 통계가 아닙니다. 아키텍처 패턴을 검증하기 위해 직접 설계한 샘플 데이터입니다.
진도군의 이중 관할 문제는 우리가 데이터에 넣은 것입니다. 시스템이 실제 데이터에서 발견한 것이 아닙니다. 이것은 순환 논리입니다. 설계자가 데이터도 만들고 결과도 확인하면, 시스템이 발견한 것이 아니라 우리가 심어둔 것을 찾은 것입니다.
Python dict와 함수로 TypeDB의 구조와 추론 규칙을 시뮬레이션했습니다. 실제 TypeDB 추론 엔진이 graph traversal을 수행한 것이 아닙니다.
이 차이는 규모가 커질수록 드러납니다. Python dict로 22개 지역은 문제없지만, 수천 개 지역과 수만 개의 관계를 다루면 실제 그래프 DB 없이는 불가능합니다.
팔란티어 AIP의 핵심은 AI 판단이 → Action → 온톨로지 상태 변경 → 실제 시스템 반영으로 이어지는 Closed-loop입니다. PATOS는 AI 판단이 JSON 파일 저장에서 멈춥니다.
"진도군에 광역 지원 요청"이라는 판단이 나와도, 그 판단이 실제 소방 지휘 시스템에 전달되지 않습니다. 판단과 현실 사이의 연결이 아직 없습니다.
"이 아키텍처 패턴으로 실제 데이터를 연결하면, 순수 통계 모델이 놓치는 구조적 취약점을 AI가 포착할 수 있다는 가설을 세웠고, 합성 데이터로 파이프라인이 end-to-end로 작동함을 확인했습니다."
POC는 가설 검증의 출발점입니다. 제품이 됐다는 뜻이 아니라, 제품으로 만들 수 있다는 근거를 쌓은 것입니다.
팔란티어 수준의 범용 플랫폼을 만드는 건 현실적인 목표가 아닙니다. 팔란티어는 20년, 3,500명, 수조 원의 인프라 위에 서 있습니다. 하지만 팔란티어가 하는 방식으로, 특정 도메인의 특정 문제를 푸는 것은 가능합니다. 그리고 그게 오히려 더 의미 있는 목표일 수 있습니다.
PATOS의 다음 단계는 명확합니다. 우선순위 순으로 정리하면 이렇습니다.
소방청 공공데이터포털(NFDS), 행정안전부 건물 현황, 기상청 API를 연결합니다. 합성 데이터가 사라지면 그 순간부터 이 시스템은 실제를 다루기 시작합니다.
효과: 판단이 실제 상황을 반영. POC → 파일럿 격상. "이 아키텍처가 실제로 다른 결론을 낸다"는 것을 입증할 수 있음.
TypeDB Cloud 또는 로컬 서버를 구동하고, Python dict 시뮬레이션을 걷어냅니다. 실제 TypeQL 쿼리로 추론 규칙이 작동하는 것을 검증합니다.
효과: 온톨로지 추론이 진짜로 작동함을 증명. 관계 수가 늘어나도 성능이 유지되는지 확인.
Claude 판단 → 소방 자원 배치 API 호출 → 온톨로지 상태 업데이트로 연결합니다. 이 루프가 완성되면 PATOS는 팔란티어 AIP와 구조적으로 동일한 Closed-loop 시스템이 됩니다.
효과: "판단이 현장을 바꾼다"는 것이 실현됨. 시스템이 단순 분석 도구에서 운영 도구로 전환.
전라남도 화재에서 시작했지만, 아키텍처는 도메인에 무관합니다. 홍수 예측, 교통 사고, 의료 자원 배분 — 구조적 맥락이 중요한 어떤 도메인에도 동일한 패턴이 적용됩니다.
목표: 공공안전 도메인의 팔란티어.
GPTsquare 발표 자료 기반 요약 · 2025-10-31
┌─────────────────────────────────────────────────────────────────────┐ │ Palantir Foundry │ │ │ │ ① Data Connection — 외부 소스 연결 (MES/ERP/Kafka/S3/RDBMS) │ │ ② Pipeline Builder — 코드없이 ETL/ELT, LLM 변환, 스트리밍/배치 │ │ ③ Ontology Manager — Object·Link·Action·Function 정의 및 버전관리 │ │ ④ Object Explorer — 객체 중심 탐색 · 관계 시각화 │ │ ⑤ Workshop / Quiver — 앱 개발 · 고급 분석 · 대시보드 │ │ ⑥ AIP Logic — LLM 블록 + 온톨로지 Action 실행 │ │ │ │ 흐름: 데이터 → 파이프라인 → 온톨로지 → 앱/에이전트 → 액션 → 피드백 │ └─────────────────────────────────────────────────────────────────────┘
아키텍처 비교 · 현재 구현 수준 · 다음 단계
| Palantir Foundry | PATOS POC | 구현 상태 |
|---|---|---|
| Object Types + Link Types | TypeDB schema (region, fire-station, jurisdiction, adjacency) | 구현됨 |
| Functions (비즈니스 로직) | TypeDB 추론 규칙 5개 (isolation, coverage-gap, forest-risk 등) | 구현됨 |
| Pipeline Builder (컨텍스트 조립) | poc_jeonnam.py build_fire_context() | 구현됨 |
| AIP Logic (LLM 추론) | Claude Code 판단 (judgment_prompt.txt → judgment_result.json) | 구현됨 |
| Semantic · Kinetic · Dynamic 레이어 | PATOS 3레이어 파이프라인 (동일 명칭 사용) | 구현됨 |
| Workshop (대시보드) | jeonnam_fire.html (Leaflet 지도 + 판단 뷰) | 부분 구현 |
전통 온톨로지 한계 → Palantir 재해석 → Foundry 전 기능 → PATOS 연결
핵심 철학: "데이터는 연결될 때 비로소 가치가 생긴다" "The worst outcome: you have data but can't use it" 제품 진화: 2008 → Gotham (정부·군·정보기관) 2016 → Foundry (기업·공공기관) 2020 → NYSE 상장 (PLTR) 2023 → AIP (AI Platform)
┌─────────────────────────────────────────────────────────┐ │ 앱/대시보드 워크플로우 알고리즘 보고서 │ └──────────────────────────┬──────────────────────────────┘ ↕ 양방향 ┌──────────────────────────┴──────────────────────────────┐ │ Ontology — 의미/운영 레이어 │ │ Objects Links Actions Functions Interfaces │ └──────────────────────────┬──────────────────────────────┘ ↕ ┌──────────────────────────┴──────────────────────────────┐ │ 데이터 파이프라인 — ETL/ELT │ │ Data Connection Pipeline Builder Kafka │ └─────────────────────────────────────────────────────────┘ 소스: MES | EDA | Historian | ERP | S3 | RDBMS | MongoDB | Kafka Closed-loop: 데이터 → 인사이트 → 액션 → 데이터
| 출동 단계 | 평균(분) | 표준편차 | 분포 |
|---|---|---|---|
| 신고접수 | 0.8 | 0.2 | |
| 현장도착 | 31.5 | 8.3 | |
| 진압활동 | 18.6 | 5.4 | |
| 잔불정리 | 9.4 | 3.1 | |
| 지원요청대기 | 12.0 | 4.7 | |
| 귀소이동 | 14.5 | 3.8 |
| 차량번호 | 출동시간(분) | 가동률 |
|---|---|---|
| SNJ-T01 | 15,213 | 151% |
| WAN-T01 | 13,528 | 135% |
| JND-T01 | 13,103 | 130% |
| GHG-T01 | 12,901 | 128% |
| HNM-T01 | 12,863 | 128% |
| 레이어 | PATOS 현재 | Foundry 대응 | 상태 |
|---|---|---|---|
| Semantic (L1) | TypeQL 스키마 (개념 설계) | Ontology Manager — Object·Link·Property | 개념 완성 |
| Kinetic (L2) | 취약도 가중 평균 산출 | Functions — 실시간 비즈니스 로직 계산 | 구현 완료 |
| Dynamic (L3) | 컨텍스트 수동 조립 | Pipeline Builder — 자동 실시간 조립 | 구현 완료 |
| Judgment (L4) | Claude Code 수동 요청 | AIP Logic — AI가 온톨로지 함수 자동 호출 | 수동 단계 |
| Action (L5) | 미구현 | Action Types — 실제 자원 배치 명령 실행 | 미구현 |
| UI (L6) | 정적 HTML SPA + Leaflet | Workshop — 노코드 앱 빌더 + Quiver 분석 | POC 수준 |
소방본부·지자체 고객 대상 POC 발표 시 실제로 나온 질문들과 검증된 답변입니다. 4개 카테고리로 구성되어 있습니다.
핵심 문제: 전남 도서·산간 지역은 화재 시 평균 출동시간이 31.5분 — 서울(5분)의 6배입니다. 데이터는 있지만 "어디에 자원을 미리 배치할지" 판단을 못 하고 있습니다.
화재 직후 현장 판단은 사람이 더 빠릅니다. PATOS가 개입하는 시점은 다릅니다 — 화재가 나기 전입니다.
팔란티어는 플랫폼, PATOS는 도메인 솔루션입니다.
| 구분 | 팔란티어 | PATOS |
|---|---|---|
| 범위 | 범용 — 어느 산업에나 | 소방 특화 솔루션 |
| 역할 | 만들 수 있는 도구 | 이미 만들어진 제품 |
| 비용 | 연 수십억 원 | 지자체 예산 수준 |
| 데이터 주권 | 미국 기업 서버 | 국내 온프레미스 |
| 온보딩 | 수개월 구축 필요 | 데이터만 연결하면 시작 |
팔란티어 = 주방용품점 전체, PATOS = 소방본부용 레시피가 완성된 밀키트
단순 자동화로 시작해도 됩니다. 3~4개 핵심 규칙만으로도 즉시 사용 가능합니다. 단 세 가지 상황에서 한계가 옵니다.
POC는 단순하게 시작 → 한계가 보일 때 온톨로지를 얹는 방식을 권장
예측이 틀려도 손해가 없습니다. 비용 구조가 비대칭입니다.
PATOS는 화재 발생을 예측하지 않습니다. 예측하는 건 다릅니다.
전남소방본부 5년치 데이터 제공 시 역으로 모델 적용 → CRITICAL 판정 조건에서 실제 피해가 통계적으로 유의미하게 컸는지 수치 제시 가능
"예측이 틀리면 손해"라는 전제를 다시 봐야 합니다. 두 가지 손해의 크기가 다릅니다.
공통점: 전부 도시 지역. 도서·농촌 환경에서의 도입은 PATOS가 선도 사례 → POC가 그 검증 과정
국내 소방청 화재취약지역 시스템 존재 — 그러나 "어디가 위험하다" 표시만, "지금 뭘 해야 하는지" 판단 레이어 없음
POC 1단계는 실시간 없이 정적 데이터로 취약도 분석만 → 데이터 연동은 2단계에서 순차 확장 권장
구체적 비용은 데이터 연동 범위·온프레미스vs클라우드·유지보수 계약에 따라 다름 — POC 완료 후 산출
PATOS는 팔란티어에 종속되지 않습니다.
| 구분 | RDB (관계형 DB) | 온톨로지 |
|---|---|---|
| 저장 단위 | 행(Row) — 데이터 | 객체+관계 — 지식 |
| 질문 방식 | "이 테이블에 뭐가 있나?" | "이 개체는 다른 개체와 어떤 관계인가?" |
| 추론 | 없음 — 명시된 것만 | 규칙으로 새로운 사실 자동 추론 |
| 확장 | 스키마 변경 어려움 | 새 속성/관계 유연하게 추가 |
RDB는 "신안군 차량 2대"를 저장. 온톨로지는 "신안군 차량 2대 + 도서지역 + 목포소방서가 관할 + 오늘 목포 차량 출동 중 → 지원 불가"를 추론
새 데이터가 들어올 때마다 규칙이 자동 평가 → 신안군이 도서지역이고 차량 2대라는 사실만 있으면 physical_isolation이 자동으로 true가 됨
패러다임 전환 맞습니다. 단, 지금은 초입입니다.