서드 파티 모델 토큰 사용량 추적

Cloud Logging 및 Observability Analytics을 사용하여 AI 개발자 도구(예: Anthropic Claude Opus 5.5 및 Anthropic Claude Sonnet 5.5)에서 서드 파티 모델의 모델, 일, 사용자별 토큰 소비량을 계산할 수 있습니다.

빠른 시작

프로젝트의 _Default 로그 버킷이 이미 Observability Analytics을 위해 업그레이드된 경우 로깅 > Observability Analytics에서 다음 쿼리를 실행하여([PROJECT_ID]를 Google Cloud 프로젝트 ID로 대체) 서드 파티 Anthropic 모델 전반에서 30일간의 토큰 사용량을 확인합니다.

SELECT
  JSON_VALUE(labels.model) AS model,
  COUNT(*) AS requests,
  SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64)) AS input_tokens,
  SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64)) AS output_tokens,
  IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64)), 0) AS cached_tokens,
  IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64)), 0) AS thoughts_tokens,
  SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
  `[PROJECT_ID].global._Default._Default`
WHERE
  log_id = "businessaicode.googleapis.com/inference_response"
  AND JSON_VALUE(labels.model_provider) = "Anthropic"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  model
ORDER BY
  total_tokens DESC

시작하기 전에

튜토리얼 단계를 실행하기 전에 프로젝트가 다음 요구사항을 충족하는지 확인하세요.

  • 메타데이터 로깅이 사용 설정되어 있습니다. inference_response 레코드에 jsonPayload.metadata 토큰 블록이 포함되도록 AI 개발자 도구 관리자 제어에 메타데이터 로깅이 사용 설정되어 있어야 합니다.
  • 로그 뷰어 역할 (roles/logging.viewer) 이상을 보유하고 있습니다. 표준 roles/logging.viewer 역할은 이 가이드 전체에서 사용되는 _Default._Default 로그 뷰에 대한 SQL 액세스 권한을 부여합니다. _Default._AllLogs 뷰를 쿼리하려면 roles/logging.privateLogViewer 또는 roles/logging.viewAccessor가 필요합니다.
  • _Default 로그 버킷이 Observability Analytics를 위해 업그레이드되었습니다.
    1. Google Cloud 콘솔에서 로깅 > 로그 스토리지로 이동하여 _Default 버킷을 찾고 Observability Analytics 열을 확인합니다.
    2. 사용 설정되어 있지 않으면 더보기 > Observability Analytics를 사용하도록 업그레이드를 클릭합니다. 업그레이드는 _Default를 인플레이스로 수정하며 실행취소할 수 없습니다.
    3. 초기 전파 허용: 버킷을 업그레이드한 후 Cloud Logging에서 새 로그 항목의 라우팅 캐시를 새로고침하는 데 30~60분이 걸리고, 이전 로그를 백필하는 데 몇 시간이 걸립니다 (백필은 업그레이드가 완료된 후 1시간 후에 시작됨).

로그 레코드의 구조

모든 추론 호출은 businessaicode.googleapis.com%2Finference_response 로그에 단일 InferenceResponseLog 항목을 내보냅니다. 모델 ID는 labels에 기록되고 토큰 수는 jsonPayload.metadata에 기록됩니다.

{
  "logName": "projects/[PROJECT_ID]/logs/businessaicode.googleapis.com%2Finference_response",
  "timestamp": "2026-10-07T17:23:03.495323480Z",
  "labels": {
    "model": "claude-sonnet-5-5",
    "model_provider": "Anthropic",
    "client_name": "antigravity_cli",
    "user_id": "user:user@example.com",
    "trajectory_id": "25cd0b58-58ea-4beb-b2d7-42e0d3fdd96d",
    "request_id": "25cd0b58-58ea-4beb-b2d7-42e0d3fdd96d-19"
  },
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.businessaicode.logging.v1.InferenceResponseLog",
    "metadata": {
      "promptTokenCount": "70825",
      "cachedContentTokenCount": "69079",
      "candidatesTokenCount": "14215",
      "totalTokenCount": "85040"
    }
  }
}

필드 참조 및 계산 규칙

LogEntry 필드 (로그 탐색기 및 로그 기반 측정항목) SQL 표현식 (Observability Analytics) 설명
labels.model JSON_VALUE(labels.model) 모델 식별자 (예: Anthropic Claude Sonnet 5.5의 경우 claude-sonnet-5-5, Anthropic Claude Opus 5.5의 경우 claude-opus-5-5)
labels.model_provider JSON_VALUE(labels.model_provider) 공급업체 이름 (예: Anthropic 또는 Google)
labels.user_id JSON_VALUE(labels.user_id) 인증된 주 구성원 (예: user:user@example.com)
labels.trajectory_id JSON_VALUE(labels.trajectory_id) 대화 또는 상담사 궤적 ID입니다. 하나의 사용자 턴은 일반적으로 하나의 trajectory_id 아래에 있는 여러 request_id 호출에 걸쳐 있습니다.
jsonPayload.metadata.promptTokenCount SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64) 통화의 총 입력 토큰 (캐시된 토큰 포함)입니다.
jsonPayload.metadata.cachedContentTokenCount SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64) 프롬프트 캐시에서 제공된 promptTokenCount의 하위 집합입니다. 0인 경우 생략됩니다. promptTokenCount 또는 totalTokenCount에 추가하지 마세요.
jsonPayload.metadata.candidatesTokenCount SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64) 모델에서 생성된 출력 토큰입니다.
jsonPayload.metadata.thoughtsTokenCount SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64) 추론 토큰(해당하는 경우) Anthropic 모델의 경우 생략됩니다.
jsonPayload.metadata.totalTokenCount SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64) 통화의 공신력 있는 총계입니다. promptTokenCount + candidatesTokenCount(+ thoughtsTokenCount(있는 경우))와 같습니다.

