
【Claude Code × OpenTelemetry】Splunk를 통해 에이전트·스킬·모델별로 비용을 확인하는 방법
요약
Claude Code 사용 시 발생하는 에이전트, 스킬, 모델별 상세 비용을 OpenTelemetry와 Splunk를 통해 모니터링하는 방법을 소개합니다. 단순 사용량 확인을 넘어 트레이스 분석과 알람 설정을 통해 효율적인 비용 관리가 가능합니다.
핵심 포인트
- OpenTelemetry를 활용한 Claude Code의 텔레메트리 계측 방법
- Splunk를 통한 에이전트·스킬·모델별 상세 비용 및 토큰 사용량 시각화
- 트레이스(Trace) 분석을 통한 에이전트 간 위임 구조 파악
- Splunk REST API를 이용한 비용 관리 대시보드 및 알람 자동 생성
서론
Claude Code에서 서브 에이전트(Sub-agent)나 스킬(Skill)을 여러 개 실행하다 보면 문득 불안해질 때가 있습니다.
"이거 어떤 에이전트가 뒤에서 비용을 얼마나 쓰고 있는 거지...?"
/usage를 확인해도 최근 24시간 동안의 대략적인 비율만 나올 뿐, "어떤 에이전트가", "어떤 모델로", "어떤 스킬을 사용하는 동안" 얼마의 비용과 몇 토큰을 사용했는지는 전혀 알 수 없습니다.
이러한 흔한 고민을 OpenTelemetry와 Splunk를 사용하여 해결할 수 있었기에, 이 기사에서 소개하고자 합니다.
이 기사에서 하는 일 · 할 수 있게 되는 것
- Claude Code의 에이전트 팀을 OpenTelemetry로 계측(Instrumentation)하여 Splunk Observability Cloud로 전송
- Splunk 측에서 다음 6가지 관점으로 "누가·무엇에·얼마나" 비용이 들었는지 확인
- 에이전트별 비용
- 스킬별 비용
- 모델별 비용
- 이벤트 (API 1건당 실제 금액 명세)
- 트레이스 (Trace, 위임의 중첩 구조)
- 알람 (Alert, 비용 폭주 감지)
- 비용 관리를 위한 대시보드와 알람을 Splunk의 REST API를 통해 코드로 생성
검증 환경
| 항목 | 내용 |
|---|---|
| OS | Windows 11 (WSL 없음 · 네이티브 Claude Code) |
| ... | ? |
| ※ 에이전트와 스킬의 상세 내용은 후술합니다. |
리포지토리는 여기입니다. 검증에 사용한 에이전트나 앱 등 모든 것이 포함되어 있습니다.
셋업 (Claude Code → Collector → Splunk)
전체 구조는 이 3단계입니다.
Claude Code가 OTLP (OpenTelemetry Protocol)로 텔레메트리(Telemetry)를 내보내면, 로컬의 Collector가 이를 받아 스크러빙(Scrubbing)한 뒤 Splunk로 흘려보냅니다.

Claude Code 측 설정
.claude/settings.json에 환경 변수를 작성하기만 하면 됩니다.
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
...
포인트가 두 가지 있습니다.
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1을 설정하면 후술할 트레이스(Trace, waterfall)가 출력됩니다.- 마지막의
OTEL_RESOURCE_ATTRIBUTES를 통해project나run과 같은 자신만의 라벨을 모든 데이터에 붙일 수 있습니다. 이번에는run=zenn을 붙였습니다. 이것이 Splunk 측에서 필터링 및 그룹화의 키가 됩니다.
Collector 측 설정
Splunk가 배포하는 OpenTelemetry Collector를 Docker로 실행합니다.
메트릭(Metrics) / 트레이스(Trace) / 이벤트를 각각 별도의 파이프라인으로 흘려보내는 것이 포인트라고 생각합니다.
receivers:
otlp:
protocols:
...
※ 토큰은 코드에 직접 쓰지 않고, collector/.env에서 ${SPLUNK_ACCESS_TOKEN}으로 읽어오도록 했습니다.
개발 팀 (에이전트 4개)
실제 작은 웹 개발 흐름(요구사항 → 구현 → 리뷰 → 테스트 → 출시)을 그대로 에이전트에게 할당했습니다.
계획 담당인 tech-lead가 메인(main)이며, 무거운 작업만 서브 에이전트에게 던지는 형태입니다. 모델은 역할의 중요도에 따라 변경했습니다.
| 에이전트 | 모델 | 역할 | 이 모델을 선택한 이유 |
|---|---|---|---|
| tech-lead (main) | Opus | 요구사항 정리 · 계획 · 위임 · 통합 | 전체를 보고 판단하는 사령탑. 가장 똑똑한 모델을 배치 |
| ... |
스킬
스킬은 아래의 4가지입니다.
| 스킬 | 종류 | 내용 | 연결 대상 |
|---|---|---|---|
design-system | 지식 | 배색·여백·명명·액세서빌리티(Accessibility) 규약 | frontend-dev / code-reviewer |
test-strategy | 지식 | 테스트 방침·커버리지(Coverage) 개념 | qa-tester |
commit-convention | 지식 | Conventional Commits 규칙 | tech-lead (커밋 시) |
quality-gate | 절차 | 타입 체크 → 빌드 → Lighthouse를 순차적으로 실행하는 출하 게이트 | tech-lead가 /quality-gate로 실행 |
만든 앱
이 팀에게 매일의 습관을 기록하는 「습관 트래커(Habit Tracker)」라는 앱을 만들게 했습니다. 습관을 추가하고, 오늘의 분량을 체크하면 연속 일수가 나오고, localStorage에 저장되는 아주 흔한 앱입니다.
「흔한 개발 태스크를 현실적인 팀 편성으로 돌렸을 때, 비용과 위임 구조가 어떻게 보이는가」를 확인하고 싶었기에 실제 앱을 만들게 했습니다.

