Token Stats: 비용 관점의 통계 기준 및 차트 해석
이미 클라이언트를 Antigravity Tools에 연결했지만, "누가 돈을 쓰고 있는지, 어디서 비싼지, 특정 모델이 갑자기 급증했는지"는 직관으로 판단하기 어렵습니다. 이 수업에서는 Token Stats 페이지의 데이터 기준을 명확히 설명하고, 차트로 빠르게 비용 문제를 찾는 방법을 가르칩니다.
수업을 마치면 할 수 있는 것
- Token Stats 데이터가 어디서 오는지 설명할 수 있습니다(언제 기록되는지, 어떤 경우 누락되는지)
- 시간/일/주로 관찰 창을 전환하여 "하루만 보는" 오류 판단을 피합니다
- "모델별/계정별" 두 가지 뷰에서 추세 차트로 이상치 피크를 찾습니다
- Top 리스트로 가장 비싼 모델/계정을 찾고, 요청 로그로 돌아가 근본 원인을 찾습니다
현재 겪고 있는 문제
- 호출이 비싸졌다고 느끼지만, 모델이 바뀌었는지, 계정이 바뀌었는지, 특정 날 사용량이 급증한 것인지 모릅니다
X-Mapped-Model을 보았지만, 통계가 어떤 모델 기준으로 계산되는지 확실하지 않습니다- Token Stats에서 간혹 0이거나 "데이터 없음"으로 나오는데, 트래픽이 없는 것인지 통계가 안 된 것인지 모릅니다
언제 이 기능을 사용해야 하나요
- 비용 최적화를 할 때: "가장 비싼 것"을 먼저 정량화
- 급격한 제한/이상을 문제 해결할 때: 피크 시간대로 요청 로그를 대조
- 모델 라우팅/할당량 관리 구성 변경 후 비용이 예상대로 감소하는지 검증할 때
Token Stats란 무엇인가?
Token Stats는 Antigravity Tools의 로컬 사용량 통계 페이지입니다: 프록시가 요청을 전달한 후, 응답 JSON 또는 스트림 데이터에서 usage/usageMetadata의 토큰 수를 추출하려 시도하고, 각 요청을 계정 및 모델별로 로컬 SQLite(token_stats.db)에 기록한 다음, UI에서 시간/모델/계정별로 집계하여 표시합니다.
먼저 한 가지 쉽게 빠지는 포인트를 설명합니다
Token Stats의 "모델" 기준은 요청의 model 필드에서 옵니다(또는 Gemini의 /v1beta/models/<model> 경로 파싱), 라우팅 후의 X-Mapped-Model과 같지 않습니다.
🎒 시작 전 준비
- 이미 프록시 호출을 한 번 실행했습니다(
/healthz헬스 체크에만 머물지 않음) - 업스트림 응답이 파싱 가능한 토큰 사용량 필드를 반환합니다(그렇지 않으면 통계가 누락됨)
함께 읽을 것 권장
모델 매핑으로 model을 다른 물리적 모델로 라우팅하고 있다면, 먼저 **모델 라우팅: 사용자 정의 매핑, 와일드카드 우선순위 및 프리셋 전략**을 보고, 다시 돌아와서 "통계 기준"을 보면 더 직관적입니다.
핵심 아이디어
Token Stats 데이터 체인을 세 단계로 나눌 수 있습니다:
- 프록시 미들웨어가 응답에서 토큰 사용량 추출(
usage/usageMetadata호환, 스트림도 파싱) - 동시에
account_email + input_tokens + output_tokens를 얻으면, 로컬 SQLite(token_stats.db)에 기록 - UI는 Tauri
invoke(get_token_stats_*)로 집계 데이터를 가져와서 시간/일/주로 표시
따라해보기
1단계: 먼저 "트래픽"이 있는지 확인
이유 Token Stats 통계는 실제 요청에서 옵니다. 프록시만 시작하고 모델 요청을 한 번도 보내지 않으면, 페이지가 "데이터 없음"을 표시합니다.
방법: **로컬 리버스 프록시 시작 및 첫 번째 클라이언트 연결**에서 이미 검증된 호출 방법을 재사용하여 1-2회 요청을 보냅니다.
볼 수 있는 것: Token Stats 페이지가 "로딩 중/데이터 없음"에서 차트나 리스트로 바뀝니다.
2단계: 올바른 시간 창 선택(시간/일/주)
이유 동일한 데이터라도 다른 창에서 보면 "피크/추세"가 완전히 다릅니다. UI의 세 가지 창에 대한 데이터 범위도 다릅니다:
- 시간: 최근 24시간
- 일: 최근 7일
- 주: 최근 4주(추세 뷰는 최근 30일로 집계)
볼 수 있는 것: 전환 후 추세 차트의 가로축이 바뀝니다(시간은 "시간" 표시, 일은 "월/일", 주는 "년-W주차").
3단계: 먼저 상단 총괄 보고 "비용 규모" 결정
이유 총괄 카드가 먼저 세 가지 질문에 답할 수 있습니다: 총량이 큰지, 입력/출력 비율이 이상한지, 참여한 계정/모델이 갑자기 늘어났는지.
다음 항목을 중점적으로 보세요:
- 총 토큰(
total_tokens) - 입력/출력 토큰(
total_input_tokens/total_output_tokens) - 활성 계정 수(
unique_accounts) - 사용 모델 수(UI는 "모델별 통계 리스트"의 길이를 직접 사용)
볼 수 있는 것: "활성 계정 수"가 급증하면 일반적으로 짧은 시간 내에 더 많은 계정을 실행했다는 의미입니다(예: 로테이션 전략으로 전환).
4단계: "모델별/계정별 사용 추세"로 이상치 피크 잡기
이유 추세 차트는 "갑자기 비싸지는 것"을 잡기에 가장 적합한 입구입니다. 원인을 먼저 알 필요 없이 "어느 날/어느 시간에 급증했는지" 먼저 표시하세요.
방법:
- 추세 차트 오른쪽 상단에서 "모델별 / 계정별" 전환
- 마우스를 올려서(Tooltip) Top 값을 보고, "갑자기 첫 번째로 올라간 것"을 우선적으로 주목
볼 수 있는 것:
- 모델별: 특정 모델이 특정 시간대에 급증
- 계정별: 특정 계정이 특정 시간대에 급증
5단계: Top 리스트로 "가장 비싼 대상"을 고정
이유 추세 차트는 "언제 이상한지" 알려주고, Top 리스트는 "가장 비싼 것이 누구인지" 알려줍니다. 이 두 가지를 교차하면 빠르게 문제 해결 범위를 찾을 수 있습니다.
방법:
- "모델별" 뷰에서 "모델별 상세 통계" 테이블의
total_tokens / request_count / 비율보기 - "계정별" 뷰에서 "계정 상세 통계" 테이블의
total_tokens / request_count보기
볼 수 있는 것: 가장 비싼 모델/계정이 앞에 있고, request_count가 "한 번에 특별히 비싼지" "횟수가 특별히 많은지" 구분할 수 있습니다.
6단계(선택 사항): token_stats.db 찾기, 백업/대조
이유 "통계 누락"을 의심하거나 오프라인 분석을 하고 싶을 때, SQLite 파일을 직접 가져오는 것이 가장 확실합니다.
방법: Settings의 Advanced 영역에서 "데이터 디렉터리 열기"를 클릭하면 데이터 디렉터리에서 token_stats.db를 찾을 수 있습니다.
볼 수 있는 것: 파일 목록에 token_stats.db가 있습니다(파일명은 백엔드에서 하드코딩됨).
체크포인트 ✅
- Token Stats 통계가 "응답의 usage/usageMetadata 추출 후 로컬 SQLite에 저장"이라는 것을 명확히 설명할 수 있습니다. 클라우드 청구가 아닙니다.
- "모델별/계정별" 두 가지 추세 뷰에서 구체적인 피크 시간대를 가리킬 수 있습니다.
- Top 리스트로 실행 가능한 문제 해결 결론을 줄 수 있습니다: 먼저 어느 모델 또는 계정을 검토할지.
함정 경고
| 현상 | 일반적인 원인 | 할 수 있는 것 |
|---|---|---|
| Token Stats가 "데이터 없음" 표시 | 실제 모델 요청이 없음; 또는 업스트림 응답에 파싱 가능한 토큰 필드가 없음 | 먼저 검증된 클라이언트로 요청 보내기; 응답에 usage/usageMetadata가 포함되어 있는지 확인 |
| 통계가 "모델"별로 보이지 않음 | 통계 기준은 요청의 model을 사용하고, X-Mapped-Model이 아님 | 모델 라우팅을 "요청 모델 -> 매핑 모델"로 간주; 통계는 "요청 모델"을 봄 |
| 계정 차원 누락 | X-Account-Email을 얻고 토큰 사용량을 파싱할 때만 기록됨 | 요청이 실제 계정 풀에 도달했는지 확인; 다음 요청 로그/응답 헤더와 대조 |
| Proxy Monitor 활성화 후 통계가 너무 큼 | Proxy Monitor 활성화 시, 각 요청의 토큰이 두 번 기록됨 | 알려진 구현 세부 사항으로 상대적 추세 분석에는 영향 없음; 정확한 값이 필요하면 Monitor를 일시적으로 비활성화하고 다시 측정 |
이 수업 요약
- Token Stats의 핵심 가치는 "비용 문제를 정량화"하는 것입니다. 먼저 위치를 지정한 다음 최적화합니다.
- 통계 기록 시 계정과 토큰 사용량은 필수입니다. 모델이 누락되면
"unknown"으로 기록됩니다(기록 방지하지 않음). - 더 세밀한 비용 제어를 하려면, 다음은 일반적으로 모델 라우팅 또는 할당량 관리로 돌아갑니다.
다음 수업 예고
다음 수업에서는 긴 세션의 "隐性 안정성 문제"를 해결합니다: 긴 세션 안정성: 컨텍스트 압축, 서명 캐시 및 도구 결과 압축.
배우게 될 것:
- 세 가지 점진적 컨텍스트 압축이 각각 무엇을 하는지
- 왜 "서명 캐시"가 400 서명 오류를 줄일 수 있는지
- 도구 결과 압축은 무엇을 삭제하고 무엇을 유지하는지
부록: 소스 코드 참조
펼쳐서 소스 코드 위치 확인
업데이트 시간: 2026-01-23
| 기능 | 파일 경로 | 행 번호 |
|---|---|---|
| --- | --- | --- |
| Token Stats UI: 시간 창/뷰 전환 및 데이터 가져오기 | src/pages/TokenStats.tsx | 49-166 |
| Token Stats UI: 빈 데이터 프롬프트("데이터 없음") | src/pages/TokenStats.tsx | 458-507 |
| 토큰 사용량 추출: 요청에서 model 파싱, 응답에서 usage/usageMetadata 파싱 | src-tauri/src/proxy/middleware/monitor.rs | 32-120 |
| 토큰 사용량 추출: 스트림 및 JSON 응답에서 usage 필드 파싱 | src-tauri/src/proxy/middleware/monitor.rs | 122-336 |
| Token Stats 기록 지점: 계정+토큰 얻기 후 SQLite에 기록 | src-tauri/src/proxy/monitor.rs | 79-136 |
데이터베이스 파일명 및 테이블 구조: token_stats.db / token_usage / token_stats_hourly | src-tauri/src/modules/token_stats.rs | 58-126 |
기록 로직: record_usage(account_email, model, input, output) | src-tauri/src/modules/token_stats.rs | 128-159 |
| 쿼리 로직: 시간/일/주, 계정별/모델별, 추세 및 총괄 | src-tauri/src/modules/token_stats.rs | 161-555 |
Tauri 명령: get_token_stats_*가 프론트엔드에 노출 | src-tauri/src/commands/mod.rs | 791-847 |
| 애플리케이션 시작 시 Token Stats DB 초기화 | src-tauri/src/lib.rs | 50-56 |
설정 페이지: 데이터 디렉터리 가져오기/열기(token_stats.db 찾기용) | src/pages/Settings.tsx | 76-143 |