Big Project · AI's EYE 12

ROI: 화면 장식에서 운영 인원 측정 정책으로

YOLO가 사람을 탐지했다면 화면 안의 박스를 모두 더하는 것이 가장 객관적으로 보인다. 사람이 보이는데 왜 일부를 집계에서 제외하는지 의문이다.

근거 · 프로젝트 문서 · 코드 · 테스트

1장: Raw YOLO의 한계와 비현실적 운영 지표

솔라는 노트북 화면에 떠 있는 영상에 완전히 매료되었다. 화면 속에서는 수많은 사람들이 분주하게 움직였고, 인공지능 모델은 실시간으로 사람들을 찾아 네모난 상자(bounding box)를 그려내고 있었다. ‘Person 98.7%’, ‘Person 92.1%’. 정확도와 함께 깜빡이는 상자들은 마치 기술의 승리를 증명하는 듯했다.

“언니, 이거 봐. YOLO 모델이 사람을 이렇게나 잘 찾아내. 화면에 보이는 박스 수만 세면 매장에 몇 명 있는지 바로 알 수 있잖아. 완전 객관적이지 않아?”

솔라는 어깨너머로 지켜보던 루나에게 흥분된 목소리로 말했다. 복잡한 매장 상황을 단 하나의 숫자로 요약할 수 있다는 생각에 마음이 들떴다. ‘현재 고객 수: 27명.’ 얼마나 명쾌한가.

루나는 말없이 듣고 있다가, 솔라의 노트북 옆에 자신의 태블릿을 내려놓았다. 그리곤 방금 솔라가 보고 있던 것과 비슷한, 하지만 다른 매장의 실시간 CCTV 영상 두 개를 화면에 띄웠다.

“이 화면들로도 한번 세어볼래?”

솔라는 자신만만하게 고개를 끄덕였다. 첫 번째 영상은 매장 입구 쪽을 바깥에서 비추는 카메라였다. 화면 속에는 대기 줄로 보이는 몇몇 사람과 그들 주변으로 분주히 오가는 행인들이 뒤섞여 있었다. YOLO 모델은 어김없이 화면에 들어온 모든 사람에게 상자를 그리고 있었다.

하나, 둘, 셋… 솔라의 손가락이 화면을 가리키며 숫자를 더해갔다. “…열둘, 열셋. 어?” 솔라의 손가락이 멈칫했다. 방금 센 사람 중 두 명은 매장 앞을 그냥 지나가던 행인이었다. 한 명은 길 건너편에서 신호를 기다리고 있었다. 모델은 그들까지 ‘Person’으로 탐지해 정확히 숫자에 포함시키고 있었다.

“잠깐만. 이 사람들은 우리 매장 손님이 아닌데… 이것도 세야 해?”

솔라의 목소리에 처음의 흥분은 사라지고 미세한 균열이 보였다. 객관적이라고 믿었던 숫자에 사업 목적과 무관한 ‘노이즈’가 섞여들고 있었다.

루나는 대답 대신 두 번째 영상을 가리켰다. 매장 안쪽, 유리창 너머 좌석 공간을 비추는 카메라였다. 아늑한 조명 아래 손님들이 앉아 있었지만, 상황은 더 나빴다. 유리창에 조명이 반사되어 특정 구역은 아예 형태를 알아보기 힘들었고, 기둥 뒤에 가려진 사람은 상반신만 겨우 보였다. 모델은 눈에 잘 띄는 손님 서너 명만 탐지할 뿐, 구석진 자리에 앉은 사람이나 반쯤 가려진 사람은 놓치고 있었다.

“이쪽은… 화면엔 세 명이라고 나오는데, 내 눈에는 적어도 다섯 명은 앉아있어. 저기 기둥 뒤에 사람도 박스가 안 생겼고. 그럼 이 숫자는 그냥 틀린 거잖아.”

솔라는 허탈한 표정으로 태블릿을 바라보았다. ‘탐지된 모든 객체를 센다’는 단순하고 객관적이라 믿었던 원칙이 두 개의 실제 영상 앞에서 무너져 내렸다. 첫 번째 영상에서는 매장과 무관한 사람까지 더해서 숫자가 부풀려졌고, 두 번째 영상에서는 측정해야 할 사람을 놓쳐서 숫자가 줄어들었다.

