지난 글에서 소리를 주고받는 에이전트를 다뤘다. 텍스트만 다루던 구조에 다른 종류의 신호가 들어오면 무엇이 달라지는가가 주제였는데, 검색 쪽에서도 같은 문제가 있다.
기업 문서를 RAG로 다루기 시작하면 금방 벽에 부딪힌다. 사내에 쌓인 자료가 순수한 글이 아니기 때문이다. 재무 보고서는 표가 본문이고, 장비 매뉴얼은 도해가 본문이며, 계약서와 영수증은 아예 스캔 이미지다. 텍스트 추출기를 돌리면 표는 줄이 뒤섞이고 도표는 통째로 사라진다. 문서에서 가장 정보 밀도가 높은 부분이 색인에 안 들어간다.
멀티모달 RAG는 이 부분을 검색 대상으로 되돌리는 일이다.
그림을 검색 가능하게 만드는 세 가지 길
핵심 질문은 하나다. 검색 색인에 무엇을 넣을 것인가. 여기서 갈린다.
텍스트로 옮기는 길은 지금도 가장 널리 쓰인다. VLM에게 그림을 설명하게 하고, 그 설명문과 OCR 결과를 원래 문단과 함께 색인한다. 색인 이후는 평범한 텍스트 검색이라 하이브리드 검색이든 메타데이터 필터든 쓰던 것을 그대로 쓸 수 있다.
이 방식의 약점은 명확하다. 설명문에 안 적힌 것은 검색되지 않는다. "2분기 매출 추이를 보여 주는 막대그래프"라고만 적어 두면 "3월에 매출이 꺾인 자료"라는 질문에 안 걸린다. 그래서 설명문을 만들 때 무엇을 적게 할지가 실제 성능을 정한다. 요령은 일반적인 캡션을 만들지 말고 검색될 만한 것을 적게 하는 것이다. 축 이름, 범례, 단위, 눈에 띄는 값과 변곡점, 표의 열 이름을 문장으로 풀어 쓰게 한다.
같은 공간에 넣는 길은 CLIP 계열의 멀티모달 임베딩을 써서 그림과 글을 하나의 벡터 공간에 놓는다. 질문 문장을 임베딩하면 그림이 바로 검색된다. 설명문을 만들 필요가 없으니 색인이 싸고 빠르다.
대신 임베딩 모델이 학습한 범위 안에서만 동작한다. 사진이나 일러스트에는 잘 맞지만, 글자가 빽빽한 도표나 표에는 약한 경우가 많다. 이런 모델은 대체로 "무엇이 찍혀 있는가"를 배웠지 "이 표의 4행 3열이 얼마인가"를 배우지 않았다.
페이지를 통째로 두는 길은 최근에 실용화된 방식이다. 문서를 텍스트로 뜯지 않고 페이지를 이미지 그대로 두고, 시각 문서 검색 모델로 색인한다. 문서 파싱 단계가 통째로 사라지므로 표가 무너지거나 단이 뒤섞이는 문제도 함께 사라진다. 페이지를 여러 벡터로 표현하고 질의 토큰과 잘게 견주는 늦은 상호작용 방식이 여기 쓰인다.
대가는 색인 비용과 조각 크기다. 페이지 하나가 검색 단위가 되므로 인용이 페이지 단위로 거칠어진다. "이 문단에서 나왔다"가 아니라 "이 페이지 어딘가에 있다"가 된다.
실무에서는 셋 중 하나를 고르기보다 문서 종류마다 다르게 태우는 경우가 많다. 사진 자산은 공동 임베딩, 보고서·매뉴얼은 페이지 통째, 이미 잘 정리된 텍스트 문서는 기존 파이프라인 그대로 두는 식이다.
색인하는 것과 넣어 주는 것을 나눈다
여기가 멀티모달 RAG에서 가장 자주 놓치는 설계 지점이다. 검색에 쓰는 형태와 답을 만들 때 넣어 주는 형태가 같아야 할 이유가 없다.
검색은 글끼리 견주는 편이 안정적이다. 순위를 조절하기 쉽고, 왜 이게 걸렸는지 확인하기도 쉽다. 반면 답을 쓸 때는 원본 그림을 그대로 보는 편이 훨씬 정확하다. 설명문에 안 적힌 값을 물어봐도 모델이 그림을 보고 읽어 낼 수 있기 때문이다.
그래서 흔한 구성은 이렇다. 색인에는 설명문과 OCR 결과를 넣고, 검색에 걸린 조각의 원본 이미지를 꺼내 생성 단계에서 VLM에 함께 넣는다.
이 구성이 가능하려면 조건이 하나 있다. 조각마다 원본으로 되돌아갈 정보를 남겨 둬야 한다. 파일 경로, 페이지 번호, 그림의 좌표 상자까지 메타데이터로 저장한다. 이걸 안 해 두면 나중에 원본을 넣고 싶어도 못 넣고, 사용자에게 "여기 보세요"라고 위치를 보여 줄 수도 없다. 색인을 다시 만드는 것보다 처음부터 남기는 편이 훨씬 싸다.
무엇을 한 조각으로 묶을 것인가
텍스트 청킹의 규칙을 그대로 가져오면 그림이 있는 문서에서 어긋난다. 그림과 그 그림을 설명하는 문장이 서로 다른 조각에 들어가는 일이 아주 흔하기 때문이다.
묶는 원칙은 "사람이 이해하는 데 필요한 최소 단위" 다.
- 그림 하나 + 캡션 + 그 그림을 언급하는 본문 문단을 한 조각으로 묶는다. 「그림 3에서 보듯이」로 시작하는 문단은 그림 3과 함께 있어야 뜻이 산다
- 표는 통째로 한 조각이다. 행 수가 많다고 잘라 두면 열 이름이 없는 조각이 생겨 아무 데도 못 쓴다. 너무 큰 표는 잘라야 하지만, 자를 때마다 열 이름 줄을 복사해 붙인다
- 여러 쪽에 걸친 표는 이어 붙인다. 페이지가 넘어가며 잘린 표는 파싱 단계에서 합치지 않으면 뒤쪽 조각이 고아가 된다
- 문서 제목·절 제목·발행일을 조각마다 붙인다. 그림 하나만 떼어 놓으면 어느 문서의 무엇인지 알 수 없다
두 종류의 점수를 어떻게 섞나
텍스트 색인과 이미지 색인을 함께 두면 결과가 두 줄로 나온다. 이걸 한 줄로 세워야 하는데, 두 점수는 서로 비교할 수 있는 값이 아니다. 텍스트 임베딩의 코사인 유사도 0.82와 이미지 검색 점수 0.61 중 무엇이 더 관련 있는지 알 수 없다.
그래서 값 자체를 섞지 말고 순위를 섞는다. 각 목록에서 몇 번째였는지만 보고 합치는 방식(RRF 같은)이 안정적이고, 새 색인을 하나 더 붙일 때 가중치를 다시 조율하지 않아도 된다.
그리고 합친 뒤에 재순위를 한 번 더 태우는 편이 낫다. 이때 재순위 모델도 그림을 볼 수 있는 것이면 좋고, 아니면 설명문 기준으로만 다시 세운다.
새로 생기는 실패 방식
멀티모달로 넘어오면 텍스트 RAG에 없던 실패가 몇 가지 추가된다. 미리 알고 있으면 진단이 훨씬 빠르다.
그림을 잘못 읽는다. 막대그래프의 값을 눈대중으로 읽어 "약 340만 원"이라고 답하는 경우다. 정확한 숫자가 필요한 질문이라면 그림이 아니라 원본 데이터나 표를 찾아야 한다. 모델이 그림에서 읽은 값은 근사치라는 전제로 다룬다.
엉뚱한 그림을 근거로 든다. 비슷하게 생긴 도표가 문서에 여러 개 있을 때 자주 난다. 조각에 그림 번호와 캡션을 붙여 두고, 답변에 어느 그림을 봤는지 표시하게 하면 사용자가 바로 확인할 수 있다.
스캔 품질에서 조용히 무너진다. 기울어진 스캔, 도장이 겹친 글자, 흐린 팩스 문서에서 OCR이 틀리는데 오류가 아니라 그럴듯한 다른 글자로 바뀐다. 색인 시점에 OCR 신뢰도를 함께 저장해 두고, 낮은 조각은 답변에 쓰기 전에 표시하는 것이 좋다.
같은 내용이 두 형태로 들어가 중복된다. 그림과 그 그림의 설명문을 둘 다 색인하면 검색 결과 상위가 사실상 같은 것으로 채워진다. 색인에 넣을 때 어느 쪽을 대표로 삼을지 정해 두거나, 결과를 낼 때 원본 자산 기준으로 중복을 제거한다.
비용은 어디에 붙는가
멀티모달 RAG의 비용 구조는 텍스트 RAG와 모양이 다르다.
| 항목 | 언제 드는가 | 성격 |
|---|---|---|
| 설명문·OCR 생성 | 색인할 때 한 번 | 문서가 안 바뀌면 다시 안 든다 |
| 임베딩 | 색인할 때 한 번 | 텍스트보다 벡터 수가 많아질 수 있다 |
| 벡터 저장 | 계속 | 페이지를 여러 벡터로 두는 방식은 저장량이 훨씬 크다 |
| 생성 단계의 이미지 토큰 | 질의마다 | 여기가 가장 크게 는다 |
마지막 항목을 특히 주의한다. 이미지를 모델에 넣으면 해상도에 따라 토큰이 붙는데, 고해상도 페이지 이미지 세 장이면 텍스트 조각 몇십 개보다 비쌀 수 있다. 그래서 생성에 넣는 이미지 수를 검색 결과 수와 따로 관리한다. 상위 20개를 검색하되 이미지로 넣는 것은 상위 3개까지로 두고, 나머지는 설명문 텍스트로만 넣는 식이다.
해상도도 조절 대상이다. 도표의 추세만 보면 되는 질문에 원본 해상도를 넣을 이유가 없다. 반대로 작은 글자를 읽어야 하는 문서는 해상도를 낮추면 그냥 못 읽는다. 문서 종류마다 해상도 기준을 정해 둔다.
평가에서 무엇을 봐야 하나
RAG 평가의 기본 지표는 그대로 쓰되, 두 가지를 더 본다.
시각 질의만 따로 모은 평가 집합이 첫째다. "매출이 꺾인 분기", "경고 표시가 있는 부품"처럼 답이 그림에만 있는 질문을 30~50개 만들어 검색 재현율을 잰다. 전체 평가에 섞어 두면 텍스트 질의에 묻혀 안 보인다.
근거로 든 자산이 맞는지가 둘째다. 답이 맞았어도 다른 그림을 근거로 들었다면 우연히 맞은 것이다. 답변에 자산 식별자를 함께 내게 하고, 그것이 정답 자산과 일치하는지를 따로 센다. 멀티모달 평가에서 쓰는 방식들을 여기에 붙일 수 있다.
어디부터 시작할까
한꺼번에 다 하려 들면 오래 걸리고 무엇이 효과를 냈는지도 모른다. 순서는 이렇게 잡는 것이 무난하다.
- 지금 색인에서 무엇이 빠지고 있는지 센다. 문서 100건을 골라 표·도표·스캔이 몇 개인지, 그중 몇 개가 텍스트로 들어갔는지 본다. 이 숫자가 작으면 멀티모달로 갈 이유가 없다
- 표부터 처리한다. 대부분의 기업 문서에서 답이 가장 자주 들어 있는 곳이고, 표 이해는 그림보다 다루기 쉽다
- 설명문 생성을 붙여 텍스트 경로로 먼저 태운다. 기존 검색을 그대로 쓰므로 변경이 작고, 여기서 이미 상당 부분이 해결된다
- 원본 이미지를 생성 단계에 넣는다. 조각에 남겨 둔 경로로 원본을 꺼내 VLM에 함께 넣는다
- 그래도 못 찾는 질의가 남으면 공동 임베딩이나 페이지 통째 색인을 추가한다
정리
- 기업 문서에서 정보 밀도가 가장 높은 곳이 표와 도표인데, 텍스트 추출만 하면 그 부분이 색인에서 빠진다
- 그림을 색인에 넣는 길은 셋이다 — 텍스트로 옮기기 · 공동 임베딩 · 페이지 통째. 문서 종류마다 다르게 태워도 된다
- 설명문을 만들 때는 일반적인 캡션이 아니라 검색될 만한 것을 적게 한다. 축 이름, 단위, 변곡점, 열 이름
- 색인 형태와 생성 형태를 나눈다. 검색은 글로 하고 답은 원본 그림을 보고 쓰게 하는 구성이 흔하다
- 그러려면 조각마다 파일 경로·페이지·좌표를 남겨 둬야 한다. 나중에 붙이려면 색인을 다시 만들어야 한다
- 그림과 캡션과 그 그림을 언급하는 문단은 한 조각으로 묶는다. 표는 통째로 두고, 자를 때는 열 이름을 복사한다
- 텍스트 점수와 이미지 점수는 값끼리 섞지 말고 순위로 합친다
- 새 실패가 생긴다 — 그림 값을 눈대중으로 읽기, 엉뚱한 그림 인용, 스캔 OCR의 조용한 오류, 같은 내용의 중복 색인
- 비용은 생성 단계의 이미지 토큰에 몰린다. 검색 결과 수와 이미지로 넣는 수를 따로 관리한다
- 평가는 시각 질의만 모은 집합과 근거로 든 자산이 맞았는지를 따로 본다
읽어주셔서 감사합니다. 😊

