Claude Code를 여러 에이전트, 여러 모델로 돌릴 때 가장 먼저 부딪히는 문제는 비용입니다. "이번 주에 얼마 썼지?"는 간단한 질문이지만, 에이전트 A는 Pro를 쓰고 B는 Sonnet을 쓰면, 총합만 보고서는 어디에서 예산이 새는지 알 수 없습니다. sqgroup-official은 10월 31일 cc-token-ledger를 공개했습니다. Claude Code 대화에서 날짜·에이전트·모델별로 토큰 사용량을 집계하는 테이블을 만드는 도구입니다. 이 글은 원문과 저장소 문서를 읽은 뒤, 집계 테이블을 Node.js로 작은 예제로 재현한 기록입니다. cc-token-ledger 자체를 빌드하거나 실행하지는 않았습니다.
"날짜·에이전트·모델" 세 축이 의미하는 것
원문은 cc-token-ledger를 "token usage table by date/agent/model from Claude Code conversations"라고 소개합니다. 단일 총합이 아니라, 세 가지 축으로 나누어 집계합니다.

이미지: sqgroup-official/cc-token-ledger 공식 저장소 스크린샷.
이 설계가 의미하는 것은 두 가지입니다. 첫째, 예산 분배가 명확해집니다. 에이전트 A의 Pro 모델 사용량과 B의 Sonnet 사용량을 나누면, 어디에서 예산이 새는지 알 수 있습니다. 둘째, 모델 교체 효과를 측정할 수 있습니다. "Pro에서 Sonnet으로 바꾸면 얼마나 절약되는가"를 날짜별로 비교할 수 있습니다.
토큰 집계 테이블의 세 단계
cc-token-ledger가 수행하는 작업은 세 단계로 나눌 수 있습니다.
첫째, 대화 로그 수집입니다. Claude Code가 생성하는 대화 로그에서 토큰 사용량을 추출합니다. 이 단계는 로그 파일이나 API 응답을 파싱하여 완료할 수 있습니다.
둘째, 축 분류입니다. 추출한 토큰을 날짜·에이전트·모델의 세 가지 축으로 분류합니다. 같은 날짜라도 에이전트가 다르면 다른 행에 기록됩니다.
셋째, 테이블 렌더링입니다. 분류된 데이터를 테이블로 렌더링합니다. 총합, 평균, 추세를 함께 표시하면 분석이 쉬워집니다.
Node.js로 재현한 작은 예제
CodeBridge는 Node.js로 cc-token-ledger의 핵심 흐름을 작은 예제로 구현했습니다. 실제 cc-token-ledger의 구현을 재현한 것이 아니라, 로그 수집 → 분류 → 테이블 렌더링이라는 흐름만 보여줍니다.
import fs from "node:fs";
import path from "node:path";
class TokenLedger {
constructor() {
this.entries = [];
}
addEntry(date, agent, model, promptTokens, completionTokens) {
this.entries.push({
date, agent, model,
promptTokens, completionTokens,
totalTokens: promptTokens + completionTokens
});
}
buildTable() {
const byDate = new Map();
const byAgent = new Map();
const byModel = new Map();
for (const entry of this.entries) {
// By date
if (!byDate.has(entry.date)) byDate.set(entry.date, 0);
byDate.set(entry.date, byDate.get(entry.date) + entry.totalTokens);
// By agent
if (!byAgent.has(entry.agent)) byAgent.set(entry.agent, 0);
byAgent.set(entry.agent, byAgent.get(entry.agent) + entry.totalTokens);
// By model
if (!byModel.has(entry.model)) byModel.set(entry.model, 0);
byModel.set(entry.model, byModel.get(entry.model) + entry.totalTokens);
}
return {
byDate: Object.fromEntries(byDate),
byAgent: Object.fromEntries(byAgent),
byModel: Object.fromEntries(byModel)
};
}
renderMarkdown() {
const table = this.buildTable();
let md = "| Category | Total Tokens |\n| --- | --- |\n";
for (const [date, tokens] of Object.entries(table.byDate)) {
md += `| ${date} | ${tokens.toLocaleString()} |\n`;
}
md += "\n| Agent | Total Tokens |\n| --- | --- |\n";
for (const [agent, tokens] of Object.entries(table.byAgent)) {
md += `| ${agent} | ${tokens.toLocaleString()} |\n`;
}
md += "\n| Model | Total Tokens |\n| --- | --- |\n";
for (const [model, tokens] of Object.entries(table.byModel)) {
md += `| ${model} | ${tokens.toLocaleString()} |\n`;
}
return md;
}
}
export { TokenLedger };
이 예제는 cc-token-ledger의 구현을 그대로 옮긴 것이 아닙니다. 로그 수집 → 분류 → 테이블 렌더링이라는 흐름만 보여줍니다. 실제 cc-token-ledger는 Claude Code의 로그 형식에 맞춰 파싱 로직이 더 복잡할 수 있습니다.
cc-token-ledger를 고를 때 확인할 질문
cc-token-ledger의 문서를 읽고 바로 적용할 수 있는 점검 항목을 정리하면 다음과 같습니다.
| 질문 | 확인할 증거 | 흔한 오해 |
|---|---|---|
| 로그 형식은 Claude Code 버전에 따라 달라지는가 | 버전별 테스트 결과 | 모든 Claude Code 버전에서 동일한 로그 형식을 사용한다 |
도입 전에 남는 제약
cc-token-ledger에는 Claude Code의 로그 형식이 기본으로 들어 있지 않습니다. 로그 형식이 버전마다 달라질 수 있으므로, 파싱 로직을 확인해야 합니다. 원문은 날짜·에이전트·모델별로 나누어 집계할 수 있다는 장점을 강조하지만, 로그 형식이 변경되면 테이블이 깨질 수 있습니다.
비용 계산의 정확도, 과거 데이터 재집계 가능성, 다중 계정 지원 여부는 이 글에서 측정하지 않았습니다. 특히 "토큰 수 × 단가"가 항상 정확한 비용으로 이어지는 것은 아니며, 할인가나 볼륨 디스카운트가 적용되면 테이블과 실제 청구서가 다를 수 있습니다.
cc-token-ledger에서 배울 점은 로그 파싱 방법이나 테이블 렌더링 방식이 아닙니다. 토큰 사용량을 단일 총합에서 세 축으로 나누어 보는 구조입니다. 다음에 Claude Code 비용을 분석할 때는 총액보다 "어디에서, 어떤 모델로, 얼마나 썼는지"를 테이블로 만들어 보시길 권합니다.
아래 유료 강의는 Claude Code를 포함한 AI 코딩 하네스의 검증과 제약 설계를 다룹니다. cc-token-ledger 자체의 사용법이나 이 실험의 재현을 제공하는 강의는 아니며, 링크는 홍보 링크입니다.