PDF 지원

PDF 지원 (PDF support)

제공하는 PDF의 텍스트, 그림, 차트, 표에 대해 Claude에게 물어볼 수 있어요. 금융 보고서 분석, 법률 문서에서 핵심 정보 추출, 문서 번역 보조, 문서 정보를 구조화된 형식으로 변환하는 등의 작업에 활용할 수 있어요. 표준 PDF라면 어떤 것이든 처리해요.

출처: 문서

본문

제공하는 PDF의 텍스트, 그림, 차트, 표에 대해 Claude에게 물어볼 수 있어요. 몇 가지 사용 사례:

  • 금융 보고서를 분석하고 차트/표 이해하기
  • 법률 문서에서 핵심 정보 추출하기
  • 문서 번역 보조
  • 문서 정보를 구조화된 형식으로 변환하기

시작하기 전에

PDF 요구 사항 확인

Claude는 표준 PDF라면 무엇이든 처리할 수 있어요. 요청 크기가 다음 요구 사항을 충족하는지 확인하세요.

요구 사항 한도
최대 요청 크기 32 MB (플랫폼별로 다름)
요청당 최대 페이지 수 600 (요청의 컨텍스트 창이 1M 토큰 미만이면 100)
형식 표준 PDF (비밀번호/암호화 없음)

두 한도 모두 PDF와 함께 보내는 다른 콘텐츠를 포함한 전체 요청 페이로드에 적용돼요. 큰 PDF는 Files API로 업로드하고 file_id로 참조해서 요청 페이로드를 작게 유지하는 걸 고려해 보세요.

밀도 높은 PDF(작은 글꼴 페이지가 많거나, 복잡한 표, 무거운 그래픽)는 페이지 한도에 도달하기 전에 컨텍스트 창을 채울 수 있어요. 큰 PDF가 있는 요청은 Files API를 써도 페이지 한도 전에 실패할 수 있어요. 문서를 구간으로 나눠 보세요. 큰 파일은 각 페이지가 이미지로 처리되므로 임베디드 이미지를 다운샘플링해도 도움이 될 수 있어요.

PDF 지원은 Claude의 비전 능력에 의존하므로 다른 비전 작업과 같은 제한 사항과 고려 사항이 적용돼요.

지원되는 플랫폼과 모델

모든 활성 모델이 PDF 처리를 지원해요. Amazon Bedrock의 Converse API를 통한 PDF 지원은 Amazon Bedrock PDF support를 보세요.

Amazon Bedrock PDF 지원

Converse API로 PDF 지원을 쓸 때( Claude on Amazon Bedrock (Opus 4.6 and earlier)의 일부)는 두 가지 문서 처리 모드가 있어요.

**중요:** Converse API에서 Claude의 완전한 시각적 PDF 이해 능력에 접근하려면 인용(citations)을 활성화해야 해요. 인용을 활성화하지 않으면 API는 기본적인 텍스트 추출로만 돌아가요. [인용 작업](https://platform.claude.com/docs/en/build-with-claude/citations)에 대해 자세히 알아보세요.
문서 처리 모드
  1. Converse Document Chat (원래 모드 - 텍스트 추출만)

    • PDF에서 기본적인 텍스트 추출 제공
    • PDF 안의 이미지, 차트, 시각적 레이아웃 분석 불가
    • 3페이지 PDF에 약 1,000 토큰 사용
    • 인용이 활성화되지 않았을 때 자동으로 사용
  2. Claude PDF Chat (새 모드 - 완전한 시각적 이해)

    • PDF의 완전한 시각적 분석 제공
    • 차트, 그래프, 이미지, 시각적 레이아웃 이해·분석 가능
    • 포괄적인 이해를 위해 각 페이지를 텍스트와 이미지로 모두 처리
    • 3페이지 PDF에 약 7,000 토큰 사용
    • Converse API에서 인용 활성화 필요
주요 제한 사항
  • Converse API: 시각적 PDF 분석에는 인용 활성화가 필요해요. 현재 인용 없이 시각적 분석을 쓰는 옵션은 없어요(InvokeModel API와 달리).
  • InvokeModel API: 강제 인용 없이 PDF 처리에 대한 완전한 제어 제공.

일반적인 문제

Converse API를 쓸 때 Claude가 PDF의 이미지나 차트를 보지 못한다면, 인용 플래그를 활성화해야 할 가능성이 커요. 켜지 않으면 Converse는 기본 텍스트 추출로만 돌아가요.

이것은 Converse API의 알려진 제약이에요. 인용 없이 시각적 PDF 분석이 필요한 애플리케이션이라면 InvokeModel API를 대신 사용하는 것을 고려하세요. .txt, .csv, .md 같은 일반 텍스트 파일은 document 블록에서 직접 쓸 수 있어요. MIME 타입 `text/plain`으로 Files API에 업로드하고 `file_id`로 참조하세요. .xlsx나 .docx 같은 바이너리 형식은 document 블록에서 지원되지 않으며 먼저 텍스트나 PDF로 변환해야 해요. [다른 파일 형식 작업](https://platform.claude.com/docs/en/build-with-claude/files#working-with-other-file-formats)을 보세요.

Claude로 PDF 처리하기

첫 PDF 요청 보내기

Messages API를 쓰는 간단한 예부터 시작해요. PDF는 세 가지 방법으로 Claude에 제공할 수 있어요.

  1. 온라인에 호스팅된 PDF를 URL 참조로
  2. base64로 인코딩된 PDF를 document 콘텐츠 블록으로
  3. Files APIfile_id
Amazon Bedrock과 Google Cloud에서는 현재 base64 인코딩 소스만 사용할 수 있어요. Microsoft Foundry에서는 Azure에 호스팅된 배포에 Files API가 지원되지 않아요.
옵션 1: URL 기반 PDF 문서

가장 간단한 방법은 URL에서 PDF를 직접 참조하는 거예요.

```bash cURL curl https://api.anthropic.com/v1/messages \ -H "content-type: application/json" \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "url", "url": "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf" } }, { "type": "text", "text": "What are the key findings in this document?" }] }] }' ```
ant messages create --transform content --format yaml <<'YAML'
model: claude-opus-5-5
max_tokens: 1024
messages:
  - role: user
    content:
      - type: document
        source:
          type: url
          url: https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf
      - type: text
        text: What are the key findings in this document?
YAML
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "document",
                    "source": {
                        "type": "url",
                        "url": "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf",
                    },
                },
                {"type": "text", "text": "What are the key findings in this document?"},
            ],
        }
    ],
)

