iOS · SwiftUI · 온디바이스 Vision · App Store 출시

지우는 앱이 아니라,
지울 사진을 찾아주는 앱

사진이 수만 장 쌓이면 흔들린 사진, 아무것도 안 찍힌 사진, 비슷한 사진을 하나씩 넘겨 보며 지울 엄두가 나지 않습니다. PhotoSlimmer는 그 후보를 기기 안에서만 찾아 보여 주고, 지울지 말지는 사람이 정합니다.

해결하려는 문제

제 아이폰에는 사진이 8만 장 있습니다. 정리하려고 앨범을 열면 10분 만에 포기하게 됩니다.

직접 넘겨 보기에는 너무 많다

흔들린 사진, 주머니에서 찍힌 검은 사진, 같은 장면을 열 번 찍은 사진이 수천 장 섞여 있지만, 그걸 찾으려면 8만 장을 다 봐야 합니다.

가족 사진을 서버에 올리고 싶지 않다

사진 정리 앱 상당수가 분석·광고 SDK를 넣거나 구독을 요구합니다. 아이 사진이 든 라이브러리를 그런 앱에 맡기고 싶지 않았습니다.

앱이 알아서 지우는 것은 더 무섭다

삭제는 되돌릴 수 없습니다. 그래서 자동화는 "후보를 찾는 것"까지만 하고, 삭제는 반드시 사람이 고르고 확인하도록 했습니다.

지금 되는 것

App Store에 출시되어 실제로 동작하는 범위만 적었습니다. (2026-05-10 개발 시작 · 현재 v1.5.8 출시 중)

정리 후보

흐린 사진 찾기

화면을 격자로 나눠 "가장 선명한 부분"의 선명도를 재서 전체가 흐린 사진을 추려 줍니다. 어두운 사진은 선명도가 낮게 나오는 착시가 있어 판정에서 따로 걸러냅니다. 미리 선택해 두지 않습니다 — 고르는 것은 사용자입니다.

유사한 사진

같은 순간을 묶어서 보여주기

촬영 시각으로 같은 순간을 찾고 이미지 임베딩으로 검증해 묶습니다. 묶음 안에서 얼굴 품질이 가장 좋은 사진에 별 배지를 답니다.

백그라운드 스캔

앱을 닫아도 이어지는 스캔

iOS의 백그라운드 처리 작업으로 화면을 잠가도 스캔이 계속됩니다. 기간을 골라 나눠서 스캔할 수 있습니다.

프라이버시

사진이 기기를 떠나지 않는다

분석 경로에는 네트워크 접근이 없습니다. 분석·광고 SDK도, 자체 수집도 없어 App Store 프라이버시 라벨이 "데이터를 수집하지 않음"입니다.

AI 활용 방식

AI는 두 곳에 있습니다. 제품 안에서 사진을 보는 AI와, 이 제품을 만드는 과정의 AI입니다.

제품 안의 AI — 전부 온디바이스

Apple Vision 사전학습 모델

  • 미학 점수 — 모든 사진에 계산·저장. 라벨 실측에서 빈 사진·어두움·흐림 모두에 가장 강한 신호로 확인돼, 후보 판정에 반영하는 작업 중
  • 이미지 임베딩(FeaturePrint, 768차원) — 유사한 사진 묶기
  • 얼굴 검출·품질·랜드마크 — 묶음 안에서 남길 사진 추천
  • 장면·문자·동물 분류 — 스크린샷·문서를 결함 판정에서 분리

서버 모델은 쓰지 않습니다. 직접 학습시킨 모델도 아직 제품에 넣지 않았습니다 — 검증이 끝나지 않았기 때문입니다.

만드는 과정의 AI

Claude Code가 주 개발자

  • 기획·구현·디버깅·30개 언어 현지화까지 Claude Code로 진행 (커밋 452개, Swift 약 3.5만 줄)
  • 병렬 서브에이전트 5개로 스캔·저장·Vision·UI 축을 나눠 코드 검토
  • OpenAI Codex로 교차 검증 — 다른 모델에게 설계를 공격하게 한 자문 기록 19건
  • 앱 아이콘은 Gemini 이미지 생성으로 제작
가장 중요하게 쓴 방식

"측정 없는 임계값 변경 금지" — AI에게 건 규칙

AI는 그럴듯한 숫자를 쉽게 지어냅니다. 그래서 프로젝트 규칙으로 못 박았습니다: 모든 임계값은 제가 직접 라벨링한 사진으로 잰 근거가 있어야 한다. 앱 안에 라벨링 도구를 만들어 실제 라이브러리에서 사진을 뽑아 결함을 표시하고, 그 결과로 신호별 AUC를 냅니다. Claude가 세운 가설도 같은 방식으로 기각됩니다 — 실제로 "입력 해상도가 원인"이라는 가설과 "얼굴 선명도로 눈감음을 잡을 수 있다(소표본 AUC 0.795)"는 가설은 추가 측정에서 각각 기각(후자는 0.522)됐습니다.

사람이 발견하고, AI가 진단하고, 라벨이 확정한다 — 9월 20일 하루의 기록

"흐림 점수가 실제 흔들림과 안 맞는다"

