Image rights / copyright detection system: SQLite store, HTTP app, search integrations (Naver, Google Custom Search, Google Cloud Vision web detection), image analysis (fingerprints, face/person detection, evidence enrichment, risk scoring), an admin/review layer, governance and retention policies, batch jobs, and a browser-based operator GUI. This baseline incorporates a full code-review remediation pass (46 fixes; 358 tests passing). Highlights: CRITICAL - Prevent evidence cascade-delete during the schema-constraint migration by disabling FK enforcement around the table rebuild. Security - Sandbox served media (neutralize stored XSS from uploaded/collected SVGs) via CSP + nosniff on the untrusted media routes. - Strip embedded EXIF/GPS from external image derivatives before they are sent to third-party APIs. - Return a clean 404 (not an uncaught StopIteration) for PATCH on an unknown provider. Correctness - LLM-summary failures no longer add +30 to the risk score. - Decode only explicit JS escapes so Korean image URLs are not mangled. - Consume search quota only after a successful request. - Naver/Google adapters map responses inside the failure boundary, so a malformed response degrades to evidence instead of crashing enrichment. - Domain-aware provider attribution; face-box IoU de-duplication; count searches (not result items); per-box crop isolation; clamp evidence confidence and Google CSE num; real submittedEpoch; and more. Robustness - Offline LLM connect fast-fails (short connect timeout) so seed/reload requests are not stalled; full read timeout preserved for generation. - Malformed numeric env vars fall back to defaults instead of crashing startup. Performance - Per-submission evidence reads (no full-table scan per rescore), audit-log LIMIT, lazy active-store lookup, hoisted timestamps. Tests - ~24 regression tests added pinning the above fixes. Runtime data (data/, outputs/, *.sqlite3, *.log), secrets (.env), and node_modules are gitignored.
15 KiB
| date | topic |
|---|---|
| 2026-05-25 | image-rights-review-enrichment |
Image Rights Review Enrichment
Summary
기존 이미지 권리 리스크 필터를 보강해 운영자가 한 신청을 상세 검토할 때 원본 이미지, 위험도, 내부 분석, Naver 검색 근거, Google Web Detection 근거, 내부 LLM 요약, 최종 판정 액션을 한 화면에서 확인하게 한다. 1차 보강의 중심은 상세 검토 화면이며, 검색 보강과 LLM은 운영자 판단을 돕는 근거 정리 역할로 제한한다.
Problem Frame
현재 필터 코어는 이미지 지문, 얼굴/사람 존재 신호, 외부 Web Detection, 점수화, 운영자 요약을 표현할 수 있다. 하지만 실제 운영자가 신청 단위로 "이 이미지를 상품화해도 되는가"를 판단하려면 여러 근거가 한 화면에 정리되어야 한다.
특히 한국 연예인, 방송/웹툰/게임 캐릭터, 팬아트, AI 생성 이미지처럼 검색 근거가 중요한 사례에서는 빈 기준 DB만으로는 초기에 탐지력이 부족하다. 운영자는 검색어를 직접 떠올리고 결과를 해석하는 시간을 줄여야 하며, 검색 결과가 왜 위험 신호인지 빠르게 확인해야 한다.
Naver 검색은 한국어 웹/이미지 근거를 찾는 데 유용하지만, 공식 이미지 검색 API는 이미지 업로드 역검색이 아니라 텍스트 쿼리 기반 검색이다. 따라서 Naver는 원본이나 축소 이미지를 보내는 역검색 채널이 아니라, 내부 분석과 LLM이 만든 한국어 후보 쿼리를 검색해 근거 URL과 이미지를 보강하는 채널로 다룬다.
Actors
- A1. 신청자: 상품화할 이미지를 제출하지만 자동 분석 결과는 보지 않는다.
- A2. 운영자: 상세 검토 화면에서 위험 근거를 확인하고 승인, 보류, 반려를 최종 선택한다.
- A3. 권리 리스크 필터: 이미지 분석, 검색 근거 수집, 점수화, 요약 생성을 수행한다.
- A4. 내부 LLM: 후보 검색어 생성, 검색 결과 구조화, 운영자용 요약을 수행하되 점수와 최종 판정은 하지 않는다.
- A5. Naver 검색 API: 한국어 텍스트 쿼리 기반 이미지/웹 검색 결과를 제공한다.
- A6. Google Cloud Vision Web Detection: 승인된 조건에서 이미지의 웹 엔티티, 매칭 이미지, 유사 이미지, 포함 페이지 근거를 제공한다.
Key Flows
-
F1. 검색 보강 분석
- Trigger: 신청 이미지의 위험도 분석이 실행된다.
- Actors: A3, A4, A5, A6
- Steps: 필터가 내부 분석 근거를 만들고, 내부 LLM이 이미지 라벨/텍스트/기준 DB 후보/기존 근거를 바탕으로 한국어 검색 쿼리를 생성한다. Naver 검색 API는 텍스트 쿼리로 한국어 이미지/웹 근거를 반환한다. 승인된 경우 Google Web Detection도 축소 파생 이미지를 통해 웹 근거를 반환한다. 모든 근거는 출처, 쿼리, 시간, 신뢰도, 실패 사유와 함께 저장된다.
- Outcome: 운영자 상세 검토 화면에서 사용할 수 있는 검색 근거와 요약이 생성된다.
- Covered by: R1, R2, R3, R4, R5, R6, R7, R12
-
F2. 상세 검토
- Trigger: 운영자가 검토 큐에서 신청 하나를 연다.
- Actors: A2, A3, A4
- Steps: 화면은 신청 이미지, 위험 점수와 등급, 상위 위험 사유, 내부 지문/기준 DB 근거, Naver 근거, Google 근거, 내부 LLM 요약, 분석 실패/스킵 사유를 함께 보여준다. 운영자는 근거 링크를 확인하고 승인, 보류, 반려 중 하나를 수동으로 선택하며 메모를 남긴다.
- Outcome: 자동 분석은 추천으로만 사용되고 최종 상태는 운영자 판정으로 기록된다.
- Covered by: R8, R9, R10, R11, R13, R14
-
F3. 판정 기반 기준 DB 누적
- Trigger: 운영자가 신청을 반려하거나 위험 엔티티를 수동 등록한다.
- Actors: A2, A3
- Steps: 반려 이미지의 지문과 판정 사유는 자동 누적 후보 또는 자동 기준 항목으로 남고, 운영자가 명시적으로 등록한 유명인/캐릭터/작품/별칭/정책 메모는 수동 기준 항목으로 남는다. 자동 항목과 수동 항목은 출처가 분리되어야 하며 정정 시 비활성화할 수 있어야 한다.
- Outcome: 빈 기준 DB에서 시작해도 운영자의 실제 판정이 이후 검토 품질을 높인다.
- Covered by: R15, R16, R17
-
F4. 정정 및 오염 방지
- Trigger: 운영자가 이전 반려나 기준 DB 항목이 잘못되었다고 판단한다.
- Actors: A2, A3
- Steps: 운영자는 해당 판정이나 기준 항목을 정정하고, 그 판정에서 파생된 자동 기준 항목을 비활성화하거나 재검토 대상으로 돌린다.
- Outcome: 잘못된 반려가 미래 신청의 위험도를 계속 올리는 오염을 줄인다.
- Covered by: R16, R17, R18
Requirements
상세 검토 화면
- R1. 시스템은 신청 단위 상세 검토 화면에서 원본 또는 내부 검토용 이미지, 0-100 위험 점수, 위험 등급, 상위 위험 사유를 함께 보여줘야 한다.
- R2. 상세 검토 화면은 근거를 내부 지문/기준 DB, Naver 검색, Google Web Detection, 내부 LLM 요약, 분석 실패/스킵 사유로 구분해 보여줘야 한다.
- R3. 화면은 운영자가 근거 URL, 이미지 URL, 썸네일, 출처 페이지, 검색 쿼리, 검색 시각을 확인할 수 있게 해야 한다.
- R4. 상위 위험 사유는 운영자가 바로 이해할 수 있는 문장으로 제공하되, 원천 근거와 연결되어야 한다.
- R5. 분석 실패, 외부 API 비활성화, 쿼터 초과, 검색 결과 없음은 숨기지 않고 상세 화면에 운영 사유로 표시해야 한다.
Naver 검색 보강
- R6. Naver 검색은 공식 검색 API를 통한 텍스트 쿼리 기반 근거 수집으로 제한한다.
- R7. Naver에는 원본 이미지나 축소 파생 이미지를 업로드하지 않으며, 공식 문서상 확인된 이미지 업로드 역검색 기능이 없는 것으로 취급한다.
- R8. Naver 검색 쿼리는 내부 분석 결과, OCR/라벨 후보, 기준 DB 후보, Google 근거, 운영자 등록 별칭을 바탕으로 생성할 수 있다.
- R9. Naver 검색 결과는 위험 점수를 직접 결정하지 않고, 제목, 설명, 이미지 URL, 썸네일, 원문 링크, 순위, 쿼리와 함께 근거 후보로 저장해야 한다.
- R10. Naver 검색 결과가 한국 연예인, 작품명, 캐릭터명, 방송/웹툰/게임명과 강하게 연결될 때만 위험 사유로 승격해야 한다.
내부 LLM 사용
- R11. 내부 LLM의 역할은 후보 쿼리 생성, 검색 결과 구조화, 중복/상충 근거 정리, 운영자용 요약 작성으로 제한한다.
- R12. 내부 LLM 출력은 위험 점수의 직접 입력값이나 최종 판정 근거가 아니라, 출처가 연결된 근거를 사람이 읽기 쉽게 정리한 보조 설명이어야 한다.
- R13. 내부 LLM 요약은 어떤 근거 URL과 검색 결과에서 나온 주장인지 추적 가능해야 하며, 출처 없는 추정은 위험 사유로 사용하지 않는다.
- R14. 원본 이미지, 신청자 개인정보, 외부 전송이 금지된 자료를 외부 LLM에 보내지 않는다. 이 보강 범위에서 LLM은 내부 운영 환경 또는 동등한 비보관 계약이 확인된 환경만 허용한다.
운영자 판정과 기준 DB
- R15. 상세 검토 화면의 승인, 보류, 반려 액션은 자동 분석과 분리되어야 하며 운영자가 명시적으로 선택해야 한다.
- R16. 반려 판정은 이후 유사 이미지 탐지를 위한 기준 DB 누적 후보 또는 자동 기준 항목을 만들 수 있어야 한다.
- R17. 자동 누적 항목, 운영자 수동 등록 항목, 검색 결과 기반 후보는 출처와 신뢰 수준이 구분되어야 한다.
- R18. 잘못된 판정이나 잘못된 기준 항목은 비활성화, 정정, 재검토 처리가 가능해야 한다.
- R19. 신청자 화면에는 위험 점수, 검색 근거, 내부 LLM 요약, 외부 API 사용 여부를 노출하지 않는다.
안전 경계
- R20. Google Image Search, Google Lens, Naver 웹 UI를 자동화하거나 스크래핑하지 않는다.
- R21. Google Web Detection은 기존 요구사항과 동일하게 계약, 데이터 사용 조건, 메타데이터 로그 범위, 비보관 조건이 확인된 경우에만 사용한다.
- R22. 얼굴/사람 존재 신호는 초상권 검토 신호로만 사용하며, 얼굴 인식, 유명인 식별, 생체 템플릿 저장으로 확장하지 않는다.
- R23. 검색 실패나 LLM 실패는 기존 고위험 근거를 낮추는 데 사용하지 않는다.
Acceptance Examples
- AE1. Covers R1, R2, R6, R8, R10, R11. 기준 DB가 비어 있는 상태에서 한국 연예인으로 의심되는 이미지가 들어오면, 내부 LLM은 한국어 후보 쿼리를 만들고 Naver 결과에서 인물명/작품명/이미지 링크가 연결된 근거를 상세 검토 화면에 표시한다.
- AE2. Covers R6, R7, R9. Naver 검색 보강을 실행해도 원본 이미지나 축소 이미지는 Naver에 전송되지 않고, 텍스트 쿼리와 검색 결과 메타데이터만 근거로 남는다.
- AE3. Covers R11, R12, R13. 내부 LLM이 "유명 캐릭터로 보임"이라고 요약하더라도 연결된 URL이나 검색 결과가 없으면 그 문장은 위험 점수 사유가 아니라 참고 요약으로만 표시된다.
- AE4. Covers R5, R21, R23. Naver 쿼터가 초과되거나 Google Web Detection이 비활성화되어도 내부 지문/기준 DB 근거가 고위험이면 점수는 낮아지지 않고, 실패 또는 스킵 사유가 운영자에게 표시된다.
- AE5. Covers R15, R16, R17. 운영자가 반려를 선택하면 신청 상태는 운영자 판정으로만 바뀌고, 해당 이미지 지문은 자동 누적 출처로 구분되어 이후 유사 이미지 탐지에 쓰인다.
- AE6. Covers R18. 나중에 반려가 잘못된 것으로 정정되면 그 판정에서 파생된 자동 기준 항목은 비활성화되어 이후 신청의 위험도를 올리지 않는다.
- AE7. Covers R19. 신청자는 자신의 신청 상태만 볼 수 있고, 위험 점수, Naver/Google 근거, 내부 LLM 요약, 분석 실패 사유는 볼 수 없다.
Success Criteria
- 운영자는 한 신청의 상세 화면만 보고 고위험 이미지의 주요 근거를 빠르게 파악할 수 있다.
- 한국어 검색 근거가 필요한 연예인, 방송, 웹툰, 게임, 캐릭터 사례에서 초기 기준 DB 부족을 완화한다.
- 내부 LLM은 운영자의 검색/요약 시간을 줄이지만, 출처 없는 추정이나 환각이 점수와 판정을 오염시키지 않는다.
- 반려와 정정이 기준 DB 품질을 점진적으로 높이되, 잘못된 판정이 장기 오염으로 남지 않는다.
- 이후 계획 단계가 상세 검토 화면의 근거 범위, LLM 역할, Naver 사용 경계, 신청자 비노출 정책을 새로 정의하지 않아도 된다.
Scope Boundaries
- Naver 이미지 업로드 역검색 기능은 포함하지 않는다.
- Google Image Search, Google Lens, Naver 검색 웹 UI 자동화와 스크래핑은 포함하지 않는다.
- 내부 LLM을 법적 판단자, 점수 산정자, 자동 반려 결정자로 사용하지 않는다.
- 외부 LLM 사용은 1차 보강 범위에서 제외한다. 예외가 필요하면 별도 계약/데이터 처리 검토 후 새 요구사항으로 다룬다.
- 신청자에게 자동 분석 결과를 설명하거나 이의제기 UI를 제공하는 기능은 포함하지 않는다.
- 기준 DB 전체 관리 화면, 대량 등록, 권한별 워크플로, 고급 통계 화면은 후속 보강으로 둔다.
- 브랜드 로고, 상표, 스톡 이미지 도용 전용 탐지기는 이번 보강의 중심 범위가 아니다. 검색 중 강한 근거가 발견되면 운영자 근거로만 표시한다.
Key Decisions
- 상세 검토 화면 중심: 1차 보강은 탐지 모델 자체보다 운영자가 근거를 보고 판정할 수 있는 화면을 우선한다.
- 검색 보강은 한국어 근거 확보용: Naver는 한국어 텍스트 쿼리 기반 이미지/웹 검색 근거를 보강하는 채널로 사용한다.
- 내부 LLM은 보조자: LLM은 쿼리를 만들고 결과를 정리하지만 점수와 최종 판정의 권한을 갖지 않는다.
- 근거 출처 우선: 모든 요약과 위험 사유는 가능한 한 원천 근거 URL, 검색 쿼리, 분석 출처와 연결되어야 한다.
- 오염 방지 내장: 반려 누적으로 기준 DB를 키우되, 정정과 비활성화 없이는 자동 누적이 위험하다.
Dependencies / Assumptions
- Naver 공식 이미지 검색 API 문서는 검색어와 검색 조건을 쿼리 스트링으로 전달하는 REST API로 설명하며, 검색 API 하루 호출 한도는 25,000회로 안내한다. 참고: https://developers.naver.com/docs/serviceapi/search/image/image.md
- Naver 검색 API 제품 문서도 이미지, 웹문서, 블로그, 뉴스 등 검색 결과 제공과 25,000/일 처리한도를 안내한다. 참고: https://developers.naver.com/products/service-api/search/search.md
- Naver API 이용은 제공조건, 이용 가능 횟수, 클라이언트 아이디 관리, 약관 준수가 전제다. 참고: https://developers.naver.com/products/terms
- Google Cloud Vision Data Usage FAQ는 온라인 즉시 응답 작업의 이미지 데이터는 메모리에서 처리되고 디스크에 저장되지 않으며, 일부 요청 메타데이터는 임시 로그될 수 있다고 설명한다. 참고: https://docs.cloud.google.com/vision/docs/data-usage
- Google Cloud Vision Web Detection은 웹 엔티티, 매칭 이미지, 유사 이미지, 이미지가 포함된 페이지, best guess label을 반환할 수 있다. 참고: https://docs.cloud.google.com/vision/docs/detecting-web
- 실제 관리자 앱, DB, 인증/권한 구조는 현재 작업공간에 없으므로 상세 검토 화면의 최종 UI와 저장 방식은 후속 계획에서 대상 앱 구조에 맞춰야 한다.
Outstanding Questions
Deferred to Planning
- [Affects R1-R5][Technical] 상세 검토 화면을 실제 웹 관리자 화면으로 만들지, 현재 코어에 맞춘 API/CLI 시뮬레이션으로 먼저 만들지 결정해야 한다.
- [Affects R6-R10][Needs research] Naver 검색 API의 실제 응답 품질, 결과 중복, 성인/부적절 결과, 쿼터 정책을 파일럿 샘플로 검증해야 한다.
- [Affects R11-R14][Technical] 내부 LLM의 배포 위치, 로그 보관, 프롬프트/출력 감사, 원본 이미지 입력 허용 여부를 운영 환경 기준으로 확정해야 한다.
- [Affects R16-R18][Technical] 반려 시 기준 DB에 즉시 자동 반영할지, 자동 후보로 만들고 운영자가 확정하게 할지 실제 운영 리스크를 보고 정해야 한다.