[0. 핵심 설계 규칙 (TL;DR)]

이미지를 “객관적 구조화 설명문으로 전사할 대상”으로 정의.

이미지 1장을 VLM으로 객관적 설명문으로 만들고, 이를 임베딩해 RAG 인덱스에 적재. → 다양한 다운스트림 질의는 개별 이미지에 매번 질문하지 않고 검색(retrieval)으로 흡수됨. (multi-modal embedding 모델은 추후 도입 예정)

이미지 → [VLM] 객관적 구조화 설명문 → 임베딩 → RAG 인덱스 → (다운스트림) 검색/질의응답
  • VLM은 추측/판정하지 않고 이미지에서 객관적으로 확인 가능한 요소만 빠짐없이 기술해야 한다
    • 하나의 범용 설명문이 서로 다른 유형의 질의를 한 벌의 임베딩으로 커버할 수 있도록.

[1. 문제 정의 & 접근 전환]

1.1 하나의 설명문이 커버해야 하는 다운스트림

  • 단일 범용 프롬프트로 뽑은 하나의 설명문이 임베딩 후 아래 질의 유형을 검색으로 커버해야 함.
다운스트림 유형 예시 설명문에서 이를 가능하게 하는 부분
내용 검색 “균열 보이는 현장”, “조직도 이미지”, “안전모 미착용자” Type / Summary / Details
이미지 내 텍스트 조회 “이 영수증 금액/날짜”, “명함 정보” Text(원문 그대로) / Table
단건 해석 “이 다이어그램 구조”, “그래프 최고 항목” Diagram / Chart / Details
객관적 검증 “서명 누락 여부”(이미지로 확인 가능) Details / Text
위치/시각 “토스카나에서 찍은 사진”, “2008년 촬영” Capture metadata

1.2 의도적으로 범위 밖에 둔 것

“객관 사실 전사”라는 규칙 하에 의도적으로 제외. 주관/규범/집계를 파서에서 빼야 환각과 책임 범위가 통제됨.

  • 규범적 판정 - “안전기준 충족?”처럼 국가/상황마다 다른 외부 기준이 필요한 판단은 배제. 단 “서명이 있다/없다”처럼 이미지로 객관 확인 가능한 사실은 포함.
  • PII/보안 검출 - 자체 비식별화 필요 x. (영스증/계약서 이미지 업로드 고려)

[2. 설명문 구조 - 8섹션 + 객관성 규칙]

하나의 프롬프트로 항상 동일한 섹션 틀을 채우고 내용이 없는 섹션은 생략

다양한 시나리오(영수증/차트/조직도/현장사진)를 한 틀로 흡수하고 객관 사실만 채워 환각을 줄임.

2.1 8섹션 정의

섹션 내용 역할
Type • 이미지 종류
  • 영수증
  • 명함
  • 차트
  • 조직도
  • 현장사진
  • etc …
헤더 / 검색 필터
Summary 객관적 1문장 요약 헤더 / 자기설명
Details 보이는 장면/객체/구성/배치 본문 / 외형
Text 이미지 내 텍스트 원문 그대로(verbatim) 본문 / OCR (번역 금지, 언어 보존)
Table 격자형 전부(표/시간표/가격표)를
GFM 마크다운 표로 재현
본문 / 행/열 보존
Chart 그래프(막대/선/원/산점)만. 축/범례/
계열 + 보이는 라벨/값만
본문 / 값 추정 금지
Diagram 다이어그램/플로차트/조직도의 노드/
연결 구조
본문 / 구조
Capture metadata 위치(좌표/지명)/촬영시각/방향/고도 헤더 / EXIF/geocoding 사실
  • 헤더 섹션(Type/Summary/Capture metadata): 모든 chunk에 복제되어 이미지 자체 설명을 보조
  • 본문 섹션(Details/Text/Table/Chart/Diagram): 청킹 대상.
  • 서술 언어는 출력 언어 파라미터 단 Text 섹션의 원문은 원어 그대로 보존.

2.2 객관성 8규칙

