오늘은 세 번째 미니프로젝트인 어르신 돌봄 서비스에서 담당한 AutoHealing 기능을 보완하고, 장애 시험 결과와 보고서를 정리했다. 이후 팀에서 연결한 코드와 데이터 계약을 확인하고, 프런트엔드 화면의 디자인과 가독성 개선도 지원했다.
이번 작업에서 중요했던 것은 단순히 기능이 정상적으로 실행되는지 확인하는 데 그치지 않는 것이었다. 데이터가 정확하게 저장되는지, 장애 상황에서 실제로 복구됐는지, 시험 결과를 올바르게 해석했는지, 그리고 팀원들이 같은 기준으로 기능을 이해하고 있는지까지 확인해야 했다.
특히 장애 시험에서 기대한 동작을 수행한 것과 실제 복구에 성공한 것이 서로 다른 의미라는 점이 인상 깊었다.
1. 빈 값은 정상값이 아니다
부분 바이탈 저장 문제를 보완하면서 데이터의 누락을 어떻게 처리해야 하는지 다시 생각하게 됐다.
바이탈은 심박수, 혈압 등 사용자의 생체 상태를 나타내는 데이터다. 만약 심박수는 정상적으로 전달됐지만 혈압을 받지 못했다면, 혈압을 임의의 정상값으로 채워서는 안 된다. 데이터가 없다는 사실을 정상이라는 의미로 바꿔버리기 때문이다.
이번 작업에서는 선택적으로 입력되는 항목을 NULL로 저장하고, 실제로 수집된 데이터와 위험 판정에 사용할 수 있는 데이터를 구분하는 방향으로 보완했다.
예를 들어 혈압 데이터가 누락됐을 때 이를 정상으로 판단하면 이후 위험 분석이나 보호자 알림에서도 잘못된 결과가 발생할 수 있다. 반대로 누락된 값을 명확하게 구분하면 시스템은 정보가 부족하다는 사실을 바탕으로 다음 동작을 결정할 수 있다.
이 과정에서 데이터가 없다는 것도 중요한 정보이며, 누락을 정상으로 간주하지 않는 것이 신뢰할 수 있는 시스템의 기본이라는 점을 이해했다.
2. 데이터베이스 수정은 기존 기록을 지키는 작업이다
개발 과정에서는 테이블에 컬럼을 추가하거나 구조를 변경하는 일이 단순한 수정처럼 느껴질 수 있다. 하지만 데이터베이스에 이미 운영 기록이 저장돼 있다면 고려해야 할 부분이 늘어난다.
기존 테이블을 삭제하고 다시 만들면 구조는 원하는 형태로 바꿀 수 있지만, 이전에 저장된 데이터까지 사라질 수 있기 때문이다.
이번 작업에서는 SQLite의 테이블 구조 변경과 마이그레이션, 롤백을 확인했다.
-
마이그레이션(Migration): 기존 데이터베이스의 구조를 새로운 요구사항에 맞게 변경하는 작업
-
롤백(Rollback): 작업 중 문제가 발생했을 때 변경 사항을 취소하고 이전 상태로 되돌리는 작업
-
트랜잭션(Transaction): 여러 데이터베이스 작업을 하나의 단위로 묶어 일관성을 유지하는 방법
특히 테이블 구조를 변경하더라도 기존 기록과 ID가 유지되는지 확인하는 것이 중요했다. 단순히 새로운 컬럼이 추가됐다는 사실만으로 작업이 성공했다고 판단할 수는 없었다.
이전 데이터가 그대로 유지되는지, 변경 과정에서 문제가 발생하면 원래 상태로 돌아갈 수 있는지도 검증해야 했다.
이번 경험을 통해 데이터베이스 작업은 새로운 기능을 추가하는 것뿐 아니라, 이미 쌓인 데이터를 안전하게 보존하면서 구조를 변경하는 작업이라는 점을 배웠다.
3. 정상 실행과 캐시 준비는 별개의 문제였다
바이탈 장애 시험을 진행하면서 예상과 달랐던 부분은 캐시가 준비되지 않은 상태에서 대체 Mock 데이터가 사용되는 문제였다.
캐시는 자주 사용하는 데이터를 임시로 저장해 두고 필요할 때 빠르게 조회할 수 있도록 하는 방식이다. AutoHealing에서는 정상적인 데이터 수집이 어려운 상황에서 기존에 확보한 데이터를 활용할 수 있는지가 중요하다.
처음에는 정상 시나리오가 실행됐으니 캐시도 준비돼 있을 것이라고 생각했다. 하지만 실제 흐름을 확인해 보니 시뮬레이터의 scenario가 전달되지 않았고, 대체 Mock으로 생성한 값 역시 캐시에 저장되지 않는 문제가 있었다.
여기서 중요한 것은 정상 실행 로그만으로 전체 데이터 흐름이 정상이라고 단정할 수 없다는 점이었다.
문제를 확인하기 위해서는 다음과 같은 흐름을 순서대로 살펴봐야 했다.
① 시나리오 전달
요청한 상황과 실행 조건이 제대로 전달되는가?
② 데이터 생성 및 저장
정상 데이터 또는 대체 데이터가 생성되는가?
③ 캐시 저장 및 조회
장애 시 사용할 데이터가 실제로 준비돼 있는가?
④ 장애 복구 검증
장애 상황에서 준비된 데이터를 이용해 기능이 복구되는가?
이처럼 중간 과정이 정상적으로 처리됐는지를 확인해야 마지막 결과도 정확하게 해석할 수 있다.
이번 경험을 통해 시스템의 성공 로그만 확인하는 것보다, 데이터가 만들어지고 저장되고 조회되는 전체 흐름을 추적하는 것이 문제 해결에 중요하다는 점을 배웠다.
4. 기대 동작 통과와 복구 성공은 다르다
오늘 가장 인상 깊었던 부분은 장애 시험 결과를 해석하는 과정이었다.
장애 시험 12회가 모두 기대한 방식으로 처리됐지만, 복구율은 50%였다. 처음에는 모든 시험이 통과했는데 복구율이 절반이라는 결과가 모순처럼 느껴질 수 있었다.
하지만 두 지표가 측정하는 대상을 구분하면 의미가 달라진다.
-
기대 동작 통과: 장애 상황에서 시스템이 사전에 정의한 동작을 수행했는가?
-
복구 성공: 장애가 발생했을 때 실제 기능을 정상적으로 사용할 수 있는 상태로 회복했는가?
예를 들어 캐시나 템플릿을 활용해 기능을 계속 제공할 수 있다면, 원래 경로에 문제가 발생했더라도 대체 경로를 통한 복구로 볼 수 있다.
반면 기기 제어에 실패해 사용자에게 직접 조치하도록 안내했다면, 시스템이 실패를 적절하게 처리한 것은 맞지만 기기 제어 기능 자체가 복구된 것은 아니다.
CCTV 분석 없이 나머지 정보로 서비스를 이어가는 경우도 마찬가지다. 전체 기능을 복구한 것이 아니라 일부 기능을 사용할 수 없는 상태에서 서비스를 유지하는 기능 저하에 해당할 수 있다.
| 캐시·템플릿으로 기능 제공 | 대체 경로를 통한 복구 |
| 기기 제어 실패 후 수동 조치 안내 | 실패 대응 |
| CCTV 없이 나머지 정보로 진행 | 기능 저하 상태에서 서비스 유지 |
따라서 모든 장애 시험이 예상대로 처리됐다고 해서 복구율까지 100%가 되는 것은 아니다. 장애 상황을 적절하게 처리했는지와 실제 기능이 복구됐는지는 서로 다른 기준으로 평가해야 한다.
이번 작업을 통해 지표는 단순히 계산식을 만드는 것보다 무엇을 성공으로 정의할지 먼저 결정하는 것이 중요하다는 점을 배웠다.
복구율을 높이는 것도 중요하지만, 그보다 먼저 복구 성공과 실패 대응을 명확하게 구분해야 결과를 신뢰할 수 있다.
5. 재시도와 타임아웃은 적용 위치까지 명확해야 한다
팀원과 재시도 정책을 맞추는 과정에서는 같은 용어를 사용하더라도 서로 다르게 이해할 수 있다는 점을 확인했다.
예를 들어 3회 재시도라는 표현에는 두 가지 해석이 가능하다.
-
최초 호출을 포함해 총 3회 실행한다.
-
최초 호출 이후 실패할 때마다 3회 더 재시도한다.
두 방식은 실제 호출 횟수와 소요 시간에서 차이가 발생한다. 문서에 숫자만 적어 놓으면 팀원마다 구현 방식이 달라질 수 있다.
타임아웃도 마찬가지다. 타임아웃은 요청에 응답이 오지 않을 때 일정 시간 이후 기다림을 중단하도록 제한하는 것이다. 하지만 60초라는 제한 시간을 설정했다고 해도 어떤 작업에 적용하는지에 따라 의미가 달라진다.
이번 프로젝트의 CCTV 분석 흐름에서도 백엔드가 분석 요청의 응답을 기다리는 시간과, 분석기 내부에서 비전 LLM을 한 번 호출하는 시간은 구분해야 했다.
비전 LLM은 이미지나 영상에서 시각적 정보를 분석하는 데 사용하는 대규모 언어 모델이다. 외부 요청을 기다리는 시간과 내부 모델 호출에 적용되는 시간 제한은 서로 다른 계층의 정책이기 때문에 하나의 숫자로 뭉뚱그려 이해하면 안 된다.
이 과정에서 재시도 횟수뿐 아니라 최초 호출의 포함 여부, 타임아웃의 적용 대상, 실제 호출 위치까지 명시해야 한다는 점을 배웠다.
앞으로는 재시도 정책을 정의할 때 다음 항목을 함께 확인해야겠다.
-
최초 호출을 포함한 전체 호출 횟수
-
재시도할 수 있는 오류의 종류
-
각 호출에 적용되는 타임아웃
-
상위 요청의 전체 제한 시간
-
재시도를 중단하거나 취소하는 조건
이런 기준이 명확해야 팀원들이 같은 정책을 구현하고, 장애 상황에서도 일관된 결과를 기대할 수 있다.
6. 사용자가 이해할 수 있는 화면까지 확인하기
백엔드 기능을 점검한 뒤에는 프런트엔드의 디자인과 가독성 개선도 지원했다.
프런트엔드는 사용자가 실제로 보고 조작하는 화면이다. 기능이 정상적으로 실행되더라도 화면에서 안내 문구를 읽기 어렵거나 상태를 구분하기 힘들다면 사용자는 시스템을 제대로 활용하기 어렵다.
이번에는 실제 화면을 확인하면서 배경색과 글자색의 대비, 글자 크기, 배지 표현 등을 살펴봤다. 로그인 입력 항목과 안내 문구처럼 사용자가 직접 확인해야 하는 요소의 가독성도 개선했다.
특히 취약도 표시에서는 색상만으로 상태를 구분하지 않고 하·중·상이라는 텍스트를 함께 표시하도록 했다.
색상은 화면이나 사용자의 시각적 조건에 따라 구분하기 어려울 수 있다. 따라서 색상과 텍스트를 함께 제공하면 사용자가 상태를 더 명확하게 이해할 수 있다.
이 과정에서 개발 완료의 기준을 다시 생각하게 됐다.
코드가 오류 없이 실행되는 것과 사용자가 화면의 의미를 정확하게 이해하는 것은 서로 다른 문제다. 특히 어르신 돌봄 서비스처럼 바이탈과 위험 상태, 기기 제어 결과 등을 전달하는 서비스에서는 화면의 표현 방식도 중요하다.
앞으로는 기능 테스트뿐 아니라 실제 화면에서 정보가 잘 읽히는지, 상태를 혼동하지 않는지까지 확인해야겠다.
7. 협업에서는 최신 데이터 계약을 기준으로 맞춰야 한다
이번 미니프로젝트에서는 각 팀원이 구현한 기능을 하나의 서비스로 연결하는 과정에서 데이터 계약의 중요성도 다시 확인했다.
데이터 계약은 기능을 연결할 때 서로 주고받기로 합의한 데이터의 항목과 형식, 의미를 뜻한다. 각 기능이 개별적으로 정상 작동하더라도 데이터 계약이 맞지 않으면 연결 과정에서 문제가 발생할 수 있다.
예를 들어 특정 바이탈 항목을 지원하도록 구현했더라도 팀의 최신 계약에서 해당 항목이 제외됐다면, 기존 구현을 그대로 유지하는 것이 정답은 아니다. 현재 합의된 데이터 구조와 실제 코드, 테스트 결과가 일치하는지 확인해야 한다.
최저혈압 항목도 처음에는 지원했지만 이후 팀 계약에 따라 제외됐다. 이처럼 요구사항이나 데이터 구조가 바뀌면 개인 구현 역시 현재 기준에 맞춰 조정해야 한다.
또한 협업에서는 내가 수정할 파일과 다른 팀원이 담당하는 파일을 구분하는 것도 중요했다. 모든 문제를 직접 수정하려고 하면 같은 작업을 중복해서 진행하거나 서로의 변경 사항이 충돌할 수 있기 때문이다.
이번 경험을 통해 협업은 각자 맡은 기능을 완성하는 것만으로 끝나지 않는다는 점을 배웠다.
최신 계약을 확인하고, 변경 사항을 공유하며, 각자의 구현과 테스트 결과를 같은 기준으로 맞추는 것도 개발 과정의 중요한 부분이었다.
8. 다음에 복습할 내용
이번 작업을 통해 AutoHealing의 기능 구현뿐 아니라 데이터 관리, 장애 검증, 협업 과정까지 함께 살펴볼 수 있었다. 동시에 아직 더 정확하게 이해하고 정리해야 할 내용도 확인했다.
| SQLite 트랜잭션과 마이그레이션 | 기존 데이터와 ID를 유지하면서 안전하게 스키마를 변경하는 방법 |
| 오류 유형별 처리 | 검증 실패와 일시적인 호출 장애를 구분하는 기준 |
| 재시도·타임아웃·취소 | 각각의 역할과 적용 범위, 서로 간의 관계 |
| 장애 시험 지표 | 시나리오별 성공 여부와 로그 단위 기록을 구분하는 방법 |
| Streamlit 상태 관리 | 입력값과 화면 갱신, 상태 유지가 동작하는 방식 |
| 서비스 연결 및 배포 | 개발 환경에서의 성공과 실제 서버에서의 정상 동작을 확인하는 방법 |
특히 장애 시험 결과를 해석할 때는 단순히 성공과 실패를 기록하는 데서 끝내지 않고, 각 시나리오에서 무엇을 성공으로 판단했는지부터 명확하게 정리하는 연습이 필요하다.
또한 개별 기능이 정상적으로 실행되는 것과 여러 기능이 연결된 전체 서비스가 정상적으로 작동하는 것은 다르다. 앞으로도 개별 기능 테스트와 통합 테스트를 구분하고, 실제 데이터 흐름을 확인하는 습관을 유지하고 싶다.
9. 오늘의 회고
오늘은 AutoHealing 작업을 보완하면서 장애 복구의 의미를 구체적으로 이해한 날이었다.
처음에는 기능이 오류 없이 실행되고 예상한 결과가 나오면 충분하다고 생각하기 쉽다. 하지만 실제 시스템에서는 데이터가 누락될 수도 있고, 캐시가 준비되지 않을 수도 있으며, 일부 기능이 실패한 상태에서도 나머지 서비스를 유지해야 할 수 있다.
이때 중요한 것은 모든 상황을 성공으로 처리하는 것이 아니라, 현재 시스템이 어떤 상태인지 정확하게 구분하는 것이다.
누락된 데이터는 누락된 상태로 남겨야 하고, 실패에 대응한 것과 실제 복구한 것은 구분해야 한다. 또한 재시도와 타임아웃의 기준을 명확하게 정하고, 팀원 간 데이터 계약을 일치시켜야 전체 서비스의 동작을 신뢰할 수 있다.
프런트엔드 개선을 지원하면서는 개발자가 이해하는 정보와 사용자가 화면에서 받아들이는 정보도 다를 수 있다는 점을 다시 느꼈다. 기능을 구현하는 데서 끝나는 것이 아니라, 그 결과를 사용자가 정확하게 이해할 수 있도록 전달하는 것까지 개발의 일부라는 생각이 들었다.
이번 미니프로젝트를 통해 현재 담당 기능을 보완하는 것뿐 아니라, 장애 상황을 어떻게 정의하고 검증해야 하는지, 그리고 개별 기능을 어떻게 하나의 서비스로 연결해야 하는지도 함께 고민할 수 있었다.
앞으로는 정상 동작 여부만 확인하는 데 그치지 않고, 데이터의 생성부터 저장과 조회, 장애 대응과 복구 결과까지 전체 흐름을 확인하는 개발자가 되고 싶다. 아직 데이터베이스와 비동기 호출, 배포 환경에 대한 이해는 더 보완해야 하지만, 이번에 겪은 문제를 바탕으로 각 개념을 다시 공부하고 실제 코드에서 확인해 나가겠다.
'AI 오케스트레이션 캠프 > 일차별 회고' 카테고리의 다른 글
| 63일차 회고|AutoHealing·멀티에이전트·장애 복구 검증|AI 오케스트레이션 개발자 국비지원 (0) | 2026.10.13 |
|---|---|
| 61일차 회고|AutoHealing·데이터 계약·통합 테스트|AI 오케스트레이션 개발자 국비지원 (1) | 2026.10.12 |
| 60일차 회고|평가·실패 복구·AWS CI/CD·프로젝트 설계|AI 오케스트레이션 개발자 국비지원 (0) | 2026.10.07 |
| 59일차 회고|Security & Guardrail, 멱등성, CI/CD|AI 오케스트레이션 개발자 국비지원 (0) | 2026.10.06 |
| 58일차 회고|Handoff·State·CI/CD·AWS 배포|AI 오케스트레이션 개발자 국비지원 (0) | 2026.10.02 |
댓글