VPS 무인 AI 에이전트 비용 제어 및 과금 방지 가이드
VPS에서 상시 가동되는 AI 에이전트의 토큰 비용을 관리하는 방법을 설명합니다. 루프 반복 제한, 프롬프트 캐싱, 도구 사용량 최적화 및 API 사용량 모니터링을 통해 예상치 못한 과다 청구를 방지하는 실질적인 전략을 확인하십시오.
항상 실행되는 AI 에이전트의 비용 발생을 방지하는 방법
VPS(가상 사설 서버)에서 AI 에이전트의 비용을 제어하는 핵심은 에이전트가 실행되기 전에 상한선을 설정하는 것입니다. 에이전트가 실행되는 동안 비용을 실시간으로 감시하는 사람은 없기 때문입니다. 모든 응답에 max_tokens를 사용하여 제한을 두고, 코드 내에서 루프 반복 횟수를 제한하며, 변경되지 않는 프롬프트 부분은 캐싱하고, 각 응답의 사용량을 기록하여 어떤 작업에서 비용이 발생하는지 확인해야 합니다. 서버 임대료는 매달 고정된 금액이지만, 모델 API는 토큰 단위로 과금되므로 무인 루프는 토큰을 빠르게 소진할 위험이 큽니다.
이 내용은 이미 존재하는 에이전트가 사용자가 소유한 서버에서 Messages API를 호출하는 상황을 가정합니다. VPS에서 Claude를 활용한 AI 에이전트 구축 문서에서 관련 시스템 구축 방법을 다룹니다.
무인 에이전트의 비용 구조가 다른 이유
대화형 세션에는 사람이 개입합니다. 모델이 잘못된 경로로 진입하거나 40,000줄짜리 로그를 읽을 때, 이를 지켜보는 사람이 중단시킵니다. 반면 무인 에이전트에는 이러한 제동 장치가 없습니다. 루프가 끝날 때까지 실행되고, 타이머가 다시 시작을 알리면 즉시 재가동됩니다.
사람들이 간과하는 승수는 빈도입니다. 5분 간격으로 실행되는 작업은 하루에 288번, 한 달에 약 8,640번 실행됩니다. 1회 실행 비용에 이 횟수를 곱해야 합니다. 많은 "상시 가동(always-on)" 에이전트는 실제로 항상 켜져 있을 필요가 없습니다. 특정 시간 내에 응답만 하면 되므로, 이는 스케줄링의 문제입니다.
에이전트는 대화창에서는 발생하지 않는 추가 비용을 지불합니다.
- 도구 정의가 모든 요청에 포함됩니다. 도구 사용 시스템 프롬프트는 Claude Opus 4.8에서
tool_choiceofauto또는none사용 시 290 토큰,any또는tool사용 시 410 토큰을 소모합니다. bash 도구는 325 토큰을 추가합니다. 연결하는 모든 MCP server는 해당 스키마를 무게에 더하며, MCP는 모델 컨텍스트 프로토콜을 의미합니다. - 도구 결과는 입력 토큰입니다. 8,000줄을 출력하는 명령어는 다음 요청에 8,000줄을 포함하며, 해당 턴의 이후 모든 요청에도 포함됩니다.
- 가져온 페이지는 입력 토큰입니다. 평균 10 kB 웹 페이지는 약 2,500 토큰이며, 500 kB 연구용 PDF는 약 125,000 토큰입니다.
max_content_tokens는 "PDF와 같은 이진 콘텐츠가 아닌 텍스트 콘텐츠에 적용"되기 때문에 텍스트 파일만 잘라냅니다. PDF는max_uses및allowed_domains을 사용하여 범위를 제한하십시오. - 웹 검색은 검색당 비용이 청구됩니다. 결과 개수와 관계없이 1,000회 검색당 10달러가 부과됩니다. 오류가 발생한 검색은 청구되지 않습니다.
이 모든 것은 한 번 실행할 때는 비싸지 않습니다. 하지만 8,640번 반복되면 비용이 크게 증가합니다.
하드 제한과 소프트 제한은 서로 다른 문제를 해결합니다
max_tokens는 강제됩니다. 이는 요청, 사고 과정, 응답 텍스트를 모두 합친 전체 출력에 대한 하드 제한입니다. Claude는 이 제한을 넘겨서 생성하지 않으며, 모델은 이 숫자를 직접 볼 수 없습니다. 제한에 도달하면 stop_reason: "max_tokens"이 발생하며 응답이 잘립니다. 에이전트 사용 시 주의할 점은 도구 사용 루프의 각 요청마다 고유한 max_tokens가 적용된다는 것입니다. 즉, 이는 전체 작업이 아닌 단일 응답을 제한합니다. 4,000 토큰으로 10번의 도구 호출을 수행하면 해당 턴의 총 제한은 40,000 토큰이 됩니다.
작업 예산(Task budget)은 권고 사항입니다. task_budget는 output_config 내부에 위치하며, 사고 과정, 도구 호출, 도구 결과, 출력을 포함한 전체 에이전트 루프에서 모델이 사용할 수 있는 토큰 수를 알려줍니다.
resp = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
betas=["task-budgets-2026-03-13"],
output_config={"task_budget": {"type": "tokens", "total": 64000}},
messages=messages,
)"작업 예산은 하드 제한이 아닌 소프트 힌트입니다." Claude는 작업 도중 예산을 초과할 수 있으며, 출력에 대한 강제 제한은 여전히 max_tokens입니다. "카운트다운은 모델에게만 보이며", 응답에는 남은 예산 필드가 포함되지 않습니다. 허용되는 최소 task_budget.total은 20,000 토큰이며, 이보다 작게 설정하면 400 에러가 반환됩니다. 작업량에 비해 예산이 너무 작으면 모델이 거부와 유사한 동작을 보이거나, 작업을 축소하거나 조기에 중단합니다.
비용을 절감하기는커녕 오히려 비용을 발생시키는 세부 사항이 하나 있습니다. 클라이언트가 후속 요청마다 task_budget.remaining를 감소시키면, 변경된 값이 포함된 모든 캐시된 접두사(cached prefix)가 무효화됩니다. 첫 번째 요청 시 한 번만 설정하십시오.
작업 예산은 Claude Fable 5, Claude Opus 4.8, Claude Opus 4.7에서 베타 버전으로 제공됩니다. Claude Sonnet 5와 Claude Haiku 4.5는 Not supported으로 표시되며, 작업 예산은 Claude Code에는 적용되지 않습니다. 따라서 tmux에서 분리된 Claude Code 세션은 세션 위생 관리에 의존해야 합니다.
세 번째 제한은 Claude Console에 존재합니다. 에이전트에게 별도의 작업 공간을 할당한 다음, 해당 공간에 월간 지출 한도와 분당 요청 제한을 설정하십시오. "기본 작업 공간(Default Workspace)에는 제한을 설정할 수 없으며", "작업 공간 제한의 합계가 더 크더라도 조직 전체의 제한이 항상 우선 적용됩니다". 지출 알림을 추가하여 제한 도달 전에 임계값 알림을 받도록 하십시오.
작업별 모델 선택과 실제 변화를 만드는 노력(effort) 설정
모델 선택은 작업 단위로 결정합니다. 2026년 7월 기준, 토큰 100만 개당 입력 및 출력 비용은 다음과 같습니다: Claude Fable 5는 $10와 $50, Claude Opus 4.8 및 Opus 4.7은 $5와 $25, Claude Sonnet 5는 $3와 $15, Claude Haiku 4.5는 $1와 $5입니다. Sonnet 5는 현재 "2026년 8월 31일까지 토큰 100만 개당 입력 $2, 출력 $10의 도입 가격"이 적용 중이므로 정가보다 저렴합니다. 단순히 로그 라인을 분류하는 작업에는 Opus가 필요하지 않습니다. 또한 Claude API는 무료 티어가 없으며 가입 시 제공되는 소액의 크레딧 외에는 무료 허용량이 없으므로, 작업량이 많을 경우 비용이 발생합니다.
두 번째 레버는 노력(effort) 설정입니다. output_config.effort은 low, medium, high, xhigh, max을 허용하며 기본값은 high이므로, high을 명시적으로 설정하는 것은 설정하지 않는 것과 같습니다. 노력 설정을 낮추면 추론 길이보다 더 많은 부분을 절감할 수 있습니다. 문서에 따르면 이 설정은 Claude가 도구 호출을 줄이고 여러 작업을 하나로 통합하게 만듭니다. 에이전트 작업에서는 도구 호출을 한 번 피하는 것만으로도 전체 요청 하나가 발생하지 않으므로 더 큰 비용 절감 효과가 있습니다.
주의할 점은 노력 설정이 캐시와 충돌한다는 것입니다. 요청 간에 이 값을 변경하면 프롬프트 캐싱이 무효화됩니다. 문서화된 예시에서 요청 2는 cache_read_input_tokens: 3546를 보고했고, 노력 설정을 높음에서 중간으로 변경한 요청 3은 3546 중 cache_creation_input_tokens, 0 중 cache_read_input_tokens을 보고했습니다. 따라서 작업 부하별로 노력 설정을 다르게 하되, 캐시된 대화 내부에서는 절대 변경하지 마십시오. 캐시를 깨지 않고 깊이를 조절하려면 프롬프트 내에서 제어하십시오. 최신 사용자 메시지에 "심사숙고하지 말고 직접 답변하라"와 같은 문구를 추가하면 이전의 브레이크포인트는 그대로 유지됩니다.
사고(thinking) 토큰은 출력 요금으로 청구되며 max_tokens에 포함됩니다. 답변이 잘리는 현상은 종종 사고 과정이 예산을 모두 소진했기 때문입니다. 수치는 usage.output_tokens_details.thinking_tokens에서 확인하십시오. Claude 토큰 청구서의 실제 구성 요소에서 계량 방식을 상세히 다룹니다.
안정적인 접두사를 캐싱하고 의도치 않은 무효화를 방지하십시오
캐시 쓰기 비용은 5분 캐시의 경우 기본 입력 가격의 1.25배, 1시간 캐시의 경우 2배입니다. 캐시 읽기 비용은 0.1배이므로 "5분 캐시(1.25배 쓰기)는 단 한 번의 읽기로, 1시간 캐시(2배 쓰기)는 두 번의 읽기로 비용을 회수할 수 있습니다".
상시 가동되는 에이전트에 이 방식이 적합한 이유는 한 문장으로 설명됩니다. "캐시된 콘텐츠를 사용할 때마다 추가 비용 없이 캐시가 갱신됩니다." 5분 캐시를 대상으로 2분마다 실행되는 작업은 단 한 번의 쓰기만으로 하루 종일 접두사를 활성 상태로 유지합니다.
캐시를 인지하지 못한 채 잃게 되는 세 가지 경우입니다.
접두사가 변경되는 경우. "캐시 접두사는 tools, system, messages 순서로 생성됩니다." 이 순서상 앞부분에서 바이트가 조금이라도 변경되면 그 이후의 모든 캐시가 무효화되며, 도구 정의를 수정해도 전체 캐시가 무효화됩니다. 가장 흔한 실수는 시스템 프롬프트에 타임스탬프나 실행 ID를 포함하는 것입니다. 이 경우 모든 요청이 서로 다른 접두사를 가지게 되어 매번 1.25배의 비용으로 새로운 항목을 쓰고, 기존 캐시는 읽지 못하게 됩니다. 겉보기에 동일한 호출임에도 usage.cache_read_input_tokens이 0으로 나타나는 것이 그 징후입니다. 변동성이 있는 텍스트는 가장 최근의 사용자 메시지로 옮기십시오.
접두사가 너무 짧은 경우. 각 모델에는 최소 캐시 가능 길이가 있으며, 이보다 짧으면 캐싱 없이 요청이 처리되지만 "오류는 반환되지 않습니다". Claude Opus 4.8과 Claude Sonnet 5는 1,024 토큰, Claude Haiku 4.5는 4,096 토큰이 기준입니다. 따라서 작업을 Sonnet에서 Haiku로 옮기면 캐싱이 조용히 비활성화될 수 있습니다.
대화가 룩백(lookback) 범위를 벗어나는 경우. "룩백 윈도우는 20개 블록입니다." 시스템은 브레이크포인트마다 최대 20개 위치를 확인한 뒤 중단합니다. 문서화된 예시에서 35개 블록을 가진 턴의 브레이크포인트가 35번 블록에 있다면, 시스템은 35번부터 16번 블록까지만 확인합니다. 이전 턴의 15번 블록 항목은 윈도우 범위를 벗어나므로 적중(hit)이 발생하지 않습니다. 턴마다 여러 개의 도구 사용 및 결과 블록을 추가하는 에이전트는 두세 턴 만에 20개 블록을 넘어서게 됩니다. 요청당 4개의 브레이크포인트를 사용할 수 있으므로, 하나는 최근 메시지를 위해 할당하십시오.
지연 가능한 작업은 Batches API로 전송하십시오
모든 사용량은 입력과 출력 모두 표준 API 가격의 50%로 청구됩니다. 배치 처리는 비동기 방식으로 진행되며, "대부분의 배치는 1시간 이내에 완료"됩니다. 결과는 모든 요청이 완료된 시점 또는 24시간이 지난 시점 중 먼저 도래하는 때에 제공됩니다. 이는 일반적인 경우이며 보장되는 시간은 아닙니다.
processing_status 상태가 ended로 읽힐 때까지 폴링하십시오. errored, canceled 또는 expired를 반환하는 요청은 과금되지 않습니다. 지출 한도(spend cap)를 설정하여 사용하는 경우 한 가지 주의할 점은 "배치 작업이 워크스페이스에 설정된 지출 한도를 약간 초과할 수 있다"는 것입니다.
할인은 중복 적용되며, 배치 작업은 5분 이상 소요될 수 있으므로 문서에서는 컨텍스트를 공유하는 배치 작업에 대해 1시간 캐시 사용을 권장합니다. 따라서 작업을 분리하십시오. 사람이나 웹훅이 대기해야 하는 작업은 실시간 경로에서 처리하고, 야간 요약이나 어제의 로그 분류와 같은 작업은 절반 가격인 배치 작업으로 처리하십시오.
모든 응답의 사용량 필드를 자체 저장소에 기록하기
기록하지 않은 비용은 추적할 수 없습니다. 모든 응답은 해당 요청의 비용을 알려줍니다.
u = resp.usage
row = {
"job": job_name,
"model": resp.model,
"uncached_input": u.input_tokens,
"cache_write": u.cache_creation_input_tokens,
"cache_read": u.cache_read_input_tokens,
"output": u.output_tokens,
"stop_reason": resp.stop_reason,
}API 호출당 한 행씩 JSON-lines 파일에 추가하고 작업 이름을 태그로 지정하십시오. 일주일 뒤에는 어떤 작업이 비용을 발생시키고 어떤 작업이 단순히 바쁜 척만 했는지 확인할 수 있습니다. cache_read을 주의 깊게 살펴보십시오. 0으로 채워진 열은 자체 호스팅 에이전트에서 가장 흔하게 발생하는 비용 측정 오류입니다.
한 가지 필드는 오해하기 쉽습니다. input_tokens는 마지막 캐시 중단점 이후의 토큰만 계산하므로, 실제 프롬프트 크기는 total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens입니다. 대규모 프롬프트에서 input_tokens: 400을 보고하는 에이전트가 저렴한 것은 아닙니다. 나머지는 캐시에서 가져왔기 때문입니다.
전송하기 전에 계산하십시오. 토큰 계산은 무료이며 속도 제한이 메시지 생성과 별도로 적용되므로, 비용을 지불하고 확인하는 대신 count_tokens을 사용하여 너무 큰 첨부 파일을 거부하십시오. 결과는 추정치이므로 모델별로 다시 측정해야 하며, 다른 공급업체의 토크나이저에서 얻은 계산 결과를 재사용하지 마십시오. Claude Opus 4.7 및 이후 Opus 모델, Claude Fable 5, Claude Sonnet 5는 "동일한 텍스트에 대해 약 30% 더 많은 토큰을 생성하는" 최신 토크나이저를 사용합니다. Claude Sonnet 4.6 및 이전 버전, Claude Haiku 4.5 등은 이전 토크나이저를 사용합니다.
공식적인 확인을 위해 Admin API는 https://api.anthropic.com/v1/organizations/usage_report/messages에서 사용량을, https://api.anthropic.com/v1/organizations/cost_report에서 비용을 보고합니다. 두 API 모두 관리자 키(sk-ant-admin01-...)를 x-api-key: $ANTHROPIC_ADMIN_KEY로 사용하며 anthropic-version: 2023-06-01와 함께 전달해야 합니다. 또한 bucket_width=1d, group_by[]=model, api_key_ids[]=를 매개변수로 허용합니다. 한 가지 제한 사항은 "Admin API는 개인 계정에서 사용할 수 없다"는 점입니다.
마지막 매개변수는 저렴한 비용 귀속 트릭입니다. 각 작업에 고유한 API 키를 부여하고 api_key_ids[]으로 필터링한 뒤, group_by[]=api_key_id을 사용하여 키별로 보고서를 분할하십시오. 필터는 복수형이지만 그룹화 차원은 단수형입니다. VPS에서 첫 Claude API 앱 실행하기에서 다루는 방식처럼, 키는 코드에 포함하지 말고 환경 변수에 보관하십시오.
루프 제한 설정, 필수적인 안전장치
여기서는 반복 횟수 제한이 선택 사항이 아닙니다. 루프를 직접 제어하므로 카운터 역시 직접 관리해야 합니다.
for step in range(MAX_STEPS): # MAX_STEPS = 12, never "while True"
resp = client.messages.create(...)
if resp.stop_reason != "tool_use":
break
else:
log.warning("job %s hit MAX_STEPS=%d, giving up", job_name, MAX_STEPS)위의 어떤 상한 설정도 이를 대신해주지 않습니다. max_tokens은 응답 하나를 제한할 뿐이며, 모델에게는 작업 예산에 대한 권고만 전달됩니다. 호스팅된 제품이라면 단일 턴 내 도구 호출에 대한 Claude의 제한처럼 너무 많은 호출이 발생한 세션을 중단시키겠지만, 직접 작성한 루프에는 안전장치를 추가하기 전까지는 아무런 제동 장치가 없습니다.
프로세스 외부에 두 번째 제동 장치를 설치하십시오. 상시 실행되는 프로세스 대신 systemd 타이머를 사용하여 작업을 실행하고, 서비스 유닛에 RuntimeMaxSec=를 설정하십시오. RuntimeMaxSec=600을 사용하면 작업이 멈췄을 때 10분 뒤에 강제로 종료되므로, 사용자가 알아차릴 때까지 무한정 도는 일을 방지할 수 있습니다. systemd 서비스 및 타이머로 프로그램 실행하기에서 유닛 파일 작성법을 다룹니다. 작업 결과는 journalctl -u triage-agent.service --since "1 hour ago"로 확인하십시오.
재시도 횟수도 제한해야 합니다. 무한히 재시도하는 핸들러는 모든 시도에 대해 비용을 발생시키기 때문입니다. 429나 500 오류는 백오프(backoff)를 적용하여 몇 번 재시도할 가치가 있습니다. 하지만 400 오류는 동일한 요청이 동일한 방식으로 실패하므로 재시도할 필요가 없습니다.
AI 에이전트 비용 제어는 자신의 사용량 수치를 확인하는 것에서 시작합니다
상시 가동되는 에이전트의 비용을 단정할 수 있는 사람은 없습니다. 비용은 '실행당 토큰 수'에 '하루 실행 횟수'를 곱한 값이며, 이 두 요소 모두 사용자의 환경에 따라 결정되기 때문입니다. 에이전트를 한 번 실행한 뒤 기록된 사용량 행을 읽고, 이를 자신의 일정에 맞춰 곱해 보십시오. 이틀 뒤 비용 보고서를 확인하여 계산 결과와 대조합니다. 두 수치가 일치하지 않는다면, 거의 대부분 캐시가 깨졌거나 예상보다 루프가 길게 실행된 경우입니다.
이 내용은 에이전트가 Messages API를 호출하는 사용자 본인의 프로그램이라는 가정하에 작성되었습니다. 대화형 작업의 경우, 어떤 Claude 플랜이 본인의 작업 방식에 적합한지를 확인하여 구독 모델을 검토하십시오. 여기에 기재된 모든 가격과 제한 사항은 2026년 7월 기준 Anthropic의 문서를 바탕으로 검증되었습니다. 예산을 수립하기 전에 반드시 공식 가격 페이지를 다시 확인하십시오.
FAQ
VPS에서 상시 가동되는 AI 에이전트를 운영하는 데 비용이 얼마나 드나요?
두 가지 비용이 발생하며, 그중 하나만 예측 가능합니다. 서버 비용은 매달 고정되어 있습니다. 모델 API 비용은 토큰 단위로 과금되므로, 1회 실행 시 소모되는 비용에 실행 빈도를 곱하여 계산합니다. Anthropic은 자체 호스팅되는 상시 가동 에이전트에 대한 비용 수치를 제공하지 않으므로, 제시되는 모든 숫자는 추정치로 간주해야 합니다. 실제 1회 실행 시 발생하는 로그 usage를 확인한 뒤, 본인의 실행 일정에 맞춰 곱하십시오.
max_tokens와 작업 예산(task budget)의 차이점은 무엇인가요?
max_tokens은 강제 적용되며 모델은 이를 알 수 없습니다. 이는 사고 과정을 포함한 단일 요청의 출력량을 제한하며, 이 제한에 도달하면 stop_reason: "max_tokens"가 발생합니다. 반면 작업 예산은 정반대입니다. 모델에게 해당 수치를 알려주어 에이전트 루프의 속도를 조절하게 하지만, "작업 예산은 부드러운 권고일 뿐 엄격한 제한이 아니며" 실제 강제 제한은 여전히 max_tokens입니다.
에이전트의 cache_read_input_tokens가 항상 0인 이유는 무엇인가요?
호출할 때마다 접두사(prefix)가 변경되거나, 캐시하기에는 너무 짧기 때문입니다. 흔한 원인은 시스템 프롬프트에 삽입된 타임스탬프나 실행 ID입니다. 캐시는 접두사를 기준으로 키가 생성되므로, 바이트 하나만 바뀌어도 그 이후의 모든 캐시가 무효화됩니다. 도구 정의나 effort 값을 변경해도 동일한 결과가 나타납니다. 그 외에는 크기 문제일 수 있는데, 프롬프트가 너무 짧으면 캐시되지 않으며 별도의 오류도 반환되지 않습니다.
AI 에이전트가 무한 루프에 빠지지 않게 하려면 어떻게 해야 하나요?
루프 코드 내에서 반복 횟수를 세어 고정된 최댓값에서 멈추게 하십시오. max_tokens은 단일 응답만 제한하며 에이전트는 여러 번 응답을 생성하기 때문입니다. 프로세스 외부에서 벽시계 시간(wall-clock) 제한을 추가하십시오. systemd 타이머에서 RuntimeMaxSec=을 설정하여 실행이 멈추더라도 예정된 시간에 종료되도록 하십시오. 재시도 루프 또한 비용이 발생하므로 재시도 횟수도 제한해야 합니다.
단일 Claude API 키에 지출 한도를 설정할 수 있나요?
문서화된 지출 한도는 키 단위가 아닌 워크스페이스 단위로 적용됩니다. 따라서 에이전트 전용 워크스페이스를 생성하고 해당 워크스페이스의 월간 지출 한도를 설정하십시오. "기본 워크스페이스(Default Workspace)에는 한도를 설정할 수 없습니다." 지출 알림을 추가하여 특정 임계값에 도달하면 먼저 알림을 받도록 하십시오. 비용 추적을 위해서는 각 작업마다 별도의 키를 발급하고, group_by[]=api_key_id를 사용하여 사용량 보고서를 그룹화하십시오.