← All guides

Claude Vision API 가이드: 이미지 분석 + 멀티모달 활용법

Claude Vision API로 이미지 분석 — URL/base64 업로드, OCR, 차트 해석, 상품 태깅. Python 코드 예제와 토큰 비용 계산 포함.

Claude Vision API 가이드: 이미지 분석 + 멀티모달 활용법

Claude Vision API는 이미지를 메시지 배열에 직접 포함해 텍스트와 함께 분석할 수 있습니다. 별도 설정 없이 JPEG, PNG, GIF, WebP 형식을 지원하며, URL 또는 base64 인코딩으로 전송합니다. 1개 요청당 최대 20장까지 처리 가능하고, 1080px 이미지 기준 약 1,600 토큰을 소모합니다. 이 가이드에서는 이미지 입력 방법부터 OCR, 차트 분석, 상품 태깅까지 실제 Python 코드와 함께 설명합니다.


이미지 입력 방법: URL vs base64

Claude Vision API에 이미지를 전달하는 방법은 두 가지입니다.

URL 방식 (공개 이미지)

이미지가 인터넷에 공개되어 있다면 URL을 그대로 넘기는 것이 가장 간단합니다.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "url",
                        "url": "https://example.com/chart.png"
                    }
                },
                {
                    "type": "text",
                    "text": "이 차트의 핵심 데이터 포인트를 추출해 주세요."
                }
            ]
        }
    ]
)

print(response.content[0].text)

base64 방식 (로컬 파일 / 비공개 이미지)

로컬 파일이나 비공개 이미지는 base64로 인코딩해서 전송합니다.

import base64
import anthropic

def encode_image(image_path: str) -> tuple[str, str]:
    """(base64_data, media_type) 반환"""
    extension = image_path.split(".")[-1].lower()
    media_type_map = {
        "jpg": "image/jpeg",
        "jpeg": "image/jpeg",
        "png": "image/png",
        "gif": "image/gif",
        "webp": "image/webp"
    }
    media_type = media_type_map.get(extension, "image/jpeg")

    with open(image_path, "rb") as f:
        data = base64.standard_b64encode(f.read()).decode("utf-8")

    return data, media_type

client = anthropic.Anthropic()
image_data, media_type = encode_image("screenshot.png")

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": media_type,
                        "data": image_data
                    }
                },
                {
                    "type": "text",
                    "text": "이 스크린샷에서 무엇을 볼 수 있나요?"
                }
            ]
        }
    ]
)

지원 형식: JPEG, PNG, GIF, WebP (파일당 최대 5MB)
최대 이미지 수: 1개 메시지당 최대 20장


주요 활용 사례 5가지

1. OCR — 이미지에서 텍스트 추출

스캔된 문서, 영수증, 명함 등 이미지 속 텍스트를 추출할 때 유용합니다.

def extract_text_from_image(image_path: str) -> str:
    """이미지에서 텍스트를 추출합니다."""
    data, media_type = encode_image(image_path)

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        system="당신은 OCR 전문가입니다. 이미지의 텍스트를 정확하게 추출하세요. 레이아웃을 최대한 보존하고, 불명확한 부분은 [?]로 표시하세요.",
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {"type": "base64", "media_type": media_type, "data": data}
                    },
                    {
                        "type": "text",
                        "text": "이 이미지의 모든 텍스트를 그대로 추출해 주세요."
                    }
                ]
            }
        ]
    )
    return response.content[0].text

# 사용 예시
text = extract_text_from_image("receipt.jpg")
print(text)

인쇄된 텍스트는 높은 정확도로 추출됩니다. 손글씨는 자간이 명확한 경우 양호하게 처리되지만, 흘림체 필기는 정확도가 낮을 수 있습니다.


2. 차트 및 그래프 데이터 추출

매출 보고서, 대시보드 스크린샷에서 수치 데이터를 자동으로 파싱합니다.

import json