“이걸 그대로 더하면… 한쪽에서는 길 가던 사람까지 고객이라고 하고, 다른 쪽에서는 앉아있는 손님을 없는 셈 치는 거네.”

솔라는 자조적으로 중얼거렸다. ‘현재 고객 수: 27명’이라는 숫자가 얼마나 허황될 수 있는지 깨달았다. 그것은 현실을 객관적으로 반영한 지표가 아니라, 그저 특정 소프트웨어가 화면에서 찾아낸 ‘무언가’의 개수에 불과했다.

“알겠다. 그냥 화면에 잡힌다고 전부 세면, 실제 매장 운영 상황과는 전혀 다른 비현실적인 숫자가 나오는구나. 이건 운영 지표로 쓸 수가 없어.”

탐지 결과가 곧바로 운영 지표가 될 수 없다는 사실. 그 당연해 보이는 간극을 솔라는 처음으로 온몸으로 실감했다. 기술이 보여주는 화려한 결과물과 실제 현장에서 필요한 데이터 사이의 거리는 생각보다 멀었다. 솔라는 루나를 바라보았다. 이제 그녀의 얼굴에는 새로운 질문이 떠오르고 있었다.

“객관적이라고 믿었던 탐지 결과가 왜 이렇게 비현실적인 숫자를 만드는 걸까? 그렇다면 대체 무엇을 기준으로 세고, 무엇을 버려야 하는 거지?”

2장: ROI: 장식이 아닌 측정 정책

솔라의 질문이 채 끝나기도 전에, 루나는 아무 말 없이 태블릿 화면을 조작했다. 어지럽게 흩어져 있던 YOLO의 탐지 상자들 위로, 반투명한 색상의 다각형들이 겹쳐서 나타났다. 매장 바깥을 비추던 첫 번째 카메라 영상에는 대기 줄 주변으로 파란색 영역이, 유리창 너머 좌석을 비추던 두 번째 영상에는 손님들이 앉은 공간을 따라 초록색 영역이 그려졌다.

마치 프레젠테이션 자료에 강조 표시를 한 듯한 모습이었다. 솔라는 어리둥절한 표정으로 화면을 들여다보았다. 방금 전까지 ‘무엇을 기준으로 세고 버릴까’를 고민하던 와중에 나타난 이 알록달록한 영역들은 뜬금없어 보였다. 문제를 해결하기 위한 단서라기보다는, 그저 어수선한 화면을 보기 좋게 꾸미려는 장식처럼 느껴졌다.

“언니, 이건 뭐야? 갑자기 영역은 왜 그린 거야? 보기 좋으라고?”

솔라의 목소리에는 실망감이 섞여 있었다. 그녀가 원한 것은 비현실적인 숫자를 바로잡을 명확한 ‘기준’이었지, 화면을 꾸미는 장식이 아니었다.

루나는 솔라의 질문에 바로 답하는 대신, 파란색 영역이 그려진 첫 번째 영상을 손가락으로 가리켰다. 영상 속에서는 여전히 YOLO 모델이 행인과 대기 고객을 가리지 않고 총 13개의 탐지 상자를 그리고 있었다.

“새로운 규칙을 하나 정해볼게. 이 파란색 영역 안에 탐지 상자의 일부라도 걸쳐 있는 사람만 세는 거야. 그럼 몇 명이지?”

솔라는 반신반의하며 화면을 다시 들여다보았다. 길 건너편에 있던 사람, 매장 앞을 빠르게 지나가던 행인의 탐지 상자들은 모두 파란색 영역 밖에 있었다. 파란색 영역에 걸쳐 있는 상자는 매장 입구 근처에서 서성이거나 줄을 선 사람들뿐이었다.

“하나, 둘, 셋… 다섯 명이네. 13명이 아니라.”

