dev.to

The Answer You Didn't Want: Fiskardo Evacuation Routing

원하지 않던 답: Fiskardo 대피 경로를 둘러싼 여섯 번의 디버깅

그리스 Kefalonia 섬의 디지털 트윈 프로젝트 ARGOS에서 산불 시 Fiskardo 마을의 도로 대피 시간을 pgRouting으로 계산하던 중 발견한 여섯 가지 오류를 해부한 기록입니다. 실행되는 쿼리가 옳은 쿼리는 아니라는 교훈과 함께, 검증을 거친 불편한 숫자가 데모용으로 예쁜 숫자보다 가치 있다는 메시지를 전합니다.

본문

산불이 났을 때 Fiskardo 주민을 도로로 대피시키는 데 얼마나 걸리는가. 이 질문은 겉보기에는 단순한 데이터베이스 쿼리입니다. 도로 네트워크를 불러오고 출발점을 고른 뒤 pgRouting의 pgr_dijkstra를 실행해 비용을 읽으면 됩니다. 계산 시간은 밀리초 단위이고 결과는 숫자 하나입니다. 그런데 디지털 트윈이 처음 내놓은 숫자는 말이 되지 않았고, 저자는 모델을 의심했습니다. 그 직감은 맞았지만 이유가 달랐습니다. 모델은 거짓말을 하지 않았고, 데이터가 다섯 가지 방식으로 틀렸으며 여섯 번째 문제는 저자 자신이었습니다.

죽은 테이블, 분(minute)을 미터로 읽은 컬럼, 두 개의 좌표계

첫 번째 오류는 라우팅 쿼리가 깨끗하게 실행되고 그럴듯한 경로를 반환했지만, 실제로는 이전 반복 작업에서 남은 오래된 import 테이블을 읽고 있었다는 점입니다. 지오메트리는 Kefalonia처럼 보였지만 연결성(connectivity)은 엉망인, 사실상 유령 네트워크였습니다. 저자는 이를 두고 지리공간 디버깅의 첫 번째 교훈이라 부릅니다. 실행되는 쿼리가 옳은 쿼리는 아니라는 것입니다. 살아있는 도로 네트워크는 다른 테이블에 있었고, 버그라기보다는 발굴 작업에 가까운 문제였지만 첫 쿼리가 '증명'한 모든 것은 노이즈였습니다.

두 번째 오류는 라우팅 테이블의 비용 컬럼이 cost_m이라는 이름이었는데, 저자는 미터(meter)라고 추정했으나 실제로는 분(minute)이었다는 점입니다. pgRouting 자체는 cost와 agg_cost를 반환하며, 오해를 부른 이름은 자체 파이프라인의 것이었습니다. 지금까지 보고한 모든 거리가 사실은 이동 시간이었던 셈입니다. 이런 오류는 크래시를 일으키지 않고, 누군가 스키마를 의심의 눈으로 읽을 때까지 모든 결론을 조용히 오염시킵니다. 세 번째 오류는 파이프라인 어딘가에 두 개의 투영(projection)이 섞여 들어가 서로 다른 공간 참조 체계(SRS)의 지오메트리를 함께 측정하고 있었다는 점입니다. 거리가 조용히, 일관되게 틀어졌고, 저자는 좌표계가 두 개인 디지털 트윈은 트윈이 아니라 다투는 두 장의 지도라고 표현합니다.

순서가 섞인 결과 행, 그리고 데이터 공백으로 보이는 우회로

네 번째 문제는 pgr_dijkstra가 반환하는 경로 세그먼트의 순서였습니다. 결과가 뒤섞여 보였고 경로가 자기 자신에게 되돌아가는 것처럼 보였는데, 이 버그는 저자의 것이었습니다. 데이터베이스가 반환한 순서대로 행을 읽은 것이지 seq로 정렬하지 않았기 때문입니다. 경로는 처음부터 올바랐고, 문장을 섞인 순서로 한 단어씩 읽으며 괴상하다고 부른 셈이었습니다.

이후 답은 안정됐지만 여전히 어떤 쿼리로도 탐지할 수 없는 방식으로 틀렸습니다. 경로가 15km의 해안 도로를 무시하고 내륙으로 29km를 크게 우회했기 때문입니다. 용의자는 Evreti 구간의 연결성 공백, 즉 제대로 스냅되지 않은 노드로 추정되며 속성 쿼리로는 보이지 않습니다. 도로 데이터는 깨끗해 보이고 지역 지식으로는 도로가 멀쩡한데 라우터는 29km 우회를 선호합니다. 소프트웨어 버그의 옷을 입은 데이터 공백일 가능성이 크며, 저자는 이 부검은 아직 진행 중이라고 밝힙니다.

44분이라는 불편한 숫자와 폭격당한 등대

여섯 번의 검증을 거쳐 트윈이 내놓은 답은 Agia Effimia Marina까지 29.0km, 44분, 116개 도로 세그먼트였습니다. 연기를 보며 Fiskardo에 서 있는 사람에게 44분은 편안한 숫자가 아니며, 이것이 '원하지 않던 답'입니다. 매 라운드마다 더 빠르고 짧은, 데모에서 보기 좋은 틀린 답이 있었지만 저자는 그것을 택하지 않았습니다. 이 디지털 트윈의 가치는 답을 내놓는 데 있는 것이 아니라, 저자가 여섯 번에 걸쳐 깨뜨리려 했는데도 살아남은 답이라는 데 있습니다.

같은 엔진에 다른 질문을 했을 때는 무인도의 폐등대가 소방서에서 108.1분으로 섬 전체에서 가장 도달하기 어려운 장소로 꼽힌 적도 있습니다. 이 등대는 1942년 이탈리아 폭격으로 무너졌고 잔해는 1950년 지진으로 사라졌습니다. 기술적으로는 정확하지만 맥락상 무의미한 결과입니다. 두 이야기를 합치면 설계 원칙이 나옵니다. 트윈은 엣지 케이스를 찾고 도달 가능성을 정직하게 보고하며, 인간이 맥락과 우선순위를 제공한다는 것입니다. 폭격당한 등대와 병원이 같은 접근성 점수를 받는 것은 모델의 결함이 아니라, 어떤 결정을 대신할 수 없는지 모델이 정확히 보여주는 것입니다.

대피 계획은 숫자 위에서 돌아갑니다. 죽은 테이블과 분을 미터로 읽는 컬럼, 미해결 해안 우회가 있는 검증되지 않은 모델에서 나온 숫자라면 그 계획은 지도가 붙은 소문에 불과합니다. 검증된 불편한 숫자가 지어낸 편안한 숫자보다 가치 있으며, 이것이 '블랙박스 금지'의 실제 의미라고 저자는 말합니다. ARGOS의 모든 모델은 무엇을 어떤 사건에 대해 검증했고 무엇이 되고 안 됐는지를 함께 담고 있으며, 방법론과 코드, 그 과정에서 나온 모든 틀린 답까지 github.com/argos-geo/kefalonia-digital-twin에 공개돼 있습니다.

원문: dev.to / 번역·요약: Trawling