AI

Copilot AIクレジット可視化入門——usage metrics APIをFirestoreに蓄積する

GitHub Copilot usage metrics APIに追加されたai_credits_usedを題材に、Next.js + Firestoreで日次のAI利用量を見える化する実装を解説します。

2026年6月21日
GitHub CopilotAIFirestoreNext.jsGitHub Actions
Copilot AIクレジット可視化入門——usage metrics APIをFirestoreに蓄積する

はじめに

GitHub Copilotをチームで使っていて、こんな確認に時間がかかっていませんか?

確認したいことよくある困りごと
誰がどれくらいAI機能を使っているか管理画面だけでは日次の比較がしづらい
チームごとの利用傾向メンバーの所属情報と結合する必要がある
予算超過の兆候請求が確定する前に変化を見たい

2026年6月19日、GitHubはCopilot usage metrics APIのユーザー単位レポートに ai_credits_used を追加したと発表しました。これは各ユーザーが1日に消費したAIクレジット数を示すフィールドです。

本記事では、架空の営業支援SaaS「LeadPort」を題材に、GitHub CopilotのAIクレジット利用量をGitHub Actionsで日次取得し、Firestoreへ蓄積してNext.jsの管理画面で確認する流れを解説します。

何が変わったのか

GitHubの発表によると、ai_credits_used はユーザーレベルの users-1-dayusers-28-day レポートで利用できます。対象はOrganizationとEnterpriseの両方です。

重要なのは、この値が「請求書の明細そのもの」ではない点です。GitHubは ai_credits_used を利用分析のためのメトリクスとして扱い、請求確認はusage-based billing APIや請求画面を見るよう説明しています。また、現時点では機能別、モデル別、利用面別には分解されません。

LeadPortでは、請求確定後に慌てるのではなく、毎朝の定点観測で「どのチームの利用が伸びているか」「オンボーディング対象が使えているか」を見ます。

取得に使う公式エンドポイント

Organization単位で日次のユーザー利用量を取る場合、GitHub Docsに記載されているエンドポイントは次です。

GET /orgs/{org}/copilot/metrics/reports/users-1-day?day=YYYY-MM-DD

Enterprise単位では次を使います。

GET /enterprises/{enterprise}/copilot/metrics/reports/users-1-day?day=YYYY-MM-DD

このAPIは、ユーザー行を直接JSONで返すのではなく、期限付きの download_links を返します。リンク先のNDJSONをさらにダウンロードして、1行ずつ処理する設計です。

チーム別に集計したい場合は、日次の user-teams-1-day レポートと users-1-day レポートを user_idday で結合します。GitHub Docsでは、28日分のユーザーレポートを単日のチーム所属レポートに結合しないよう注意されています。チーム異動があると、過去の利用を現在のチームへ誤って寄せてしまうためです。

ハンズオン1: Firestoreの保存形を決める

まず、日次ユーザー行をそのまま近い形で保存します。最初から複雑な集計ドキュメントだけにすると、あとから指標が増えたときに再計算しづらくなります。

import { FieldValue, type Firestore } from "firebase-admin/firestore";

type CopilotUserUsageRow = {
  day: string;
  organization_id?: number;
  enterprise_id?: number;
  user_id: number;
  user_login: string;
  ai_credits_used?: number;
};

export async function saveCopilotUsageRows(
  db: Firestore,
  rows: CopilotUserUsageRow[],
) {
  const batch = db.batch();

  for (const row of rows) {
    const id = `${row.day}_${row.user_id}`;
    const ref = db.collection("copilotDailyUsage").doc(id);

    batch.set(
      ref,
      {
        ...row,
        aiCreditsUsed: row.ai_credits_used ?? 0,
        syncedAt: FieldValue.serverTimestamp(),
      },
      { merge: true },
    );
  }

  await batch.commit();
}

ai_credits_used はAPI側のフィールド名として保持しつつ、アプリ内では aiCreditsUsed に寄せています。LeadPortでは、元データと表示用データの両方を残し、仕様変更時に追跡しやすくします。

ハンズオン2: GitHub APIからNDJSONを取得する

次に、GitHub Actionsから実行する同期スクリプトを作ります。ここではOrganization単位の例に絞ります。

type ReportResponse = {
  download_links: string[];
  report_day?: string;
};