숫자가 극적으로 줄었다. ‘13명’이라는 숫자는 기술이 탐지한 객관적 사실이었지만, ‘5명’이라는 숫자는 ‘대기 고객일 가능성이 높은 사람’이라는 사업적 목적에 더 가까웠다. 솔라는 그제야 깨달았다. 파란색 영역은 단순한 장식이 아니었다. 그것은 ‘무시할 것’과 ‘주목할 것’을 구분하는 경계선, 즉 필터였다.

루나는 이번엔 초록색 영역이 그려진 두 번째 영상을 보여주었다. 유리창의 빛 반사가 심해 탐지가 거의 불가능했던 구역은 처음부터 초록색 영역에서 제외되어 있었다.

“여기도 같은 규칙을 적용해 봐.”

“…여긴 세 명. 아까랑 똑같긴 한데…” 솔라는 잠시 생각에 잠겼다. “하지만 이 규칙을 쓰면, 빛 반사 때문에 측정이 안 되는 영역에 우연히 사람이 탐지되더라도 우리 고객 수에 포함되지 않겠네. 그리고 우리가 측정할 수 없는 영역은 아예 처음부터 세지 않겠다고 선언하는 거구나.”

그녀는 두 영상을 번갈아 보았다. 파란색 다각형과 초록색 다각형. 그 선들은 ‘어디를’ 볼 것인지를 정의함으로써, ‘누구를’ 셀 것인지에 대한 질문에 답하고 있었다. 객관성을 훼손하는 필터가 아니라, 오히려 무의미한 데이터를 걸러내고 유효한 신호만 남겨 지표의 의미를 바로 세우는 ‘측정 정책’이었다.

“알겠다… 이 선들이 바로 기준이었구나. YOLO가 사람을 얼마나 잘 찾느냐의 문제가 아니었어. 우리가 ‘우리의 고객’을 어디에 있는 사람으로 정의할 것인지, 그 규칙을 정하는 게 먼저였던 거야.”

솔라는 자신이 ‘객관적’이라는 단어에 갇혀 있었다는 것을 깨달았다. 기술이 뱉어내는 모든 결과를 무비판적으로 수용하는 것이 객관성이 아니었다. 서비스의 목적에 맞게 ‘무엇을 진짜 데이터로 인정할 것인가’에 대한 합의가 필요했고, 화면 위의 저 다각형들이 바로 그 합의의 구체적인 표현이었다.

루나가 조용히 입을 열었다.

“맞아. 이 영역을 ‘관심 영역(Region of Interest)’, 줄여서 ROI라고 불러. 이 사례에서 ROI는 보기 좋은 오버레이가 아니라, 우리 서비스가 무엇을 셀 것인지 명시적으로 공개하는 측정 규칙 그 자체인 셈이지.”

‘측정 규칙’. 그 단어가 솔라의 머릿속에 박혔다. 이제 ROI는 더 이상 장식으로 보이지 않았다. 그것은 비즈니스 논리가 담긴 하나의 엄연한 정책이었다. 솔라의 눈빛이 다시 날카로워졌다. 하나의 의문이 풀리자, 곧바로 다음 단계의 현실적인 질문이 떠올랐다.

“좋아, ROI가 측정 정책이라는 건 이해했어. 그런데 이 중요한 선은 대체 누가 그리는 거지? 매장 주인이 가구 배치를 바꿀 때마다 개발자가 밤새 코드를 수정해야 하나? 이 정책이 바뀌면 시스템은 이전 버전이랑 헷갈리지 않고 어떻게 알아듣는담?”

3장: 측정 정책으로서의 ROI 정의 및 관리

솔라는 노트북을 덮고, 대신 책상 위에 새 노트를 펼쳤다. 방금 전까지 머릿속을 채웠던 질문들이 하얀 종이 위에서 소용돌이쳤다. ‘누가, 어떻게, 언제 이 선들을 관리하는가?’ 그녀는 펜을 들고 직접 그 흐름을 그려보기 시작했다. 복잡한 문제는 직접 그려봐야 직성이 풀리는 성격이었다.

