토큰과 비용 — usage 측정 · 모델 선택
Article
4강과 5강에서 두 번 미뤄둔 숫자가 있다. "대화가 길어질수록 매번 더 많이 보낸다"는 문장을 말로만 하고 넘어갔다. 오늘은 그 문장을 진짜 숫자로 만든다. 그리고 3강에서 딱 한 번 계산해본 비용 공식을, 세 모델에 나란히 돌려서 저울질해본다.
대화가 쌓일수록 입력 토큰이 얼마나 느나
4강에서 만든 ask() 함수를 그대로 쓴다. 이번엔 매 호출마다 response.usage.input_tokens 를 찍어 다섯 턴 동안 어떻게 변하는지 본다.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const messages: Anthropic.MessageParam[] = [];
async function ask(userText: string) {
messages.push({ role: "user", content: userText });
const response = await client.messages.create({
model: "claude-haiku-4-5",
max_tokens: 200,
system: "너는 친절한 한국어 어시스턴트다. 답은 항상 한 문장으로 짧게 한다.",
messages,
});
const text = response.content[0].type === "text" ? response.content[0].text : "";
messages.push({ role: "assistant", content: text });
console.log(`\n> ${userText}`);
console.log(text);
console.log(
`(누적 메시지 ${messages.length}개, 이번 호출 입력 토큰: ${response.usage.input_tokens})`,
);
}
await ask("내 이름은 민준이야.");
await ask("나는 서울에 살아.");
await ask("나는 개발자야.");
await ask("나는 커피를 좋아해.");
await ask("지금까지 내가 말한 걸 한 문장으로 정리해줘.");
실행해본다.
npx tsx --env-file=.env index.ts
- > 내 이름은 민준이야.
- 안녕하세요, 민준이님! 만나뵙게 되어 반갑습니다.
- (누적 메시지 2개, 이번 호출 입력 토큰: 59)
- > 나는 서울에 살아.
- 서울에서 사시는군요, 멋진 곳이네요!
- (누적 메시지 4개, 이번 호출 입력 토큰: 108)
- > 나는 개발자야.
- 개발자로 일하시니 정말 멋진 직업이네요!
- (누적 메시지 6개, 이번 호출 입력 토큰: 146)
- > 나는 커피를 좋아해.
- 커피를 좋아하시니 개발자로서 더욱 잘 어울리는 것 같아요!
- (누적 메시지 8개, 이번 호출 입력 토큰: 189)
- > 지금까지 내가 말한 걸 한 문장으로 정리해줘.
- 서울에 사는 개발자 민준이님은 커피를 좋아하시네요!
- (누적 메시지 10개, 이번 호출 입력 토큰: 259)
숫자를 막대로 나란히 놓으면 늘어나는 게 눈에 보인다.
세 모델에 같은 질문을 던져본다
3강에서 본 가격표를 다시 꺼낸다. 이번엔 표로만 보지 않고, 같은 질문을 Haiku · Sonnet · Opus 세 모델에 실제로 보내서 답변과 비용을 나란히 비교한다.
| claude-haiku-4-5 | $1.00 | $5.00 | 가장 저렴하고 빠르다 |
| claude-sonnet-5 | $3.00 | $15.00 | 속도와 성능의 균형 |
| claude-opus-4-8 | $5.00 | $25.00 | 가장 똑똑하지만 가장 비싸다 |
my-ai-assistant 폴더에 models.ts 를 만든다. 같은 질문을 배열로 돌면서 모델만 바꿔 부른다.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const PRICING = {
"claude-haiku-4-5": { input: 1.0, output: 5.0 },
"claude-sonnet-5": { input: 3.0, output: 15.0 },
"claude-opus-4-8": { input: 5.0, output: 25.0 },
};
const question = "타입스크립트를 한 문장으로 설명해줘.";
for (const model of Object.keys(PRICING) as (keyof typeof PRICING)[]) {
const response = await client.messages.create({
model,
max_tokens: 200,
messages: [{ role: "user", content: question }],
});
const text = response.content[0].type === "text" ? response.content[0].text : "";
const { input_tokens, output_tokens } = response.usage;
const price = PRICING[model];
const cost =
(input_tokens / 1_000_000) * price.input +
(output_tokens / 1_000_000) * price.output;
console.log(`\n=== ${model} ===`);
console.log(text);
console.log(
`입력 토큰: ${input_tokens}, 출력 토큰: ${output_tokens}, 비용: 약 $${cost.toFixed(6)}`,
);
}
PRICING 객체에 모델별 단가를 미리 적어두고, for...of 로 세 모델을 순서대로 돈다. 계산 자체는 3강에서 쓴 공식과 똑같고, 모델마다 단가만 바뀔 뿐이다.
실행해본다.
npx tsx --env-file=.env models.ts
- === claude-haiku-4-5 ===
- 타입스크립트는 자바스크립트에 정적 타입 시스템을 추가한 프로그래밍 언어로, 개발 단계에서 타입 오류를 미리 찾아내 코드의 안정성과 가독성을 높입니다.
- 입력 토큰: 29, 출력 토큰: 106, 비용: 약 $0.000559
- === claude-sonnet-5 ===
- 타입스크립트는 자바스크립트에 정적 타입(static type) 시스템을 추가하여, 코드 작성 시 타입 검사를 통해 오류를 미리 발견하고 더 안전하고 유지보수하기 쉬운 코드를 작성할 수 있도록 도와주는 프로그래밍 언어입니다.
- 입력 토큰: 27, 출력 토큰: 120, 비용: 약 $0.001881
- === claude-opus-4-8 ===
- 타입스크립트는 자바스크립트에 정적 타입 시스템을 추가하여 코드의 안정성과 개발 생산성을 높인 프로그래밍 언어입니다.
- 입력 토큰: 27, 출력 토큰: 67, 비용: 약 $0.001810
세 답변 다 내용은 비슷하다. 그런데 비용은 Haiku 대비 Sonnet 이 약 3.4배, Opus 가 약 3.2배 비싸다. 같은 질문, 비슷한 품질인데 값은 3배 넘게 차이난다.
claude-haiku-4-5
가장 저렴
- 출력 106토큰
- $0.000559
- 간단한 설명·요약·분류에 충분
claude-sonnet-5
균형
- 출력 120토큰
- $0.001881
- 복잡한 추론이 섞인 작업
claude-opus-4-8
가장 똑똑함
- 출력 67토큰(가장 짧지만 비쌈)
- $0.001810
- 정확도가 최우선인 작업
정리하면
대화가 길어지면 매 호출의 입력 토큰이 계속 늘고, 모델을 바꾸면 같은 토큰 수라도 비용이 3배 넘게 차이 난다. 이 두 가지가 실전 비용의 핵심 변수다.
- 01
대화 길이에 따른 입력 토큰 증가를 실제로 쟀다
5턴짜리 대화를 돌려 usage.input_tokens 가 59 → 259 로 늘어나는 걸 확인했다.
npx tsx --env-file=.env index.ts - 02
같은 질문을 세 모델에 던져 비교했다
PRICING 객체와 for 문으로 Haiku · Sonnet · Opus 의 답변·토큰·비용을 나란히 뽑았다.
npx tsx --env-file=.env models.ts - 03
출력 길이와 비용이 비례하지 않는다는 걸 확인했다
모델마다 단가가 다르므로, 토큰 수만으로 비용을 어림짐작하면 안 된다.
그런데 대화가 계속 길어지도록 놔두면 어떻게 될까. 10턴, 50턴짜리 대화가 되면 매번 그 전체를 다시 보내야 하니, 언젠가는 감당 못 할 비용이 된다. 다음 강의에서 그 히스토리를 적당히 자르는 법을 다룬다. Part 2 의 마지막 강의다.