1
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?

OpenAI APIのOutput料金にはReasoningも含まれる

1
Last updated at Posted at 2026-07-28

OpenAI APIの料金を計算するとき、ReasoningモデルのOutputは、画面に表示された文章のトークン数だけではありません。

内部で使用されたReasoningトークンも、Outputトークンに含まれます。

つまり、「出力された文章のトークン数を調査し、outputに該当する値として使用する」だけでは、計算的に不十分だということになります。

completion_tokens
├─ 表示された回答
└─ reasoning_tokens

そのため、料金計算にはcompletion_tokensを使います。

completion_tokens + reasoning_tokensとすると、Reasoningを二重計上するため注意が必要です。

Chat Completions APIでは completion_tokens、Responses APIでは output_tokens を料金計算に使います。いずれもReasoningトークンを含むため、Reasoningトークンを別途加算してはいけません。

実際の使用量を確認する

APIレスポンスのusageを返却JSONに追加すると、実際のトークン数を調査できます。

//Chat Completions API で、input output のトークン数をチェックする
if (DEBUG_MODE) {
  const usage = data?.usage ?? {};
  const details = usage.completion_tokens_details ?? {};

  obj.tokenUsage = {
    input: Number(usage.prompt_tokens) || 0,
    outputIncludingReasoning:
      Number(usage.completion_tokens) || 0,
    reasoning:
      Number(details.reasoning_tokens) || 0,
    total: Number(usage.total_tokens) || 0
  };
}

下記のような仕組みも良いかもしれません。

const MODELS = [
  { name: "gpt-5-nano", inRate: 0.05, outRate: 0.40 },
  { name: "gpt-4.1-nano", inRate: 0.10, outRate: 0.40 },
  { name: "gpt-4o-mini", inRate: 0.15, outRate: 0.60 },
  { name: "gpt-5.6-luna", inRate: 0.20, outRate: 1.20 },
  { name: "gpt-5.4-nano", inRate: 0.20, outRate: 1.25 },
  { name: "gpt-5-mini", inRate: 0.25, outRate: 2.00 },
  { name: "gpt-4.1-mini", inRate: 0.40, outRate: 1.60 },
  { name: "gpt-5.4-mini", inRate: 0.75, outRate: 4.50 },
  { name: "gpt-5.1", inRate: 1.25, outRate: 10.00 },
  { name: "gpt-5.2", inRate: 1.75, outRate: 14.00 },
  { name: "gpt-5.4", inRate: 2.50, outRate: 15.00 },
  { name: "gpt-5.6-terra", inRate: 2.50, outRate: 15.00 },
  { name: "gpt-5.5", inRate: 5.00, outRate: 30.00 },
  { name: "gpt-5.6-sol", inRate: 5.00, outRate: 30.00 }
];

const FLEX = [
  { base: "gpt-5-nano", label: "gpt-5-nano Flex", factor: 0.5 },
  { base: "gpt-5.4-nano", label: "gpt-5.4-nano Flex", factor: 0.5 },
  { base: "gpt-5.6-luna", label: "gpt-5.6-luna Flex", factor: 0.5 },
  { base: "gpt-5-mini", label: "gpt-5-mini Flex", factor: 0.5 },
  { base: "gpt-5.4-mini", label: "gpt-5.4-mini Flex", factor: 0.5 },
  { base: "gpt-5.1", label: "gpt-5.1 Flex", factor: 0.5 },
  { base: "gpt-5.2", label: "gpt-5.2 Flex", factor: 0.5 },
  { base: "gpt-5.4", label: "gpt-5.4 Flex", factor: 0.5 },
  { base: "gpt-5.6-terra", label: "gpt-5.6-terra Flex", factor: 0.5 },
  { base: "gpt-5.5", label: "gpt-5.5 Flex", factor: 0.5 },
  { base: "gpt-5.6-sol", label: "gpt-5.6-sol Flex", factor: 0.5 }
];

function getModelRate(modelName, isFlex = false) {
  if (!isFlex) {
    return MODELS.find(model => model.name === modelName) ?? null;
  }

  const flex = FLEX.find(item =>
    item.base === modelName || item.label === modelName
  );

  if (!flex) return null;

  const baseModel = MODELS.find(model => model.name === flex.base);
  if (!baseModel) return null;

  return {
    name: flex.label,
    inRate: baseModel.inRate * flex.factor,
    outRate: baseModel.outRate * flex.factor
  };
}

if (DEBUG_MODE) {
  const usage = data?.usage ?? {};
  const details = usage.completion_tokens_details ?? {};

  const inputTokens = Number(usage.prompt_tokens) || 0;
  const outputTokens = Number(usage.completion_tokens) || 0;
  const reasoningTokens = Number(details.reasoning_tokens) || 0;
  const totalTokens = Number(usage.total_tokens) || 0;

  // 実際に使用した条件に合わせて変更
  let modelName = "gpt-5.6-luna";
  const isFlex = true;
  const yenPerDollar = 168;

  modelName = modelName.replace(" (<272K)", "")

  const rate = getModelRate(modelName, isFlex);

  let cost = null;

  if (rate) {
    const inputCostUsd =
      (inputTokens / 1_000_000) * rate.inRate;

    // completion_tokensにはReasoningトークンも含まれる
    const outputCostUsd =
      (outputTokens / 1_000_000) * rate.outRate;

    cost = Number(
      ((inputCostUsd + outputCostUsd) * yenPerDollar).toFixed(2)
    );
  }

  obj.tokenUsage = {
    input: inputTokens,
    outputIncludingReasoning: outputTokens,
    reasoning: reasoningTokens,
    total: totalTokens,
    cost
  };
}

モデルやreasoning_effortによって使用量は変わるため、実際の処理で記録して比較するのも有効です。

API料金シミュレーター

以下のサイトでは、Input、Reasoning込みのOutput、為替、1日の実行回数を入力して料金を比較できます。

https://uni928.github.io/Uni928PublicHTMLs/index14.html

次の金額をモデル別に確認できます。

  • 1リクエストあたりの料金
  • 1か月あたりの料金(30日)

為替は、円安に備えて実勢レートより少し高めに設定しています。

また、「URLをコピー」を押すと、入力値を含んだ共有用URLを発行できます。

https://uni928.github.io/Uni928PublicHTMLs/index14.html?i=3500&o=3000&fx=168&d=1000

上司への料金見積もりの共有にも使えます。

API料金を計算するときは、OutputにReasoningも含まれることを忘れないようにしたいです。

1
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
1
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?