cost-accrual-tracker について
LLM実行中にAPIコストを積算する実装スキルです。実行パイプラインやコスト表示を対象に、中断時の部分コスト記録と予算超過時の自動停止方法を扱います。
主な機能
- 01トークン使用量からコストを算出
- 02実行中にコストを段階的に積算
- 03中断時の部分コストを記録
- 04予算しきい値による自動停止
- 05複数の実行ノードのコストを集計
活用シーン
- 01実行画面でリアルタイムコストを表示
- 02中断時に発生済みコストを保持
- 03予算超過時にタスクを停止
- 04DAG内の複数ノードのコストを集計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill cost-accrual-trackerインストール後、Claude Code で/cost-accrual-trackerを入力して読み込まれたか確認します。
同梱ファイル.claude-plugin/plugin.jsonreferences/claude-api-pricing.md
詳細
コスト累積トラッカー
LLM の実行中に API コストをリアルタイムで追跡し、中断時には部分的なコストにも対応します。
使用するタイミング
✅ 次の場合に使用します:
- 実行中のリアルタイムコスト追跡を実装する
- 実行が中断された場合に部分的なコストを取得する
- 実行 UI 用のコスト表示ウィジェットを構築する
- 実行パイプラインにトークンカウントを統合する
- 自動停止機能付きの予算しきい値を追加する
❌ 次の場合には使用しません:
- 実行前のコスト見積もり(料金計算ツールを使用してください)
- 課金システムの設計(billing-system スキルを使用してください)
- 価格帯の管理や割引
- 過去のコスト分析ダッシュボード
主なパターン
1. トークンベースのコスト計算
interface TokenUsage {
inputTokens: number;
outputTokens: number;
cacheReadTokens?: number; // Prompt caching hits
cacheWriteTokens?: number; // Prompt caching misses
}
interface CostCalculation {
inputCostUsd: number;
outputCostUsd: number;
cacheSavingsUsd?: number;
totalCostUsd: number;
}
function calculateCost(usage: TokenUsage, model: string): CostCalculation {
const pricing = MODEL_PRICING[model];
const inputCostUsd = (usage.inputTokens / 1_000_000) * pricing.inputPerMTok;
const outputCostUsd = (usage.outputTokens / 1_000_000) * pricing.outputPerMTok;
return {
inputCostUsd,
outputCostUsd,
totalCostUsd: inputCostUsd + outputCostUsd,
};
}
2. 増分累積パターン
完了時だけでなく、コストが発生するたびに追跡します:
class CostAccrualTracker {
private totalInputTokens = 0;
private totalOutputTokens = 0;
private accruedCostUsd = 0;
private readonly model: string;
constructor(model: string) {
this.model = model;
}
/**
* Called after each API response (streaming or complete)
*/
recordUsage(usage: TokenUsage): void {
this.totalInputTokens += usage.inputTokens;
this.totalOutputTokens += usage.outputTokens;
const cost = calculateCost(usage, this.model);
this.accruedCostUsd += cost.totalCostUsd;
}
/**
* Get current accrued cost (for real-time display)
*/
getCurrentCost(): number {
return this.accruedCostUsd;
}
/**
* Finalize on completion or abort
*/
finalize(reason: 'completed' | 'aborted' | 'failed'): CostReport {
return {
totalInputTokens: this.totalInputTokens,
totalOutputTokens: this.totalOutputTokens,
totalCostUsd: this.accruedCostUsd,
completionReason: reason,
finalizedAt: Date.now(),
};
}
}
3. 中断対応のコスト取得
重要:中断時には、必ず部分的なコストを取得してください:
// In execution handler
const tracker = new CostAccrualTracker(model);
try {
for await (const chunk of executeStream(request)) {
if (abortSignal.aborted) {
// CRITICAL: Capture cost BEFORE throwing
const partialCost = tracker.finalize('aborted');
onCostUpdate(partialCost);
throw new AbortError('Execution aborted');
}
tracker.recordUsage(chunk.usage);
onCostUpdate(tracker.getCurrentCost());
}
return tracker.finalize('completed');
} catch (error) {
if (error instanceof AbortError) {
throw error; // Already handled
}
return tracker.finalize('failed');
}
4. 予算しきい値パターン
予算を超過したら実行を自動停止します:
interface BudgetConfig {
maxCostUsd: number;
warnAtPercentage: number; // e.g., 0.8 for 80%
onWarn?: (current: number, max: number) => void;
onExceed?: (current: number, max: number) => void;
}
function createBudgetGuard(config: BudgetConfig) {
return {
check(currentCostUsd: number): 'ok' | 'warn' | 'exceed' {
const percentage = currentCostUsd / config.maxCostUsd;
if (percentage >= 1.0) {
config.onExceed?.(currentCostUsd, config.maxCostUsd);
return 'exceed';
}
if (percentage >= config.warnAtPercentage) {
config.onWarn?.(currentCostUsd, config.maxCostUsd);
return 'warn';
}
return 'ok';
}
};
}
アンチパターン
中断時に失われるコスト
初心者の考え:「中断時にエラーを投げればよい」
実際には:中断前にコストを取得しないと、次の情報が失われます:
- 実行途中までのトークン使用量データ
- 課金の正確なコスト報告
- デバッグ用の監査証跡
経緯:以前から存在する問題ですが、高価なモデル(GPT-4、Claude Opus)の登場で深刻になりました。
正しい方法:中断エラーを投げる前に、部分データを指定して必ず finalize() を呼び出してください。
デバウンスなしのポーリング
初心者の考え:「リアルタイム更新のため、コストエンドポイントを100ミリ秒ごとにポーリングする」
実際には:
- 帯域幅と CPU を浪費します
- コストが更新されるのは API の応答後だけです
- 応答レートを上回る頻度のポーリングには意味がありません
正しい方法:1~2秒間隔でポーリングするか、実行ストリームからのイベント駆動型更新を使用してください。
プロンプトキャッシュを無視する
初心者の考え:「トークン数にトークン単価を掛ければよい」
実際には:Claude のプロンプトキャッシュによってコストモデルが変わります:
- キャッシュ読み取りは90%安くなります
- 初回使用時にはキャッシュ書き込みに追加料金がかかります
- キャッシュを無視すると、コストが不正確になります
経緯:
- 2024年以前:キャッシュなし。計算はシンプルでした
- 2024年以降:Claude のプロンプトキャッシュには個別の追跡が必要です
正しい方法:cache_read_input_tokens と cache_creation_input_tokens を個別に追跡してください。
リクエストごとのコストオブジェクト
初心者の考え:「リクエストごとに新しいトラッカーを作成する」
実際には:複数のノードを含む DAG の実行では、次のことが必要です:
- すべてのノードのコストを集計する
- 特定のノードにコストを割り当てる
- 親実行に対してコストを集計する
正しい方法:階層型の追跡を使用し、ノードごとのトラッカーから実行レベルへ集計します。
状態の流れ
┌─────────────────────────────────────────┐
│ CostAccrualTracker │
└─────────────────────────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ recordUsage() │ │ getCurrentCost()│ │ finalize() │
│ │ │ │ │ │
│ After each API │ │ For real-time │ │ On completion, │
│ response │ │ display │ │ abort, or fail │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ CostReport │
│ { inputTokens, outputTokens, totalCostUsd, completionReason } │
└─────────────────────────────────────────────────────────────────┘
UI 表示パターン
実行 UI でコストをリアルタイムに表示する場合:
// Poll every 2 seconds while executing
useEffect(() => {
if (status !== 'running') return;
const interval = setInterval(async () => {
const response = await fetch(`/api/execute/${executionId}`);
const data = await response.json();
setAccruedCost(data.cost.accruedUsd);
setTokens({
input: data.cost.inputTokens,
output: data.cost.outputTokens,
});
}, 2000);
return () => clearInterval(interval);
}, [executionId, status]);
// Display format
<div className="cost-display">
<span className="cost-amount">${accruedCost.toFixed(4)}</span>
<span className="token-count">
{tokens.input.toLocaleString()} in / {tokens.output.toLocaleString()} out
</span>
</div>
統合ポイント
| コンポーネント | 担当 |
|---|---|
CostAccrualTracker | 実行ごとのトークンカウントとコスト計算 |
ExecutionManager | DAG 実行全体のコスト集計 |
BudgetGuard | しきい値の監視と自動停止 |
/api/execute/:id | ポーリングによる現在のコストの公開 |
| コスト表示ウィジェット | リアルタイムの UI 描画 |
参考資料
現在の Claude API 料金については、/references/claude-api-pricing.md を参照してください。