프롬프트에 명시하는 제약(실험 및 튜닝 결과).

  1. 보이는 것만 기술 - 추론/추측/인상 평가 금지 (들판 사진을 좌표만 보고 “아레초 농가”로 단정 X)
  2. 규범적 판정 금지 - 외부 기준이 필요한 적법성/안전기준 판단 X
  3. 텍스트 번역 금지, 원문 보존 - 판독 불가 시 [판독불가]
  4. 표/차트 값 임의 계산/추정 금지 - 인쇄된 값/라벨만
  5. 촬영 메타데이터는 “메타데이터 기반 사실”로 분리 표기 - 시각적 관찰과 섞지 않음
  6. 빈 섹션은 생략 - 없는 정보를 채우지 않음
  7. 섹션 내용을 코드펜스로 감싸지 않음 - 마크업 추가 금지 (영수증 OCR을 코드펜스로 감싸 렌더 깨진 이슈 보정)
  8. 섹션 간 중복 회피 - Details=외형 / Text=원문 전사 / Table=격자 / Diagram=구조로 역할 분리
  • 시나리오 튜닝 과정에서의 주요 보정: ① Text 코드펜스 금지, ② 시간표/일정표를 Chart가 아닌 Table로 라우팅, ③ 섹션 중복 축소.
  • 위 8가지 규칙은 관념/추측으로 고정된 것이 아닌 반복 실험을 통해 고정된 것들임

2.3 길이 정책 - 생성부 제한, 추출부 무제한

  • 생성 섹션(VLM 서술: Summary/Details/Chart/Diagram): 완만한 상한(Summary 1문장, Details ≤~200단어 등).
  • 추출 섹션(verbatim: Text/Table): 인위적 상한 없음 - 자르면 검색 recall이 깨진다. 길이는 이미지 내용에 종속.
  • VLM 호출은 max_completion_tokens를 넉넉히(8192) 두어 긴 문서 truncation을 방지.

생성은 절제, 추출은 보존 → 객관적 사실을 빠짐없이 전사하기 위함


[3. 위치 파이프라인 설계]

위치 정보는 이미지에서 추측한 정보가 아닌 메타데이터에서만 추출

3.1 위치 정보 성격별 조사

작업 필요한 것 도구 의존성
① 좌표(위/경도) 읽기 EXIF GPS IFD 어느 라이브러리나 동일 결과
② XMP/IPTC 지명 태그 읽기 XMP/IPTC 블록 특정 라이브러리만 가능
③ reverse geocoding(좌표→지명) 외부 API 또는 오프라인 DB 메타데이터 라이브러리와 무관

결론: ①+③. 좌표를 읽어 지명으로 변환하는 채택. 이미지 위치 메타데이터에 대해 일관적으로 정상 동작하는 것으로 확인 (동작 안정성 확보)

3.2 좌표 추출 - Pillow

6개 메타데이터 라이브러리에 동일 샘플을 적용한 결과 모두 같은 좌표를 산출함을 확인. 좌표 정확도는 변별력이 없으므로 선택 기준은 견고성/포맷/생태계가 됨

  • Pillow 채택:
    • VLM 파이프라인은 어차피 이미지를 디코딩/리사이즈로 Pillow에 넣는다
    • 이미 존재하는 의존성이라 좌표 읽기에 재활용.
      • 포맷 커버리지 넓고 견고.

3.3 좌표 → 지명 - offline geocoder

  • 오프라인 reverse_geocoder 채택:
    • api key X / 네트워크X / 무제한
    • 좌표→국가/행정구역/도시(도시 레벨). (도로명/POI까지는 필요하지 X)
    • 좌표를 외부로 전송하지 않아 프라이버시에도 유리.
    • 대량 배치/rate limit 회피에 강점.

3.4 VLM 주입 - 관찰과 사실의 분리

  • 좌표/지명/방향/촬영시각을 촬영 메타데이터 문자열로 만들어 Capture metadata 섹션 입력으로 주입
  • VLM에는 이를 “메타데이터 기반 사실”로 표기하고 시각적 관찰과 정보를 혼합하지 않도록 지시

[4. 청킹 전략]

