0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Notion Agent APIのクレジット使用量が小数に変更|credits_usedの丸め規則と対応

0
Posted at

はじめに

Notion Agent API のクレジット使用量フィールドが、整数ではなく小数でクレジットを返すようになりました。あわせて、フィールドごとの丸め規則(どちらも切り捨て)が固定されています。

フィールドの型は以前から number なので、スキーマ上は互換です。ただし**「クレジットは整数で返る」という前提でコードを書いていた場合**は、デシリアライズエラー、バリデーション失敗、表示や集計のズレが起きる可能性があります。

📌 影響を受ける人

  • Agent API の credits_used / total_credits_used を取得して、コストの可視化・課金按分・アラートに使っている人
  • Go / Java / Kotlin / Swift / Rust など、静的型付け言語で int として型定義している人
  • 「クレジットは整数」という前提でバリデーションや UI 表示を作っている人

変更の全体像

影響を受けるエンドポイントとフィールドは次の3つです。

変更内容

⚠️ Breaking Change(整数前提の実装のみ)
型は以前から number でしたが、整数前提の実装は小数を受け取ると壊れる可能性があります。severity は high、対応が必要です。

丸め規則の一覧

エンドポイント フィールド 丸め規則 例
Retrieve a session credits_used 小数点以下最大2桁(切り捨て) 12.456789 → 12.45
Query sessions credits_used 小数点以下最大2桁(切り捨て) 12.456789 → 12.45
Retrieve agent insights total_credits_used 1以上は整数(切り捨て) 12.7 → 12
Retrieve agent insights total_credits_used 1未満は有効数字最大2桁(切り捨て) 0.456789 → 0.45

ポイント

  • 丸めは四捨五入ではなく切り捨てです。12.7 は 13 ではなく 12 になります。
  • 丸めはフィールドごとに毎回同じ規則で行われるため、結果は決定的です。
  • total_credits_used は値の大きさで規則が変わります。1未満は有効数字2桁、1以上は整数です。
  • 切り捨てのため、セッション単位の credits_used を合算しても、total_credits_used とは一致しない場合があります。請求の厳密な突合に使う場合は注意してください。

影響を受けやすい実装パターン

パターン 起きうる問題
int / long にデシリアライズしている パースエラー、または小数部の欠落
Number.isInteger() や整数正規表現で検証している 正常なレスポンスが不正扱いになる
表示や集計が整数前提(parseInt や整数への丸め) 0.45 が 0 になるなど、少額が見えなくなる
浮動小数点で合算している 誤差が蓄積する

影響と対応

対応チェックリスト

  1. 型定義の見直し: int を float / double / decimal に変更する
  2. バリデーションの見直し: 整数チェックを外し、0 以上の数値かどうかを検証する
  3. 表示の見直し: 少額(例: 0.45)が 0 と表示されないようにする
  4. 集計の見直し: 金額・クレジットの合算は decimal 系の型を使う。切り捨て済みの値なので、合算結果が total_credits_used と完全一致するとは限らない
  5. テストの追加: 12.45、0.45、12 のような値をテストデータに加える

💡 Tips
小数2桁の値は、100倍した整数(センチクレジット)として保持する方法もあります。誤差を避けつつ、既存の整数ベースの集計基盤を流用できます。ただし total_credits_used は規則が異なるので、同じ変換を使ってよいか事前に確認してください。

CLAUDE.md への追記案

Claude Code などでこの API を扱うプロジェクトでは、次のような注意書きを残しておくと、整数前提のコードを生成されにくくなります。

## Notion API / Agent API 利用上の注意
- Agent APIの credits_used(Retrieve a session / Query sessions)は小数点以下最大2桁の小数で、切り捨てで返る。
- total_credits_used(Retrieve agent insights)は、1以上なら切り捨てた整数、1未満なら有効数字2桁(切り捨て)で返る。
- 整数を前提にした型定義・パース・集計は使わず、float/decimal として扱う。

コード例

TypeScript

Before(整数前提)

type Session = { id: string; credits_used: number };

function validate(s: Session) {
  if (!Number.isInteger(s.credits_used)) {
    throw new Error("credits_used must be an integer"); // 12.45 で例外
  }
}

const label = `${Math.round(s.credits_used)} credits`; // 0.45 → "0 credits"

After(小数対応)

type Session = { id: string; credits_used: number };

function validate(s: Session) {
  if (!Number.isFinite(s.credits_used) || s.credits_used < 0) {
    throw new Error("credits_used must be a non-negative number");
  }
}

// 表示は小数点以下2桁。API側で切り捨て済みなので再度丸めない
const label = `${s.credits_used.toFixed(2)} credits`;

Python(集計)

Before

total = sum(int(s["credits_used"]) for s in sessions)  # 小数部が落ちる

After

from decimal import Decimal

# JSON を float 経由にしない: json.loads(..., parse_float=Decimal)
total = sum((s["credits_used"] for s in sessions), Decimal("0"))

Go(静的型付け言語の例)

Before

type Session struct {
    CreditsUsed int `json:"credits_used"` // 12.45 でデコードエラー
}

After

type Session struct {
    CreditsUsed float64 `json:"credits_used"`
}

まとめ

  • Agent API のクレジット使用量が小数で返るようになった(型は以前から number)。
  • credits_used は小数点以下最大2桁、total_credits_used は1以上なら整数・1未満なら有効数字最大2桁。どちらも切り捨て。
  • 整数型でのデシリアライズ、整数前提のバリデーション、整数前提の表示・集計がある場合は修正が必要。
  • 対応は、型を float / decimal にする、検証を緩める、少額表示を確認する、の3点。
  • 切り捨ての影響で合算値と total_credits_used がずれることがあるため、突合用途では仕様を踏まえて設計する。

コストの可視化やアラートを Agent API に依存している場合は、早めに自分のコードを確認しておくことをおすすめします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?