CPN 한국어 자습서 · Claude Certified Developer — Foundations Prep
2-10 · 멀티모달 · 배치 처리
Multimodal and Batch Ingestion
앞선 레슨들이 대화 사이에 Claude가 무엇을 기억하는지를 다뤘다면, 이번에는 무엇을 보내는지로 질문이 옮겨 갑니다. 이미지와 PDF는 Claude가 프롬프트의 첫 글자를 읽기도 전에 컨텍스트 예산을 먼저 소모하기 때문에, 요청을 짜는 방식과 한 번에 담을 수 있는 양이 달라집니다. 뒤이어 입력이 수천 건으로 늘었을 때 요청을 하나씩 보내는 대신 쓰는 Message Batches API까지 이어집니다.
이 장에서 배우는 것What you'll learn
약 20분이미지가 차지하는 비주얼 토큰을 미리 계산하는 법
이미지를 보내는 세 가지 방법 — Inline base64 · URL 참조 · Files API
PDF를 보낼 때 쓰는 document 블록과 멀티모달 프롬프팅
대량 입력을 처리하는 Message Batches API와 동기 API의 선택 기준
멀티모달과 배치가 맞물리는 조건과 어긋나는 실패 방식
리스트를 쪼개 반복 호출하는 것이 배치가 아닌 이유
file_id로 이후 요청에서 불러 쓰는 방법.image 블록과 짝을 이룬다.이미지와 PDF는 공짜가 아닙니다. Claude가 프롬프트를 읽기 전에 이미 컨텍스트 예산을 씁니다. 그래서 파이프라인을 짜기 전에, 이미지 한 장이 얼마나 차지하는지 계산해 보는 것부터 시작합니다.
Claude는 이미지를 조각(patch) 단위로 봅니다. 이미지를 28×28 픽셀 블록으로 나누면 블록 하나가 비주얼 토큰 하나입니다. 그래서 이미지 한 장의 비용은 (가로 ÷ 28) × (세로 ÷ 28) 비주얼 토큰이 됩니다. 예를 들어 1,000 × 1,000 픽셀 이미지는 (1000÷28) × (1000÷28) = 36 × 36, 약 1,296 비주얼 토큰입니다. 이 정도면 고해상도 스크린샷 열 장이 상세한 시스템 프롬프트 하나만큼의 컨텍스트를 차지합니다.
모델마다 기본으로 받아들이는 최대 이미지 해상도가 정해져 있습니다. 긴 변 길이 제한과 비주얼 토큰 제한 두 가지로 표현되고, 등급마다 값이 다릅니다. 최신 모델은 표준 등급보다 훨씬 큰 이미지를 받습니다. 두 제한 중 하나를 넘는 이미지는 처리 전에 축소되므로, 위 계산식은 축소된 크기에 적용됩니다. 등급별 현재 제한값은 세대가 바뀔 때마다 달라져 왔고 앞으로도 그럴 수 있으니, Vision 문서(Resolution and token cost)에서 만들 때마다 확인하는 것이 좋습니다.
이 계산은 설계 단계에서 의미가 있습니다. 이미지를 처리하는 파이프라인을 만든다면, 처리 코드를 쓰기 전에 대표적인 프로덕션 이미지 한 장의 토큰 비용을 모델의 컨텍스트 한도한 요청에 담을 수 있는 토큰의 총량. 이미지·PDF가 여기서 예산을 먼저 가져간다.와 견줘 봅니다. 예산을 넘긴 파이프라인은 이미지 크기를 줄이는 10분짜리 작업으로 해결되는 경우가 많습니다. 배포한 뒤에 알아차리면 손보는 데 더 오래 걸립니다.
이미지도 텍스트처럼 자리를 차지합니다. 큰 사진 몇 장이 긴 설명글 하나만큼의 공간을 먹는 셈이라, 파이프라인을 짜기 전에 사진 한 장이 얼마나 차지하는지 먼저 재 보는 것이 좋습니다.
이미지를 Claude에 보내는 방법은 세 가지이고, 각각 잘 맞는 상황이 다릅니다. 어떤 이미지를 얼마나 자주 보내는지에 따라 고르면 됩니다.
INLINE BASE64 · URL · FILES API — 전송 방법 비교
| 방법 | 동작 방식과 부담 | 잘 맞는 상황 |
|---|---|---|
| Inline base64 | 이미지 바이트를 base64 문자열로 바꿔 메시지 블록에 바로 담습니다. 인코딩된 데이터 전체가 매 요청에 함께 전송되어, 큰 이미지에서는 요청 크기와 지연이 커집니다. | 업로드 단계를 더할 만큼의 이득이 없는, 한 번만 쓰는 이미지에 좋습니다. 같은 이미지를 반복해 보내면 비용이 배로 늘어나므로, 재사용할 것 같으면 다른 방법을 고려합니다. |
| URL 참조 | 공개적으로 접근 가능한 URL을 소스 블록에 넣으면 Claude가 요청 시점에 이미지를 가져옵니다. 요청에 데이터가 실리지 않는 대신, 그 URL이 그 순간 안정적이고 공개돼 있으며 접근 가능해야 한다는 의존이 생깁니다. | 이미 안정적인 공개 URL에 올라가 있고 내가 관리하는 이미지에 좋습니다. 인증 뒤에 있거나, 만료가 짧은 서명이 걸렸거나, 요청 시점의 접근을 보장하기 어려운 것에는 쓰지 않습니다. |
| Files API | 파일을 별도 API 호출로 한 번 올리고, 받은 file_id를 이후 요청에서 참조합니다. 업로드는 한 번만 드는 비용이고, 이후 요청은 바이트 대신 ID만 실어 전송 부담이 거의 0으로 떨어집니다. 현재 베타이며 Bedrock·Vertex AI에서는 쓸 수 없으니, 배포 환경에서 사용 가능한지 확인합니다. | 같은 이미지·PDF가 여러 요청에 나타나거나, 다시 보내면 요청 크기를 차지할 만큼 자산이 클 때 좋습니다. 자산 관리를 추론 호출과 분리하고 싶을 때 가장 깔끔하고, 대화가 여러 차례 이어지는 동안 쓰이는 이미지에도 맞습니다. 기록이 길어져도 file_id는 데이터를 싣지 않기 때문입니다. |
한 번 쓰면 Inline base64, 여러 번 쓰면 Files API, 안정적인 공개 URL이 이미 있으면 URL 참조 — 재사용 여부가 선택의 갈림길입니다.
PDF는 image가 아니라 document 블록으로 보냅니다. 소스 구조는 이미지와 같아서 base64, URL, Files API의 file_id 중 무엇이든 됩니다.
document 블록에는 필수인 name 필드가 없습니다. 읽기 좋은 문서 이름을 담는 title 필드와 추가 정보를 담는 context 필드를 선택적으로 넣을 수 있지만, PDF를 보내는 데 둘 다 꼭 필요하지는 않습니다. 토큰 비용이나 Files API 재사용을 비롯한 나머지 동작은 이미지와 똑같이 적용됩니다.
PDF를 담는 document 블록 — source 구조는 이미지와 같다
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "<base64-encoded-pdf-bytes>"
},
"title": "contract_review.pdf"
}이미지와 PDF를 분석할 때도 앞 절에서 본 프롬프팅 기법이 그대로 적용됩니다. 그냥 "이 이미지를 설명해 줘"라고만 하면 얕은 결과가 나오는데, 이유는 맨 텍스트 프롬프트와 같습니다 — Claude가 겨냥할 목표 구조가 없기 때문입니다.
다만 이미지에는 텍스트에 없는 모호함이 있습니다. 겹쳐 있는 물체, 깊이와 공간 관계, 일부만 보이는 가림 같은 것들입니다. 시각 분석 프롬프트는 이런 모호함을 Claude가 어떻게 다뤄야 하는지 짚어 주는 것이 좋습니다. 예를 들어 "물체가 겹치면 각각 따로 설명하고 겹친 부분을 표시하라"는, 텍스트 전용 프롬프트에서는 쓸 일이 없는 구체적인 제약입니다.
같은 프롬프트 패턴을 입력 수백, 수천 건에 적용해야 한다면 동기 API는 맞지 않는 방식입니다. 동기 호출은 하나가 끝날 때까지 다음이 막힙니다. 규모가 커지면 스레드를 계속 붙잡고 있거나, 수천 개의 동시 연결을 요청 한도에 부딪혀 가며 유지하게 됩니다.
Message Batches API는 한 번의 배치 호출에 최대 100,000건 또는 256MB까지(둘 중 먼저 도달하는 쪽) 받습니다. 배치를 제출하면 batch_id를 받고, 완료될 때까지 폴링합니다. 배치가 끝나면 결과를 내려받습니다. 배치 요청의 토큰당 비용은 동기 요청보다 낮습니다.
절충점은 지연 시간입니다. 배치 처리는 완료 시점이 일정하지 않아 최대 24시간까지 걸릴 수 있고, 그보다 훨씬 빠른 경우도 많습니다. 그래서 오프라인 파이프라인, 평가 작업, 데이터 처리처럼 실시간 사용자 상호작용이 아닌 곳에 맞습니다.
SYNCHRONOUS vs BATCH — 상황별 맞는 방식
| 상황 | 맞는 API | 이유 |
|---|---|---|
| 사용자가 사진을 올리고 즉시 분류 결과를 기대한다 | 동기 API | 실시간 응답이 필요합니다. 대화형 사용에는 배치의 지연을 받아들일 수 없습니다. |
| 매일 밤 파이프라인이 고객 기록 5,000건을 분류한다 | Message Batches API | 지연이 제약이 아닙니다. 비용 절감과 비동기 처리가 모두 이득입니다. |
| 평가 작업이 새 프롬프트를 예시 2,000건에 시험한다 | Message Batches API | 실시간 요구가 없는 오프라인 작업입니다. 배치가 맞는 방식입니다. |
| 챗봇이 사용자 메시지에 답을 만든다 | 동기 API | 사용자가 기다리고 있어, 배치를 쓰면 받아들이기 어려운 지연이 생깁니다. |
동기 API는 지금 답을 기다리는 상황용이고, 배치 API는 많은 일을 몰아서 나중에 받는 상황용입니다.
이 조합은 같은 자산을 재사용하면서 수천 건의 입력에 구조화된 출력이 필요한 오프라인 작업에 잘 맞습니다.
매일 밤 이미지를 고정된 분류 체계에 맞춰 분류하는 파이프라인이 교과서적인 예입니다. Files API가 중복 업로드를 없애고, Batches API가 지연을 흡수하고, 구조화된 출력 기법이 결과를 기계가 읽을 수 있는 형태로 유지합니다.
맞물림이 깨지는 실패는 두 가지입니다.
작업을 덩어리로 쪼개 하나씩 차례로 처리하는 것은 배치가 아닙니다. 단계만 더 붙은 직렬 처리에 가깝습니다. Message Batches API가 대량 작업을 위해 따로 있는 이유가 여기 있습니다 — 동기 API에 입력을 반복 호출하면, 리스트를 아무리 잘게 나눠도 물량이 실제로 커지는 순간 요청 한도에 걸리기 때문입니다.
매일 밤 실행하는 분류 작업이 사흘째 같은 지점에서 요청 한도에 걸리는 상황입니다. 선임 개발자가 던진 한 가지 질문이 진짜 원인을 드러냅니다.
INTERNAL CHANNEL — 요청 한도에 걸리는 야간 작업 대화
| 개발자 | 매일 밤 실행하는 분류 작업이 자꾸 요청 한도에 걸려요. 이미 작은 덩어리로 나눠 봤는데, 더 해 볼 수 있는 게 뭐가 있을까요? |
|---|---|
| 선임 개발자 | 그걸 어떻게 제출하고 있는데요? |
| 개발자 | 리스트를 반복해 항목마다 API를 한 번씩 호출하고 있어요. |
| 선임 개발자 | 그건 배치가 아니에요. 동기 엔드포인트에 직렬로 호출하는 거죠. 리스트를 덩어리로 쪼개도 API가 보는 건 달라지지 않아요. 여전히 항목 하나에 요청 하나가 연달아 들어가는 겁니다. |
| 개발자 | 그러면 동기 호출을 수천 번 하고 있어서 요청 한도가 걸리는 거네요? |
| 선임 개발자 | 맞아요. Message Batches API는 한 번의 배치 호출에 최대 100,000건 또는 256MB까지 받고, batch_id를 돌려준 뒤 비동기로 처리해요. 완료될 때까지 폴링, 즉 코드가 일정 간격으로 배치 상태를 되물으며 끝났는지 확인하는 거죠. 토큰당 비용은 동기보다 낮고, 개별 요청을 수천 번 보내는 게 아니니 요청 한도도 걸리지 않아요. |
| 개발자 | 그럼 절충점은요? |
| 선임 개발자 | 지연 시간이 일정하지 않아요. 배치 처리는 몇 시간이 걸릴 수도 있어요. 실시간 사용자 상호작용이었다면 잘못된 선택이겠죠. 하지만 매일 밤 실행하는 분류 작업에는 딱 맞습니다. |
custom_id 필드를 붙여 결과를 입력과 맞추면 됩니다.아래 세 가지 상황에 각각 맞는 전송 방법을 골라 보세요. 잘못 고르면 어떤 대가를 치르는지가 해설에 함께 나옵니다. 정답을 먼저 떠올려 본 뒤 골라 보세요. 맞히면 설명이 나옵니다.
Q1파이프라인의 모든 요청에 들어가는 참조용 제품 도면. 어떤 방법이 맞을까요?
같은 이미지가 매 요청에 반복되므로, 한 번 올려 file_id로 부르는 Files API가 맞습니다. Inline base64로 하면 매 요청마다 전체 데이터를 다시 실어, 전송 부담과 지연이 매번 붙습니다.
Q2지원 엔지니어가 한 번만 보내는 UI 버그 스크린샷. 어떤 방법이 맞을까요?
한 번만 쓸 자산이므로 메시지 블록에 바로 담는 Inline base64가 맞습니다. Files API로 올리면, 딱 한 번 쓰고 말 자산에 업로드 왕복 단계가 더해집니다.
Q3고객 피드백 5,000건을 분류하는 작업. 어떤 방법이 맞을까요?
대량·오프라인 작업이므로 한 번에 제출하고 결과를 받아오는 Message Batches API가 맞습니다. 동기 API로 하면 요청을 하나씩 처리하거나, 수천 개의 동시 연결을 요청 한도에 부딪혀 가며 관리해야 합니다.
모듈 2의 다음 레슨으로 이어집니다. 한국어판이 준비되는 대로 볼 수 있습니다. → 다음 레슨으로
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 38개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.