print(message.content)
const anthropic = new Anthropic();

const response = await anthropic.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "url",
            url: "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
          }
        },
        {
          type: "text",
          text: "What are the key findings in this document?"
        }
      ]
    }
  ]
});

console.log(response);
var client = new AnthropicClient();

// Create document block with URL
var documentParam = new DocumentBlockParam
{
    Source = new UrlPdfSource
    {
        Url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf",
    },
};

// Create a message with document and text content blocks
var message = await client.Messages.Create(new MessageCreateParams
{
    Model = Model.ClaudeOpus5_5,
    MaxTokens = 1024,
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new List<ContentBlockParam>
            {
                documentParam,
                new TextBlockParam("What are the key findings in this document?"),
            },
        },
    ],
});

Console.WriteLine(string.Join("\n", message.Content));
client := anthropic.NewClient()

message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
	Model:     anthropic.ModelClaudeOpus5_5,
	MaxTokens: 1024,
	Messages: []anthropic.MessageParam{
		anthropic.NewUserMessage(
			anthropic.NewDocumentBlock(anthropic.URLPDFSourceParam{
				URL: "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf",
			}),
			anthropic.NewTextBlock("What are the key findings in this document?"),
		),
	},
})
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", message.Content)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Create document block with URL
DocumentBlockParam documentParam = DocumentBlockParam.builder()
  .source(
    UrlPdfSource.builder()
      .url(
        "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
      )
      .build()
  )
  .build();

// Create a message with document and text content blocks
MessageCreateParams params = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(1024)
  .addUserMessageOfBlockParams(
    List.of(
      ContentBlockParam.ofDocument(documentParam),
      ContentBlockParam.ofText(
        TextBlockParam.builder()
          .text("What are the key findings in this document?")
          .build()
      )
    )
  )
  .build();

Message message = client.messages().create(params);
System.out.println(message.content());
$client = new Client();

$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'url',
                        'url' => 'https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf',
                    ],
                ],
                [
                    'type' => 'text',
                    'text' => 'What are the key findings in this document?',
                ],
            ],
        ],
    ],
    model: 'claude-opus-5-5',
);

echo $message;
anthropic = Anthropic::Client.new

message = anthropic.messages.create(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "url",
            url: "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
          }
        },
        {type: "text", text: "What are the key findings in this document?"}
      ]
    }
  ]
)

puts(message.content)

응답은 Claude의 분석을 content의 텍스트 블록으로, 토큰 소모는 usage로 반환해요.

{
  "id": "msg_01Hfp8YuFjQ55VgWbpdHDehB",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5-5",
  "content": [
    {
      "type": "text",
      "text": "This document is an addendum to the Claude 3 model card, reporting updated evaluation results. The key findings include..."
    }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 45000,
    "output_tokens": 300
  }
}
옵션 2: base64 인코딩 PDF 문서

로컬 시스템에서 PDF를 보내야 하거나 URL을 쓸 수 없을 때는 이렇게 해요.

```bash cURL # Method 1: Fetch and encode a remote PDF curl -sL "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf" | base64 | tr -d '\n' > pdf_base64.txt

Method 2: Encode a local PDF file

base64 document.pdf | tr -d '\n' > pdf_base64.txt

Create a JSON request file using the pdf_base64.txt content

jq -n --rawfile PDF_BASE64 pdf_base64.txt '{ "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": $PDF_BASE64 } }, { "type": "text", "text": "What are the key findings in this document?" }] }] }' > request.json

Send the API request using the JSON file

curl https://api.anthropic.com/v1/messages
-H "content-type: application/json"
-H "x-api-key: $ANTHR...KEY"
-H "anthropic-version: 2023-06-01"
-d @request.json


```bash CLI
ant messages create \
  --model claude-opus-5-5 \
  --max-tokens 1024 \
  --transform content \
  --format yaml <<'YAML'