1단계: 로그 탐색기에서 수신 로그 확인하기

SQL 쿼리를 실행하기 전에 토큰 메타데이터가 포함된 inference_response 레코드가 프로젝트에 도착하는지 확인합니다.

  1. Google Cloud 콘솔에서 로깅 > 로그 탐색기를 엽니다.
  2. 다음 쿼리를 쿼리 편집기에 붙여넣고 [PROJECT_ID]를 프로젝트 ID로 바꿉니다.

    logName="projects/[PROJECT_ID]/logs/businessaicode.googleapis.com%2Finference_response"
    labels.model_provider="Anthropic"
    
  3. 쿼리 실행을 클릭합니다.

  4. 로그 필드 창에서 model을 클릭하여 Anthropic 모델 전반의 요청 분포를 확인합니다. 이 뷰는 토큰이 아닌 요청을 집계합니다.

2단계: Observability Analytics에서 모델별 토큰 합계

  1. Google Cloud 콘솔에서 로깅 > Observability Analytics을 엽니다.
  2. 기간 선택기를 지난 30일로 설정합니다 (기간 선택기는 SQL WHERE 절 외에도 쿼리 결과를 제한합니다).
  3. 다음 쿼리를 붙여넣고 실행합니다. 이때 [PROJECT_ID]는 프로젝트 ID로 바꿉니다.

    SELECT
      JSON_VALUE(labels.model) AS model,
      COUNT(*) AS requests,
      SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64)) AS input_tokens,
      SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64)) AS output_tokens,
      IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64)), 0) AS cached_tokens,
      IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64)), 0) AS thoughts_tokens,
      SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
    FROM
      `[PROJECT_ID].global._Default._Default`
    WHERE
      log_id = "businessaicode.googleapis.com/inference_response"
      AND JSON_VALUE(labels.model_provider) = "Anthropic"
      AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
    GROUP BY
      model
    ORDER BY
      total_tokens DESC
    

3단계: 일반적인 SQL 레시피

로깅 > Observability Analytics에서 다음 SQL 쿼리를 사용하여 일일 토큰 추세와 사용자별 토큰 기여도를 분석합니다.

모델별 일일 토큰 추세

SELECT
  TIMESTAMP_TRUNC(timestamp, DAY) AS day,
  JSON_VALUE(labels.model) AS model,
  COUNT(*) AS requests,
  SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
  `[PROJECT_ID].global._Default._Default`
WHERE
  log_id = "businessaicode.googleapis.com/inference_response"
  AND JSON_VALUE(labels.model_provider) = "Anthropic"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  day, model
ORDER BY
  day DESC, total_tokens DESC

사용자별, 모델별 기여 분석

SELECT
  JSON_VALUE(labels.user_id) AS user_id,
  JSON_VALUE(labels.model) AS model,
  COUNT(*) AS requests,
  SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
  `[PROJECT_ID].global._Default._Default`
WHERE
  log_id = "businessaicode.googleapis.com/inference_response"
  AND JSON_VALUE(labels.model_provider) = "Anthropic"
  AND JSON_VALUE(labels.user_id) IS NOT NULL
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  user_id, model
ORDER BY
  total_tokens DESC

4단계: Cloud Monitoring 대시보드에 고정

대시보드에는 두 가지 옵션이 있습니다. 기록 또는 임시 SQL 분석이 필요한지 아니면 경량의 연속 측정항목이 필요한지에 따라 선택할 수 있습니다.

접근 방법 용도 30일이 지난 기록을 보관하는가? user_id 그룹화 지원 여부
옵션 A: Observability Analytics에서 SQL 차트 저장 측정항목 설정이 필요 없는 모델별, 일별, 사용자별 표 및 차트 로그 버킷 보관 기간 (기본 30일)에 의해 제한됨 예 (카디널리티 한도 없음)
옵션 B: 로그 기반 분포 측정항목 지속적 모니터링 시계열 및 카디널리티가 낮은 라벨에 대한 알림 예 (Monitoring에 저장됨) 아니요 (카디널리티가 높으면 측정항목 할당량이 소진됨)

옵션 A: Observability Analytics에서 직접 저장

  1. 2단계의 쿼리 또는 모니터링 가능성 분석의 모델별 일일 토큰 추세 쿼리를 실행합니다.
  2. 시각적 시계열 또는 막대 그래프를 원하는 경우 결과 창을 표에서 차트로 전환합니다.
  3. 결과 창 툴바에서 대시보드에 저장을 클릭한 후 기존 Monitoring 대시보드를 선택하거나 새 대시보드를 만듭니다.

옵션 B: 로그 기반 분포 측정항목 만들기

  1. Google Cloud 콘솔에서 로깅 > 로그 기반 측정항목으로 이동한 후 측정항목 만들기를 클릭합니다.
  2. 측정항목 유형으로 분포를 선택합니다.
  3. 1단계의 쿼리를 필터 필드에 붙여넣고 필드 이름을 jsonPayload.metadata.totalTokenCount로 설정합니다.
  4. 다음 두 라벨을 추가합니다.
    • model이 labels.model에 매핑됨
    • model_provider이 labels.model_provider에 매핑됨

다음 단계