솔라의 상상 속 시스템은 단순했다. 먼저, 점주가 사용하는 관리자 페이지 화면을 네모나게 그렸다. 화면 안에는 CCTV 영상이 보이고, 그 위에 ‘ROI 그리기’라는 버튼이 덩그러니 놓여 있었다. 점주가 이 버튼을 눌러 원하는 영역을 그리면… 그 다음은? 솔라는 잠시 펜을 멈췄다. 그녀가 상상할 수 있는 가장 현실적인 방법은 이것이었다. 점주가 영역을 그린 뒤 ‘저장’ 버튼을 누르면, 시스템이 해당 화면을 캡처해서 개발팀의 이메일이나 슬랙으로 전송한다. 그럼 그걸 받은 개발자가 이미지의 픽셀 좌표를 따서 코드에 반영하고, 서버에 새로 배포한다. 솔라는 화살표와 함께 ‘개발자에게 수정 요청’이라고 적었다. 그리고 그 아래에 작게 덧붙였다. ‘배포까지 최소 반나절’.

그녀는 자신이 그려놓은 흐름도를 보고 인상을 찌푸렸다.

“이건 너무 말이 안 되는데… 매장 가구 배치를 아침에 바꿨는데, 저녁에나 데이터에 반영된다는 거잖아. 그 사이에 쌓인 데이터는 다 오염된 거고. 그리고 매장이 수백 개면 개발자는 ROI만 그리다 하루가 다 가겠네.”

그녀의 혼잣말을 들은 루나가 조용히 다가와 솔라의 노트를 들여다보았다. 루나는 솔라가 그린 투박한 흐름도를 잠시 보더니, 아무 말 없이 솔라의 펜을 빌려 그 옆에 새로운 다이어그램을 그리기 시작했다.

루나의 그림은 솔라의 것과 시작은 비슷했지만, 전혀 다른 길로 뻗어 나갔다. ‘점주용 설정 화면’이라는 상자에서 나온 화살표는 ‘개발자’가 아니라 ‘ROI 설정 DB’라는 새로운 상자로 향했다. 그리고 그 데이터베이스 상자 안에는 { "id": "roi-123", "version": 1.0, "points": [...] } 같은 텍스트가 적혀 있었다. 화살표 위에는 ‘저장 및 승인 요청’이라고 쓰여 있었다.

솔라는 눈을 떼지 못하고 루나의 손끝을 따라갔다. 데이터베이스 옆에는 ‘Vision Worker’라는 또 다른 상자가 그려졌다. 그리고 데이터베이스에서 Vision Worker로 향하는 점선 화살표 위에는 이런 글자가 적혔다.

GET /api/v1/roi/camera-A?status=approved

솔라는 두 개의 다이어그램을 번갈아 보았다. 자신이 그린 ‘사람’ 중심의 수동적인 흐름과, 루나가 그린 ‘시스템’ 중심의 자동화된 흐름. 차이는 명확했다.

“아…”

탄성과 함께 깨달음이 찾아왔다. 솔라는 루나가 그린 다이어그램의 ‘ROI 설정 DB’ 상자를 손가락으로 가리켰다.

“점주가 그린 영역이 그냥 그림 파일로 전달되는 게 아니었구나. 좌표랑 속성이 담긴, 버전이 붙은 데이터 조각으로 저장되는 거였어. 그리고 ‘승인’이라는 절차가 있네. 점주가 마음대로 바꿀 때마다 실시간으로 반영되는 게 아니라, 관리자가 확인하고 적용하는 단계가 있는 거고.”

그녀의 손가락이 ‘Vision Worker’ 상자로 옮겨갔다.

“그리고 이 ‘Vision Worker’라는 녀석은 개발자의 수정 배포를 기다리는 게 아니야. 그냥 자기가 일할 시간이 되면, 정해진 주소(API)로 가서 ‘지금 써도 된다고 승인된 최신 버전의 정책 좀 주세요’ 하고 물어보기만 하면 되는 거네.”

솔라의 머릿속에서 모든 조각이 맞춰졌다. ROI는 한 번 정해지면 코드에 박제되는 규칙이 아니었다. 그것은 독립적인 생명주기를 가진 설정 ‘데이터’였다. 점주는 UI를 통해 그 데이터를 생산하고, 시스템은 버전을 붙여 안전하게 보관하며, Vision Worker는 약속된 API를 통해 그 데이터를 소비한다. 생산자와 소비자가 서로를 직접 알 필요 없이, ‘측정 정책 데이터’라는 명확한 계약을 통해 완전히 분리되어 있었다. 매장 주인이 가구 배치를 백 번 바꿔도 개발자는 코드를 한 줄도 건드릴 필요가 없었다.