messages:
  - role: user
    content:
      - type: document
        source:
          type: base64
          media_type: application/pdf
          data: "@./document.pdf"
      - type: text
        text: What are the key findings in this document?
YAML
import base64
import httpx2

# First, load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_data = base64.standard_b64encode(
    httpx2.get(pdf_url, follow_redirects=True).content
).decode("utf-8")

# Alternative: Load from a local file
# with open("document.pdf", "rb") as f:
#     pdf_data = base64.standard_b64encode(f.read()).decode("utf-8")

# Send to Claude using base64 encoding
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "document",
                    "source": {
                        "type": "base64",
                        "media_type": "application/pdf",
                        "data": pdf_data,
                    },
                },
                {"type": "text", "text": "What are the key findings in this document?"},
            ],
        }
    ],
)

print(message.content)
// Method 1: Fetch and encode a remote PDF
const pdfURL =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
const pdfResponse = await fetch(pdfURL);
const arrayBuffer = await pdfResponse.arrayBuffer();
const pdfBase64 = Buffer.from(arrayBuffer).toString("base64");

// Method 2: Load from a local file
// import { readFile } from "node:fs/promises";
// const pdfBase64 = (await readFile('document.pdf')).toString('base64');

// Send the API request with base64-encoded PDF
const anthropic = new Anthropic();
const response = await anthropic.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "base64",
            media_type: "application/pdf",
            data: pdfBase64
          }
        },
        {
          type: "text",
          text: "What are the key findings in this document?"
        }
      ]
    }
  ]
});

console.log(response);
var client = new AnthropicClient();

// Method 1: Download and encode a remote PDF
var pdfUrl = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
using var httpClient = new HttpClient();
var pdfBase64 = Convert.ToBase64String(await httpClient.GetByteArrayAsync(pdfUrl));

// Method 2: Load from a local file
// var pdfBase64 = Convert.ToBase64String(await File.ReadAllBytesAsync("document.pdf"));

// Create document block with base64 data
var documentParam = new DocumentBlockParam
{
    Source = new Base64PdfSource { Data = pdfBase64 },
};

// Create a message with document and text content blocks
var message = await client.Messages.Create(new MessageCreateParams
{
    Model = Model.ClaudeOpus5_5,
    MaxTokens = 1024,
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new List<ContentBlockParam>
            {
                documentParam,
                new TextBlockParam("What are the key findings in this document?"),
            },
        },
    ],
});

Console.WriteLine(string.Join("\n", message.Content));
// First, load and encode the PDF
pdfURL := "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
resp, err := http.Get(pdfURL)
if err != nil {
	panic(err)
}
defer resp.Body.Close()
pdfBytes, err := io.ReadAll(resp.Body)
if err != nil {
	panic(err)
}
pdfBase64 := base64.StdEncoding.EncodeToString(pdfBytes)

// Alternative: Load from a local file (add "os" to the imports)
// pdfBytes, err := os.ReadFile("document.pdf")
// pdfBase64 := base64.StdEncoding.EncodeToString(pdfBytes)

// Send to Claude using base64 encoding
client := anthropic.NewClient()
message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
	Model:     anthropic.ModelClaudeOpus5_5,
	MaxTokens: 1024,
	Messages: []anthropic.MessageParam{
		anthropic.NewUserMessage(
			anthropic.NewDocumentBlock(anthropic.Base64PDFSourceParam{
				Data: pdfBase64,
			}),
			anthropic.NewTextBlock("What are the key findings in this document?"),
		),
	},
})
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", message.Content)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Method 1: Download and encode a remote PDF
String pdfUrl =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(pdfUrl)).GET().build();

HttpResponse<byte[]> response = httpClient.send(
  request,
  HttpResponse.BodyHandlers.ofByteArray()
);
String pdfBase64 = Base64.getEncoder().encodeToString(response.body());

// Method 2: Load from a local file
// byte[] fileBytes = Files.readAllBytes(Path.of("document.pdf"));
// String pdfBase64 = Base64.getEncoder().encodeToString(fileBytes);

// Create document block with base64 data
DocumentBlockParam documentParam = DocumentBlockParam.builder()
  .source(Base64PdfSource.builder().data(pdfBase64).build())
  .build();

// Create a message with document and text content blocks
MessageCreateParams params = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(1024)
  .addUserMessageOfBlockParams(
    List.of(
      ContentBlockParam.ofDocument(documentParam),
      ContentBlockParam.ofText(
        TextBlockParam.builder()
          .text("What are the key findings in this document?")
          .build()
      )
    )
  )
  .build();

Message message = client.messages().create(params);
System.out.println(message.content());
$client = new Client();

// First, load and encode the PDF
$pdf_url = 'https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf';
$pdf_data = base64_encode(file_get_contents($pdf_url));

// Alternative: Load from a local file
// $pdf_data = base64_encode(file_get_contents('document.pdf'));

// Send to Claude using base64 encoding
$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => 'application/pdf',
                        'data' => $pdf_data,
                    ],
                ],
                [
                    'type' => 'text',
                    'text' => 'What are the key findings in this document?',
                ],
            ],
        ],
    ],
    model: 'claude-opus-5-5',
);