async function fetchReportLinks(org: string, day: string, token: string) {
  const url = new URL(
    `https://api.github.com/orgs/${org}/copilot/metrics/reports/users-1-day`,
  );
  url.searchParams.set("day", day);

  const response = await fetch(url, {
    headers: {
      Accept: "application/vnd.github+json",
      Authorization: `Bearer ${token}`,
      "X-GitHub-Api-Version": "2026-03-10",
    },
  });

  if (response.status === 204) {
    return [];
  }

  if (!response.ok) {
    throw new Error(`GitHub API failed: ${response.status}`);
  }

  const body = (await response.json()) as ReportResponse;
  return body.download_links;
}

async function downloadNdjson<T>(url: string): Promise<T[]> {
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Report download failed: ${response.status}`);
  }

  const text = await response.text();
  return text
    .split("\n")
    .filter(Boolean)
    .map((line) => JSON.parse(line) as T);
}

必要な権限は、Organizationでは「Organization Copilot metrics」のread権限です。従来の個人アクセストークンを安易に共有するより、GitHub Appやfine-grained personal access tokenで用途を絞るほうが運用しやすいです。

ハンズオン3: GitHub Actionsで日次同期する

LeadPortでは、毎朝9時JSTに前日分を同期します。GitHub ActionsのcronはUTCなので、0 0 * * * がJSTの9時です。

name: Sync Copilot Usage

on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:
    inputs:
      day:
        description: "YYYY-MM-DD"
        required: false
        type: string

jobs:
  sync:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"
      - run: yarn install --frozen-lockfile
      - name: Sync usage
        env:
          GITHUB_COPILOT_METRICS_TOKEN: ${{ secrets.COPILOT_METRICS_TOKEN }}
          GITHUB_ORG: ${{ vars.GITHUB_ORG }}
          TARGET_DAY: ${{ github.event.inputs.day }}
          FIREBASE_SERVICE_ACCOUNT_JSON: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}
        run: node scripts/sync-copilot-usage.mjs

当日分はまだ処理されていない可能性があります。スクリプト側では TARGET_DAY が空なら前日を選び、204が返った場合は失敗ではなく「まだデータなし」としてログに残す運用にします。

Next.js管理画面で見る指標

Firestoreに蓄積したら、Next.js App RouterのServer Componentで日次集計を表示できます。

import { getFirestore } from "firebase-admin/firestore";

type DailyCopilotSummary = {
  day: string;
  activeUsers: number;
  totalAiCredits: number;
};

export async function getDailyCopilotSummary(
  day: string,
): Promise<DailyCopilotSummary> {
  const db = getFirestore();
  const snapshot = await db
    .collection("copilotDailyUsage")
    .where("day", "==", day)
    .get();

  let totalAiCredits = 0;
  let activeUsers = 0;

  snapshot.forEach((doc) => {
    const data = doc.data() as { aiCreditsUsed?: number };
    const credits = data.aiCreditsUsed ?? 0;
    totalAiCredits += credits;
    if (credits > 0) activeUsers += 1;
  });

  return { day, activeUsers, totalAiCredits };
}

表示では、個人をランキングするよりもチーム単位の傾向を優先します。AI利用量は成果の代理指標ではありません。LeadPortでは、PR作成数、レビュー待ち時間、問い合わせ対応時間などの業務指標と並べ、使いすぎの検出だけでなく、活用できていないチームの支援にも使います。

運用チェックリスト

項目判断基準
権限Copilot metricsのreadに限定する
保存範囲原則として日次集計とGitHub loginだけにする
取り扱い個人評価ではなくチーム支援・予算管理に使う
請求確認ai_credits_used だけで請求額を断定しない
集計チーム別は日次user-teamsと日次usersを結合する

特に最後の2つは重要です。ai_credits_used は利用傾向を早く見るためのフィールドであり、モデル別の料金や追加課金額を確定するものではありません。請求の正確な確認には、GitHubのbilling系APIや管理画面を併用します。

参考リンク

まとめ

ai_credits_used の追加により、CopilotのAI利用量をユーザー単位の日次メトリクスとして扱いやすくなりました。Next.js + Firestoreの構成なら、GitHub Actionsで毎日NDJSONを取得し、管理画面に小さく可視化できます。

最初は「前日分の合計」「アクティブユーザー数」「チーム別の増減」だけで十分です。請求額を断定するダッシュボードではなく、予算と活用状況を早めに把握する運用メーターとして育てていくのが現実的です。