Big Project · AI's EYE 15
ROI 설정, 왜 저장만으로는 안 될까요? 견고한 데이터 분석 시스템을 위한 라이프사이클
ROI 설정을 저장하면 화면의 선만 바뀌고 앞으로 들어오는 분석부터 적용될 것 같다. 왜 승인과 버전, 과거 좌표 재판정이 모두 필요한지 모호하다.
근거 · 프로젝트 문서 · 코드 · 테스트
1장: 저장한 ROI가 바로 적용되지 않는 이유: 승인의 역할
솔라는 모니터 한구석에 떠 있는 시스템 알림을 보며 미간을 찌푸렸다. 개발팀에서 공유한 짧은 메모였다.
승인 ROI v7과 v3으로 매장별 402건, 총 804건의 상태·이미지를 재분석했다.
단어들은 모두 알았다. ROI는 ‘관심 영역(Region of Interest)’의 약자로, 영상 분석에서 특정 구역을 지정하는 설정이라는 것쯤은 알고 있었다. 하지만 문장 전체의 뜻은 선뜻 와닿지 않았다. ROI 설정을 새로 바꿨으면, 앞으로 들어오는 영상부터 그 새로운 설정으로 분석하면 되는 것 아닌가? 왜 굳이 과거의 이미지 804개를 ‘다시’ 분석했다는 걸까? 솔라는 고개를 갸웃거리며 자리에서 일어났다.
“언니, 나 질문.”
솔라는 거실에서 노트북으로 무언가 작업하고 있던 루나에게 다가가 알림 메시지를 보여주었다.
“ROI 설정을 바꾸면, 그냥 그 시점부터 새로 들어오는 데이터에만 적용되는 거 아니야? 그런데 여기서는 왜 과거 데이터를 ‘재분석’했다고 하는 거야? 이미 끝난 분석을 왜 다시 해?”
솔라의 목소리에는 당연한 것을 묻는 듯한 뉘앙스가 섞여 있었다. 설정이란 미래를 바꾸는 것이지, 과거를 수정하는 것이 아니라는 믿음이 단단해 보였다.
루나는 솔라의 질문을 듣고 잠시 생각에 잠기더니, 자신의 노트북 화면을 솔라 쪽으로 돌렸다. 화면에는 가상의 동네 빵집 매장 관리자 페이지가 떠 있었다. 매장 입구를 비추는 CCTV 영상과 함께 ‘오늘의 방문객: 152명’이라는 숫자가 보였다. 영상 위에는 초록색 네모 상자가 그려져 있었다.
“솔라, 네가 이 빵집 사장님이라고 해보자. 저 초록색 상자가 우리가 말하는 ROI야. 저 안에 사람이 들어와야 방문객으로 집계되는 거지. 그런데 최근에 가게 리모델링을 해서 출입문 위치를 바꿨어. 그래서 ROI를 새로 그려야 해. 한번 해볼래?”
“그거야 간단하지.”
솔라는 자신만만하게 마우스를 잡았다. 새로운 출입문 위치에 맞춰 초록색 상자를 그리려는데, 마음이 급했던 탓인지 손이 미끄러져 상자가 출입문 한쪽 구석만 살짝 걸치도록 그려졌다.
“어이쿠, 실수.”
솔라는 멋쩍게 웃으며 다시 그리려고 했다. 루나가 그런 솔라의 손을 가볍게 막았다.
“잠깐. 바쁜 사장님은 이런 실수를 하고도 그냥 ‘저장’ 버튼을 누를 수 있어. 일단 그대로 저장했다고 상상해 봐. 자, 이제 어떤 일이 벌어질까?”
“음… 이제부터 들어오는 손님 대부분은 집계가 안 되겠네. 내가 실수했으니까. 빨리 다시 고쳐야겠지. 하지만 어제까지의 방문객 수에는 아무 영향 없는 거 아니야? 과거 기록은 이미 확정된 거니까.”
솔라의 대답은 명쾌했다. 설정 변경의 영향은 미래에 한정된다는, 처음의 생각과 조금도 달라지지 않은 대답이었다.
“그럴까?”
루나는 키보드를 몇 번 두드렸다. 화면의 ‘오늘의 방문객’ 숫자가 순식간에 바뀌기 시작했다. 152, 87, 23, 5. 어제 자 방문객 집계 보고서의 숫자도 188에서 12로 곤두박질쳤다.
“잠깐만, 왜 어제 방문객 수가 바뀌어? 내가 방금 선을 잘못 그린 건데?”
솔라의 눈이 동그래졌다.
“솔라 네 말대로라면, 즉 ‘저장’ 버튼이 곧 ‘운영 기준 즉시 변경’을 의미한다면 이런 일이 벌어질 수 있어. 시스템이 새로운 ROI 설정을 ‘유일한 진실’로 받아들이고, 그 기준으로 모든 과거 데이터를 다시 해석하는 거지. ‘어제 방문객은 몇 명이었지?’라는 질문을 받을 때마다, 방금 네가 실수로 그린 작은 상자를 기준으로 다시 세는 거야.”
루나의 설명에 솔라는 입을 다물지 못했다. 단순히 미래의 데이터 수집에 오류가 생기는 것과는 차원이 다른 문제였다.
“그럼 내가 저장 버튼 한번 잘못 누르면, 지난달 전체 매출 분석 보고서가 전부 엉망이 될 수도 있다는 거네? 이건 그냥 설정 실수가 아니라, 데이터 전체의 신뢰성을 파괴하는 거잖아.”
“바로 그거야. 중요한 통계에 영향을 미치는 설정은 그렇게 가볍게 다뤄지면 안 돼. 그래서 우리는 두 단계를 분리하는 거야. 하나는 네가 방금 한 것처럼 자유롭게 설정을 그려보고 저장하는 ‘초안 저장’ 단계, 그리고 또 하나는 ‘이 설정이 이제부터 우리 시스템의 공식적인 기준입니다’라고 도장을 찍어주는 ‘승인’ 단계.”
루나는 말을 이었다.
“점주가 실수로 그린 설정 초안이 곧바로 운영 기준이 되면, 데이터 집계는 순식간에 신뢰를 잃게 돼. ‘승인’이라는 절차는 그런 실수를 막아주는 첫 번째 안전장치인 셈이야.”
그제야 솔라는 고개를 끄덕였다. ‘저장’과 ‘승인’의 무게가 완전히 다르다는 것을 깨달았다. 실수를 막고 데이터의 일관성을 지키기 위해, 변경 사항을 운영에 반영하기 전 검토하고 확정하는 공식적인 단계가 반드시 필요했다.
“아… 알겠다. ‘저장’은 그냥 스케치 같은 거고, ‘승인’을 해야 진짜 분석에 사용되는 거구나. 데이터가 맘대로 바뀌면 안 되니까 당연히 그래야 했네.”
문제를 이해했다는 안도감도 잠시, 솔라의 머릿속에 새로운 질문이 떠올랐다.
“그런데 언니, 만약 어렵게 승인까지 받은 설정이 잘못됐다는 걸 나중에 알게 되면 어떡해? 아니면, 계절마다 출입구가 바뀌는 가게라서, 작년에 쓰던 설정으로 다시 돌아가고 싶을 수도 있잖아. 한번 승인된 설정은 그걸로 끝인 거야? 새로운 설정으로 덮어쓰면 이전 기록은 사라지는 건가?“
2장: ‘버전’이라는 시간 여행 도구: 설정 변경 이력 관리
솔라의 질문에 루나는 바로 대답하는 대신, 다시 빵집 매장 관리자 페이지로 시선을 돌렸다. 솔라가 던진 ‘만약’의 상황들—승인된 설정이 잘못된 경우, 과거 설정으로 돌아가야 하는 경우—은 화면 위에서 조용히 펼쳐지고 있었다. 루나는 ‘승인된 ROI: 출입구 v3 (동계)’라고 적힌 부분 옆의 작은 시계 아이콘을 클릭했다.
그러자 화면 한쪽에 새로운 창이 나타났다. 창의 제목은 ‘ROI 설정 이력’이었다. 그 아래에는 마치 문서 파일 목록처럼 여러 항목이 날짜와 함께 정리되어 있었다.
ROI v3- 동계 출입구 (2023-11-01) [현재 승인]ROI v2- 하계 특별 행사용 (2023-06-01)ROI v1- 초기 설정 (2023-01-05)
“어?”
솔라는 자기도 모르게 짧은 소리를 냈다. 그녀가 생각한 것은 ‘덮어쓰기’였다. 새로운 설정을 승인하면 이전 설정은 사라지거나, 최소한 비활성화된 채 잊힐 거라고 예상했다. 하지만 루나가 보여준 화면은 달랐다. 모든 변경 사항이 ‘버전’이라는 이름표를 달고 차곡차곡 쌓여 있었다. 마치 타임캡슐처럼 과거의 모든 설정이 그 모습 그대로 보존되어 있었다.
“아, 그냥 예전 설정을 백업해두는 거구나. 그래서 만약 지금 승인된 v3가 잘못됐다는 걸 알면, v2로 되돌릴 수 있게. 덮어쓰는 게 아니라 선택하는 거였네.”
솔라는 스스로 답을 찾았다는 듯 뿌듯한 표정을 지었다. 최신 버전이 가장 중요하고, 나머지는 만약을 위한 기록 보관용이라는 생각이었다.
“반은 맞고, 반은 틀려.”
루나는 차분하게 말했다.
“그럼 이 상황을 한번 생각해 봐. 이 빵집이 작년에 여름 특별 행사로 가게 전면을 터서 새로운 출입구를 사용했어. 그게 바로 v2 설정이야. 그리고 이제 다시 여름이 되어서, 작년과 똑같은 행사를 열기로 했어. 그럼 어떻게 해야 할까?”
“음… 간단하지. 방금 본 이력 창에서 v2를 찾아서 다시 ‘승인’ 버튼을 누르면 되겠네.”
솔라는 자신 있게 대답했다. 루나는 솔라의 말대로 화면의 v2 항목 옆에 있는 ‘이 버전으로 승인’ 버튼을 눌렀다. 그러자 CCTV 영상 위에 그려져 있던 초록색 ROI 상자가 즉시 위치를 바꿨다. 겨울 동안 사용하던 좁은 출입문에서, 작년 여름에 사용했던 넓은 개방형 입구 위치로 정확하게 이동했다.
“봐, 간단하잖아. 새로 그릴 필요도 없이…”
솔라의 말이 중간에 멈췄다. 그녀는 방금 자신이 뱉은 말의 진짜 의미를 깨달았다. ‘새로 그릴 필요도 없이.’
“맞아. ‘새로 그릴 필요도 없이’가 핵심이야.”
루나가 솔라의 생각을 읽은 듯 말했다.
“만약 우리가 버전을 관리하지 않고, 그냥 ‘최신 승인본’ 하나만 가지고 있었다면 어땠을까? 여름이 되어 다시 ROI를 변경해야 할 때, 작년 여름의 그 정확한 위치와 크기를 기억해서 ‘비슷하게’ 다시 그려야 했겠지. 하지만 ‘비슷하게’는 데이터 분석에서 매우 위험한 말이야. 1픽셀 차이로 하루 방문객 수가 수십 명씩 달라질 수 있으니까.”
그제야 솔라는 버전 관리의 진짜 목적을 이해했다. 이건 단순히 실수를 대비한 백업이 아니었다. 설정 하나하나를 독립적이고 완전한 ‘공식 문서’로 취급하는 행위였다. 각 버전은 특정 시점의 명확한 ‘기준’ 그 자체였고, 언제든 다시 불러와 똑같은 기준으로 분석을 재현할 수 있게 해주는 약속이었다.
“아… 그럼 이건 단순한 수정 이력이 아니네. 마치… 공식 도면 보관소 같아. 각 버전이 하나의 완성된 도면인 거고, 우리는 필요할 때마다 보관소에서 가장 적합한 도면을 꺼내서 ‘이게 지금의 공식 도면입니다’라고 선포하는 거구나.”
“정확해. 그렇게 매장과 카메라별로 모든 설정 변경 이력을 ‘버전’으로 저장해두면, 실수가 있더라도 언제든 안정적인 과거로 돌아갈 수 있고, 특정 시점의 분석 기준이 무엇이었는지 명확하게 증명할 수 있어. 데이터의 신뢰성은 바로 이런 추적 가능성에서 나오거든.”
이제 솔라는 ‘승인’이라는 개념에 ‘버전’이라는 시간의 축이 더해져 데이터 관리 시스템이 훨씬 더 견고해진다는 것을 알 수 있었다. 덮어쓰는 세계가 아니라, 차곡차곡 쌓아 올리는 세계였다.
안도의 한숨을 내쉬던 솔라의 눈에 문득 화면의 변화가 다시 들어왔다. 방금 v3에서 v2로 승인 설정을 바꾸자, 화면의 ROI 상자가 옮겨갔다. 그 모습을 물끄러미 보던 솔라의 미간이 다시 좁혀졌다.
“언니, 그런데 이상한 점이 있어. 방금 우리가 설정을 v2로 바꿨잖아. 그럼 이제부터 들어오는 손님은 v2로 세는 건 알겠어. 그런데 어제, 그러니까 v3가 기준이었을 때 집계된 방문객 수는 어떻게 되는 거야? 그 숫자는 v3 기준으로 남아야 해, 아니면 우리가 방금 바꾼 v2 기준으로 다시 계산되어야 해?“
3장: 과거 데이터를 ‘다시’ 분석하는 이유: 소급 적용의 힘
솔라의 질문이 채 끝나기도 전에, 루나는 조용히 화면의 구성을 바꿨다. 거대한 CCTV 영상과 설정 이력 창이 작아지고, 그 자리를 단순한 표 하나가 채웠다. 표의 제목은 ‘최근 5일간 일별 방문객 수’였다.
| 날짜 | 분석 기준 ROI | 방문객 수 |
|---|---|---|
| 10월 28일 (토) | v3 (동계) | 192명 |
| 10월 29일 (일) | v3 (동계) | 214명 |
| 10월 30일 (월) | v3 (동계) | 158명 |
| 10월 31일 (화) | v3 (동계) | 180명 |
| 11월 1일 (수) | v2 (하계) | 95명 |
표 자체는 지극히 평범했다. 하지만 솔라의 눈은 ‘분석 기준 ROI’라고 적힌 세 번째 열에 고정되었다. 바로 어제인 10월 31일까지의 데이터는 모두 ‘v3’ 기준으로 분석되었지만, 오늘 날짜인 11월 1일의 데이터는 방금 전 자신들이 바꾼 ‘v2’ 기준으로 분석되어 있었다. 솔라가 조금 전 고개를 갸웃하며 던졌던 질문이 눈앞의 현실이 되어 나타난 것이다.
“언니, 이거 봐. 어제 방문객이랑 오늘 방문객은 서로 다른 잣대로 센 거잖아. 어제는 v3, 오늘은 v2. 그럼 이 표에 있는 숫자들을 그냥 더해서 ‘최근 5일간 총 방문객 수’를 계산하면, 그게 의미가 있는 숫자야?”
솔라의 목소리에는 이제 막 발견한 문제의 심각성을 확인하려는 다급함이 묻어났다.
“좋은 지적이야. 솔라 네가 이 빵집의 데이터 분석가라고 해보자. 사장님이 와서 물었어. ‘지난주 토요일이랑 오늘 수요일 중에 언제가 더 붐볐나요?’ 라고. 뭐라고 대답할래?”
루나는 질문으로 질문에 답했다.
“음… 토요일은 192명이고, 수요일은 95명이니까… 당연히 토요일이 더 붐볐다고… 잠깐.”
솔라는 대답을 하다 말고 입을 다물었다. 너무나 당연해 보이는 비교 속에 숨어있는 함정을 스스로 발견한 것이다.
“v3는 좁은 출입문을 기준으로 하고, v2는 넓게 개방된 출입문을 기준으로 하잖아. 잣대 자체가 다른데… 두 숫자를 그냥 비교하면 안 되겠네. 마치 한 명은 미터(m)로 길이를 재고 다른 한 명은 야드(yd)로 재 놓고, 그냥 숫자만 보고 뭐가 더 길다고 말하는 거랑 똑같은 거잖아.”
솔라는 이마를 짚었다. 데이터의 일관성이 깨졌을 때 어떤 혼란이 발생하는지 명확하게 보였다. 주간 보고서, 월간 보고서는 물론, 작년 동기 대비 방문객 추이를 분석하는 일도 불가능해진다. 모든 비교 분석의 전제가 무너지는 셈이었다.
“맞아. 그래서 우리에겐 선택지가 필요해. 이 문제를 어떻게 해결할 수 있을까?”
“방법이… 있나? 이미 분석이 끝나버린 과거 데이터인데.”
“두 가지 방법이 있어.”
루나는 키보드를 두드려 화면에 텍스트를 입력했다.
방법 1: 과거를 버린다.
- 11월 1일 이전의 모든 데이터(v3 기준)는 신뢰할 수 없다고 판단, 폐기한다.
- 오직 v2 기준으로 분석된 새로운 데이터만 사용한다.
방법 2: 과거를 현재의 기준으로 다시 해석한다.
- 11월 1일 이전의 모든 데이터(v3 기준)를, 새로운 기준인 v2로 다시 분석한다.
- 모든 데이터의 분석 기준을 v2로 통일시킨다.
솔라는 화면에 나타난 두 가지 선택지를 뚫어지게 쳐다봤다. 방법 1은 터무니없었다. 기준이 바뀔 때마다 과거 데이터를 전부 버린다면, 축적된 데이터라는 개념 자체가 성립하지 않는다.
“당연히 방법 2지. 모든 데이터를 동일한 v2 기준으로 다시 분석해서, 전체 데이터의 기준을 맞춰야지. 그래야 어제와 오늘을 공정하게 비교할 수 있으니까. 아…”
탄식과 함께, 솔라의 머릿속에 흩어져 있던 퍼즐 조각들이 맞춰지기 시작했다. 그녀는 처음 자신을 혼란스럽게 했던 개발팀의 알림 메시지를 떠올렸다.
승인 ROI v7과 v3으로 매장별 402건, 총 804건의 상태·이미지를 재분석했다.
“그럼 저 ‘재분석했다’는 말이 바로 이거였구나! 분석 기준이 바뀌어서, 과거의 데이터와 현재의 데이터 사이에 일관성이 깨지는 걸 막으려고, 의도적으로 과거의 이미지들을 새로운 기준으로 ‘다시 분석’해서 기준점을 통일시킨 거였어.”
이제 그 문장은 더 이상 이해할 수 없는 외계어가 아니었다. 데이터의 신뢰성을 지키기 위한 필사적인 노력의 증거처럼 보였다. 실수를 바로잡는 소극적인 행위가 아니라, 데이터의 가치를 높이기 위한 적극적인 작업이었다. 분석 기준이 달라진 과거 데이터를 그대로 두는 것이 오히려 데이터를 오염시키는 일이었다.
“정확해. 그렇게 정책이나 설정이 바뀌었을 때, 과거의 데이터까지 새로운 기준으로 다시 처리해서 데이터 전체의 일관성을 유지하는 걸 ‘소급 적용’이라고 불러. 데이터 분석 시스템의 신뢰성은 이런 견고한 소급 적용 절차에 크게 의존해.”
루나의 설명에 솔라는 고개를 깊게 끄덕였다. 저장, 승인, 그리고 버전을 넘어 설정 변경이 과거에 미치는 영향까지 고려해야 한다는 사실을 깨달았다. ‘재분석’이라는 단어의 무게가 완전히 다르게 느껴졌다.
그때, 솔라의 머리에 또 다른 의문이 스쳤다.
“언니, 그럼 궁금한 게 있어. 방금 말한 대로라면, 어제(10월 31일) 데이터는 두 개가 존재하게 되는 거잖아? 원래 분석했던 ‘v3 기준 180명’이라는 결과랑, 오늘 재분석한 ‘v2 기준 몇 명’이라는 새로운 결과. 그럼 우리 시스템은 뭘 진짜로 기억해야 해? 재분석하면 이전 결과는 그냥 덮어쓰고 사라지는 거야? 아니면 둘 다 가지고 있는 건가? 만약 둘 다 있다면, 내가 보는 이 숫자가 어떤 기준으로 분석된 건지 어떻게 알 수 있지?“
4장: 판정 이력 추적: 프레임에 남기는 ROI 버전의 흔적
솔라의 질문은 허공에 잠시 머물렀다. “재분석하면 이전 결과는 그냥 덮어쓰고 사라지는 거야? 아니면 둘 다 가지고 있는 건가?” 루나는 대답 대신, 솔라의 질문이 가리키는 바로 그 지점을 화면에 펼쳐 보였다. 방금 전까지 보던 ‘일별 방문객 수’ 표에서 ‘10월 31일’ 행을 클릭하자, 표 아래로 새로운 내용이 나타났다.
그것은 일별 집계가 아닌, 훨씬 더 미세한 단위의 기록이었다. 마치 은행 거래 내역처럼 시간 순서대로 나열된 데이터의 흐름이었다. 하지만 어딘가 이상했다. 솔라는 눈을 가늘게 뜨고 화면을 들여다봤다.
| frame_id | processed_at | person_detected |
|---|---|---|
| … | … | … |
| 1667203200-12345 | 2023-10-31 10:00:05 | true |
| 1667203200-12345 | 2023-11-01 09:30:10 | false |
| 1667203200-12346 | 2023-10-31 10:00:06 | true |
| … | … | … |
“언니, 이거 봐. 데이터가 꼬인 것 같아.”
솔라가 화면의 특정 두 줄을 손가락으로 가리켰다. frame_id가 ‘1667203200-12345’로 동일한 기록이 연달아 두 개나 있었다. 하나는 어제 날짜로 처리되었고 person_detected가 ‘true’였지만, 바로 아래 줄은 오늘 날짜로 처리되었고 같은 프레임임에도 불구하고 person_detected가 ‘false’였다.
“같은 사진 한 장을 분석했는데, 어떻게 결과가 다를 수 있어? 하나는 사람이 있다고 하고, 다른 하나는 없다고 하잖아. 이거 시스템에 버그 생긴 거 아니야? 중복 데이터가 쌓이고 있는데?”
솔라의 판단은 단호했다. 하나의 원본(프레임)에는 하나의 결과만 있어야 한다는 상식이 흔들리는 상황을 받아들이기 어려웠다. 최신 정보로 갱신하는 과정에서 생긴 오류라고 생각하는 것이 자연스러웠다.
루나는 솔라가 가리키는 두 줄 옆으로 스크롤 막대를 조금 움직였다. 그러자 표의 숨겨진 열이 나타났다. 솔라가 미처 보지 못했던 정보였다.
| frame_id | processed_at | person_detected | model_version | roi_version |
|---|---|---|---|---|
| … | … | … | … | … |
| 1667203200-12345 | 2023-10-31 10:00:05 | true | 2.1.0 | v3 |
| 1667203200-12345 | 2023-11-01 09:30:10 | false | 2.1.0 | v2 |
| 1667203200-12346 | 2023-10-31 10:00:06 | true | 2.1.0 | v3 |
| … | … | … | … | … |
“다시 한번 볼래? 이 두 줄은 정말 똑같은 정보일까?”
새로운 열이 드러나자, 솔라는 잠시 말을 잃었다. frame_id는 동일했지만, roi_version 열의 값이 명백히 달랐다. 첫 번째 줄은 ‘v3’, 두 번째 줄은 ‘v2’.
순간 머릿속에서 모든 조각이 맞춰졌다. 이것은 오류나 중복이 아니었다. 의도적으로 남겨진, 너무나도 명백한 역사의 증거였다.
“아…!”
솔라는 나지막이 탄성을 내뱉었다.
“이건 버그가 아니구나. 판정 기록 그 자체네. 이 12345번 프레임은 처음에는 v3 기준으로 분석돼서 ‘사람이 있다’고 판정받았고, 나중에 우리가 기준을 바꾸자 v2로 다시 분석돼서 ‘사람이 없다’는 새로운 판정을 받은 거야. 이 roi_version이라는 꼬리표가 두 결과를 구분해 주고 있었던 거네.”
두 개의 다른 결과는 더 이상 모순이 아니었다. 각각 다른 맥락과 기준 아래에서 내려진, 둘 다 ‘참’인 기록이었다. 만약 저 roi_version 열이 없었다면, 같은 프레임에 대한 상반된 두 결과 앞에서 누구도 진실을 알 수 없었을 것이다. 데이터는 그 즉시 신뢰를 잃고, 분석가는 혼란에 빠졌을 터였다.
“만약 시스템 전체의 최신 승인 버전이 v2라는 사실만 알고 있었다면, v3로 분석된 저 첫 번째 결과는 영원히 미스터리로 남았을 거야. ‘왜 이 프레임만 결과가 이상하지?’ 하면서. 모든 판정 결과 하나하나에 어떤 버전의 자를 사용했는지 도장을 찍어두는 게 이렇게 중요한 거였구나.”
솔라는 이제 데이터 집계 보고서의 숫자 너머를 보고 있었다. 모든 프레임에 frame_id, processed_at, model_version, 그리고 roi_version을 남겼다는 개발팀의 메모가 이제는 시스템의 신뢰성을 지키는 주문처럼 느껴졌다. 각 데이터 조각이 자신의 출생 증명서를 지니고 있는 셈이었다. 덕분에 언제든, 어떤 결과든 그 근거를 추적하고 검증할 수 있었다. 이것이 바로 ‘판정 이력 추적’의 힘이었다.
“맞아. 분석 결과는 숫자만 덜렁 남겨두면 그 가치를 쉽게 잃어버려. ‘어떤 기준’으로 얻은 결과인지를 함께 기록해야만 비로소 완전한 정보가 되는 거야. 그래야 우리는 과거의 어떤 결과와도 오늘의 결과를 공정하게 비교할 수 있고, 설령 기준이 잘못되었음을 나중에 발견하더라도 어떤 데이터가 영향을 받았는지 정확히 찾아내서 바로잡을 수 있지.”
저장, 승인, 버전, 소급 적용, 그리고 이제 판정 이력 기록까지. 솔라는 엉킨 실타래가 풀리듯 각각의 단계가 왜 필요한지, 어떻게 서로 맞물려 돌아가는지 차례차례 이해할 수 있었다.
그녀는 고개를 끄덕이며 마지막 퍼즐 조각을 찾으려는 듯 질문을 던졌다.
“그럼 이제 알겠어. 설정 실수를 막기 위해 ‘승인’을 하고, 변경 이력을 남기기 위해 ‘버전’을 만들고, 일관성을 위해 ‘재분석’을 하고, 추적을 위해 ‘버전 기록’을 남기는 거구나. 그런데 언니, 이 모든 과정들이 합쳐지면 어떤 모습이 되는 거야? 설정 하나를 바꾸겠다는 요청이 들어왔을 때부터, 시스템이 이 모든 안전장치를 거쳐서 안정적으로 결과를 내놓기까지의 전체 흐름이 궁금해.”
5장: 설정 변경, 더 이상 불안하지 않게: 견고한 라이프사이클 완성
솔라의 마지막 질문은 이전의 질문들과는 무게가 달랐다. “어떻게 합쳐지는 거야?” 라는 물음은, 흩어진 구슬들을 실에 꿰어 목걸이를 완성하려는 마지막 시도처럼 들렸다. 루나는 말없이 노트북 화면을 정리했다. 복잡한 데이터 표와 CCTV 영상이 사라지고, 그 자리에 아주 단순한 도식이 나타났다. 마치 지하철 노선도처럼, 다섯 개의 상자가 화살표로 연결된 그림이었다.
[초안 저장] -> [승인] -> [버전 생성] -> [재분석 작업 생성] -> [판정 기록]
솔라는 도식을 보자마자 고개를 끄덕였다. “아, 전체 흐름이 이거구나. 일단 설정을 저장하고, 승인을 받으면, 그게 새로운 버전으로 등록되고, 그걸로 과거 데이터를 재분석한 다음, 마지막으로 각 데이터에 버전 꼬리표를 붙여서 기록한다. 순서대로 진행되는 체크리스트 같네.” 솔라의 해석은 명료했지만, 여전히 각 단계를 독립된 칸막이로 여기는 듯한 뉘앙스가 있었다. 마치 공장의 각 공정이 자기 일만 하면 끝이라는 식이었다.
루나는 아무 말 없이 첫 번째 상자인 [초안 저장]을 클릭했다. 그러자 상자 아래로 작은 시나리오 창이 하나 열렸다.
상황: A빵집 점주가 전화를 걸어왔다. “지난달에 설정했던 겨울용 ROI가 잘못됐어요. 출입문 옆 창문 유리에 비친 그림자까지 사람으로 인식하는 것 같아요. 지난달 방문객 통계가 너무 부풀려진 것 같습니다. 수정이 가능할까요?”
“자, 솔라. 네가 이 요청을 받은 담당자야. 이 도식을 보면서 한번 이 상황을 해결해볼래? 첫 단계는 뭘까?”
솔라는 자신 있게 대답했다. “일단 점주와 화면을 보면서 그림자가 포함되지 않도록 ROI를 새로 그려서 초안 저장을 하겠지. 아직 승인 전이니까, 이 단계에서는 어떤 통계에도 영향을 주지 않을 거고.”
루나는 고개를 끄덕이며 다음 단계인 [승인] 상자를 가리켰다. 솔라는 망설임 없이 말을 이었다.
“새로 그린 ROI가 정확하다는 게 확인되면, 승인 버튼을 누를 거야. 그러면 시스템은 이제부터 이 새로운 설정을 공식 기준으로 사용하기 시작하겠지.”
여기까지는 이전 장들에서 확인했던 내용의 복습처럼 느껴졌다. 하지만 루나가 [승인] 상자를 클릭하자, 놀라운 일이 벌어졌다. [승인] 상자가 환하게 빛나자마자, 오른쪽의 [버전 생성]과 [재분석 작업 생성] 상자가 마치 연쇄 반응처럼 동시에, 자동으로 환하게 빛났다. 솔라가 생각했던 순차적인 ‘체크리스트’와는 전혀 다른 모습이었다.
“어… 잠깐만. 나는 그냥 ‘승인’ 버튼 하나만 눌렀는데, 왜 뒤에 있는 단계들이 한꺼번에 움직여?”
솔라의 눈이 동그래졌다. 그녀는 승인 따로, 버전 관리 따로, 재분석 따로라고 생각했다. 필요할 때마다 각 기능을 수동으로 실행하는 모습을 상상했다.
“바로 그게 이 라이프사이클의 핵심이야.”
루나가 차분하게 설명했다.
“견고한 시스템은 사람의 선의나 꼼꼼함에 의존하지 않아. ‘승인’이라는 단 하나의 행위를, 뒤따라와야 할 모든 안전장치를 깨우는 ‘방아쇠’로 사용하는 거지. 우리가 승인 버튼을 누르는 순간, 시스템은 내부적으로 이렇게 움직여. 첫째, ‘새로운 공식 기준(v4)이 생겼다. 기존 기준(v3)은 역사 기록으로 보관한다’ 며 버전을 만들고. 둘째, ‘새 기준(v4)의 영향을 받는 과거 데이터는 뭐지? 아, 지난 한 달 치구나. 그럼 그 데이터들을 모두 v4로 다시 분석하라’는 작업 목록을 수백, 수천 개씩 만들어내는 거야.”
그제야 솔라는 자신이 놓치고 있던 가장 중요한 그림을 보았다. 저장, 승인, 버전, 재분석, 기록은 그저 나열된 기능이 아니었다. 하나의 유기적인 생명체처럼, 설정 변경이라는 자극에 대해 데이터의 일관성과 신뢰성을 지키기 위해 동시다발적으로 반응하는 자동화된 시스템이었다. ‘승인’은 단순히 문을 여는 행위가 아니라, 문이 열림과 동시에 조명이 켜지고, 환기 시스템이 돌고, 보안 카메라가 녹화를 시작하게 만드는 통합 스위치였던 것이다.
솔라는 처음 자신을 혼란에 빠뜨렸던 그 메시지를 다시 떠올렸다.
승인 ROI v7과 v3으로 매장별 402건, 총 804건의 상태·이미지를 재분석했다.
이제 그 문장은 더 이상 개발팀의 딱딱한 업무 보고가 아니었다. 견고한 설정 변경 라이프사이클이 성공적으로 작동했다는 생생한 증거였다.
“아… 이제야 알겠어. 저 문장의 진짜 뜻은 이거였네. ‘누군가 v7과 v3라는 새로운 기준을 승인했고, 그 행동 하나가 방아쇠가 되어, 시스템이 알아서 일관성이 깨질 위험이 있는 과거 이미지 804개를 찾아내 새로운 기준으로 다시 분석하는 작업까지 모두 자동으로 마쳤습니다.’ 라는 뜻이었구나. 사람이 실수할 틈도 없이, 시스템이 스스로 데이터의 건강을 지켜낸 거네.”
이 모든 과정이 통합적으로 이해되자, 솔라는 안도의 한숨을 내쉬었다. 더 이상 설정 변경이 불안한 사건으로 느껴지지 않았다. 예측 가능하고 통제 가능한, 신뢰할 수 있는 프로세스였다.
문득 솔라의 머릿속에 자신이 최근에 다른 팀과 논의하던 문제가 스쳤다.
“언니, 우리 팀에서 쓰는 상품 가격 관리 시스템이 있는데, 가끔 할인율을 잘못 입력해서 난리가 나. 관리자가 급하게 원래 가격으로 되돌려도, 어떤 고객이 잘못된 가격으로 구매했는지, 그래서 얼마나 손실이 났는지 파악하려면 판매 기록 데이터베이스를 통째로 뒤져야 하거든. 거기도 이 라이프사이클을 적용할 수 있을 것 같아. 가격 변경을 ‘초안’으로 올리고, ‘승인’을 받아야만 실제 판매가에 적용되게 하고, 모든 가격 변경을 ‘버전’으로 남기는 거지. 그러면 어떤 가격 버전에서 문제가 생겼는지 바로 알 수 있으니까….”
솔라는 혼잣말처럼 중얼거리며, 눈앞의 도식을 자신의 문제에 덧대어 보고 있었다. ‘설정 변경 견고성’이라는 보이지 않는 원칙이, 이제 그녀가 시스템을 바라보는 새로운 안경이 되어 있었다.