echo $message;
require "open-uri"

# First, load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_bytes = URI.open(pdf_url, "rb") { |f| f.read }
pdf_data = [pdf_bytes].pack("m0") # Base64-encode without newlines

# Alternative: Load from a local file
# pdf_data = [File.binread("document.pdf")].pack("m0")

# Send to Claude using base64 encoding
anthropic = Anthropic::Client.new
message = anthropic.messages.create(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "base64",
            media_type: "application/pdf",
            data: pdf_data
          }
        },
        {type: "text", text: "What are the key findings in this document?"}
      ]
    }
  ]
)

puts(message.content)
옵션 3: Files API

반복해서 쓸 PDF이거나 인코딩 오버헤드를 피하고 싶다면 Files API를 사용해요.

```bash cURL # First, upload your PDF to the Files API FILE_ID=$(curl -sS -X POST https://api.anthropic.com/v1/files \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" \ -F "[email protected]" | jq -r '.id')

Then use the returned file_id in your message

curl https://api.anthropic.com/v1/messages
-H "content-type: application/json"
-H "x-api-key: $ANTHR...KEY"
-H "anthropic-version: 2023-06-01"
-d @- <<EOF { "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "file", "file_id": "$FILE_ID" } }, { "type": "text", "text": "What are the key findings in this document?" }] }] } EOF


```bash CLI
# First, upload your PDF to the Files API
FILE_ID=$(ant files upload \
  --file ./document.pdf \
  --transform id \
  --raw-output)

# Then use the returned file_id in your message
ant messages create \
  --transform content \
  --format yaml <<YAML
model: claude-opus-5-5
max_tokens: 1024
messages:
  - role: user
    content:
      - type: document
        source:
          type: file
          file_id: $FILE_ID
      - type: text
        text: What are the key findings in this document?
YAML
client = anthropic.Anthropic()

# Upload the PDF file
with open("/path/to/document.pdf", "rb") as f:
    file_upload = client.files.upload(file=("document.pdf", f, "application/pdf"))

# Use the uploaded file in a message
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "document",
                    "source": {"type": "file", "file_id": file_upload.id},
                },
                {"type": "text", "text": "What are the key findings in this document?"},
            ],
        }
    ],
)

print(message.content)
import Anthropic, { toFile } from "@anthropic-ai/sdk";
import fs from "node:fs";

const anthropic = new Anthropic();

// Upload the PDF file
const fileUpload = await anthropic.files.upload({
  file: await toFile(fs.createReadStream("/path/to/document.pdf"), undefined, {
    type: "application/pdf"
  })
});

// Use the uploaded file in a message
const response = await anthropic.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "file",
            file_id: fileUpload.id
          }
        },
        {
          type: "text",
          text: "What are the key findings in this document?"
        }
      ]
    }
  ]
});

console.log(response);
var client = new AnthropicClient();

// Upload the PDF file
var fileUpload = await client.Files.Upload(new FileUploadParams
{
    File = new BinaryContent
    {
        Stream = File.OpenRead("/path/to/document.pdf"),
        FileName = "document.pdf",
        ContentType = new("application/pdf"),
    },
});

// Use the uploaded file in a message
var message = await client.Messages.Create(new MessageCreateParams
{
    Model = Model.ClaudeOpus5_5,
    MaxTokens = 1024,
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new List<ContentBlockParam>
            {
                new DocumentBlockParam
                {
                    Source = new FileDocumentSource { FileID = fileUpload.ID },
                },
                new TextBlockParam("What are the key findings in this document?"),
            },
        },
    ],
});

Console.WriteLine(string.Join("\n", message.Content));
client := anthropic.NewClient()

// Upload the PDF file
pdfFile, err := os.Open("/path/to/document.pdf")
if err != nil {
	panic(err)
}
defer pdfFile.Close()

fileUpload, err := client.Files.Upload(context.TODO(), anthropic.FileUploadParams{
	File: anthropic.File(pdfFile, "document.pdf", "application/pdf"),
})
if err != nil {
	panic(err)
}

// Use the uploaded file in a message
message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
	Model:     anthropic.ModelClaudeOpus5_5,
	MaxTokens: 1024,
	Messages: []anthropic.MessageParam{
		anthropic.NewUserMessage(
			anthropic.NewDocumentBlock(anthropic.FileDocumentSourceParam{
				FileID: fileUpload.ID,
			}),
			anthropic.NewTextBlock("What are the key findings in this document?"),
		),
	},
})
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", message.Content)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Upload the PDF file
FileMetadata file = client
  .files()
  .upload(FileUploadParams.builder().file(Path.of("/path/to/document.pdf")).build());

// Use the uploaded file in a message
MessageCreateParams params = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(1024)
  .addUserMessageOfBlockParams(
    List.of(
      ContentBlockParam.ofDocument(
        DocumentBlockParam.builder().fileSource(file.id()).build()
      ),
      ContentBlockParam.ofText(
        TextBlockParam.builder()
          .text("What are the key findings in this document?")
          .build()
      )
    )
  )
  .build();

Message message = client.messages().create(params);
System.out.println(message.content());
use Anthropic\Core\FileParam;

$client = new Client();

