도구 사용이 많은 워크플로우의 비용 절감하기
도구를 사용하는 에이전트는 모든 요청마다 모든 것을 다시 전송합니다. 프로그래매틱 도구 호출과 프롬프트 캐싱은 각각 비용의 서로 다른 부분을 절감합니다.
이 영상의 데모는 2026년 9월에 녹화되었습니다. Claude Sonnet 5(claude-sonnet-5)에서 실행되었으며, 최신 모델에서는 결과가 다를 수 있습니다.
도구를 사용하는 에이전트는 모든 요청마다 모든 것을 다시 전송하므로, 비용은 도구 호출이 늘어날 때마다 함께 증가합니다. 각 요청은 도구 정의, 시스템 프롬프트, 질문, 그리고 지금까지의 모든 도구 결과를 함께 담고 있습니다. 이것들이 바로 입력 토큰이며, 각각에 대해 비용이 청구됩니다.
프로그래매틱 도구 호출과 프롬프트 캐싱은 모두 이 비용을 줄여줍니다.
Meridian은 엔지니어 40명으로 구성된 가상의 엔지니어링 컨설팅 회사입니다. 이 회사의 에이전트는 다음과 같은 질문 하나를 받았습니다: 2026년 6월에 가동률이 70% 미만이었던 엔지니어는 누구인가? 이 에이전트에는 두 가지 도구가 있었습니다. list_employees는 직원 명단을 반환하고, get_employee_hours는 한 엔지니어의 근무 시간표를 반환합니다.
이 질문에 답하는 데 에이전트는 42번의 요청과 1,124,799개의 입력 토큰을 사용했습니다. 전체 실행 비용은 토큰 기준으로 $2.29였습니다.
각 요청의 입력 토큰 측정하기
응답이 돌아올 때마다 usage.input_tokens를 출력하세요. 이 수치가 비용이 어디에서 발생하는지 보여주기 때문입니다.
resp = client.messages.create(...)
print(resp.usage.input_tokens, "input tokens")Meridian의 에이전트는 각 응답이 하나의 도구 호출을 요청하는 전형적인 루프로 동작합니다. 이 중 두 건의 수치를 살펴보겠습니다.
| 요청 | 담고 있는 내용 | 입력 토큰 |
|---|---|---|
| 요청 1 | 도구 정의, 시스템 프롬프트, 질문 | 606 |
| 요청 37 | 동일한 내용에 이전 36건의 도구 결과 추가 | 47,905 |
요청 1은 모든 요청이 기본적으로 전송하는 내용만 담고 있습니다. 이후의 요청들은 도구 호출과 그 결과를 추가로 더해갑니다. 두 수치를 비교하면 어느 부분이 늘어났는지 알 수 있습니다.
Claude가 읽는 내용에서 도구 결과 제외하기
프로그래매틱 도구 호출(새 탭에서 열림)을 사용하면 Claude는 도구를 호출하는 스크립트를 작성하고, 코드 실행 도구가 이를 컨테이너 안에서 실행합니다. 스크립트가 출력한 내용만 Claude에 전달됩니다. Meridian의 근무 시간표 40건은 스크립트 쪽에 남아 있고, Claude는 짧은 출력 결과만 받습니다.
먼저 사용 중인 도구와 모델을 확인하세요. 2026년 10월 기준으로, 프로그래매틱 도구 호출은 strict: true로 표시된 도구를 지원하지 않습니다(새 탭에서 열림). 또한 Claude가 한 응답에서 하나의 도구만 호출하도록 제한하는 tool_choice 설정인 disable_parallel_tool_use도 지원하지 않습니다. tool_choice로는 Claude가 스크립트 안의 도구를 호출하도록 강제할 수 없습니다.
Claude Haiku 4.5는 이 기능을 지원하지 않습니다. 이 기능은 Claude API, AWS의 Claude Platform, 그리고 Anthropic에서 호스팅되는 Microsoft Foundry 배포에서 실행됩니다.
프로그래매틱 도구 호출을 켜려면 네 가지를 변경해야 합니다.
tools목록에 코드 실행 도구를 추가하세요.- 스크립트가 호출할 수 있는 도구를 표시하세요. 각 도구에 버전
code_execution_20260120이상(새 탭에서 열림)의 코드 실행 도구를 지정하는allowed_callers필드를 추가하세요. - 컨테이너의 ID를 다시 전송하세요. 도구 호출을 위해 멈춘 각 응답에서 이를 읽어온 다음, 도구 결과를 반환하는 요청과 함께 전송하세요.
- 각 도구의 결과를 설명하세요. 설명에는 결과가 어떤 형태인지 명시해야 합니다. 스크립트가 그것을 파싱해야 하기 때문입니다. 다음은 Meridian의
get_employee_hours에 대한 설명입니다.
Returns one engineer's hours for the month as JSON: {"name": str, "billable_hours": float, "utilization": float 0-1}
다음은 이러한 변경을 적용한 후 Meridian의 루프입니다.
CODE_EXECUTION = "code_execution_20260120"
TOOLS = [
{"type": CODE_EXECUTION, "name": "code_execution"},
{**LIST_EMPLOYEES, "allowed_callers": [CODE_EXECUTION]},
{**GET_EMPLOYEE_HOURS, "allowed_callers": [CODE_EXECUTION]},
]
messages = [{"role": "user", "content": QUESTION}]
container = None
while True:
resp = client.messages.create(
model="claude-sonnet-5", max_tokens=4096,
tools=TOOLS, messages=messages, container=container,
)
print(resp.usage.input_tokens, "input tokens")
if resp.stop_reason not in ("tool_use", "pause_turn"):
break
container = resp.container.id
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason == "tool_use":
messages.append({"role": "user", "content": run_tools(resp)})
print("".join(b.text for b in resp.content if b.type == "text"))LIST_EMPLOYEES와GET_EMPLOYEE_HOURS는 Meridian의 도구 정의입니다.- 여러분이 직접 작성한
run_tools가 각 도구 호출을 실행하고 결과를 반환합니다. pause_turn이 발생하면 루프는 응답을 다시 전송하고 계속 진행합니다.
스크립트가 도구를 호출하면, 응답의 stop_reason은 "tool_use"가 됩니다. 여러분의 코드가 도구를 실행하고, 그 결과는 Claude가 아니라 스크립트로 전달됩니다. 스크립트는 도구를 병렬로 실행할 수 있으므로, 하나의 응답이 하나 이상의 도구 호출을 담을 수 있습니다.
다음은 동일한 질문을 두 가지 방식으로 답변한 결과입니다.
| 실행 방식 | 요청 수 | 도구 호출 수 | 입력 토큰 | 토큰 비용 |
|---|---|---|---|---|
| 전형적인 루프 | 42 | 41 | 1,124,799 | $2.29 |
| 프로그래매틱 도구 호출 | 3 | 41 | 28,486 | $0.0667 |
두 실행 모두 동일한 질문, 동일한 도구, claude-sonnet-5를 사용했습니다. 비용은 2026년 9월 기준 가격(새 탭에서 열림)을 사용했으며, 코드 실행 시간은 토큰과 별도로 청구됩니다.
프로그래매틱 도구 호출은 서로 의존하지 않는 조회 작업에 적합합니다. Claude가 다음 도구 호출을 하기 전에 각 결과를 추론해야 하는 경우에는 도움이 크지 않습니다.
반복되는 도구 정의 캐싱하기
프롬프트 캐싱을 사용하면 API는 여러분이 표시한 캐시 지점까지, 즉 요청의 앞부분을 저장합니다. 그 앞부분을 다시 읽을 때의 비용은 훨씬 저렴합니다.
두 번째 Meridian 에이전트에는 도구가 14개 있으며, 그 정의는 매 요청마다 다시 전송되는 3,305개의 토큰에 해당합니다.
마지막 도구에 cache_control을 붙이면 캐시 지점이 표시되고, 목록 전체가 캐시됩니다. 이는 한 줄이면 됩니다.
TOOLS[-1]["cache_control"] = {"type": "ephemeral"}Claude Sonnet 5에서는 앞부분을 읽는 비용이 일반 입력 가격의 10분의 1(새 탭에서 열림)입니다. 이를 쓰는 비용은 일반 입력 가격의 1.25배입니다.
캐시된 앞부분은 기본적으로 5분 동안 유지되며, 사용할 때마다 갱신됩니다. 요청 간격이 더 먼 경우에는 cache_control에 "ttl": "1h"를 추가하여 1시간 동안 유지할 수 있습니다. 1시간짜리 캐시를 쓰는 비용은 일반 입력 가격의 2배(새 탭에서 열림)입니다.
Meridian은 동일한 8개의 질문을 캐시를 사용한 경우와 사용하지 않은 경우로 각각 실행했습니다. 전체 입력 비용은 $0.0554에서 $0.0154로 줄었습니다.
자동 캐싱(새 탭에서 열림)을 사용하면, 요청의 최상위 수준에 cache_control 필드 하나만 넣으면 API가 캐시 지점을 대신 지정해 줍니다.
캐싱을 켠 후에는 다음 세 가지를 주의해야 합니다.
- 도구 정의를 하나라도 변경하면 캐시 전체가 무효화됩니다.
- Sonnet 5에서는 캐시된 앞부분이 최소 1,024 토큰 이상이어야 합니다. 그보다 짧으면 아무것도 캐시되지 않으며, 이에 대한 오류도 표시되지 않습니다.
- 캐싱이 켜져 있으면
input_tokens에는 캐시된 앞부분이 포함되지 않으므로, 요청의 실제 총합은input_tokens,cache_read_input_tokens,cache_creation_input_tokens를 모두 더한 값입니다.
적합한 곳에 두 기능을 함께 사용하기
다음 순서로 적용하세요.
- 캐싱부터 시작하세요. 한 줄이면 됩니다.
- 프로그래매틱 도구 호출을 테스트하세요. 평소 트래픽의 일부를
allowed_callers를 사용한 경우와 사용하지 않은 경우로 각각 실행한 다음, 각 실행의 청구된 입력 토큰을 비교하세요.
아래의 두 가지 Meridian 요청에 대해, 입력 토큰 대부분을 차지하는 부분을 찾은 다음 이를 줄여줄 기능을 선택해 보세요.
핵심 요약
- 모든 요청은 모든 것을 다시 전송하므로, 이전 도구 결과에 대해 반복해서 비용을 지불하게 됩니다.
- 응답이 돌아올 때마다
usage.input_tokens를 출력하여, 요청의 어느 부분이 가장 많은 비용을 차지하는지 파악하세요. - 캐싱부터 시작하세요. 도구 목록의 마지막 도구에
cache_control을 추가하세요. - 도구 호출이 서로 의존하지 않는 경우, 코드 실행 도구와
allowed_callers를 사용하여 프로그래매틱 도구 호출을 설정하세요. 이후의 모든 요청에 컨테이너의 ID를 함께 전송하세요.