‘측정 정책’. 이틀 전만 해도 장식이라 생각했던 ROI가 이제는 버전 관리되고, API로 조회되며, 시스템의 여러 구성 요소가 의존하는 핵심적인 ‘계약(Contract)’으로 보였다. 솔라는 자신이 처음 그렸던 조잡한 흐름도를 부끄럽게 내려다보았다. 기술의 문제를 기술이 아닌, 사람의 노동으로 해결하려 했던 наив한 발상이었다.

“이제 알겠어. ROI는 그냥 선이 아니라, 버전 관리되는 서비스의 설정 그 자체구나. 그래서 가구 배치가 바뀌어도, 정책이 바뀌어도 시스템이 헷갈리지 않고 안정적으로 운영될 수 있었던 거네.”

솔라는 루나가 그려준 다이어그램을 한참 동안 들여다보았다. 깔끔하게 정리된 흐름 속에서 이제 단 한 곳, ‘Vision Worker’라는 상자만이 여전히 미지의 영역으로 남아 있었다. 그녀는 그 상자를 펜 끝으로 톡톡 두드리며 새로운 질문을 던졌다.

“좋아, 그럼 이 Vision Worker는 승인된 최신 버전의 ROI 데이터를 받아왔어. 이제 이 다각형 좌표랑, YOLO가 찾아낸 사람들의 네모난 상자들을 가지고 있겠지. 그런데… 둘을 어떻게 비교해서 이 사람이 영역 ‘안’에 있는지 ‘밖’에 있는지 최종 판정을 내리는 거야? 그냥 겹치기만 하면 세는 건가?”

4장: ROI 기반 측정의 기술적 적용

루나는 솔라의 노트, 바로 직전까지 복잡한 시스템 다이어그램이 그려져 있던 페이지의 빈 공간에 간결한 그림 두 개를 나란히 그렸다. 왼쪽에는 복잡한 다각형 하나를 그리고 그 옆에 { "type": "waiting", "points": [...] } 라고 적었다. 오른쪽에는 단순한 직사각형 하나를 그리고 { "class": "person", "bbox": [x, y, w, h] } 라고 썼다.

이것이 바로 솔라가 마지막에 던졌던 질문의 핵심이었다. Vision Worker가 API를 통해 가져온 다각형(ROI)과, YOLO 모델이 실시간으로 찾아내는 사각형(bounding box). 시스템은 이 두 개의 완전히 다른 도형 정보를 가지고 어떻게 ‘안’과 ‘밖’이라는 명확한 판정을 내리는 걸까. 솔라는 루나가 그려놓은 두 도형을 빤히 쳐다보았다. 마치 기하학 문제지 같았다.

“음… 그냥 이 사각형이 다각형 안에 완전히 포함되면 세는 거 아닐까? 겹치는 부분이 있으면 일단 ‘안’에 있다고 보는 거지.”

솔라는 가장 단순하고 직관적인 방법을 제시했다. 그녀의 생각 속에서 시스템은 마치 마법처럼, 겹치기만 하면 알아서 정확하게 사람들을 분류해 줄 것 같았다.

루나는 대답 대신 펜을 들어, 두 도형이 애매하게 겹쳐 있는 상황 세 가지를 추가로 그렸다. 첫 번째는 사람의 바운딩 박스(bbox)가 ROI 영역의 경계선에 살짝 걸쳐 있는 모습. 두 번째는 박스의 절반 정도만 ROI 안으로 들어온 모습. 마지막은 상반신은 ROI 안에 있지만, 박스의 아랫부분은 밖에 있는, 마치 사람이 카운터에 기대어 서 있는 듯한 모습이었다.

“이 세 경우는 전부 ‘안’일까, ‘밖’일까? 아니면 어떤 건 ‘안’이고 어떤 건 ‘밖’일까? 만약 그렇다면 기준은 뭐지?”