// Upload the PDF file
$file_upload = $client->files->upload(
    file: FileParam::fromResource(fopen('/path/to/document.pdf', 'r'), contentType: 'application/pdf'),
);

// Use the uploaded file in a message
$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'file',
                        'fileID' => $file_upload->id,
                    ],
                ],
                [
                    'type' => 'text',
                    'text' => 'What are the key findings in this document?',
                ],
            ],
        ],
    ],
    model: 'claude-opus-5-5',
);

echo $message;
anthropic = Anthropic::Client.new

# Upload the PDF file
file_upload = File.open("/path/to/document.pdf", "rb") do |f|
  anthropic.files.upload(
    file: Anthropic::FilePart.new(f, filename: "document.pdf", content_type: "application/pdf")
  )
end

# Use the uploaded file in a message
message = anthropic.messages.create(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {type: "file", file_id: file_upload.id}
        },
        {type: "text", text: "What are the key findings in this document?"}
      ]
    }
  ]
)

puts(message.content)

PDF 지원 동작 방식

Claude에 PDF를 보내면 다음 단계가 일어나요.

* 시스템은 문서의 각 페이지를 이미지로 변환해요. * 각 페이지의 텍스트를 추출해 각 페이지의 이미지와 함께 제공해요. * 문서는 분석을 위해 텍스트와 이미지의 조합으로 제공돼요. * 덕분에 차트, 다이어그램, 기타 비텍스트 콘텐츠 같은 PDF의 시각적 요소에 대한 인사이트를 요청할 수 있어요. Claude는 응답할 때 텍스트와 시각적 내용을 모두 참조할 수 있어요. PDF 지원을 다음과 통합하면 성능을 더 높일 수 있어요.
* [프롬프트 캐싱 사용](https://platform.claude.com/docs/en/build-with-claude/pdf-support#use-prompt-caching): 반복 분석의 성능 개선
* [문서 배치 처리](https://platform.claude.com/docs/en/build-with-claude/pdf-support#process-document-batches): 대용량 문서 처리
* [도구 사용](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview): 도구 입력으로 쓸 문서의 특정 정보 추출

비용 추정하기

PDF 파일의 토큰 수는 문서에서 추출한 전체 텍스트와 페이지 수에 따라 달라져요.

  • 텍스트 토큰 비용: 페이지마다 콘텐츠 밀도에 따라 1,500~3,000 토큰을 보통 사용해요. 표준 API 가격이 적용되며 추가 PDF 수수료는 없어요.
  • 이미지 토큰 비용: 각 페이지가 이미지로 변환되므로 같은 이미지 기반 비용 계산이 적용돼요.

토큰 계산으로 특정 PDF의 비용을 추정할 수 있어요.

PDF 처리 최적화

성능 개선

최적 결과를 위한 모범 사례를 따르세요.

  • 요청에서 텍스트보다 PDF를 앞에 배치
  • 표준 글꼴 사용
  • 텍스트가 명확하고 읽기 쉽게
  • 페이지를 올바른 세로 방향으로 회전
  • 프롬프트에서 논리적 페이지 번호(PDF 뷰어 기준) 사용
  • 필요하면 큰 PDF를 청크로 분할
  • 반복 분석을 위해 프롬프트 캐싱 활성화

구현 확장

대용량 처리를 위한 접근법:

프롬프트 캐싱 사용

반복 쿼리 성능을 높이려면 프롬프트 캐싱으로 PDF를 캐시하세요.

```bash cURL curl -sL "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf" | base64 | tr -d '\n' > pdf_base64.txt # Create a JSON request file using the pdf_base64.txt content jq -n --rawfile PDF_BASE64 pdf_base64.txt '{ "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": $PDF_BASE64 }, "cache_control": { "type": "ephemeral" } }, { "type": "text", "text": "Which model has the highest human preference win rates across each use-case?" }] }] }' > request.json

Then make the API call using the JSON file

curl https://api.anthropic.com/v1/messages
-H "content-type: application/json"
-H "x-api-key: $ANTHR...KEY"
-H "anthropic-version: 2023-06-01"
-d @request.json


```bash CLI
ant messages create --transform content --format yaml <<'YAML'
model: claude-opus-5-5
max_tokens: 1024
messages:
  - role: user
    content:
      - type: document
        source:
          type: base64
          media_type: application/pdf
          data: "@./document.pdf"
        cache_control:
          type: ephemeral
      - type: text
        text: Which model has the highest human preference win rates across each use-case?
YAML
import base64
import httpx2

# First, load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_data = base64.standard_b64encode(
    httpx2.get(pdf_url, follow_redirects=True).content
).decode("utf-8")

# Create a message with the cached document
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "document",
                    "source": {
                        "type": "base64",
                        "media_type": "application/pdf",
                        "data": pdf_data,
                    },
                    "cache_control": {"type": "ephemeral"},
                },
                {
                    "type": "text",
                    "text": "Which model has the highest human preference win rates across each use-case?",
                },
            ],
        }
    ],
)

print(message.content)
// First, load and encode the PDF
const pdfURL =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
const pdfResponse = await fetch(pdfURL);
const arrayBuffer = await pdfResponse.arrayBuffer();
const pdfBase64 = Buffer.from(arrayBuffer).toString("base64");

