특수 데이터 RAG
이미지+텍스트 멀티모달 검색
특수 데이터 RAG
Multimodal RAG · GraphRAG · 데이터 형태별 검색 전략
텍스트 너머의 데이터를 검색한다
이미지·표·비디오·관계 — 데이터 형태에 맞는 RAG 확장 전략
텍스트 너머의 RAG
왜 특수 데이터인가 · 두 가지 확장
특수 데이터 RAG
텍스트 청킹·임베딩만으로는 닿지 않는 데이터 — 형태에 맞춘 RAG 확장
특수 데이터 RAG
문서 밖의 정보 — 이미지·표·비디오·음성, 그리고 엔티티 간 관계까지 검색 대상으로
- 이미지·표 — 메뉴 비교표, 차트
- 비디오·음성 — 영상 강의, 상담 녹음
- 관계 — 엔티티 간 연결과 의존
- 전략 — 데이터 형태가 파이프라인을 결정
표준 RAG 파이프라인(문서 → 청킹 → 임베딩 → 검색)은 앞 모듈에서 완성했습니다.
이 모듈은 그 파이프라인이 못 다루는 데이터를 다룹니다.
벡터 검색이 놓치는 질문
"예약금 환불 규정이 어떻게 되나요?"는 restaurant-policy.pdf 청크로 풀렸습니다 — 다음 두 부류는 같은 방법으로 풀리지 않습니다
형태의 문제 — 이미지 속 정보
"가격 비교표에서 디너 가격은 얼마야?"
- 메뉴 비교표·차트는 이미지 — 텍스트로 추출되지 않으면 검색에서 통째로 누락
- 비디오·음성은 아예 인덱싱 대상이 아님 — 존재하지만 찾을 수 없는 지식
관계의 문제 — 연결된 지식
"트라토리아 벨라와 페어링 가능한 와인 전부 알려줘"
- 벡터 검색은 유사 문서 몇 개만 반환 — 실제 페어링 가능한 와인은 12개
- "런치를 디너로 바꾸면 뭐가 달라져?" — 코스 간 의존 관계 정보가 필요
검색이 실패하는 원인은 모델이 아니라 데이터 형태입니다 — 이미지는 벡터에 없고, 관계는 청크에 없습니다.
두 가지 확장 — 형태에 맞는 해법
문제의 성격이 다르면 해법도 두 갈래
벡터 스토어·Knowledge Base 같은 기반은 그대로 둡니다.
인덱싱과 검색 방식을 데이터 형태에 맞게 바꾸는 것이 이 모듈의 주제입니다.
Multimodal RAG
이미지·표 인덱싱 · 비디오·음성 · Data Automation
Multimodal RAG
텍스트뿐 아니라 이미지·표·비디오·음성을 함께 인덱싱하고 검색하는 RAG
Multimodal RAG
텍스트 질문 하나로 이미지 속 표, 영상 속 설명까지 찾아냅니다
- 이미지·표 — Vision 추출 또는 멀티모달 임베딩
- 비디오·음성 — Transcribe + 타임스탬프 청킹
- 자동화 — Bedrock Data Automation 파싱
- 검색 — 텍스트 쿼리로 이미지까지
파이프라인의 뼈대는 그대로 — 바뀌는 것은 인덱싱 앞단뿐입니다.
특수 포맷을 벡터 공간에 올리는 방법만 익히면 됩니다.
두 가지 인덱싱 경로 — 변환 vs 직접 임베딩
이미지를 벡터 공간에 올리는 두 경로 — 규모와 정확도 요구가 갈림길
Vision 캡셔닝 → 텍스트 임베딩
변환 후 인덱싱
- Vision 모델이 이미지를 캡션·마크다운 표로 변환
- 기존 텍스트 RAG 파이프라인과 그대로 호환
- 변환 프롬프트를 도메인에 맞게 커스터마이즈 가능
- 인제스트가 느리고 비용 높음 — 이미지마다 LLM 호출
상세하고 정밀한 이미지 설명이 검색 품질을 좌우할 때 — 캡션 프롬프트가 재현율을 결정합니다.
멀티모달 임베딩
직접 인덱싱
- Nova Multimodal Embeddings가 이미지·비디오·오디오를 직접 벡터화
- 모든 모달리티를 하나의 통합 의미 공간에 — 텍스트 쿼리로 비디오 검색
- 인제스트가 빠르고 비용 효율 — LLM 호출 없음
- 이미지 입력 쿼리 시 지연도 유리
대규모·범용 크로스모달 검색의 기본 선택 — AWS 공식 비교 기준 인제스트 비용·속도 우위입니다.
갈림길은 규모가 아니라 설명의 정밀도입니다 — 도메인 특화 설명이 필요하면 캡셔닝, 대규모 범용 크로스모달 검색이면 멀티모달 임베딩.
멀티모달 임베딩 모델 — Titan vs Nova
직접 임베딩 경로의 모델 선택 — 모달리티 커버리지와 차원이 가르는 기준
| 항목 | Titan Multimodal G1 | Nova Multimodal Embeddings |
|---|---|---|
| 모달리티 | 텍스트 + 이미지 2종 | 텍스트 · 이미지 · 문서 이미지 · 비디오 · 오디오 5종 |
| 출력 차원 | 1,024 · 384 · 256 | 3,072 · 1,024 · 384 · 256 |
| 텍스트 입력 | 최대 256 토큰 (영어) | 최대 8K 토큰 |
| 세그멘테이션 | 없음 | 비동기 API가 긴 비디오·오디오·텍스트 자동 분할 |
| 용도 최적화 | 없음 | embeddingPurpose — 인덱스·검색·분류·클러스터링별 |
신규 구축은 Nova Multimodal Embeddings가 기본 — 5개 모달리티를 하나의 통합 의미 공간에 올려, 텍스트 질문으로 비디오 구간까지 찾습니다. Knowledge Base 임베딩 모델로도 선택할 수 있습니다(멀티모달 리트리벌).
이미지 속 표를 꺼내는 코드 — Vision 추출
가격 비교표 이미지를 마크다운 표로 변환해 기존 벡터 스토어에 추가
import boto3
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
def extract_table_from_image(image_path: str) -> str:
with open(image_path, "rb") as f:
image_bytes = f.read()
# ① 이미지와 텍스트를 한 메시지로 전달 — Vision 모델이 표를 읽음
response = bedrock.converse(
modelId="us.anthropic.claude-sonnet-4-6",
messages=[{"role": "user", "content": [
{"image": {"format": "png", "source": {"bytes": image_bytes}}}, # ② 표·차트는 PNG
{"text": "이 가격 비교표를 마크다운 테이블로 변환해주세요. 모든 숫자를 정확하게 포함하세요."}, # ③ 추출 프롬프트
]}],
)
# ④ 반환된 마크다운 표 → 기존 텍스트 임베딩 파이프라인에 그대로 추가
return response["output"]["message"]["content"][0]["text"]
- bedrock.converse — 이미지+텍스트를 한 메시지로. 요청당 이미지 20개 · 이미지당 3.75MB·8,000px 제한 — 대용량은 S3 URI 소스로
- "format": "png" — 표·차트는 PNG가 텍스트 추출 정확도가 높음 (사진은 JPEG)
- 프롬프트 — "모든 숫자를 정확하게". 검색 최적화 캡션이 재현율을 좌우
- 인덱싱 — 추출된 마크다운 표는 평범한 텍스트 — 기존 벡터 스토어에 그대로 추가
표 이미지가 검색 가능한 텍스트로
Vision 추출의 입력과 출력 — 이미지였던 표가 임베딩 가능한 마크다운이 되는 순간
| 코스 | 평일 | 주말 |
|---|---|---|
| 런치 | 45,000 | 55,000 |
| 디너 | 89,000 | 99,000 |
→
converse
Vision
비디오·음성 — 트랜스크립트 + 타임스탬프
영상과 녹음을 검색 가능한 텍스트로 — 구간까지 짚어주는 답변
-
1
변환
Amazon Transcribe로 음성을 텍스트로 — 한국어 포함 100+ 언어, 화자 분리·자동 언어 감지 지원.
-
2
청킹
트랜스크립트를 60초 단위로 분할 — 비디오 1시간이면 약 60개 청크, 임베딩 비용은 미미.
-
3
메타데이터
각 청크에 start_time·end_time과 원본 파일 경로를 기록 — 출처 추적의 재료.
-
4
답변
"2분 30초~3분 30초 구간에서 설명합니다" — 프론트엔드에서 해당 구간 점프 링크 생성.
파이프라인 자체는 텍스트 RAG와 같습니다 — 차이를 만드는 것은 타임스탬프 메타데이터입니다.
파싱 자동화 — Bedrock Data Automation
PDF의 표·이미지·텍스트를 자동 구조화 — Knowledge Base 파싱 전략으로 직접 연결
import boto3
bedrock_agent = boto3.client("bedrock-agent", region_name="us-east-1")
# ① Knowledge Base 데이터 소스에 Data Automation 파싱 전략 연결
bedrock_agent.create_data_source(
knowledgeBaseId="KB-RESTAURANT-001",
name="terms-with-tables",
dataSourceConfiguration={
"type": "S3",
"s3Configuration": {"bucketArn": "arn:aws:s3:::restaurant-docs"},
},
vectorIngestionConfiguration={"parsingConfiguration": {
# ② 파서 지정 — 인제스트 시 자동 파싱
"parsingStrategy": "BEDROCK_DATA_AUTOMATION",
# ③ MULTIMODAL — 텍스트 + 표 + 이미지를 모두 구조화 추출
"bedrockDataAutomationConfiguration": {"parsingModality": "MULTIMODAL"},
}},
)
- create_data_source — S3 원본을 Knowledge Base에 연결하면서 파싱 전략까지 선언. 별도 전처리 파이프라인 불필요
- parsingStrategy — 파서 선택: BDA(완전관리형·페이지 과금) vs 파운데이션 모델 파서(추출 프롬프트 커스터마이즈·토큰 과금)
- parsingModality — MULTIMODAL이면 표·이미지까지 구조화, TEXT_ONLY는 표를 평문으로 뭉침. 이미지 원본은 Supplemental Data Storage(S3)에 저장돼 출처로 반환 — Knowledge Base 생성 후 추가 불가
GraphRAG
엔티티·관계 · 하이브리드 검색 · Neptune Analytics
GraphRAG
엔티티와 관계로 지식을 구조화해, 벡터 검색이 못 푸는 관계 질문에 답하는 RAG
GraphRAG
유사한 문서를 찾는 대신, 관계의 선을 따라 답을 모읍니다
- Entity — 문서에서 추출한 개체 (노드)
- Relation — 개체 간 관계 (포함·의존·호환)
- 다중 홉 — A→B→C 경로 추론
- 하이브리드 — 그래프 탐색 + 벡터 검색 결합
"페어링 가능한 와인 전부" — 유사 문서 몇 개가 아니라 관계를 끝까지 따라가야 하는 질문이 GraphRAG의 자리입니다.
GraphRAG 아키텍처
문서 하나에서 그래프와 벡터를 함께 만들고 검색에서 결합 — 벡터는 유사도, 그래프는 관계 담당
그래프 구축 과정
LLM 자동 추출 + 사람 검증 — 문서가 트리플이 되기까지 4단계
-
1
엔티티 추출
LLM에 문서를 입력해 (엔티티, 타입)을 추출합니다 — 레스토랑 · 와인 · 코스 같은 도메인 개체.
-
2
관계 추출
엔티티 쌍 사이의 관계 유형을 추론합니다 — includes · requires · pairs_with 같은 명시적 엣지.
-
3
사람 검증
추출된 트리플을 도메인 전문가가 샘플 검증합니다 — LLM 오추출을 보정하는 품질 게이트.
-
4
적재 · 증분 갱신
Neptune Analytics 또는 인메모리 그래프에 적재합니다 — 문서 변경 시 영향받는 엔티티·관계만 증분 업데이트.
추출은 자동, 품질은 사람 — 샘플 검증 없는 그래프는 오추출을 그대로 추론에 사용하게 됩니다.
그래프 + 벡터 — 하이브리드 에이전트
질문 유형에 따라 그래프 검색과 벡터 검색을 골라 쓰는 에이전트
핵심 포인트
- search_graph
- "페어링 가능한 와인 전부" — 관계·의존성 질문 담당
- search_docs
- "예약 취소 절차는?" — 정책·설명 텍스트 질문 담당
- 자동 선택
- 시스템 프롬프트의 기준대로 에이전트가 도구를 고름
- 복합 질문
- "디너로 바꾸면 뭐가 달라지고, 취소 규정은?" — 두 도구 결합
코드
from strands import Agent, tool
import boto3
bedrock_rt = boto3.client("bedrock-agent-runtime", region_name="us-east-1")
# 그래프 검색 도구 — 엔티티의 관계를 직접 탐색
@tool
def search_graph(entity_name: str, relation: str = "") -> str:
"""레스토랑·와인·코스 간 관계를 그래프에서 검색합니다."""
return format_relations(find_related(find_entity(entity_name), relation))
# 벡터 검색 도구 — 정책·설명 텍스트는 Knowledge Base Retrieve로, 선택은 에이전트가
@tool
def search_docs(query: str) -> str:
"""메뉴·정책·FAQ 텍스트를 벡터 검색합니다."""
resp = bedrock_rt.retrieve(knowledgeBaseId="KB-RESTAURANT-001",
retrievalQuery={"text": query})
return "\n\n".join(r["content"]["text"] for r in resp["retrievalResults"][:3])
agent = Agent(tools=[search_graph, search_docs])
그래프 적용 기준
모든 질문에 그래프가 필요한 것은 아님 — 두 번의 질문으로 판단
벡터 RAG가 실패한 질문 중 관계 추론 비중이 크면(예시 기준: 30%+) 도입 가치가 있습니다 — 시작은 인메모리, 확장은 Neptune입니다.
선택 가이드
데이터 형태별 전략 · 실습
데이터 형태별 전략 선택
질문을 받으면 데이터 형태부터 — 형태가 전략과 도구를 결정
| 데이터 형태 | 대표 질문 | 전략 | 핵심 도구 |
|---|---|---|---|
| 텍스트 문서 | "예약 취소 절차는?" | 표준 벡터 RAG | Knowledge Bases (Knowledge Bases 모듈) |
| 이미지 · 표 | "비교표에서 디너 가격은?" | Vision 추출 또는 멀티모달 임베딩 | Claude Vision · Nova MM Embeddings |
| 비디오 · 음성 | "몇 분쯤에 설명하나?" | 트랜스크립트 + 타임스탬프 청킹 | Amazon Transcribe |
| 복잡한 PDF | 표·이미지가 섞인 약관 | 자동 구조화 파싱 | Bedrock Data Automation |
| 관계 질문 | "페어링 가능한 와인 전부?" | GraphRAG 하이브리드 | Neptune Analytics |
직접 구축 전에 확인 — Knowledge Base 멀티모달 리트리벌(Nova Multimodal Embeddings를 Knowledge Base 임베딩 모델로)과 BDA·파운데이션 모델 멀티모달 파서로 이미지·비디오·오디오를 관리형으로 인덱싱할 수 있습니다.
Knowledge Base 3종의 선택 기준은 Knowledge Bases 모듈에서 다뤘습니다 — 여기서의 결정 축은 데이터 형태입니다.
특수 데이터 RAG 실습
멀티모달 검색과 그래프 검색을 직접 구축합니다
학습 목표
- Vision 모델로 이미지 속 표를 추출해 벡터 스토어에 인덱싱
- 텍스트 쿼리로 이미지 정보를 검색하는 Multimodal RAG 완성
- 엔티티·관계를 추출해 지식 그래프 구축
- 그래프 검색 + 벡터 검색 하이브리드 에이전트 구현
이미지·표·비디오는 멀티모달로, 관계는 그래프로 — 형태에 맞게 확장