Implementation Map

API로 구현될 내부 함수 매핑

Sprint 1 데모앱은 HTTP API 서버를 따로 두지 않고 Streamlit 단일 프로세스 안에서 기능 함수를 직접 호출한다. 다만 Sprint Backlog의 API 의미는 유지되어 있으며, 이후 Flutter/FastAPI 구조로 옮길 때 아래 함수들이 route handler의 핵심 로직이 된다.

현재 구조 판단

현재 구현은 REST endpoint 없음, 내부 함수 호출 있음 상태다. 즉 /searches 같은 URL은 존재하지 않지만, 같은 의미의 검색 기능은 search_by_image(), search_by_text()로 구현되어 있다.

이 선택은 Sprint 1에서 네트워크, gateway, serialization보다 모델 추론과 검색 결과 검증을 먼저 고정하기 위한 것이다. 함수 경계가 이미 나뉘어 있으므로 Sprint 2에서 API route로 감싸는 작업은 비교적 직접적이다.

Backlog API 의미와 현재 함수명

API 의미 현재 구현 함수/클래스 파일 설명
/images/validation
이미지 파일 검증
validate_image_file() src/landmark_demo/inference.py 확장자, 파일 크기, MIME/header 성격을 확인해 업로드 가능한 이미지인지 판단한다.
이미지 품질 검증 assess_image_quality() src/landmark_demo/inference.py 흐림, 어두움, 너무 작은 이미지 여부를 계산해 low_quality 판단 근거를 만든다.
/image-embeddings
이미지 임베딩 생성
ImageRecognizer.encode()
OnnxImageRecognizer.encode()
src/landmark_demo/inference.py PyTorch 또는 ONNX image encoder를 실행해 검색에 사용할 image embedding을 만든다.
텍스트 임베딩 생성 TextEncoder.encode()
OnnxTextEncoder.encode()
src/landmark_demo/inference.py 자연어 검색어를 MobileCLIP2 text embedding으로 변환한다. ONNX/INT8 경로에서도 같은 인터페이스를 사용한다.
/searches
이미지 검색
search_by_image() src/landmark_demo/search.py image embedding과 class prototype index를 cosine으로 비교해 Top-3 후보를 만든다.
/searches
자연어 검색
search_by_text() src/landmark_demo/search.py text embedding, text catalog index, keyword/alias score를 결합해 Top-3 후보를 만든다.
신뢰도 정책 apply_decision_policy() src/landmark_demo/search.py matched, ambiguous, out_of_scope, low_quality 상태와 reason code를 결정한다.
Top-3 결과 응답/표시 render_top3() src/landmark_demo/app.py 검색 결과를 카드 3개로 표시하고, 각 후보의 상세 페이지 이동 버튼을 만든다.
/landmarks/{landmark_id}
상세 정보 조회
render_landmark_page()
bundle.info_by_id
src/landmark_demo/app.py
src/landmark_demo/data.py
assets/landmark_info.json에서 이름, 별칭, 설명, 좌표, hero image를 읽어 상세 화면을 구성한다.
검색 로그 저장 DebugLogger.log() src/landmark_demo/logging_util.py 검색 모드, 입력 ID, 처리 시간, Top-3, score, decision status, reason code를 logs/demo.jsonl에 기록한다.

현재 호출 흐름

이미지 검색
  app.py
    ├─ validate_image_file()
    ├─ assess_image_quality()
    ├─ ImageRecognizer.encode() 또는 OnnxImageRecognizer.encode()
    ├─ search_by_image()
    ├─ apply_decision_policy()
    ├─ DebugLogger.log()
    └─ render_top3() → render_landmark_page()

자연어 검색
  app.py
    ├─ TextEncoder.encode() 또는 OnnxTextEncoder.encode()
    ├─ search_by_text()
    ├─ apply_decision_policy()
    ├─ DebugLogger.log()
    └─ render_top3() → render_landmark_page()

Sprint 2에서 API로 바꿀 때

API 서버를 도입한다면 새로 만들어야 하는 것은 모델 로직이 아니라 route handler와 request/response schema다. 예를 들어 POST /searches는 업로드된 이미지를 받은 뒤 내부에서 validate_image_file(), OnnxImageRecognizer.encode(), search_by_image(), apply_decision_policy()를 순서대로 호출하면 된다.

추가될 API route 감쌀 내부 함수 주의점
POST /images/validation validate_image_file(), assess_image_quality() 앱과 서버가 같은 품질 기준을 써야 한다. 임계값은 config로 관리한다.
POST /searches search_by_image(), search_by_text() image/text 모드를 request field로 구분하거나 endpoint를 분리할 수 있다.
GET /landmarks/{landmark_id} bundle.info_by_id Sprint 1은 JSON lookup이고, Sprint 2에서 DB로 옮겨도 response shape는 유지하는 것이 좋다.
POST /image-embeddings OnnxImageRecognizer.encode() 외부 공개 API라기보다 디버그/검증용 endpoint가 적합하다. 실제 앱에서는 embedding을 그대로 노출하지 않아도 된다.