Claude API에서 Messages 말고 Batches·Files·Managed Agents가 필요한 때
기다리는 사람이 없으면 Batches다
기다리는 사람이 있으면 Messages, 없으면 Batches로 보냅니다.
| 상황 | 고를 API | 기억할 것 |
|---|---|---|
| 방금 들어온 문의 하나를 분류 | Messages | 대화를 매번 처음부터 보낸다 |
| 지난달 문의 3만 건을 다시 분류 | Batches | 반값, 결과는 24시간 안에 순서 없이 |
| 환불 정책 PDF를 요청마다 함께 읽힘 | Files + Messages | 한 번 올리고 file_id로 가리킨다 |
| 주문 조회·환불 실행을 Claude가 이어서 | Messages + 도구 사용 | 루프와 도구는 내 서버 |
| 문의 CSV로 월간 리포트를 만드는 긴 작업 | Managed Agents | 세션 시간도 과금 |
지금 들어온 문의와 지난달 문의는 모델과 프롬프트가 같은 요청을 씁니다. ask()가 만든 요청을 Messages에는 그대로, Batches에는 custom_id를 붙여 넣습니다. custom_id는 결과를 원래 문의와 짝짓는 이름표입니다.
const policy = { type: "document", source: { type: "file", file_id: POLICY_FILE_ID }, cache_control: { type: "ephemeral" },};const ask = (text) => ({ model: "claude-opus-5-5", max_tokens: 1024, messages: [{ role: "user", content: [policy, { type: "text", text: `문의 유형(배송·환불·기타): ${text}` }] }],});const msg = await client.messages.create(ask("환불은 언제 들어오나요?"));const batch = await client.messages.batches.create({ requests: tickets.map((t) => ({ custom_id: t.id, params: ask(t.text) })),});PDF 업로드와 배치 결과 받기까지 붙인 코드
위 코드 앞에 클라이언트와 업로드를, 뒤에 결과 받기를 붙입니다. custom_id는 영문·숫자·하이픈·밑줄 1~64자이고, 배치 하나에 100,000건 또는 256 MB까지 넣습니다. 24시간 안에 못 끝낸 요청은 expired로 오고 값을 내지 않습니다. 결과는 29일 동안 받습니다. 배치는 5분을 넘겨 돌 수 있어 cache_control에 ttl: "1h"를 주면 캐시가 더 잘 맞습니다.
import Anthropic, { toFile } from "@anthropic-ai/sdk";import fs from "node:fs";const client = new Anthropic(); // ANTHROPIC_API_KEY를 읽는다const { id: POLICY_FILE_ID } = await client.files.upload({ file: await toFile(fs.createReadStream("refund-policy.pdf"), undefined, { type: "application/pdf" }),});const tickets = [{ id: "T-20481", text: "배송이 일주일째 안 와요" }]; // DB에서 읽은 지난달 문의while ((await client.messages.batches.retrieve(batch.id)).processing_status !== "ended") { await new Promise((r) => setTimeout(r, 60_000));}const labels = new Map(); // custom_id → 분류for await (const r of await client.messages.batches.results(batch.id)) { if (r.result.type !== "succeeded") continue; // errored·expired는 다시 보낼 목록으로 labels.set(r.custom_id, r.result.message.content.find((b) => b.type === "text")?.text);}Batches와 Files는 길만 바꾼다
모델을 부르는 곳은 Messages 하나이고, Batches와 Files는 요청과 파일이 오가는 길만 바꿉니다.
문의 1건은 바로 답이 오고, 3만 건은 큐를 거쳐 24시간 안에 온다
for 문으로 3만 번 불러도 분류는 되지만, 기다리는 사람이 없는 일에 정가를 내는 셈입니다. Batches는 같은 일을 절반 값에 합니다.
요금은 글을 잘게 나눈 단위인 토큰 수로 매겨집니다. file_id는 업로드를 한 번으로 줄일 뿐이고, 요청에 붙인 PDF는 매번 입력 토큰으로 과금됩니다. PDF 몫의 값은 프롬프트 캐싱으로 줄입니다. cache_control을 붙인 PDF는 5분 안에 다시 오면 기본 입력 단가의 10% 이하로 과금됩니다.
에이전트는 루프를 어디서 돌리느냐로 고른다
에이전트는 도구를 부르고 결과를 읽는 루프를 일이 끝날 때까지 도는 프로그램입니다. 루프를 내 서버에서 돌리면 Messages에 도구를 얹고, Anthropic에 맡기면 Managed Agents를 씁니다.
환불 처리는 주문 DB와 결제 API가 있는 내 서버에서 돌립니다. Claude가 tool_use 블록으로 주문 조회를 부탁하면 서버가 주문을 찾아 tool_result로 돌려줍니다. 이 왕복은 SDK의 Tool Runner가 대신 돌립니다.
월간 리포트는 Managed Agents에 맡깁니다. 작업마다 격리된 컨테이너인 샌드박스가 뜨고, Files로 올린 문의 CSV를 거기 붙이면 에이전트가 몇십 분 동안 집계해 리포트 파일을 남깁니다.
세션은 에이전트가 작업 하나를 하는 실행 단위이고, 실행 중인 시간만 시간당 $0.08로 과금됩니다.
| Messages + 도구 사용 | Managed Agents | |
|---|---|---|
| 루프 | 내 서버 | Anthropic |
| 도구가 도는 곳 | 내 서버 | 세션 샌드박스 |
| 대화 기록 | 매번 내가 보낸다 | 세션에 남는다 |
| 과금 | 토큰 | 토큰 + 세션 시간 |
Bedrock·Google Cloud·Microsoft Foundry로 Claude를 쓴다면
Messages는 어느 플랫폼에서나 씁니다. Batches와 Managed Agents는 Claude API와 Claude Platform on AWS에서만 씁니다. Files는 여기에 더해 Microsoft Foundry에서도 쓰고, Foundry에서는 Hosted on Anthropic 배포여야 합니다. Messages 요청 크기는 Claude API 32 MB, Bedrock 20 MB, Google Cloud 30 MB까지입니다.