def extract_chart_data(image_path: str) -> dict:
    """차트 이미지에서 데이터를 JSON으로 추출합니다."""
    data, media_type = encode_image(image_path)

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {"type": "base64", "media_type": media_type, "data": data}
                    },
                    {
                        "type": "text",
                        "text": """이 차트의 데이터를 JSON 형식으로 추출하세요:
{
  "chart_type": "bar|line|pie|scatter",
  "title": "차트 제목",
  "x_axis": "X축 레이블",
  "y_axis": "Y축 레이블",
  "data_points": [{"label": "...", "value": 숫자}]
}
정확한 값이 보이지 않으면 눈금 기준으로 추정하세요."""
                    }
                ]
            }
        ]
    )
    return json.loads(response.content[0].text)

# 사용 예시
chart = extract_chart_data("quarterly_sales.png")
print(chart["data_points"])

막대/선형 차트에서 레이블이 명확한 경우 약 85~90% 정확도로 데이터를 추출합니다.


3. UI 스크린샷 분석 (QA 자동화)

체크아웃 페이지, 폼 레이아웃 등 UI 스크린샷을 분석해 QA 프로세스를 자동화합니다.

def analyze_ui_screenshot(screenshot_path: str, expected: str) -> dict:
    """UI 스크린샷을 예상 동작과 비교 분석합니다."""
    data, media_type = encode_image(screenshot_path)

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        system="QA 엔지니어로서 UI 스크린샷을 분석합니다. 관찰 내용을 구체적으로 설명하세요.",
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {"type": "base64", "media_type": media_type, "data": data}
                    },
                    {
                        "type": "text",
                        "text": f"""이 스크린샷을 분석하세요.
예상 동작: {expected}

JSON으로 응답하세요:
{{
  "matches_expected": true/false,
  "issues": ["발견된 문제 목록"],
  "elements_visible": ["확인된 UI 요소들"]
}}"""
                    }
                ]
            }
        ]
    )
    return json.loads(response.content[0].text)

# 사용 예시
result = analyze_ui_screenshot(
    "checkout.png",
    "신용카드 입력 필드와 '결제하기' 버튼이 있는 결제 폼"
)
print(result)

before/after 스크린샷 두 장을 동시에 보내 레이아웃 변경을 감지하는 회귀 테스트에도 활용할 수 있습니다.


4. 상품 이미지 태깅 (이커머스)

상품 사진을 분석해 카테고리, 색상, 재질 등의 메타데이터를 자동으로 생성합니다.

def tag_product_image(image_path: str) -> dict:
    """상품 이미지에서 태그와 메타데이터를 추출합니다."""
    data, media_type = encode_image(image_path)

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {"type": "base64", "media_type": media_type, "data": data}
                    },
                    {
                        "type": "text",
                        "text": """이 상품 이미지를 분석해 JSON으로 반환하세요:
{
  "category": "상품 카테고리",
  "subcategory": "세부 카테고리",
  "colors": ["색상1", "색상2"],
  "material": "소재 (추정)",
  "style_tags": ["태그1", "태그2", "태그3"],
  "description_ko": "한국어 상품 설명 2문장"
}"""
                    }
                ]
            }
        ]
    )
    return json.loads(response.content[0].text)

# 배치 처리 예시
import glob

product_images = glob.glob("products/*.jpg")
tags = [tag_product_image(img) for img in product_images[:10]]

수백 개의 상품 이미지를 일괄 처리할 때는 Batch API를 함께 사용하면 비용을 50% 절감할 수 있습니다.


5. 의료 이미지 분석 (주의사항 포함)

중요 면책 조항: Claude의 의료 이미지 분석은 진단 목적으로 사용할 수 없습니다. 반드시 의료 전문가의 판단을 따르세요. 아래 예시는 연구 또는 보조 참고용 구현 패턴만을 보여줍니다.

def analyze_medical_image(image_path: str, context: str) -> str:
    """
    의료 이미지 분석 — 반드시 전문가 검토 필수.
    진단 목적으로 사용 금지.
    """
    data, media_type = encode_image(image_path)

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        system="""의료 이미지 분석 보조 도구입니다.
중요: 이 분석은 전문 의료인의 판단을 대체하지 않습니다.
관찰 내용만 기술하고, 진단을 내리지 마세요.""",
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {"type": "base64", "media_type": media_type, "data": data}
                    },
                    {
                        "type": "text",
                        "text": f"환자 맥락: {context}\n이미지에서 관찰되는 내용을 객관적으로 기술하세요."
                    }
                ]
            }
        ]
    )
    return response.content[0].text