실제로 이 팀이 진행한 흐름은 다음과 같습니다.

이 1회 개발의 총비용은 $1.76였습니다. 그럼 그 내역을 살펴보겠습니다.
본론: 6가지 관점으로 「누가·무엇에·얼마를」 확인하기
비용과 토큰은 메트릭(Metrics) claude_code.cost.usage / claude_code.token.usage에 담겨 전달됩니다. 여기에는 속성(Attribute)이 붙어 있어, Splunk의 SignalFlow에서 sum(by=[...])를 하는 것만으로 원하는 축으로 나눌 수 있습니다.
① 에이전트별 비용
가장 먼저 알고 싶은 부분입니다.
속성 query_source (main / subagent / auxiliary)와 model로 나눕니다.
# claude_code.* 는 COUNTER (Delta) 형식이므로 rollup='sum'으로 합산합니다
data('claude_code.cost.usage', filter=filter('run','zenn'), rollup='sum')
.sum(by=['query_source','model']).publish()
결과:
| query_source × 모델 | 실체 | 비용 |
|---|---|---|
| main × Opus | tech-lead (메인 스레드) | $0.92 |
| ... | ||
![]() |
사령탑인 tech-lead (Opus)가 전체의 절반을 차지합니다. 구현을 담당하는 frontend-dev (Sonnet)가 그다음이며, 리뷰와 테스트 (Haiku)가 가장 저렴합니다. 의도한 대로 배분되었으며, 심지어 이를 실제 금액으로 확인할 수 있습니다.
② 스킬별 비용
다음은 스킬입니다. 속성 skill.name으로 나눕니다.
data('claude_code.cost.usage', filter=filter('run','zenn'), rollup='sum')
.sum(by=['skill.name']).publish()
결과:
| skill.name | 종류 | 비용 |
|---|---|---|
| quality-gate | 능동 invoke (출하 게이트) | $0.32 |
| ... | ||
![]() |
이 또한 스킬별 비용을 잘 확인할 수 있게 되어 있습니다. 흔히 있는 일이지만, 스킬은 많아지기 쉽기 때문에 이 기능은 매우 유용합니다.
③ 모델별 비용
속성을 단순하게 model로만 설정하면 모델별 총액이 나옵니다.
결과:
| 모델 | 비용 |
|---|---|
| Opus | $0.92 |
| ... | |
![]() |
①을 「누가」로 나눈 것이라면, 이것은 「무엇으로」 나눈 관점입니다. Opus가 지배적인 이유는 main의 tech-lead가 모든 공정의 판단에 관여하고 있기 때문입니다. 「Opus를 어디까지 사용할 것인가」를 고민할 때, 이 비율이 출발점이 됩니다.
④ 이벤트: API 1개당 명세
지금까지는 합산된 데이터였지만, API 레벨에서도 비용을 확인할 수 있습니다.
OTEL_LOGS_EXPORTER=otlp
를 추가하면 claude_code.api_request 이벤트가 흐르며, 1개 요청(request)마다 cost_usd와 prompt.id를 가집니다. prompt.id는 '하나의 지시가 일으킨 모든 API 호출'을 묶는 ID입니다.
이번에 tech-lead에게 던진 지시는 실질적으로 1개였습니다. 그것이 내부적으로 다음과 같이 전개되었습니다.
prompt.id = ea0eda6f… ( api_request 102개 / 합계 $1.7575 )
Opus query_source=sdk $0.08895 ← 가장 비싼 1개
…(Opus / Sonnet / Haiku 합쳐서 102개)
단 한 번의 "앱 만들어줘"가 내부적으로 102개의 API로 분열되어 합계 $1.76이 되었습니다. 엄청난 숫자네요... 메트릭스(Metrics)에서는 "Opus로 얼마"까지 확인 가능하지만, 이벤트(Event)라면 "어떤 요청(request)이 얼마"인지에 대한 명세가 됩니다.
이벤트 예시:

⑤ 트레이스(Trace): 하나의 지시가 가지치기되는 모습을 보기
①에서는 code-reviewer와 qa-tester를 구분할 수 없었습니다. 둘 다 Haiku를 사용하는 자체 제작 서브 에이전트(sub-agent)라 메트릭스의 속성(attribute)이 동일하기 때문입니다.
여기서 트레이스(Trace)가 필요합니다.
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1을 설정하면, 1개 지시의 가지치기가 하나의 트레이스로 Splunk APM에 나타납니다. interaction을 부모로 하여 llm_request와 tool(Bash 등)이 중첩(nest)되며, tech-lead → 서브 에이전트로의 위임이 그대로 워터폴(waterfall) 형태로 나타납니다.
게다가 llm_request는 agent_id를, tool은 subagent_type을 가지므로, 같은 Haiku라도 별도의 스팬(span)으로 분리할 수 있습니다. 즉, 동일한 모델이라도 서브 에이전트별로 비용을 확인할 수 있습니다.
예시:

⑥ 알람(Alert): 비용 폭주 감시하기
마지막은 예방책입니다. 이것이 가장 실용적일지도 모릅니다.
에이전트가 폭주하거나, 실수로 고가의 모델을 계속 돌려놓았을 때를 대비해 알람을 설정해 보았습니다. detect(when(...))를 사용하여 "최근 30분 동안 run의 비용이 $0.50를 초과하면 Warning"이라고 선언합니다.
A = data('claude_code.cost.usage', filter=filter('run','zenn'), rollup='sum')
.sum(by=['run']).sum(over='30m')
detect(when(A > 0.5)).publish('claude-run-cost-over-50c-30m')
이번 빌드는 여유롭게 $0.50를 초과했기 때문에, 이 알람이 제대로 작동했습니다. 임계값(threshold)은 용도에 따라 다르겠지만, "1개 세션에서 얼마를 넘기면 인지하고 싶은가"를 정해두면 블랙박스가 조용히 불어나는 것을 막을 수 있습니다.
알람 화면:

보너스: 대시보드와 알람을 코드로 만들기
지금까지의 차트와 알람을 매번 GUI에서 일일이 만드는 것은 번거롭습니다. Splunk Observability Cloud는 대시보드와 디텍터(detector)를 REST API로 만들 수 있으므로, 전부 코드로 생성했습니다.
차트는 POST /v2/chart에 SignalFlow를 전달하기만 하면 됩니다.
await api('POST', '/v2/chart', {
name: '[Claude Code] 에이전트별 비용',
programText: "data('claude_code.cost.usage', filter=filter('run','zenn'), rollup='sum')"
...
⑥의 디텍터도 같은 방식으로 POST /v2/detector를 사용합니다. 이렇게 하면 ①~④의 차트를 나열한 대시보드와 비용 폭주를 감시하는 디텍터가 재현 가능한 형태로 코드에 남습니다. --destroy로 제거도 가능합니다. 이른바 observability-as-code 방식입니다. 스크립트는 리포지토리의 scripts/provision-splunk.mjs에 모아두었습니다.
"/usage로 하면 안 돼?"를 실제로 시도해 본
「표준 /usage 명령어를 사용하면 되지 않을까?」라고 생각하실 수도 있습니다. 그래서 직접 실행해 보았습니다.
Skills % of usage Subagents % of usage
/quality-gate 2% commit-convention 2% ← skill 이름이 혼입됨
/commit-convention 1% frontend-dev 1%
나오는 정보는 %뿐이며, 실제 금액이나 토큰 사용량은 나오지 않습니다. 일상적인 감각을 익히기에는 /usage가 빠르지만, "실제 금액으로・자신만의 라벨을 사용하여・트레이스(Trace)와 대조하기"에는 적합하지 않습니다. Splunk가 정말 편리하다는 것을 다시 한번 느끼게 됩니다.
요약
Claude Code의 OpenTelemetry 내보내기(Export)와 Splunk를 결합하면, 멀티 에이전트(Multi-agent) 개발의 "누가・무엇에・얼마를" 사용하는지를 한눈에 파악할 수 있습니다.
- 메트릭(Metrics)을 통해
에이전트별・스킬별・모델별 집계 (①②③) - 이벤트(Event)를 통해
API 1건당 실제 금액과prompt.id단위의 그룹화 (④) - 트레이스(Trace)를 통해
**위임(Delegation)의 중첩(Nest)**과 동일 모델의 서브 에이전트(Sub-agent) 분리 (⑤) - 디텍터(Detector)를 통해
비용 폭주 감지 (⑥). 게다가 전부 REST API로 코드화 가능
OpenTelemetry와 Splunk를 결합하면 정말 편리하다는 것을 느꼈으며, 향후 에이전트(Agent) 시대에 필수적인 요소가 될 것이라는 생각도 듭니다.
조금이나마 도움이 되기를 바랍니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기