루나의 질문에 솔라는 말문이 막혔다. ‘그냥 겹치면 센다’는 단순한 규칙은 이 애매한 경계선 위의 사례들 앞에서 힘을 잃었다. 첫 번째 경우, 단 1픽셀이라도 겹쳤다고 해서 그 사람을 대기 고객으로 세는 것이 맞을까? 세 번째 경우, 몸의 일부만 들어왔는데 그를 온전한 한 명으로 세어야 할까? 마법처럼 보였던 판정의 과정에는 생각보다 훨씬 더 까다로운 정책적 결정이 숨어 있었다.

“어렵네… 그냥 겹친다고 다 세면, 스쳐 지나가는 사람까지 전부 포함될 수도 있겠어. 그렇다고 완전히 들어온 것만 세면, 경계에 서 있는 사람은 놓치게 되고. 정말 어떻게 하지?”

솔라의 고민이 깊어질 무렵, 루나가 그림 위에 점 하나를 찍고 작은 화살표를 그렸다.

“이 문제를 푸는 한 가지 방법은, 사람을 대표하는 단 하나의 점을 정하는 거야. 예를 들면 사람의 발밑, 즉 ‘발점(foot-point)’을 기준으로 삼는 거지. 바운딩 박스 전체가 아니라, 그 박스의 맨 아랫변 중앙에 있는 점 하나가 ROI 다각형 안에 들어오는지 아닌지만 보는 거야.”

‘발점’. 솔라는 그 단어를 곱씹으며 루나가 그린 세 가지 시나리오에 새로운 규칙을 적용해 보았다. 경계선에 살짝 걸친 박스. 그 사람의 발점이 ROI 밖에 있다면 그는 ‘밖’이다. 상반신만 안으로 들어온 사람. 역시 발점이 밖에 있으므로 ‘밖’이다. 이제 기준이 명확해졌다. 복잡했던 면과 면의 관계 문제가, 점 하나가 다각형 안에 포함되는지에 대한 단순한 기하학 문제로 바뀌었다.

“아하! 그럼 박스가 얼마나 겹치는지 계산할 필요 없이, 그냥 발점 좌표 하나만 체크하면 되는구나. 사람이 서 있는 공간을 기준으로 하니까 훨씬 더 합리적이야.”

“맞아. 하지만 늘 발점만 쓸 수 있는 건 아니야. 사람이 앉아 있거나, 카메라 각도 때문에 발이 보이지 않는 경우도 있으니까. 그럴 땐 다른 규칙을 쓰지. 예를 들어 ‘바운딩 박스가 ROI 영역과 50% 이상 겹칠 경우에만 포함한다’ 같은 규칙.”

루나는 두 번째 규칙을 설명하며, 이 기술적인 판정 로직 역시 고정된 것이 아님을 보여주었다. 입구(entrance)나 대기(waiting) 구역처럼 서 있는 사람이 많은 곳에서는 ‘발점’ 규칙이 유용할 수 있고, 좌석(seat) 구역처럼 앉아 있는 사람이 대부분인 곳에서는 ‘bbox 중첩(overlap)’ 규칙이 더 정확할 수 있었다.

솔라는 비로소 모든 것을 이해했다. Vision Worker는 단순히 ROI의 다각형 좌표만 가져오는 것이 아니었다. 그 ROI에 어떤 판정 규칙을 적용할지에 대한 정보, 즉 entrance, waiting, staff, seat 같은 각 영역의 목적에 맞는 판정 로직까지 함께 가져오는 것이었다.

{"name": "waiting_line", "points": [...], "rule": "foot_point"} {"name": "main_seats", "points": [...], "rule": "overlap", "threshold": 0.6}

솔라의 머릿속에 이런 형태의 데이터 구조가 그려졌다. 측정 정책이란, 영역을 정의하는 선과 그 선을 해석하는 규칙의 조합이었다. ‘마법’이 아니라, 처음부터 끝까지 구체적이고 명시적인 약속과 계산의 연속이었던 것이다. 바운딩 박스와 ROI의 교차 여부를 판정하는 로직은, 서비스의 목적에 맞춰 선택하고 설정할 수 있는 또 하나의 중요한 정책이었던 셈이다.