// Create a message with the cached document
const anthropic = new Anthropic();
const response = await anthropic.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "base64",
            media_type: "application/pdf",
            data: pdfBase64
          },
          cache_control: { type: "ephemeral" }
        },
        {
          type: "text",
          text: "Which model has the highest human preference win rates across each use-case?"
        }
      ]
    }
  ]
});

console.log(response);
var client = new AnthropicClient();

// Download and encode the PDF
var pdfUrl = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
using var httpClient = new HttpClient();
var pdfBase64 = Convert.ToBase64String(await httpClient.GetByteArrayAsync(pdfUrl));

var message = await client.Messages.Create(new MessageCreateParams
{
    Model = Model.ClaudeOpus5_5,
    MaxTokens = 1024,
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new List<ContentBlockParam>
            {
                new DocumentBlockParam
                {
                    Source = new Base64PdfSource { Data = pdfBase64 },
                    CacheControl = new CacheControlEphemeral(),
                },
                new TextBlockParam("Which model has the highest human preference win rates across each use-case?"),
            },
        },
    ],
});

Console.WriteLine(message);
// First, load and encode the PDF
pdfURL := "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
resp, err := http.Get(pdfURL)
if err != nil {
	panic(err)
}
defer resp.Body.Close()
pdfBytes, err := io.ReadAll(resp.Body)
if err != nil {
	panic(err)
}
pdfBase64 := base64.StdEncoding.EncodeToString(pdfBytes)

// Create a document block with cache control
client := anthropic.NewClient()
message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
	Model:     anthropic.ModelClaudeOpus5_5,
	MaxTokens: 1024,
	Messages: []anthropic.MessageParam{
		anthropic.NewUserMessage(
			anthropic.ContentBlockParamUnion{
				OfDocument: &anthropic.DocumentBlockParam{
					Source: anthropic.DocumentBlockParamSourceUnion{
						OfBase64: &anthropic.Base64PDFSourceParam{
							Data: pdfBase64,
						},
					},
					CacheControl: anthropic.NewCacheControlEphemeralParam(),
				},
			},
			anthropic.NewTextBlock("Which model has the highest human preference win rates across each use-case?"),
		),
	},
})
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", message.Content)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Download and encode the PDF
String pdfUrl =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(pdfUrl)).GET().build();

HttpResponse<byte[]> response = httpClient.send(
  request,
  HttpResponse.BodyHandlers.ofByteArray()
);
String pdfBase64 = Base64.getEncoder().encodeToString(response.body());

MessageCreateParams params = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(1024)
  .addUserMessageOfBlockParams(
    List.of(
      ContentBlockParam.ofDocument(
        DocumentBlockParam.builder()
          .source(Base64PdfSource.builder().data(pdfBase64).build())
          .cacheControl(CacheControlEphemeral.builder().build())
          .build()
      ),
      ContentBlockParam.ofText(
        TextBlockParam.builder()
          .text(
            "Which model has the highest human preference win rates across each use-case?"
          )
          .build()
      )
    )
  )
  .build();

Message message = client.messages().create(params);
System.out.println(message);
$client = new Client();

// Load and encode the PDF
$pdf_url = 'https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf';
$pdf_data = base64_encode(file_get_contents($pdf_url));

$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => 'application/pdf',
                        'data' => $pdf_data,
                    ],
                    'cache_control' => ['type' => 'ephemeral'],
                ],
                [
                    'type' => 'text',
                    'text' => 'Which model has the highest human preference win rates across each use-case?',
                ],
            ],
        ],
    ],
    model: 'claude-opus-5-5',
);

echo $message;
require "open-uri"

# Load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_bytes = URI.open(pdf_url, "rb") { |f| f.read }
pdf_data = [pdf_bytes].pack("m0") # Base64-encode without newlines

anthropic = Anthropic::Client.new

message = anthropic.messages.create(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "document",
          source: {
            type: "base64",
            media_type: "application/pdf",
            data: pdf_data
          },
          cache_control: {type: "ephemeral"}
        },
        {
          type: "text",
          text: "Which model has the highest human preference win rates across each use-case?"
        }
      ]
    }
  ]
)

puts(message.content)
문서 배치 처리

Message Batches API로 한 요청에서 여러 PDF를 처리하세요.

```bash cURL curl -sL "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf" | base64 | tr -d '\n' > pdf_base64.txt # Create a JSON request file using the pdf_base64.txt content jq -n --rawfile PDF_BASE64 pdf_base64.txt '{ "requests": [ { "custom_id": "my-first-request", "params": { "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": $PDF_BASE64 } }, { "type": "text", "text": "Which model has the highest human preference win rates across each use-case?" }] }] } }, { "custom_id": "my-second-request", "params": { "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [{ "role": "user", "content": [{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": $PDF_BASE64 } }, { "type": "text", "text": "Extract 5 key insights from this document." }] }] } }] }' > request.json

Then make the API call using the JSON file

curl https://api.anthropic.com/v1/messages/batches
-H "content-type: application/json"
-H "x-api-key: $ANTHR...KEY"
-H "anthropic-version: 2023-06-01"
-d @request.json


```bash CLI
ant messages:batches create <<'YAML'
requests:
  - custom_id: my-first-request
    params:
      model: claude-opus-5-5
      max_tokens: 1024
      messages:
        - role: user
          content:
            - type: document
              source:
                type: base64
                media_type: application/pdf
                data: "@./document.pdf"
            - type: text
              text: >-
                Which model has the highest human preference win rates
                across each use-case?
  - custom_id: my-second-request
    params:
      model: claude-opus-5-5
      max_tokens: 1024
      messages:
        - role: user
          content:
            - type: document
              source:
                type: base64
                media_type: application/pdf
                data: "@./document.pdf"
            - type: text
              text: Extract 5 key insights from this document.
