1. 문서 개요
| 항목 |
내용 |
| 문서 목적 |
Cohere Embed v4를 Amazon Bedrock Runtime API로 호출하기 위한 개발 가이드 |
| 대상 모델 |
Cohere Embed v4 |
| 호출 방식 |
Amazon Bedrock Runtime InvokeModel |
| 주요 용도 |
RAG, 문서 검색, 상품 검색, 이미지 검색, 멀티모달 검색, 분류용 임베딩, 클러스터링용 임베딩 |
| 제외 범위 |
Cohere 직접 API, Cohere SDK, 자체 모델 배포, Bedrock Knowledge Base 자동 구성 |
| 핵심 특징 |
텍스트, 이미지, 텍스트와 이미지 혼합 입력을 하나의 임베딩 모델로 처리 가능 |
Cohere Embed v4는 텍스트와 이미지를 같은 의미 공간의 벡터로 변환할 수 있는 멀티모달 임베딩 모델이다. 따라서 텍스트 검색뿐 아니라 이미지 검색, 상품 이미지 검색, PDF 페이지 검색, 차트와 표 검색, 스캔 문서 검색에도 사용할 수 있다.
2. Bedrock 호출 개요
| 구분 |
설정값 |
| AWS 서비스 |
bedrock-runtime |
| API |
InvokeModel |
| Content-Type |
application/json |
| Accept |
application/json |
| 권한 |
bedrock:InvokeModel |
| 서울 리전 |
ap-northeast-2 |
| 서울 리전 권장 모델 ID |
global.cohere.embed-v4:0 |
| 일반 In-Region 모델 ID 예시 |
cohere.embed-v4:0 |
| Streaming |
미지원 |
서울 리전에서 사용할 경우에는 global inference profile을 사용하는 구성이 안전하다.
| 환경변수 |
권장값 |
| AWS_REGION |
ap-northeast-2 |
| BEDROCK_COHERE_EMBED_MODEL_ID |
global.cohere.embed-v4:0 |
3. API Request Body 전체 요약
| 필드 |
필수 여부 |
타입 |
주요 값 |
설명 |
| input_type |
필수 |
string |
search_document, search_query, classification, clustering |
임베딩의 사용 목적을 지정 |
| texts |
선택 |
string array |
텍스트 배열 |
텍스트만 임베딩할 때 사용 |
| images |
선택 |
string array |
data:image 형식의 base64 문자열 |
이미지만 임베딩할 때 사용 |
| inputs |
선택 |
object array |
content 배열 |
텍스트와 이미지를 함께 임베딩할 때 사용 |
| embedding_types |
선택 |
string array |
float, int8, uint8, binary, ubinary |
반환받을 임베딩 타입 |
| output_dimension |
선택 |
integer |
256, 512, 1024, 1536 |
출력 벡터 차원 |
| truncate |
선택 |
string |
NONE, LEFT, RIGHT |
입력 길이 초과 시 자르는 방식 |
| max_tokens |
선택 |
integer |
최대 128000 |
입력당 토큰 예산 |
입력 필드는 texts, images, inputs 중 목적에 맞는 하나를 선택하는 방식으로 설계하는 것이 안전하다.
| 입력 목적 |
사용 필드 |
| 텍스트만 임베딩 |
texts |
| 이미지만 임베딩 |
images |
| 텍스트와 이미지를 함께 임베딩 |
inputs |
4. input_type 선택 기준
input_type은 가장 중요한 파라미터다. 단순히 입력 형식을 뜻하는 값이 아니라, 모델에게 이 임베딩을 어떤 용도로 사용할지 알려주는 값이다.
| input_type |
사용 목적 |
대표 사용처 |
검색용 여부 |
| search_document |
검색 대상 데이터를 임베딩 |
문서 chunk, 상품 설명, FAQ, PDF 페이지, 상품 이미지 |
예 |
| search_query |
검색 조건을 임베딩 |
사용자 질문, 검색어, 사용자 업로드 이미지, 이미지와 텍스트 조건 |
예 |
| classification |
분류 모델의 입력 feature 생성 |
리뷰 감성 분류, 문의 유형 분류, 문서 유형 분류 |
아니오 |
| clustering |
비슷한 데이터끼리 묶기 위한 feature 생성 |
VOC 그룹화, 상품군 자동 묶기, 유사 이미지 군집화 |
아니오 |
5. search_document
5.1 개념
| 항목 |
내용 |
| 의미 |
검색 대상이 되는 데이터를 임베딩하는 모드 |
| 저장 위치 |
Vector DB에 저장되는 데이터 |
| 대표 대상 |
문서, 상품, FAQ, 매뉴얼, 약관, OCR 텍스트, PDF 페이지, 상품 이미지 |
| 검색 구조 |
search_document로 저장하고 search_query로 검색 |
5.2 언제 사용하는가
| 상황 |
search_document 사용 여부 |
| RAG 문서 chunk를 저장한다 |
사용 |
| 상품명과 상품설명을 저장한다 |
사용 |
| FAQ 데이터를 저장한다 |
사용 |
| PDF 페이지 OCR 결과를 저장한다 |
사용 |
| 상품 이미지를 저장한다 |
사용 |
| 이미지와 상품명을 함께 저장한다 |
사용 |
| 사용자가 입력한 검색어를 임베딩한다 |
사용하지 않음 |
| 사용자가 올린 검색용 이미지를 임베딩한다 |
사용하지 않음 |
5.3 판단 기준
| 질문 |
답 |
| 이 데이터가 Vector DB에 저장될 검색 대상인가? |
예라면 search_document |
| 이 데이터가 사용자의 검색 조건인가? |
예라면 search_query |
6. search_query
6.1 개념
| 항목 |
내용 |
| 의미 |
검색을 수행하기 위한 질의나 조건을 임베딩하는 모드 |
| 저장 위치 |
일반적으로 Vector DB에 저장하지 않음 |
| 대표 대상 |
사용자 질문, 검색어, 검색 조건, 사용자 업로드 이미지 |
| 검색 구조 |
search_query 벡터로 search_document 벡터를 검색 |
6.2 언제 사용하는가
| 상황 |
search_query 사용 여부 |
| 사용자가 검색창에 입력한 문장을 임베딩한다 |
사용 |
| RAG 질문을 임베딩한다 |
사용 |
| 사용자가 올린 이미지로 유사 상품을 찾는다 |
사용 |
| 이미지와 텍스트 조건을 함께 입력받아 검색한다 |
사용 |
| 상품 설명을 Vector DB에 저장한다 |
사용하지 않음 |
| 문서 chunk를 Vector DB에 저장한다 |
사용하지 않음 |
6.3 판단 기준
| 질문 |
답 |
| 이 입력이 검색을 수행하기 위한 조건인가? |
예라면 search_query |
| 이 입력이 검색 대상 DB에 저장될 원본 데이터인가? |
예라면 search_document |
7. classification
7.1 개념
| 항목 |
내용 |
| 의미 |
분류 작업에 사용할 feature vector를 생성하는 모드 |
| 대표 목적 |
라벨 분류 |
| 사용 예 |
리뷰 감성 분류, 문의 유형 분류, 문서 유형 분류 |
| 주의점 |
Embed v4가 직접 라벨을 반환하는 것은 아님 |
classification은 임베딩 벡터를 만들 뿐이다. 실제 라벨 예측은 별도의 분류기, nearest label 방식, LightGBM, MLP, 로지스틱 회귀, SVM 등으로 처리해야 한다.
7.2 언제 사용하는가
| 상황 |
classification 사용 여부 |
| 리뷰를 긍정, 부정, 중립으로 분류한다 |
사용 |
| 고객 문의를 배송, 환불, 교환으로 분류한다 |
사용 |
| 문서를 계약서, 영수증, 청구서로 분류한다 |
사용 |
| 상품 이미지를 카테고리별로 분류한다 |
사용 |
| 사용자 검색어로 문서를 찾는다 |
사용하지 않음 |
| 상품 검색 인덱스를 만든다 |
사용하지 않음 |
8. clustering
8.1 개념
| 항목 |
내용 |
| 의미 |
비슷한 데이터끼리 자동으로 묶기 위한 feature vector를 생성하는 모드 |
| 대표 목적 |
군집 분석 |
| 사용 예 |
VOC 주제 그룹화, 유사 상품 묶기, 유사 이미지 묶기 |
| 후처리 |
K-Means, DBSCAN, HDBSCAN 같은 클러스터링 알고리즘 필요 |
8.2 언제 사용하는가
| 상황 |
clustering 사용 여부 |
| 고객 문의를 비슷한 주제끼리 묶는다 |
사용 |
| 상품 이미지를 비슷한 것끼리 그룹화한다 |
사용 |
| 리뷰를 주제별로 자동 그룹화한다 |
사용 |
| 중복 이미지 후보를 찾는다 |
사용 |
| 사용자의 검색어로 문서를 찾는다 |
사용하지 않음 |
| RAG 검색용 문서를 저장한다 |
사용하지 않음 |
9. input_type 최종 판단표
| 목적 |
입력 예시 |
사용해야 할 input_type |
| 문서 검색용 인덱스 생성 |
약관, 매뉴얼, FAQ, 보고서 chunk |
search_document |
| 상품 검색용 인덱스 생성 |
상품명, 상품 설명, 상품 속성 |
search_document |
| 이미지 검색용 인덱스 생성 |
상품 이미지, 문서 이미지, PDF 페이지 이미지 |
search_document |
| 사용자 텍스트 검색 |
검은색 가벼운 운동화 찾아줘 |
search_query |
| 사용자 이미지 검색 |
사용자가 업로드한 신발 사진 |
search_query |
| 사용자 이미지와 텍스트 조건 검색 |
이 사진과 비슷한데 검은색으로 찾아줘 |
search_query |
| 리뷰 감성 분류 |
배송이 늦어서 불만입니다 |
classification |
| 문의 유형 분류 |
환불하고 싶습니다 |
classification |
| 비슷한 문의 묶기 |
여러 VOC 문장 묶음 |
clustering |
| 유사 이미지 그룹화 |
상품 이미지 묶음 |
clustering |
10. 입력 방식 선택 기준
10.1 texts
| 항목 |
내용 |
| 사용 목적 |
텍스트만 임베딩 |
| 대표 입력 |
문서 chunk, 상품 설명, FAQ, 검색어, 질문 |
| 요청당 최대 개수 |
96개 |
| 함께 쓰면 안 되는 필드 |
images |
| 텍스트와 이미지를 함께 넣어야 하는 경우 |
inputs 사용 |
| 사용 예 |
권장 여부 |
| 문서 chunk 저장 |
권장 |
| 사용자 질문 검색 |
권장 |
| 상품 설명 검색 |
권장 |
| 이미지와 상품명을 함께 검색 대상으로 저장 |
inputs 권장 |
10.2 images
| 항목 |
내용 |
| 사용 목적 |
이미지만 임베딩 |
| 대표 입력 |
상품 이미지, 사용자 검색 이미지, 문서 페이지 이미지 |
| 전달 방식 |
data:image 형식의 base64 문자열 |
| 지원 형식 |
png, jpeg, webp, gif |
| 이미지 최대 크기 |
5MB |
| 요청당 최대 개수 |
96개 |
| 전체 요청 payload |
약 20MB 제한 |
| 사용 예 |
input_type |
| 상품 이미지를 검색 대상으로 저장 |
search_document |
| 사용자 업로드 이미지로 유사 상품 검색 |
search_query |
| 상품 이미지를 카테고리 분류 feature로 변환 |
classification |
| 이미지들을 유사한 그룹으로 묶기 |
clustering |
10.3 inputs
| 항목 |
내용 |
| 사용 목적 |
텍스트와 이미지를 하나의 의미 단위로 함께 임베딩 |
| 대표 입력 |
상품 이미지와 상품명, PDF 페이지와 OCR 텍스트, 차트 이미지와 설명 |
| 권장 상황 |
이미지 단독보다 텍스트 메타데이터를 함께 넣는 것이 유리한 경우 |
| 실무 중요도 |
매우 높음 |
inputs는 이미지 검색 품질을 높일 때 가장 중요하다. 이미지 하나만 넣는 것보다 이미지와 연결된 텍스트 정보를 함께 넣으면 검색 의도가 더 잘 보존된다.
| 사용 예 |
설명 |
| 상품 이미지와 상품명 |
이미지의 시각 정보와 상품명을 함께 반영 |
| PDF 페이지 이미지와 페이지 번호 |
시각 구조와 문서 위치를 함께 반영 |
| 차트 이미지와 캡션 |
차트의 시각 정보와 의미 설명을 함께 반영 |
| OCR 텍스트와 원본 이미지 |
OCR 오류를 이미지 정보로 보완 |
11. 이미지 입력 지원 상세
11.1 이미지 입력이 필요한 경우
| 상황 |
이미지 입력 필요성 |
| 상품 이미지 기반 검색 |
높음 |
| 사용자가 올린 이미지와 유사한 상품 검색 |
높음 |
| PDF가 스캔본이라 텍스트 추출이 불완전함 |
높음 |
| 문서에 표, 차트, 도식이 많음 |
높음 |
| 상품 설명이 짧고 이미지가 핵심 정보임 |
높음 |
| 텍스트 설명만으로 충분한 FAQ 검색 |
낮음 |
11.2 이미지 검색 패턴
| 패턴 |
인덱싱 입력 |
검색 입력 |
사용 예 |
| 텍스트에서 텍스트 검색 |
texts와 search_document |
texts와 search_query |
일반 RAG, FAQ 검색 |
| 이미지에서 이미지 검색 |
images와 search_document |
images와 search_query |
유사 상품 이미지 검색 |
| 텍스트에서 이미지 검색 |
inputs와 search_document |
texts와 search_query |
텍스트 조건으로 이미지 상품 검색 |
| 이미지와 텍스트에서 이미지 검색 |
inputs와 search_document |
inputs와 search_query |
사진과 추가 조건으로 상품 검색 |
| PDF 페이지 검색 |
inputs와 search_document |
texts와 search_query |
문서 페이지, 표, 차트 검색 |
11.3 이미지가 검색 대상인 경우
| 항목 |
설정 |
| 입력 데이터 |
상품 이미지, PDF 페이지 이미지, 문서 이미지 |
| 입력 필드 |
images 또는 inputs |
| input_type |
search_document |
| 저장 위치 |
Vector DB |
| 대표 목적 |
나중에 사용자의 검색 조건으로 찾기 위한 대상 저장 |
11.4 이미지가 검색 조건인 경우
| 항목 |
설정 |
| 입력 데이터 |
사용자가 업로드한 이미지 |
| 입력 필드 |
images 또는 inputs |
| input_type |
search_query |
| 저장 위치 |
일반적으로 저장하지 않음 |
| 대표 목적 |
Vector DB에 저장된 search_document 벡터 검색 |
11.5 이미지와 텍스트를 함께 넣는 경우
| 항목 |
설정 |
| 입력 데이터 |
이미지와 설명, 이미지와 상품명, PDF 페이지 이미지와 OCR 텍스트 |
| 입력 필드 |
inputs |
| 권장 input_type |
저장 대상이면 search_document, 검색 조건이면 search_query |
| 장점 |
시각 정보와 텍스트 정보를 하나의 의미 벡터로 통합 |
12. 대표 API Request 구성표
12.1 문서 텍스트 저장
| 필드 |
값 |
| input_type |
search_document |
| texts |
문서 chunk 배열 |
| embedding_types |
float |
| output_dimension |
1536 |
| truncate |
RIGHT |
| 사용 목적 |
RAG 문서 인덱싱 |
12.2 사용자 질문 검색
| 필드 |
값 |
| input_type |
search_query |
| texts |
사용자 질문 배열 |
| embedding_types |
float |
| output_dimension |
문서 인덱스와 동일 |
| truncate |
RIGHT |
| 사용 목적 |
Vector DB 검색용 query vector 생성 |
12.3 상품 이미지 저장
| 필드 |
값 |
| input_type |
search_document |
| images |
상품 이미지 base64 배열 |
| embedding_types |
float |
| output_dimension |
1536 또는 1024 |
| truncate |
RIGHT |
| 사용 목적 |
이미지 기반 상품 검색 인덱스 생성 |
12.4 사용자 이미지 검색
| 필드 |
값 |
| input_type |
search_query |
| images |
사용자 업로드 이미지 base64 배열 |
| embedding_types |
float |
| output_dimension |
상품 이미지 인덱스와 동일 |
| truncate |
RIGHT |
| 사용 목적 |
유사 이미지 상품 검색 |
12.5 상품 이미지와 상품 설명 저장
| 필드 |
값 |
| input_type |
search_document |
| inputs |
상품명, 카테고리, 속성, 상품 이미지 |
| embedding_types |
float |
| output_dimension |
1536 또는 1024 |
| truncate |
RIGHT |
| 사용 목적 |
텍스트와 이미지가 함께 반영된 상품 검색 |
12.6 사용자 이미지와 텍스트 조건 검색
| 필드 |
값 |
| input_type |
search_query |
| inputs |
사용자 이미지와 검색 조건 텍스트 |
| embedding_types |
float |
| output_dimension |
검색 대상 인덱스와 동일 |
| truncate |
RIGHT |
| 사용 목적 |
사진과 추가 조건을 함께 반영한 검색 |
12.7 PDF 페이지 저장
| 필드 |
값 |
| input_type |
search_document |
| inputs |
PDF 페이지 이미지, 파일명, 페이지 번호, OCR 텍스트, 엔티티 |
| embedding_types |
float |
| output_dimension |
1536 |
| truncate |
RIGHT |
| 사용 목적 |
표, 차트, 스캔 문서를 포함한 문서 검색 |
12.8 분류용 임베딩
| 필드 |
값 |
| input_type |
classification |
| texts, images 또는 inputs |
분류 대상 데이터 |
| embedding_types |
float |
| output_dimension |
1536 또는 1024 |
| truncate |
RIGHT |
| 사용 목적 |
별도 분류 모델의 입력 feature 생성 |
12.9 클러스터링용 임베딩
| 필드 |
값 |
| input_type |
clustering |
| texts, images 또는 inputs |
군집화 대상 데이터 |
| embedding_types |
float |
| output_dimension |
1536, 1024 또는 512 |
| truncate |
RIGHT |
| 사용 목적 |
유사 데이터 그룹화 |
13. output_dimension 선택 기준
| output_dimension |
권장 사용처 |
장점 |
단점 |
| 256 |
초대규모 1차 후보 검색 |
저장공간과 비용 절감 |
정확도 손실 가능 |
| 512 |
대량 상품 검색, 대량 이미지 검색 |
비용과 품질 균형 |
정밀 RAG에는 부족할 수 있음 |
| 1024 |
상품 검색, 일반 의미 검색 |
실무 균형점 |
최고 정확도는 아님 |
| 1536 |
RAG, PDF 검색, 이미지와 문서 혼합 검색 |
정확도 우선 |
저장공간과 검색 비용 증가 |
실무 권장값은 다음과 같다.
| 목적 |
권장 차원 |
| 정확도 우선 RAG |
1536 |
| PDF, 표, 차트, 스캔 문서 검색 |
1536 |
| 상품 검색 |
1024 또는 1536 |
| 이미지 상품 검색 |
1024 또는 1536 |
| 대량 데이터 1차 후보 검색 |
512 |
| 저장공간 최우선 |
256 또는 512 |
주의할 점은 Vector DB의 dimension과 output_dimension이 반드시 같아야 한다는 점이다.
14. embedding_types 선택 기준
| embedding_type |
설명 |
권장 사용처 |
| float |
일반 실수형 벡터 |
기본 권장 |
| int8 |
8-bit 정수형 벡터 |
저장공간 절감 |
| uint8 |
unsigned 8-bit 정수형 벡터 |
특수 인덱싱 |
| binary |
이진 벡터 |
초고속 후보 검색 |
| ubinary |
unsigned 이진 벡터 |
특수 목적 |
일반적인 OpenSearch, Elasticsearch, pgvector, Pinecone, Milvus 연동에서는 float를 기본으로 사용한다.
| 상황 |
권장 embedding_type |
| 일반 RAG |
float |
| 상품 검색 |
float |
| 이미지 검색 |
float |
| 정밀 검색 |
float |
| 대량 후보 검색 최적화 |
int8, binary 검토 |
| 저장공간 최적화 실험 |
int8, uint8 검토 |
복수 embedding type을 동시에 요청하면 응답 구조가 달라지므로, 일반 운영에서는 float 하나만 사용하는 편이 단순하다.
15. truncate 선택 기준
| truncate |
의미 |
권장 상황 |
| RIGHT |
뒤쪽 토큰을 자름 |
일반 기본값 |
| LEFT |
앞쪽 토큰을 자름 |
뒷부분이 더 중요한 특수 데이터 |
| NONE |
길이 초과 시 오류 |
데이터 품질 검증, 개발 단계 |
실무 기본값은 RIGHT다. 다만 RAG에서는 긴 문서를 그대로 넣기보다 적절히 chunking한 뒤 임베딩하는 것이 일반적으로 더 낫다.
16. Response 구조 요약
16.1 embedding_types가 하나인 경우
| 필드 |
타입 |
설명 |
| id |
string |
요청 식별자 |
| embeddings |
array |
입력 개수만큼 반환되는 벡터 배열 |
| response_type |
string |
embeddings_floats 등 응답 타입 |
| texts |
array |
입력 텍스트가 있는 경우 반환될 수 있음 |
16.2 embedding_types가 여러 개인 경우
| 필드 |
타입 |
설명 |
| id |
string |
요청 식별자 |
| embeddings |
object |
embedding type별 벡터 객체 |
| embeddings.float |
array |
float 벡터 배열 |
| embeddings.int8 |
array |
int8 벡터 배열 |
| response_type |
string |
embeddings_by_type 등 응답 타입 |
| 요청 방식 |
응답 구조 |
| embedding_types가 float 하나 |
embeddings가 배열 |
| embedding_types가 float와 int8 여러 개 |
embeddings가 타입별 객체 |
17. Vector DB 저장 메타데이터
임베딩 벡터만 저장하면 나중에 모델 변경, 차원 변경, 재색인, 품질 비교가 어렵다. 최소한 다음 메타데이터를 함께 저장하는 것이 좋다.
| 메타데이터 |
설명 |
| model_provider |
cohere |
| model_name |
embed-v4 |
| bedrock_model_id |
global.cohere.embed-v4:0 |
| input_type |
search_document 등 |
| embedding_type |
float 등 |
| output_dimension |
1536 등 |
| input_modality |
text, image, image_text |
| source_id |
원본 문서나 상품 ID |
| source_uri |
S3 URI, 문서 경로, 이미지 URI |
| chunk_index |
문서 chunk 번호 |
| page |
PDF 페이지 번호 |
| created_at |
임베딩 생성 시각 |
| chunking_strategy |
chunk 생성 방식 |
이미지 임베딩에서는 다음 메타데이터가 특히 중요하다.
| 메타데이터 |
설명 |
| image_uri |
원본 이미지 위치 |
| image_mime_type |
image/jpeg, image/png 등 |
| image_width |
이미지 너비 |
| image_height |
이미지 높이 |
| image_role |
상품 대표 이미지, 상세 이미지, PDF page image 등 |
| related_text |
이미지와 함께 임베딩한 텍스트 설명 |
18. 실무 설계 패턴
18.1 일반 RAG
| 단계 |
입력 |
input_type |
저장 여부 |
| 문서 인덱싱 |
문서 chunk |
search_document |
저장 |
| 사용자 질문 |
질문 텍스트 |
search_query |
미저장 |
| 검색 |
query vector와 document vector 비교 |
해당 없음 |
해당 없음 |
| 답변 생성 |
검색된 문서와 질문 |
해당 없음 |
선택 |
18.2 상품 텍스트 검색
| 단계 |
입력 |
input_type |
저장 여부 |
| 상품 인덱싱 |
상품명, 설명, 속성 |
search_document |
저장 |
| 사용자 검색 |
자연어 검색어 |
search_query |
미저장 |
| 검색 |
상품 벡터 검색 |
해당 없음 |
해당 없음 |
18.3 상품 이미지 검색
| 단계 |
입력 |
input_type |
저장 여부 |
| 상품 이미지 인덱싱 |
상품 이미지 또는 이미지와 상품 설명 |
search_document |
저장 |
| 사용자 이미지 검색 |
사용자 업로드 이미지 |
search_query |
미저장 |
| 검색 |
이미지 벡터 유사도 검색 |
해당 없음 |
해당 없음 |
18.4 PDF 멀티모달 검색
| 단계 |
입력 |
input_type |
저장 여부 |
| PDF 전처리 |
페이지 이미지 변환, OCR, 메타데이터 추출 |
해당 없음 |
선택 |
| 페이지 인덱싱 |
페이지 이미지와 OCR 텍스트 |
search_document |
저장 |
| 사용자 질문 |
질문 텍스트 |
search_query |
미저장 |
| 검색 |
질문 벡터와 페이지 벡터 비교 |
해당 없음 |
해당 없음 |
18.5 이미지와 텍스트 조건 검색
| 단계 |
입력 |
input_type |
저장 여부 |
| 상품 인덱싱 |
상품 이미지와 상품명, 속성 |
search_document |
저장 |
| 사용자 검색 |
업로드 이미지와 추가 조건 텍스트 |
search_query |
미저장 |
| 검색 |
query vector와 상품 vector 비교 |
해당 없음 |
해당 없음 |
19. 잘못된 사용 예시
| 잘못된 사용 |
왜 문제인가 |
올바른 사용 |
| 사용자 검색어를 search_document로 임베딩 |
검색 조건을 검색 대상으로 취급함 |
search_query 사용 |
| 문서 chunk를 search_query로 저장 |
검색 대상을 query로 취급함 |
search_document 사용 |
| 상품 이미지를 search_query로 저장 |
상품 이미지는 검색 대상임 |
search_document 사용 |
| 사용자 업로드 이미지를 search_document로 검색 |
사용자 이미지는 검색 조건임 |
search_query 사용 |
| 검색용 인덱스에 classification 사용 |
classification은 분류 feature용임 |
search_document와 search_query 사용 |
| 검색용 벡터와 clustering 벡터를 혼용 |
목적이 다른 벡터 공간을 섞음 |
목적별 인덱스 분리 |
| output_dimension을 바꾸고 기존 인덱스 사용 |
Vector DB 차원 불일치 |
인덱스 재생성 |
| texts와 images를 직접 함께 사용 |
혼합 입력 방식이 아님 |
inputs 사용 |
20. 운영 권장 기본값
20.1 RAG
| 필드 |
값 |
| input_type |
인덱싱은 search_document, 검색은 search_query |
| 입력 필드 |
texts |
| embedding_types |
float |
| output_dimension |
1536 |
| truncate |
RIGHT |
20.2 상품 검색
| 필드 |
값 |
| input_type |
인덱싱은 search_document, 검색은 search_query |
| 입력 필드 |
texts 또는 inputs |
| embedding_types |
float |
| output_dimension |
1024 또는 1536 |
| truncate |
RIGHT |
20.3 상품 이미지 검색
| 필드 |
값 |
| input_type |
인덱싱은 search_document, 검색은 search_query |
| 입력 필드 |
images 또는 inputs |
| embedding_types |
float |
| output_dimension |
1024 또는 1536 |
| truncate |
RIGHT |
20.4 PDF, 표, 차트 검색
| 필드 |
값 |
| input_type |
search_document |
| 입력 필드 |
inputs |
| embedding_types |
float |
| output_dimension |
1536 |
| truncate |
RIGHT |
20.5 분류
| 필드 |
값 |
| input_type |
classification |
| 입력 필드 |
texts, images 또는 inputs |
| embedding_types |
float |
| output_dimension |
1024 또는 1536 |
| truncate |
RIGHT |
20.6 클러스터링
| 필드 |
값 |
| input_type |
clustering |
| 입력 필드 |
texts, images 또는 inputs |
| embedding_types |
float |
| output_dimension |
512, 1024 또는 1536 |
| truncate |
RIGHT |
21. 에러 처리 기준
21.1 재시도 대상
| 오류 |
처리 |
| ThrottlingException |
지수 백오프 후 재시도 |
| ServiceUnavailableException |
재시도 |
| InternalServerException |
재시도 |
| ModelTimeoutException |
입력 크기 축소 또는 재시도 |
| ModelNotReadyException |
짧은 대기 후 재시도 |
권장 재시도 간격은 500ms, 1s, 2s, 4s 방식의 지수 백오프다. 운영에서는 jitter를 추가한다.
21.2 재시도하지 않을 대상
| 오류 |
가능 원인 |
처리 |
| ValidationException |
요청 형식 오류, 파라미터 오류, payload 초과 |
요청 수정 |
| AccessDeniedException |
IAM 권한 부족, 모델 접근 권한 부족 |
권한 확인 |
| ResourceNotFoundException |
modelId 오류, 리전 오류 |
모델 ID와 리전 확인 |
22. 최종 체크리스트
| 체크 항목 |
확인 |
| Bedrock Runtime InvokeModel을 사용한다 |
|
| IAM Role에 bedrock:InvokeModel 권한이 있다 |
|
| 서울 리전에서는 global.cohere.embed-v4:0 사용을 검토한다 |
|
| 문서 저장은 search_document를 사용한다 |
|
| 사용자 검색은 search_query를 사용한다 |
|
| 분류 feature 생성은 classification을 사용한다 |
|
| 군집 분석은 clustering을 사용한다 |
|
| 텍스트만 넣을 때는 texts를 사용한다 |
|
| 이미지만 넣을 때는 images를 사용한다 |
|
| 텍스트와 이미지를 함께 넣을 때는 inputs를 사용한다 |
|
| embedding_types 기본값은 float로 둔다 |
|
| output_dimension과 Vector DB dimension이 일치한다 |
|
| 요청당 입력 개수는 96개 이하로 제한한다 |
|
| 이미지 파일은 5MB 이하로 제한한다 |
|
| 전체 요청 payload는 약 20MB 이하로 관리한다 |
|
| streaming 호출을 사용하지 않는다 |
|
| model_id, input_type, output_dimension을 메타데이터로 저장한다 |
|
23. 최종 요약
| 질문 |
답 |
| 문서를 저장할 때는? |
search_document |
| 사용자의 질문을 검색할 때는? |
search_query |
| 상품 이미지를 저장할 때는? |
search_document |
| 사용자 업로드 이미지로 검색할 때는? |
search_query |
| 텍스트만 넣을 때는? |
texts |
| 이미지만 넣을 때는? |
images |
| 텍스트와 이미지를 함께 넣을 때는? |
inputs |
| 분류용 feature가 필요할 때는? |
classification |
| 유사 데이터끼리 묶을 때는? |
clustering |
| 일반적인 embedding_types는? |
float |
| 정확도 우선 output_dimension은? |
1536 |
| 상품 검색 균형값은? |
1024 또는 1536 |
| 서울 리전 모델 ID는? |
global.cohere.embed-v4:0 |
별첨 A. Python 호출 예시
아래 코드는 참고용이다. 실제 운영에서는 AWS 인증, 재시도, 로깅, 타임아웃, 배치 처리, 오류 처리를 프로젝트 표준에 맞게 추가해야 한다.
import json
import os
import boto3
from botocore.exceptions import ClientError
AWS_REGION = os.getenv("AWS_REGION", "ap-northeast-2")
MODEL_ID = os.getenv("BEDROCK_COHERE_EMBED_MODEL_ID", "global.cohere.embed-v4:0")
bedrock = boto3.client(
service_name="bedrock-runtime",
region_name=AWS_REGION
)
def invoke_embed(body):
try:
response = bedrock.invoke_model(
modelId=MODEL_ID,
body=json.dumps(body),
contentType="application/json",
accept="application/json"
)
return json.loads(response["body"].read())
except ClientError as e:
raise RuntimeError(f"Bedrock embedding request failed: {e}") from e
def embed_documents(texts, output_dimension=1536):
body = {
"input_type": "search_document",
"texts": texts,
"embedding_types": ["float"],
"output_dimension": output_dimension,
"truncate": "RIGHT"
}
payload = invoke_embed(body)
return payload["embeddings"]
def embed_query(query, output_dimension=1536):
body = {
"input_type": "search_query",
"texts": [query],
"embedding_types": ["float"],
"output_dimension": output_dimension,
"truncate": "RIGHT"
}
payload = invoke_embed(body)
return payload["embeddings"][0]
def embed_image_document(base64_image, mime_type="image/jpeg", output_dimension=1536):
body = {
"input_type": "search_document",
"images": [
f"data:{mime_type};base64,{base64_image}"
],
"embedding_types": ["float"],
"output_dimension": output_dimension,
"truncate": "RIGHT"
}
payload = invoke_embed(body)
return payload["embeddings"][0]
def embed_image_query(base64_image, mime_type="image/jpeg", output_dimension=1536):
body = {
"input_type": "search_query",
"images": [
f"data:{mime_type};base64,{base64_image}"
],
"embedding_types": ["float"],
"output_dimension": output_dimension,
"truncate": "RIGHT"
}
payload = invoke_embed(body)
return payload["embeddings"][0]
별첨 B. Java Spring Boot 호출 예시
아래 코드는 참고용이다. 실제 운영에서는 Bean 구성, client 재사용, retry policy, timeout, logging, metric 수집을 별도 구성하는 것이 좋다.
package com.example.embedding;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelRequest;
import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelResponse;
import java.util.List;
import java.util.Map;
@Service
public class CohereEmbedV4BedrockService {
private static final String MODEL_ID = "global.cohere.embed-v4:0";
private static final Region REGION = Region.AP_NORTHEAST_2;
private final BedrockRuntimeClient bedrockRuntimeClient;
private final ObjectMapper objectMapper;
public CohereEmbedV4BedrockService() {
this.bedrockRuntimeClient = BedrockRuntimeClient.builder()
.region(REGION)
.build();
this.objectMapper = new ObjectMapper();
}
public List<Double> embedDocument(String text) {
return embedSingleText(text, "search_document");
}
public List<Double> embedQuery(String text) {
return embedSingleText(text, "search_query");
}
public List<Double> embedForClassification(String text) {
return embedSingleText(text, "classification");
}
public List<Double> embedForClustering(String text) {
return embedSingleText(text, "clustering");
}
private List<Double> embedSingleText(String text, String inputType) {
try {
Map<String, Object> body = Map.of(
"input_type", inputType,
"texts", List.of(text),
"embedding_types", List.of("float"),
"output_dimension", 1536,
"truncate", "RIGHT"
);
String jsonBody = objectMapper.writeValueAsString(body);
InvokeModelRequest request = InvokeModelRequest.builder()
.modelId(MODEL_ID)
.contentType("application/json")
.accept("application/json")
.body(SdkBytes.fromUtf8String(jsonBody))
.build();
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(request);
JsonNode root = objectMapper.readTree(response.body().asUtf8String());
JsonNode vectorNode = root.get("embeddings").get(0);
return objectMapper.convertValue(
vectorNode,
objectMapper.getTypeFactory().constructCollectionType(List.class, Double.class)
);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Cohere Embed v4 on Bedrock", e);
}
}
}
참고자료
댓글