“알겠다. 결국 어떤 사람을 셀지는, 어떤 영역을 그렸느냐 뿐만 아니라, 그 영역과 사람을 어떤 규칙으로 연결하느냐에 따라 달라지는 거구나. 같은 위치에 서 있는 사람이라도, 발점 규칙을 쓰느냐, 중첩 규칙을 쓰느냐에 따라 고객이 될 수도, 아닐 수도 있겠네.”

솔라는 자신이 처음 가졌던 ‘탐지된 모든 사람은 객관적인 데이터’라는 생각이 얼마나 순진했는지 다시 한번 깨달았다. 하나의 탐지 결과를 유의미한 운영 지표로 바꾸기까지, 이토록 여러 겹의 정책적 결정이 필요했다. 솔라는 문득 이 모든 정교한 과정을 거쳐 최종적으로 만들어질 결과물이 궁금해졌다.

“이렇게 영역별로, 규칙별로 사람들을 세심하게 분류하고 나면… 우리는 대체 어떤 종류의 데이터를 얻게 되는 거야? 그냥 ‘현재 고객 수: 15명’ 같은 단순한 숫자랑은 뭔가 다를 것 같은데.”

5장: ROI를 통한 의미 있는 운영 지표 전환

솔라의 질문이 끝나자, 루나는 이전까지의 그림과 다이어그램이 가득했던 노트를 옆으로 밀어두고 자신의 태블릿 화면을 켰다. 복잡한 기술적 원리를 설명하는 대신, 그 모든 과정이 만들어낸 최종 결과물을 직접 보여주려는 듯했다. 잠시 후 태블릿 화면에 깔끔하게 정리된 대시보드가 나타났다.

처음 솔라가 상상했던 ‘현재 고객 수: 27명’ 같은 단 하나의 숫자는 어디에도 없었다. 대신, 화면은 여러 구획으로 나뉘어 있었다.

[ 실시간 운영 현황 ]
- 대기 (Waiting): 5명
- 착석 (Seated): 8명
- 직원 (Staff): 2명
- 입구 (Entrance): 1명

각 항목 옆에는 작은 그래프가 시간의 흐름에 따른 변화를 보여주고 있었다. 기술이 뱉어낸 무미건조한 탐지 결과가 아니라, 마치 매장 관리자가 직접 손으로 쓴 업무 일지처럼 보였다. 하지만 솔라의 표정은 여전히 완전히 개운치 않았다. 그녀는 고개를 갸웃거리며 화면을 톡톡 건드렸다.

“이렇게 영역별로 나눠서 보여주니까 훨씬 이해하기는 쉽네. 그런데… 이 숫자들을 정말 믿을 수 있는 걸까? 결국 우리가 어제 정한 ‘발점 규칙’이랑, 점주가 그려 넣은 그 다각형에 따라서 나온 숫자잖아. 만약 점주가 ‘대기’ 영역을 조금만 다르게 그렸으면 저 숫자는 5가 아니라 4나 6이 될 수도 있는 거고. 뭔가 완벽한 ‘진짜’ 숫자라기보다는, 여전히 불완전하고 임의적인 느낌이 들어.”

솔라의 마음속에는 아직 ‘절대적으로 객관적인 단 하나의 정답’에 대한 미련이 남아 있었다. 여러 겹의 정책을 거쳐 나온 이 숫자들은, 그 정책 자체의 임의성 때문에 신뢰하기 어렵다고 느껴졌다.

루나는 솔라의 의심에 정면으로 반박하는 대신, 그녀의 논리를 그대로 받아 안았다.

“맞아. 바로 그 점이 핵심이야.”

루나는 솔라가 가리킨 ‘대기: 5명’이라는 숫자를 손가락으로 가리켰다.

“만약 매니저가 와서 ‘왜 대기 인원이 5명으로 집계됐죠? 내 눈에는 4명 같은데요.’라고 묻는다고 상상해 봐. 솔라, 너라면 뭐라고 대답할래?”