의료 분야 배포 시에는 Anthropic의 사용 정책과 해당 국가의 의료기기 규정을 반드시 확인하세요.


비용 계산: 이미지 토큰 추정

이미지는 해상도에 따라 토큰을 소모합니다. 계산 공식:

이미지 토큰 = (가로px × 세로px) / 750
해상도 토큰 수 (근사) claude-sonnet-4-5 비용 (입력)
800 × 600 ~640 토큰 ~$0.0019
1080 × 1080 ~1,555 토큰 ~$0.0047
1920 × 1080 ~2,765 토큰 ~$0.0083
3840 × 2160 ~11,059 토큰 ~$0.0332

비용 절감 팁: 대부분의 분석 작업은 1024px 이하로 리사이즈해도 품질 차이가 없습니다. 아래 유틸리티를 활용하세요.

from PIL import Image
import io

def resize_for_claude(image_path: str, max_dimension: int = 1024) -> bytes:
    """종횡비를 유지하면서 최대 크기로 리사이즈합니다."""
    with Image.open(image_path) as img:
        img.thumbnail((max_dimension, max_dimension), Image.LANCZOS)
        buffer = io.BytesIO()
        img.save(buffer, format="PNG")
        return buffer.getvalue()

# 리사이즈 후 base64 인코딩
resized_bytes = resize_for_claude("large_image.png")
encoded = base64.standard_b64encode(resized_bytes).decode("utf-8")

1920px 이미지를 1024px로 줄이면 토큰이 약 72% 감소합니다. 대량 배치 처리에서 효과가 큽니다.


멀티모달 파이프라인 구축하기

Agent SDK Cookbook ($49)에는 문서 처리 파이프라인, 스크린샷 기반 QA 자동화, 차트 데이터 추출, 다중 이미지 분석 워크플로우 레시피가 모두 포함되어 있습니다.

Agent SDK Cookbook 구매하기 — $49


관련 가이드

Claude Vision API를 실제 서비스에 연결하려면 FastAPI로 Claude API 서버 구축하기를 참고하세요. 이미지 분석을 멀티 스텝 워크플로우로 확장하려면 Claude Agent SDK 한국어 가이드를 살펴보세요.


Frequently Asked Questions

Claude Vision API가 지원하는 이미지 형식은 무엇인가요?

JPEG, PNG, GIF, WebP를 지원합니다. 스크린샷과 다이어그램에는 PNG(무손실), 사진에는 JPEG, 웹 최적화 이미지에는 WebP를 권장합니다. 파일당 최대 크기는 5MB입니다.

이미지를 URL로 보낼 때와 base64로 보낼 때 차이가 있나요?

기능적 차이는 없습니다. URL 방식은 코드가 간단하고 요청 페이로드 크기가 작지만, 이미지가 인터넷에 공개되어 있어야 합니다. base64 방식은 로컬 파일, 비공개 이미지, 또는 서버 간 전송에 적합합니다. 프로덕션에서는 보안상 base64를 선호하는 경우가 많습니다.

한 번의 API 호출에 이미지를 몇 장까지 보낼 수 있나요?

1개 메시지당 최대 20장입니다. 실질적인 한계는 전체 토큰 예산에 따라 달라집니다. 1080px 이미지 20장은 약 31,000 토큰을 소모합니다. 대량 이미지 처리 시에는 5~10장씩 배치로 나눠 처리하는 것을 권장합니다.

Claude Vision으로 OCR 정확도는 어느 정도인가요?

인쇄된 텍스트는 고해상도(300 DPI 이상) 이미지에서 매우 높은 정확도를 보입니다. 손글씨는 자간이 명확한 경우 양호하지만, 흘림체 필기나 저해상도 이미지에서는 오류가 발생할 수 있습니다. 문서 디지털화 작업에는 스캔 품질을 충분히 확보하세요.

이미지 분석 결과를 구조화된 JSON으로 받을 수 있나요?

네. 프롬프트에 원하는 JSON 스키마를 명시하거나, Tool Use(도구 사용) 기능과 함께 사용하면 더 안정적으로 구조화된 출력을 얻을 수 있습니다. Tool Use를 활용하면 JSON 파싱 오류 없이 타입 안전한 데이터를 받을 수 있습니다.

도구와 자료