Claude API에서 Messages 말고 Batches·Files·Managed Agents가 필요한 때

동딩
2026.10.15·3분 읽기·

기다리는 사람이 없으면 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는 결과를 원래 문의와 짝짓는 이름표입니다.

js
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"를 주면 캐시가 더 잘 맞습니다.

js
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에서 읽은 지난달 문의
js
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시간 안에 온다

Files내 서버MessagesBatchesPDF 한 번file_id문의 1건+ file_id답, 바로3만 건+ custom_id대부분 한 시간,늦어도 24시간 안에결과 3만 건, 순서 섞임custom_id로 짝짓는다
환불 정책 PDF를 붙여 문의를 분류할 때

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까지입니다.

Comments

댓글

powered by giscus ↗