대시보드는 위험군인데 챌린지는 딴소리 — 자동배정 버그를 데이터로 잡다
📚 「AI 헬스케어 파이널 프로젝트」 연재 19편입니다. (18편: 물·체중·수면·운동까지, 건강 기록 기능 7종을 완성한 날)

📝 한줄 요약
같은 화면 안에서 서비스가 두 말을 했습니다. 대시보드는 사용자를 위험군으로 분류했는데 챌린지 화면은 엉뚱한 미션을 내밀었죠. 추측으로 고치지 않고 데이터를 직접 들여다봐서 진짜 원인을 잡았습니다. 그날 팀에서 정리해 보내준 수정사항 일곱 건도 함께 반영했습니다. 그중에는 “검진 수치 1,200을 1로 읽던” 황당한 버그도, “로그인했더니 내 데이터가 사라진” 무서운 버그도 있었습니다.
바쁘시면 이것만 읽어도 돼요:
- 한 서비스가 같은 사람에게 두 가지 평가를 내밀던 버그를, 데이터를 직접 열어 원인을 확정했어요
- 진짜 원인은 “트랙(미션 묶음)을 갱신하는 코드가 늘 ‘수동 지정’으로 저장”해서 자동 재계산을 건너뛴 것 — 화면의 단계 조작이 트랙까지 굳혀버린 부작용이었죠
- 검진 수치 자동입력 버그:
1,200을1로 읽어 1200배 틀린 값을 넣던 문제를 잡았어요 - 계정 전환 버그: “데이터가 사라졌다”는데 알고 보니 저장소는 멀쩡하고 화면이 옛 기억을 붙들고 있던 거였어요
- 교훈 하나로 압축하면 — 버그 원인은 짐작 말고 데이터로 확정, “사라졌다”는 먼저 저장소부터 확인
🎯 이런 분들께 도움돼요
- 같은 도구가 상황에 따라 앞뒤 안 맞는 결과를 내서 헷갈렸던 분
- “이거 버그 같은데”를 느낌이 아니라 증거로 확인하고 싶은 분
- AI에게 일을 시킬 때 원인부터 찾게 하는 법이 궁금한 분
😫 문제 상황 (Before)
우리 서비스에는 두 개의 화면이 있습니다. 하나는 대시보드로, 사용자의 콩팥 건강 상태를 한눈에 보여줍니다. 다른 하나는 챌린지 화면으로, 그 사람에게 맞는 건강 미션을 골라 보여주죠.
문제는 둘이 서로 다른 말을 하는 거였습니다. 대시보드는 어떤 사용자를 “집중 관리가 필요한 위험군”으로 분류했는데 챌린지 화면은 그 사람에게 가벼운 일상 미션을 내밀고 있었습니다. 의사 한 명이 “입원이 필요합니다”라고 하는데 같은 병원 다른 창구에서는 “비타민 잘 챙겨 드세요”라고 안내하는 격이었죠. 사용자 입장에선 어느 쪽을 믿어야 할지 혼란스럽습니다.
그날은 팀에서 그동안 모은 수정사항도 PDF로 정리해 보내줬습니다. 식이 설문을 챗봇 답변에 연결하기, 검진 수치 자동입력 손보기, 챌린지 항목 늘리기 같은 일곱 가지였죠. 이 버그 하나를 뿌리부터 잡고, 밀린 수정사항을 한 번에 반영하기로 했습니다.
🛠️ 사용한 도구
- 도구: Claude Code
- 모델: Claude Opus
- 특이사항: 추측 대신 데이터로 원인 확정(저장소 직접 조회). 팀 전달 PDF 수정사항을 순서대로 반영
🔧 작업 과정
화면 둘이 다른 말을 한다 — 짐작 대신 저장소를 열다
챌린지 수정사항2.pdf 이 파일의 수정사항을 반영해줘
먼저 의심부터 했습니다. “두 화면이 데이터를 서로 다른 곳에서 읽나? 아니면 한쪽이 늦게 갱신되나?” 그럴듯한 가설이 몇 개 떠올랐죠. 하지만 가설은 가설일 뿐입니다.
그래서 AI에게 추측을 멈추고 저장소를 직접 열어보자고 했습니다. 실제 사용자 한 명의 기록을 꺼내보니 답이 바로 나왔습니다. 그 사람은 위험도가 낮은 그룹인데도, 저장소에는 “집중케어 트랙 / 수동 지정됨”이라고 박혀 있었습니다.
여기서 ‘트랙’은 그 사람에게 묶어주는 미션 세트를 말합니다. 원래는 건강 상태가 바뀌면 트랙도 자동으로 다시 계산돼야 했죠. 그런데 진짜 원인은 이거였습니다 — 트랙을 갱신하는 코드가, 어떤 경우든 항상 ‘사용자가 수동으로 정한 값’이라고 표시해서 저장하고 있었습니다. 그러니 자동 재계산이 “어, 이건 사용자가 직접 고른 거니까 건드리면 안 되지” 하고 매번 건너뛴 거죠. 한 번 박힌 옛날 트랙이 그대로 고착됐습니다.
방아쇠는 엉뚱한 데 있었습니다. 화면에서 배지 단계를 바꾸는 버튼이 있는데, 이걸 누르면 단계만 바뀌는 게 아니라 트랙까지 “수동 지정”으로 굳혀버렸습니다. 단계를 한 번이라도 만진 사람은 그 순간부터 트랙 자동 배정이 영영 멈춘 거였죠.
해결은 명확했습니다. 트랙은 100% 자동으로만 다시 계산하게 하고, 단계 버튼은 단계만 바꾸도록 분리했습니다. 코드를 고치자, 망가져 있던 사용자의 트랙이 손도 안 댔는데 올바른 값으로 저절로 복구됐습니다.
💡 “왜 이런 일이 생기지?”는 짐작으로 답하지 마세요. 저장소(원본 데이터)를 직접 한 번 열어보면, 머릿속 가설 다섯 개보다 진실 하나가 빠릅니다.
식이 설문이 챗봇 답변에 연결되다
RAG 수정사항.pdf 위의 수정사항을 반영해서 RAG를 수정해줘
콩팥 건강에서 식습관은 큰 비중을 차지합니다. 그래서 식이 설문 여섯 문항의 답을 챗봇과 리포트가 활용하게 연결했습니다. 여기서 쓴 방식이 RAG인데, 사용자에 대한 배경 정보를 근거로 깔고 답하게 만드는 방식입니다. 예를 들어 칼륨 섭취가 위험 수준인 사람에게는, 챗봇이 일반론이 아니라 그 사람 상황에 맞는 안내를 하게 되죠.
한 가지 신경 쓴 건, 중요한 안내는 AI에게 통째로 맡기지 않았다는 점입니다. “칼륨 주의” 같은 핵심 메시지는 정해진 문구로 고정해두고, AI는 그 배경을 풀어 설명하거나 추가 질문에 답하는 역할만 맡겼습니다. 건강 정보는 매번 말이 달라지면 안 되니까요.
💡 AI가 잘하는 일과 못 맡길 일을 나누세요. 사실과 안전이 걸린 핵심 메시지는 고정하고, 풀어 설명하는 일만 AI에게. 역할을 나누면 신뢰가 올라갑니다.
진단했다는데 화면엔 안 뜬다 — CKD 그룹 매칭
챌린지 수정사항3.pdf 확인해서 수정해줘
다음 버그는 좀 더 미묘했습니다. 사용자가 문진에서 “콩팥병 진단을 받았다”고 분명히 입력했는데, 대시보드에는 여전히 일반 등급으로만 표시됐습니다.
원인을 따라가 봤습니다. 검진 결과를 저장하는 단계에서 ‘진단받았다’는 정보를 미처 읽어오지 않았고, 뒤에서 돌아가는 AI 계산이 그 자리를 일반 등급으로 덮어쓰고 있었습니다. 그래서 진단 정보가 화면까지 도달하지 못한 거죠. 진단받은 사람은 진단군으로 정확히 분류되도록 고치고, AI 계산이 그 분류를 함부로 덮어쓰지 못하게 보호 장치를 걸었습니다.
💡 정보가 “입력은 됐는데 화면엔 안 보인다”면, 중간에 누가 덮어쓰는지 의심하세요. 데이터는 한 번에 도착하지 않고 여러 손을 거칩니다.
1,200을 1로 읽던 검진 자동입력
머지 완료. ocr 개선은 여기까지 다음 단계
검진 결과지를 사진으로 찍으면 수치를 자동으로 입력해주는 기능이 있습니다. 이때 쓰는 게 OCR, 이미지 속 글자를 읽어 들이는 기술이죠. 그런데 여기서 어이없는 버그가 있었습니다. 1,200처럼 천 단위 쉼표가 들어간 숫자를, 쉼표 앞에서 끊어 1로만 읽어버렸습니다. 무려 1200배 틀린 값이 자동으로 들어가는 거죠.
쉼표를 제대로 처리하도록 고쳤습니다. 그리고 하나 더, 말도 안 되는 값은 자동입력 자체를 막는 안전장치를 넣었습니다. 사람의 검사 수치로 도저히 나올 수 없는 숫자가 읽히면, 그건 그냥 버리게 했습니다. 잘못 읽느니 비워두는 게 안전하니까요.
💡 자동화는 편한 만큼 위험합니다. “그럴듯하지만 틀린 값”이 조용히 들어가는 게 제일 무서워요. 자동입력에는 항상 “이 값이 상식적인가?” 확인하는 문지기를 두세요.
”나는 칼륨을 얼마나 먹는지 모르는데?” — 좋은 질문이 만든 설계
칼륨과 단백질에 대한 데이터를 어떻게 받지 ?? 일반 사람들이 내가 얼마나 칼륨과 단백질을 먹는지 알수 있나?
식이 설문을 다듬다가, 제가 멈칫했습니다. 콩팥 건강엔 칼륨과 단백질 섭취가 중요한데, 곰곰이 생각해보니 일반 사람은 자기가 칼륨을 하루에 몇 밀리그램 먹는지 절대 모릅니다. 저도 모르거든요. 설문에 “칼륨 섭취량을 적으세요”라고 물어봐야 아무도 못 채웁니다.
그래서 묻는 방식을 바꿨습니다. 영양소를 직접 묻지 않고, 그 영양소가 많이 든 음식을 얼마나 자주 먹는지로 돌려 물었습니다. “과일·채소·콩류를 얼마나 자주 드세요?”, “고기·생선·계란을 얼마나 자주 드세요?” 같은 식으로요. 누구나 답할 수 있는 질문으로 바꾸고, 그 빈도로 섭취 경향을 가늠하게 했습니다.
💡 사용자가 답할 수 없는 질문은 좋은 질문이 아닙니다. 정확한 숫자를 못 받으면, 누구나 아는 일상으로 돌려 물어보세요. 답이 없는 칸은 데이터가 아니라 공백일 뿐입니다.
”로그인했는데 내 데이터가 사라졌다” — 진짜 사라진 걸까?
새로운 아이디 생성 후 다시 테스트 아이디로 로그인 했는데 데이터가 사라짐
이날 가장 등골이 서늘했던 순간입니다. 새 계정을 하나 만들어 둘러본 뒤, 원래 쓰던 테스트 계정으로 다시 로그인했더니 그동안 쌓은 데이터가 죄다 사라져 있었습니다. 데이터가 날아갔다는 건 서비스에서 가장 무서운 상황이죠.
하지만 여기서 바로 손대지 않았습니다. 먼저 저장소부터 열어 확인했습니다. 그랬더니 — 데이터는 멀쩡히 다 있었습니다. 한 줄도 사라지지 않았죠. 그러니까 진짜 문제는 “데이터가 없어진 것”이 아니라 “화면이 안 보여준 것”이었습니다.
원인은 캐시였습니다. 캐시는 화면이 빠르게 보여주려고 잠깐 손에 들고 있는 임시 데이터를 말합니다. 새 계정으로 갈아탔다가 돌아왔는데, 화면이 새 계정의 텅 빈 상태를 계속 들고 있었던 거죠. 계정을 바꿀 때 이 임시 기억을 깨끗이 비우도록 고치니, 데이터가 멀쩡히 다시 나타났습니다.
💡 “사라졌다”는 신고를 받으면, 고치기 전에 저장소부터 여세요. 진짜 없어진 건지, 화면만 못 보여주는 건지부터 가립니다. 둘은 완전히 다른 문제고, 원인을 잘못 짚으면 멀쩡한 데이터를 건드리게 됩니다.
✅ 결과 (After)
Before vs After
| 항목 | Before | After |
|---|---|---|
| 대시보드 ↔ 챌린지 | 같은 사람에게 다른 평가 | 트랙 100% 자동 재계산으로 일치 |
| CKD 진단 표시 | 진단해도 일반 등급 | 진단군으로 정확히 분류 |
| 검진 자동입력 | 1,200을 1로 읽음 | 쉼표 정상 처리 + 이상값 차단 |
| 식이 설문 | 못 답하는 영양소 질문 | 음식 빈도로 바꿔 누구나 응답 |
| 계정 전환 | 데이터 사라져 보임 | 캐시 초기화로 정상 표시 |
결과물
- 한 사람에게 일관된 평가를 주는 챌린지 자동배정(버그 수정)
- 팀 전달 수정사항 일곱 건 반영(식이 RAG·진단 매칭·챌린지 확장·OCR·식이 설문·라벨·캐시)
- 검진 자동입력의 콤마·이상값 안전장치
💬 이 과정에서 배운 AI 활용 팁
효과적이었던 것
- 저장소 먼저 열기: 화면이 이상하면 추측 말고 원본 데이터를 직접 확인 — 가설 다섯 개보다 진실 하나가 빠름
- “사라졌다”의 두 갈래 가리기: 진짜 삭제인지, 화면만 못 보여주는지부터 구분
- 못 답하는 질문 걸러내기: 사용자가 모르는 걸 물으면 일상의 빈도로 돌려 묻기
이렇게 하면 안 돼요
- 증상 보고 바로 고치기: 원인을 모른 채 손대면 새 버그가 생김
- 자동입력을 무조건 믿기: 그럴듯하게 틀린 값이 제일 위험. 문지기를 둘 것
- 핵심 안내까지 AI에 통째로 맡기기: 사실·안전이 걸린 메시지는 고정하고 풀이만 맡기기
🌍 다른 업무에 적용한다면?
“같은 도구가 앞뒤 안 맞는 결과를 낸다”는 일은 어디에나 있습니다. 엑셀의 한 칸은 합계가 맞는데 옆 시트는 다르거나, 같은 보고서의 두 그래프가 다른 숫자를 말하거나. 이때 본능적으로 “어디가 틀렸지?” 추측하기 쉽지만, 가장 빠른 길은 원본 데이터를 한 번 직접 펼쳐보는 것입니다. 그리고 “데이터가 사라졌다”는 동료의 호소를 들으면, 같이 당황하기 전에 저장된 원본부터 확인하세요. 의외로 멀쩡히 다 있고, 화면만 못 따라온 경우가 많습니다.
🚀 앞으로의 계획
이번 작업으로 “진단받은 사람”과 “아직 아닌 사람”이 서비스 안에서 섞여 있던 흔적이 자꾸 드러났습니다. 진단받은 분에게는 챌린지가 아니라 의료적 안내가 맞고, 아직 진단 전인 분에게는 예방 중심의 관리가 맞습니다. 그런데 지금은 두 부류가 같은 화면, 같은 흐름을 타고 있죠. 다음 편에서는 진단받은 사람과 아직 아닌 사람을, 서비스가 처음부터 다르게 대하도록 갈래를 나누는 작업을 다룹니다. 같은 서비스 안에서 두 종류의 사용자를 위한 두 갈래 길을 내는 이야기예요. 다음 막에서 풀어볼게요.
📋 재사용 가능한 프롬프트
프롬프트 1: 짐작 대신 데이터로 원인 찾기
[화면 A]와 [화면 B]가 같은 사람에게 서로 다른 결과를 보여줘. 원인을 추측하지 말고, 실제 저장된 원본 데이터를 직접 열어 어디서 값이 어긋나는지 먼저 확인한 다음 고치자.
프롬프트 2: “데이터가 사라졌다” 진단
[사용자]가 “데이터가 사라졌다”고 해. 고치기 전에 먼저 저장소에 데이터가 실제로 남아 있는지 확인해줘. 진짜 삭제인지, 화면만 못 보여주는 문제인지부터 가려줘.
프롬프트 3: 사용자가 못 답하는 질문 바꾸기
이 설문 문항은 [전문 수치]를 직접 물어서 일반 사용자가 답하기 어려워. 같은 정보를, 누구나 아는 [일상 행동·빈도]로 돌려 물을 수 있게 질문을 다시 설계해줘.
📌 「AI 헬스케어 파이널 프로젝트」 연재 19편입니다. 다음 막에서 또 이어집니다.