YAML
import base64
import httpx2

# First, load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_data = base64.standard_b64encode(
    httpx2.get(pdf_url, follow_redirects=True).content
).decode("utf-8")

# Create a batch of requests that use the document
client = anthropic.Anthropic()
message_batch = client.messages.batches.create(
    requests=[
        {
            "custom_id": "my-first-request",
            "params": {
                "model": "claude-opus-5-5",
                "max_tokens": 1024,
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "document",
                                "source": {
                                    "type": "base64",
                                    "media_type": "application/pdf",
                                    "data": pdf_data,
                                },
                            },
                            {
                                "type": "text",
                                "text": "Which model has the highest human preference win rates across each use-case?",
                            },
                        ],
                    }
                ],
            },
        },
        {
            "custom_id": "my-second-request",
            "params": {
                "model": "claude-opus-5-5",
                "max_tokens": 1024,
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "document",
                                "source": {
                                    "type": "base64",
                                    "media_type": "application/pdf",
                                    "data": pdf_data,
                                },
                            },
                            {
                                "type": "text",
                                "text": "Extract 5 key insights from this document.",
                            },
                        ],
                    }
                ],
            },
        },
    ]
)

print(message_batch)
// First, load and encode the PDF
const pdfURL =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
const pdfResponse = await fetch(pdfURL);
const arrayBuffer = await pdfResponse.arrayBuffer();
const pdfBase64 = Buffer.from(arrayBuffer).toString("base64");

// Create a batch of requests that use the document
const anthropic = new Anthropic();
const response = await anthropic.messages.batches.create({
  requests: [
    {
      custom_id: "my-first-request",
      params: {
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [
          {
            role: "user",
            content: [
              {
                type: "document",
                source: {
                  type: "base64",
                  media_type: "application/pdf",
                  data: pdfBase64
                }
              },
              {
                type: "text",
                text: "Which model has the highest human preference win rates across each use-case?"
              }
            ]
          }
        ]
      }
    },
    {
      custom_id: "my-second-request",
      params: {
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [
          {
            role: "user",
            content: [
              {
                type: "document",
                source: {
                  type: "base64",
                  media_type: "application/pdf",
                  data: pdfBase64
                }
              },
              {
                type: "text",
                text: "Extract 5 key insights from this document."
              }
            ]
          }
        ]
      }
    }
  ]
});

console.log(response);
var client = new AnthropicClient();

// Download and encode the PDF
var pdfUrl = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
using var httpClient = new HttpClient();
var pdfBase64 = Convert.ToBase64String(await httpClient.GetByteArrayAsync(pdfUrl));

var batch = await client.Messages.Batches.Create(new BatchCreateParams
{
    Requests =
    [
        new()
        {
            CustomID = "my-first-request",
            Params = new()
            {
                Model = Model.ClaudeOpus5_5,
                MaxTokens = 1024,
                Messages =
                [
                    new()
                    {
                        Role = Role.User,
                        Content = new List<ContentBlockParam>
                        {
                            new DocumentBlockParam
                            {
                                Source = new Base64PdfSource { Data = pdfBase64 },
                            },
                            new TextBlockParam("Which model has the highest human preference win rates across each use-case?"),
                        },
                    },
                ],
            },
        },
        new()
        {
            CustomID = "my-second-request",
            Params = new()
            {
                Model = Model.ClaudeOpus5_5,
                MaxTokens = 1024,
                Messages =
                [
                    new()
                    {
                        Role = Role.User,
                        Content = new List<ContentBlockParam>
                        {
                            new DocumentBlockParam
                            {
                                Source = new Base64PdfSource { Data = pdfBase64 },
                            },
                            new TextBlockParam("Extract 5 key insights from this document."),
                        },
                    },
                ],
            },
        },
    ],
});

Console.WriteLine(batch);
// First, load and encode the PDF
pdfURL := "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
resp, err := http.Get(pdfURL)
if err != nil {
	panic(err)
}
defer resp.Body.Close()
pdfBytes, err := io.ReadAll(resp.Body)
if err != nil {
	panic(err)
}
pdfBase64 := base64.StdEncoding.EncodeToString(pdfBytes)