설명문 한 건을 1개 벡터로 임베딩하면 정보가 희석돼 recall이 떨어짐. 의미 단위로 나누되 각 chunk가 단독으로도 검색/이해 가능하게 만드는 것이 목표.

4.1 핵심 결정

항목 결정 이유
분할 단위 하이브리드(섹션 경계 우선, 작은 섹션 병합, 큰 섹션만 내부 분할) 의미 보존 + chunk 수 최소화
공통 헤더 Type/Summary/Capture metadata를 모든 chunk에 복제(≤250자) chunk 단독 자기설명성 ↑ (contextual header)
크기 상한 chunk 전체(헤더+본문) ≤ 1000자 하드 상한 길이 폭주 방지, 임베딩 입력 안정화
측정 단위 문자 수(모델 비종속) 임베딩 모델 미정 + 기존 텍스트 청커도 문자 기반. 추후 토크나이저 교체 가능하게 함수 분리
산문 분할 langchain RCTS 위임 기존 텍스트 청커와 동일 엔진/세퍼레이터/overlap
표 분할 행 경계 분할 + 헤더행 반복 표 무결성 보존(셀 중간 분할 금지)
메타 필드 type/location/timestamp를 본문 외 structured 필드로도 저장 하이브리드 검색(필터+벡터)

4.2 알고리즘 요지

  1. ## 헤더로 섹션 분리 → 공통 헤더 1블록 구성(≤250자)
  2. 본문 예산 = 상한 − 헤더 길이
  3. 섹션이 예산 이하면 atomic 유지, 초과 시 표는 행 경계, 산문은 RCTS로 분할(2번째 조각부터 (cont.) 라벨)
  4. 그리디 패킹: 본문 블록을 예산 초과 직전까지 병합(작은 섹션 흡수)
  5. 하드 상한 보장: RCTS는 soft target이므로 초과분을 한 번 더 재분할, 최후엔 hard-cut으로 강제

[5. 다국어 출력 설계]

설명문의 서술 언어(output_language)를 요청마다 결정

  • 결정 흐름: 파일 소유 회사 식별자를 파싱 메시지로 넘겨받아 → 내부 회사정보 API로 국가/언어 코드를 조회 → 언어명으로 매핑해 프롬프트에 per-request 주입.
  • fail-soft 원칙: 조회 실패/응답에 코드 없음/식별자 없음/API 미설정 - 모든 비정상 경로는 영어(English)로 귀결하며 이미지 파싱을 중단시키지 않도록 함. 위치 정보 조회 실패가 전체 파싱을 중단시키지 않는 것과 같은 원칙(부가 정보의 결핍은 본 기능을 차단하지 않는다.).
  • 언어 코드→언어명 변환은 기존에 쓰던 표준 라이브러리를 재사용해 매핑 유지 비용을 낮춤.

“보조 정보(언어/위치) 추출 실패로 인한 본 파이프라인(설명 생성) 중단은 없다” 는 일관된 방어를 유지


[6. 검증 결과]

6.1 시나리오 (E2E)

9종 시나리오로 파이프라인 전 구간을 실행, 다국어 verbatim OCR/표/차트/도식/메타데이터가 정상 산출됨을 확인.

시나리오 확인 포인트
영수증 / 제품 verbatim OCR(다국어), 촬영시각 메타데이터
차트(영/한) 축/범례/계열/인쇄값만(추정 없음), Chart 섹션
표(일) GFM 표 재현, 시간표→Table 라우팅
조직도 / 플로차트 노드/연결 구조(Diagram)
균열 현장 객관적 외형 기술(규범 판정 없음)
장소 EXIF GPS → 지명 → Capture metadata 분리 표기

6.2 청킹 (하드캡 보장)

대상 원문 chunks 최대 chunk 결과
영문 차트 1,525자 2 862자 O (≤1000)
일본어 표 1,450자 2 949자 O
조직도 2,258자 3 940자 O (섹션 분리)
합성 긴 산문 1,733자 2 940자 O (RCTS 분할 + overlap + (cont.))

전 케이스 하드 상한 ≤1000 보장, 작은 섹션 병합/큰 섹션 분할/헤더 복제/overlap 정상.