“음… 우리 시스템은 이 파란색 영역 안에 발점이 찍힌 사람만 세도록 설정되어 있어서 그렇다고 설명해야지. 그리고 그 한 명은 경계선 바로 바깥에 서 있었나 보지.”

“정확해. 그럼 다음 날 매니저가 대기 줄의 위치를 바꾸고, 직접 설정 페이지에 들어가서 파란색 ROI 영역을 수정했다고 해봐. 어제와 똑같은 위치에 서 있던 사람이라도, 새로운 ROI 경계 밖에 있다면 이제 대기 인원에서 제외되겠지. 그럼 대시보드의 숫자는 4명으로 바뀔 거야.”

루나의 설명에 솔라는 잠시 생각에 잠겼다. 똑같은 사람, 똑같은 물리적 위치, 똑같은 YOLO 탐지 결과. 하지만 ROI라는 ‘정책’ 하나가 바뀌자 최종 운영 지표가 달라졌다. 처음에는 이것이 데이터의 불완전함이나 임의성을 증명하는 약점이라고 생각했다.

하지만 다시 생각해보니, 그것은 약점이 아니었다.

“아…!”

솔라는 나지막이 탄성을 내뱉었다. 그녀는 태블릿의 대시보드와 자신이 그렸던 복잡한 시스템 흐름도를 번갈아 보았다. 그제야 모든 조각이 하나로 맞춰지는 기분이었다.

“이해했어. 이 숫자의 가치는 ‘절대적으로 정확하다’는 데 있는 게 아니었어. 숫자가 ‘어떤 규칙에 의해 산출되었는지’를 모두가 알고 있고, 그 규칙 자체를 사업 목적에 맞게 언제든 바꿀 수 있다는 데 있는 거구나.”

‘대기: 5명’이라는 숫자는 신의 계시가 아니었다. 그것은 ‘우리 서비스는 현재 버전 1.2의 ROI 설정에 따라, 발점 규칙을 적용하여 대기 인원을 이렇게 측정하기로 약속했습니다’라는 명시적인 선언의 결과물이었다. 숫자가 틀렸다고 느껴진다면, 그건 시스템의 오류가 아니라 ‘측정 정책’과 현장의 ‘운영 방식’이 어긋났다는 신호였다. 그리고 그 해결책은 코드를 수정하는 게 아니라, 점주가 직접 ROI를 수정해 정책과 현실을 일치시키는 것이었다.

솔라는 자신이 처음 ‘모든 탐지 결과를 더해야 객관적’이라고 생각했던 것이 얼마나 단편적인 생각이었는지 깨달았다. 진짜 객관성이란, 측정의 기준과 과정을 투명하게 공개하고 설명할 수 있는 ‘재현 가능성’과 ‘추적 가능성’에서 오는 것이었다.

그녀는 자신의 노트를 펼쳐, 맨 첫 장에 적어두었던 문장을 찾아냈다.

‘YOLO가 탐지한 모든 박스를 세면, 가장 객관적인 고객 수를 알 수 있다.’

솔라는 그 문장 위에 망설임 없이 두 줄을 그었다. 그리고 그 옆에 새로운 문장을 적어 내려갔다. 그녀의 펜 끝에는 더 이상 의심이 아닌 확신이 담겨 있었다.

‘측정하고 싶은 대상(대기, 착석, 직원)을 명확히 정의하는 ‘측정 정책(ROI)’이 먼저다. 신뢰할 수 있는 운영 지표는 그 정책을 투명하게 적용한 결과일 뿐이다.’

이제 ROI는 단순히 화면을 꾸미는 장식이나, 불완전한 필터가 아니었다. 그것은 데이터에 의미를 부여하고, 기술과 비즈니스를 연결하며, ‘무엇을 셀 것인가’라는 가장 근본적인 질문에 답하는 서비스의 핵심적인 정책 그 자체였다. 만약 동료가 이 시스템에 대해 묻는다면, 이제 솔라는 자신 있게 대답할 수 있었다. 이것은 사람 수를 ‘세는’ 시스템이 아니라, 운영 인원을 ‘정의하는’ 시스템이라고.