// Create a batch of requests that use the document
client := anthropic.NewClient()
batch, err := client.Messages.Batches.New(context.TODO(), anthropic.MessageBatchNewParams{
	Requests: []anthropic.MessageBatchNewParamsRequest{
		{
			CustomID: "my-first-request",
			Params: anthropic.MessageBatchNewParamsRequestParams{
				Model:     anthropic.ModelClaudeOpus5_5,
				MaxTokens: 1024,
				Messages: []anthropic.MessageParam{
					anthropic.NewUserMessage(
						anthropic.NewDocumentBlock(anthropic.Base64PDFSourceParam{
							Data: pdfBase64,
						}),
						anthropic.NewTextBlock("Which model has the highest human preference win rates across each use-case?"),
					),
				},
			},
		},
		{
			CustomID: "my-second-request",
			Params: anthropic.MessageBatchNewParamsRequestParams{
				Model:     anthropic.ModelClaudeOpus5_5,
				MaxTokens: 1024,
				Messages: []anthropic.MessageParam{
					anthropic.NewUserMessage(
						anthropic.NewDocumentBlock(anthropic.Base64PDFSourceParam{
							Data: pdfBase64,
						}),
						anthropic.NewTextBlock("Extract 5 key insights from this document."),
					),
				},
			},
		},
	},
})
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", batch)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Download and encode the PDF
String pdfUrl =
  "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf";
HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(pdfUrl)).GET().build();

HttpResponse<byte[]> response = httpClient.send(
  request,
  HttpResponse.BodyHandlers.ofByteArray()
);
String pdfBase64 = Base64.getEncoder().encodeToString(response.body());

BatchCreateParams params = BatchCreateParams.builder()
  .addRequest(
    BatchCreateParams.Request.builder()
      .customId("my-first-request")
      .params(
        BatchCreateParams.Request.Params.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024)
          .addUserMessageOfBlockParams(
            List.of(
              ContentBlockParam.ofDocument(
                DocumentBlockParam.builder()
                  .source(Base64PdfSource.builder().data(pdfBase64).build())
                  .build()
              ),
              ContentBlockParam.ofText(
                TextBlockParam.builder()
                  .text(
                    "Which model has the highest human preference win rates across each use-case?"
                  )
                  .build()
              )
            )
          )
          .build()
      )
      .build()
  )
  .addRequest(
    BatchCreateParams.Request.builder()
      .customId("my-second-request")
      .params(
        BatchCreateParams.Request.Params.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024)
          .addUserMessageOfBlockParams(
            List.of(
              ContentBlockParam.ofDocument(
                DocumentBlockParam.builder()
                  .source(Base64PdfSource.builder().data(pdfBase64).build())
                  .build()
              ),
              ContentBlockParam.ofText(
                TextBlockParam.builder()
                  .text("Extract 5 key insights from this document.")
                  .build()
              )
            )
          )
          .build()
      )
      .build()
  )
  .build();

MessageBatch batch = client.messages().batches().create(params);
System.out.println(batch);
$client = new Client();

// Load and encode the PDF
$pdf_url = 'https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf';
$pdf_data = base64_encode(file_get_contents($pdf_url));

$batch = $client->messages->batches->create(
    requests: [
        [
            'custom_id' => 'my-first-request',
            'params' => [
                'model' => 'claude-opus-5-5',
                'max_tokens' => 1024,
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => [
                            [
                                'type' => 'document',
                                'source' => [
                                    'type' => 'base64',
                                    'media_type' => 'application/pdf',
                                    'data' => $pdf_data,
                                ],
                            ],
                            [
                                'type' => 'text',
                                'text' => 'Which model has the highest human preference win rates across each use-case?',
                            ],
                        ],
                    ],
                ],
            ],
        ],
        [
            'custom_id' => 'my-second-request',
            'params' => [
                'model' => 'claude-opus-5-5',
                'max_tokens' => 1024,
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => [
                            [
                                'type' => 'document',
                                'source' => [
                                    'type' => 'base64',
                                    'media_type' => 'application/pdf',
                                    'data' => $pdf_data,
                                ],
                            ],
                            [
                                'type' => 'text',
                                'text' => 'Extract 5 key insights from this document.',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
);

echo $batch;
require "open-uri"

# Load and encode the PDF
pdf_url = "https://assets.anthropic.com/m/1cd9d098ac3e6467/original/Claude-3-Model-Card-October-Addendum.pdf"
pdf_bytes = URI.open(pdf_url, "rb") { |f| f.read }
pdf_data = [pdf_bytes].pack("m0") # Base64-encode without newlines

anthropic = Anthropic::Client.new

message_batch = anthropic.messages.batches.create(
  requests: [
    {
      custom_id: "my-first-request",
      params: {
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [
          {
            role: "user",
            content: [
              {
                type: "document",
                source: {
                  type: "base64",
                  media_type: "application/pdf",
                  data: pdf_data
                }
              },
              {
                type: "text",
                text: "Which model has the highest human preference win rates across each use-case?"
              }
            ]
          }
        ]
      }
    },
    {
      custom_id: "my-second-request",
      params: {
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [
          {
            role: "user",
            content: [
              {
                type: "document",
                source: {
                  type: "base64",
                  media_type: "application/pdf",
                  data: pdf_data
                }
              },
              {
                type: "text",
                text: "Extract 5 key insights from this document."
              }
            ]
          }
        ]
      }
    }
  ]
)

puts(message_batch)

배치는 비동기로 처리돼요. 처리 후 진행 상황을 확인하고 결과를 가져오려면 Batch processing을 보세요.

더 알아보기 (Learn more)