앱을 쓰다 든 위화감이 출발점이었습니다. Claude는 코드에서 원인을 짚었습니다 — 선명도를 재는 연산(Laplacian)에는 방향·위치 정보가 없어 배경만 흐린 좋은 사진진짜 흐린 사진을 원리상 구분하지 못한다는 것. 그런데 검증하려고 보니 라벨 자체가 둘을 섞고 있었습니다. 그래서 라벨링 도구부터 고쳤습니다: 사람도 가르기 어려운 "흔들림이냐 초점이냐"는 버리고, 누구나 판단할 수 있는 "어디가 흐린가"(전체 / 피사체만 / 배경만)로 바꿨습니다. 그 기준으로 하루에 505장을 다시 라벨링해 쟀습니다.

  • 배경만 흐린 좋은 사진 vs 진짜 흐린 사진 — 기존 선명도 신호 AUC 0.68, Apple 미학 점수 AUC 0.90
  • 현재 판정의 오검출 61장 중 23장(38%)이 바로 그 "배경만 흐린 좋은 사진"이었습니다
  • 무작위로 뽑은 사진의 23%가 배경이 흐린 사진 — 선명도 신호가 오검출로 덮이던 이유

새 신호를 만들 필요 없이, 이미 모든 사진에 계산해 두던 값으로 풀리는 문제였습니다. 판정 산식에 반영하는 작업은 다음 업데이트에 들어갑니다.

기기 없이 디버깅하는 구조

실기기 로그 → AI 분석 → 수정 → 무선 재설치

스캔은 몇 시간씩 백그라운드에서 돌기 때문에 디버거를 붙일 수 없습니다. 앱이 스스로 진단 로그(메모리, 구간별 처리량, 생명주기)를 남기게 하고, 그 로그와 크래시 리포트를 Claude가 읽어 원인을 좁힙니다. 나중에는 환경변수로 앱이 혼자 스캔을 시작하고 Mac이 로그를 회수하는 무인 실험 루프까지 만들어, 사람 손 없이 가설을 하나씩 꺼 보며 검증했습니다.

결과

전부 제 실기기(iPhone 16 Pro, 사진 8만 장)에서 잰 값입니다. 아래 개선은 9월 18~20일 개발 빌드에서 이뤄졌고, 출시 버전(v1.5.8)에는 다음 업데이트로 들어갑니다.

무엇을어떻게 찾았나
전체 라이브러리 스캔도중에 반복 종료80,167장 완주시스템 메모리 리포트로 "가장 큰 프로세스라 먼저 종료됨"을 확인 → 8만 개 객체 물질화 제거, 5장마다 저장해 중단이 손실이 아니라 일시정지가 되게 함
분석에 들어가는 이미지긴 변 120px480px"왜 흐림 검출이 약한가"를 추적하다 실제 입력이 원본의 3.5%였음을 실측으로 발견
유사 사진 조회8.2초0.02초임베딩(3KB)이 같은 테이블 페이지에 있어 전체를 읽던 것 → 커버링 인덱스
후보 분류 1회4.68초 · 461MB1.6초 · 31MB사진 객체 8만 개를 한꺼번에 만들던 것 → ID만 다루고 통과한 것만 조회
앱 데이터베이스 크기3.1GB377MB라벨 분석용으로 DB를 꺼내다 발견. 조회 문장이 읽기 잠금을 쥐고 있어 로그 파일이 한 번도 정리되지 않았음
좋은 아웃포커싱 사진과 진짜 흐린 사진 구분AUC 0.68AUC 0.90직접 라벨링한 505장으로 측정. 쓰고 있던 선명도 신호는 둘을 거의 못 갈랐고, 이미 계산해 두던 Apple 미학 점수가 가른다는 것을 확인
부풀려진 숫자를 AI가 스스로 잡아낸 사례. 첫 라벨 307장에서 "결함의 95%를 잡는 규칙"과 AUC 0.94~1.00이 나왔을 때, Claude는 그 표본이 애초에 신호의 극단에서 뽑혔다는 점을 짚고 무작위 표본으로 다시 쟀습니다. 결과는 5장 중 0장. 그래서 그 숫자는 이 페이지에 쓰지 않았고, 표본에 "신호와 무관한 무작위"와 "극단 바깥 구간"을 섞어 505장을 다시 라벨링했습니다. 위 표의 숫자는 그 두 번째 측정입니다.

아직 안 된 것

검증되지 않은 것은 되는 것처럼 쓰지 않습니다.

눈 감은 사진

라벨링한 결함의 22%가 눈 감은 사진인데, 어떤 신호로도 거의 잡히지 않습니다(미학 점수 AUC 0.54). 분석 입력 480px에서 눈은 폭 10~26픽셀에 불과하기 때문입니다. 얼굴 영역만 고해상도로 다시 보는 2단계 분석을 설계 중입니다.

측정과 제품 사이의 간격

현재 출시 버전의 판정은 직접 라벨링한 505장 기준 정밀도 50% · 재현율 44%입니다. 미학 점수만으로도 정밀도 76% · 재현율 52%가 나온다는 것을 쟀지만, 아직 제품에 넣지 않았습니다 — 컷을 정하고 회귀 테스트를 붙인 뒤에 나갑니다.

장시간 스캔 중 메모리 증가

사진 1장당 약 10KB씩 메모리가 늘어납니다. 데이터베이스·이미지 캐시는 원인이 아님을 실험으로 확인했고, 원인은 아직 찾는 중입니다.

실제 화면

App Store에 출시된 버전의 화면입니다.

홈 화면
홈 — 스캔과 결과
정리 후보 갤러리
정리 후보
삭제 전 검토
삭제 전 확인