AIコーディング 2026.06.04

ChatGPT APIの料金計算方法|gpt-4o・gpt-4o-miniのコスト比較【2026年版】

タグ:ChatGPT API / 料金 / API設計

この方法で何が解決するか

開発者がChatGPT APIを導入するときに直面する課題は「実際にいくら使うと費用になるのか」という予測の難しさです。APIの料金は複雑で、単純な「1回あたり○円」という固定値ではなく、送受信するテキスト量(トークン数)で変動します。

gpt-4o(最新の高性能モデル)とgpt-4o-mini(低コストの軽量版)どちらを選ぶかで、数倍から数十倍のコスト差が生まれることもあります。本記事では、料金体系の仕組みから実際の計算方法、コスト削減のコツ、そして予算超過を自動的に防ぐ仕組みまで、開発者が意思決定に必要な情報をまとめました。

料金体系の基本:トークンとは何か

ChatGPT APIの料金は「トークン」という単位で計算されます。トークンは、テキストを細かく分割した単位で、ざっくり「4文字でトークン1個」という目安です。

料金は以下2つで構成されます:

  • 入力トークン: APIに送信するテキスト(ユーザーの質問やシステムプロンプト)の長さ
  • 出力トークン: APIから返ってくる回答の長さ

実務的には、出力トークンの方が入力より高い単価に設定されていることが多いです。モデルが「答えを生成する」という処理が、入力を処理するより計算コストがかかるためです。

また、最も頻繁に発生するエラーの1つが『Maximum context length』エラーです。このエラーは、送信するテキストがモデルの最大トークン数を超えたときに発生します。送信前にトークン数をカウントする利点は以下の通りです:

  • エラー防止: 『Maximum context length』エラーを事前に検知し、回避できます
  • コスト最適化: 実際のAPIコール前に、必要なトークン数を把握して料金計算ができます
  • 安定性向上: トークン数が制限を超える場合、テキストを事前に分割や圧縮する対応が可能になります

gpt-4oの料金表

gpt-4oは、OpenAIが2024年以降に公開した最新の高性能モデルです。以下の価格が適用されます。

区分価格
入力トークン$0.005 / 1M tokens
出力トークン$0.015 / 1M tokens

「1M tokens」は100万トークンという意味です。つまり:

  • 入力:100万トークンで5ドル
  • 出力:100万トークンで15ドル

実際の計算例を見てみましょう。日本語で200文字の質問をして、500文字の回答が返ってきた場合を想定します。

日本語は1文字がおおよそ1.3トークンになるため:

  • 入力:200文字 × 1.3 ≒ 260トークン
  • 出力:500文字 × 1.3 ≒ 650トークン
  • 合計:910トークン

コスト計算:

入力コスト = 260 / 1,000,000 × $0.005 = $0.0000013
出力コスト = 650 / 1,000,000 × $0.015 = $0.0000098
合計 = $0.0000111(約0.15円)

1回のAPIコールで1円以下というわけです。ただし、アプリケーションが多くのユーザーからアクセスを受けると、これが累積して大きな費用になります。

gpt-4o-miniの料金表

gpt-4o-miniは軽量版で、処理速度と精度を制御したモデルです。料金も大幅に安く設定されています。

区分価格
入力トークン$0.00015 / 1M tokens
出力トークン$0.0006 / 1M tokens

gpt-4oと比べると:

  • 入力:約33分の1の安さ
  • 出力:約25分の1の安さ

同じ例(入力260トークン、出力650トークン)で計算すると:

入力コスト = 260 / 1,000,000 × $0.00015 = $0.000000039
出力コスト = 650 / 1,000,000 × $0.0006 = $0.00000039
合計 = $0.000000429(約0.000006円)

1回でほぼ無視できるコストです。ただし、精度(回答の質)がgpt-4oより落ちる可能性があるため「どのタスクでgpt-4o-miniで十分か」の判断が重要です。

実務的なコスト計算シミュレーション

実際のアプリケーションで月々どの程度費用がかかるか、3つのシナリオで計算してみます。

シナリオ1:チャットボット(月10,000リクエスト、gpt-4o使用)

想定:

  • 平均入力:500トークン
  • 平均出力:300トークン
  • 月リクエスト数:10,000回

計算:

月入力合計 = 10,000 × 500 = 5,000,000トークン
月出力合計 = 10,000 × 300 = 3,000,000トークン

入力コスト = 5,000,000 / 1,000,000 × $0.005 = $25
出力コスト = 3,000,000 / 1,000,000 × $0.015 = $45
月合計 = $70(約9,800円)

シナリオ2:同じチャットボット、gpt-4o-mini使用

同じ条件で、モデルだけgpt-4o-miniに変更:

入力コスト = 5,000,000 / 1,000,000 × $0.00015 = $0.75
出力コスト = 3,000,000 / 1,000,000 × $0.0006 = $1.8
月合計 = $2.55(約360円)

節約効果:$67.45/月(約30倍安い)

ただし、この節約は「gpt-4o-miniの精度で問題ない」という前提での話です。回答の質が落ちて、ユーザー満足度が下がっては本末転倒です。

シナリオ3:大規模な自動処理タスク(月100万リクエスト、gpt-4o-mini使用)

想定:

  • 平均入力:100トークン
  • 平均出力:200トークン
  • 月リクエスト数:1,000,000回

計算:

月入力合計 = 1,000,000 × 100 = 100,000,000トークン
月出力合計 = 1,000,000 × 200 = 200,000,000トークン

入力コスト = 100,000,000 / 1,000,000 × $0.00015 = $15
出力コスト = 200,000,000 / 1,000,000 × $0.0006 = $120
月合計 = $135(約18,900円)

gpt-4oを使った場合:

入力コスト = 100,000,000 / 1,000,000 × $0.005 = $500
出力コスト = 200,000,000 / 1,000,000 × $0.015 = $3,000
月合計 = $3,500(約490,000円)

gpt-4o-miniの節約効果:$3,365/月(約30倍安い)

大規模運用だと、この差は経営判断に直結します。

gpt-4o vs gpt-4o-mini:どっちを使うべき?

選び方の指標を整理します。

gpt-4oを選ぶべき場面

  • 高い精度が必須:複雑な推論、専門的な質問への回答、翻訳品質が重要
  • ユーザー体験が最優先:エンドユーザー向けのアプリケーション(回答の質が直結する)
  • 月のAPIコストが許容範囲:月5万円以上の予算がある、または利用が限定的

実例:

  • 医療・法務相談アプリ
  • 高度な文章作成支援ツール
  • プロダクト向けAIアシスタント機能

gpt-4o-miniを選ぶべき場面

  • 定型的なタスク:分類、要約、簡易なコーディング補助
  • 大量の自動処理が必要:データ処理、バッチ処理、社内ツール
  • コスト最優先:スタートアップやサイドプロジェクト
  • 精度の低下が許容できる:間違いがあっても修正可能な業務

実例:

  • チャットボット(簡易問答)
  • テキスト分類・タグ付けシステム
  • 社内ドキュメント要約ツール
  • Webスクレイピング後のデータ整形

実際には、ハイブリッド戦略も有効です。複雑なリクエストはgpt-4oで処理し、簡単な質問はgpt-4o-miniで処理するなど、タスクの難度に応じて使い分けることで、コストと品質のバランスを取ることができます。

APIコストの予測と監視の方法

開発段階での予測:tiktokenによるトークン数計算

OpenAIが公開しているPythonライブラリ「tiktoken」を使うと、APIを呼び出す前にローカルでトークン数を即座に計算できます。まずは必要なライブラリをインストールします。

pip install openai tiktoken

動作確認済みバージョン:

  • openai: 1.0以上(推奨 1.3以上)
  • tiktoken: 0.5以上

基本的なトークン数計算:

import tiktoken

# モデルのエンコーディングを取得
encoding = tiktoken.encoding_for_model("gpt-4o")

# テキストをトークン化
text = "これはテストのテキストです。ChatGPT APIを使用しています。"
tokens = encoding.encode(text)

# トークン数を取得
token_count = len(tokens)
print(f"トークン数: {token_count}")

このコードはローカルで実行でき、計算速度も非常に高速なため、リアルタイムで予算チェックができます。

メッセージリスト全体のトークンカウント

Chat Completionsエンドポイント(複数の会話メッセージを送信する場合)では、メッセージ自体だけでなく、OpenAIが追加するオーバーヘッド(システムプロンプトやメタデータ)も含めてカウントする必要があります。

import tiktoken

def count_messages_tokens(messages, model="gpt-4o"):
    """メッセージリスト全体のトークン数をカウント"""
    encoding = tiktoken.encoding_for_model(model)
    
    # モデルによってオーバーヘッドが異なる
    if model.startswith("gpt-4"):
        tokens_per_message = 3
        tokens_per_name = 1
    else:
        tokens_per_message = 4
        tokens_per_name = -1
    
    num_tokens = 0
    
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    
    num_tokens += 3  # API応答の予約トークン
    return num_tokens

# 使用例
messages = [
    {"role": "system", "content": "あなたは有能なアシスタントです。"},
    {"role": "user", "content": "PythonでAPIを使う方法を教えてください。"}
]

token_count = count_messages_tokens(messages, model="gpt-4o")
print(f"メッセージ全体のトークン数: {token_count}")

コスト計算の実装

単にトークン数を知るだけでなく、実際の料金を計算する仕組みも用意しておくと便利です。料金は定期的に更新されるため、アプリケーション内に料金テーブルとして管理します:

import tiktoken
from typing import Dict

# ChatGPT API料金(1M トークンあたりの価格、USD)
PRICING = {
    "gpt-4o": {
        "input": 0.005,
        "output": 0.015
    },
    "gpt-4o-mini": {
        "input": 0.00015,
        "output": 0.0006
    }
}

def estimate_cost(
    model: str,
    prompt_text: str,
    estimated_output_tokens: int = 500
) -> Dict[str, float]:
    """
    APIリクエストの予想コストを計算
    """
    encoding = tiktoken.encoding_for_model(model)
    prompt_tokens = len(encoding.encode(prompt_text))

    pricing = PRICING.get(model)
    if not pricing:
        raise ValueError(f"不明なモデル: {model}")

    input_cost = (prompt_tokens / 1_000_000) * pricing["input"]
    output_cost = (estimated_output_tokens / 1_000_000) * pricing["output"]
    total_cost = input_cost + output_cost

    return {
        "model": model,
        "prompt_tokens": prompt_tokens,
        "estimated_output_tokens": estimated_output_tokens,
        "estimated_input_cost": round(input_cost, 6),
        "estimated_output_cost": round(output_cost, 6),
        "estimated_total_cost": round(total_cost, 6),
        "currency": "USD"
    }

# 使用例
prompt = "次のテキストを日本語で要約してください:" + "A" * 5000
cost_estimate = estimate_cost("gpt-4o", prompt, estimated_output_tokens=200)

print(f"モデル: {cost_estimate['model']}")
print(f"入力トークン: {cost_estimate['prompt_tokens']}")
print(f"予想出力トークン: {cost_estimate['estimated_output_tokens']}")
print(f"予想総コスト: ${cost_estimate['estimated_total_cost']}")

本番環境での監視

OpenAIダッシュボード(https://platform.openai.com/account/billing/overview)では、リアルタイムの利用状況と費用が表示されます。毎週チェックして「想定より使ってないか、多いか」を確認しましょう。思わぬ大量リクエストや無限ループで月10万円超になっていた、という話も聞きます。

Python SDKを使う場合、以下のような形でAPIコールの結果を記録し、使用量を追跡できます:

from openai import OpenAI

client = OpenAI(api_key="your-api-key")

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "こんにちは"}
    ]
)

# トークン数と推定コストを取得
input_tokens = response.usage.prompt_tokens
output_tokens = response.usage.completion_tokens

print(f"入力: {input_tokens}トークン")
print(f"出力: {output_tokens}トークン")

# 推定コスト(gpt-4oの場合)
estimated_cost = (input_tokens / 1_000_000 * 0.005) + (output_tokens / 1_000_000 * 0.015)
print(f"このコール: ${estimated_cost:.6f}")

このログを集計して、週単位・月単位で費用を追跡するのが良い習慣です。

JavaScriptを使う場合:

import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "こんにちは" }]
});

const inputTokens = response.usage.prompt_tokens;
const outputTokens = response.usage.completion_tokens;

console.log(`入力: ${inputTokens}トークン`);
console.log(`出力: ${outputTokens}トークン`);

// 推定コスト(gpt-4oの場合)
const estimatedCost = (inputTokens / 1_000_000 * 0.005) + (outputTokens / 1_000_000 * 0.015);
console.log(`このコール: $${estimatedCost.toFixed(6)}`);

自律型予算ゲートの構築

大規模な自動処理では、単なるコスト計算ではなく、予算を超えたらリクエストを自動的に停止する仕組みが有効です。

from datetime import datetime
from typing import Tuple

class BudgetGate:
    """APIコストの予算管理と自動停止機能を提供する"""

    def __init__(self, daily_budget_usd: float, monthly_budget_usd: float):
        self.daily_budget = daily_budget_usd
        self.monthly_budget = monthly_budget_usd
        self.daily_spent = 0.0
        self.monthly_spent = 0.0
        self.day_started = datetime.now().date()
        self.month_started = datetime.now().replace(day=1).date()

    def check_budget(self, cost: float) -> Tuple[bool, str]:
        """リクエストの実行が予算内かどうかをチェック"""
        current_date = datetime.now().date()
        if current_date > self.day_started:
            self.daily_spent = 0.0
            self.day_started = current_date

        current_month_start = datetime.now().replace(day=1).date()
        if current_month_start > self.month_started:
            self.monthly_spent = 0.0
            self.month_started = current_month_start

        if self.daily_spent + cost > self.daily_budget:
            return False, f"日次予算超過: {self.daily_spent:.4f} + {cost:.4f} > {self.daily_budget}"

        if self.monthly_spent + cost > self.monthly_budget:
            return False, f"月次予算超過: {self.monthly_spent:.4f} + {cost:.4f} > {self.monthly_budget}"

        return True, "予算内。実行可能"

    def record_cost(self, cost: float):
        """コスト実績を記録"""
        self.daily_spent += cost
        self.monthly_spent += cost

    def get_status(self) -> Dict:
        """現在の予算状況を取得"""
        return {
            "daily_spent": round(self.daily_spent, 4),
            "daily_budget": self.daily_budget,
            "daily_remaining": round(self.daily_budget - self.daily_spent, 4),
            "monthly_spent": round(self.monthly_spent, 4),
            "monthly_budget": self.monthly_budget,
            "monthly_remaining": round(self.monthly_budget - self.monthly_spent, 4),
        }

# 使用例
budget_gate = BudgetGate(daily_budget_usd=50.0, monthly_budget_usd=1000.0)

cost = 0.15
can_execute, message = budget_gate.check_budget(cost)

if can_execute:
    print(f"リクエスト実行: {message}")
    budget_gate.record_cost(cost)
else:
    print(f"リクエスト中止: {message}")

print(budget_gate.get_status())

この自律型ゲートにより、予算を超えるリスクなく大規模処理を自動実行できます。

コスト削減の実践的なコツ

1. プロンプトの最適化

余計な説明を削ぎ落とし、必要最小限の入力で目的の出力を得る工夫は、トークン数削減に直結します。

悪い例

あなたはプロの翻訳者です。これからお願いする英文を正確に、かつ自然な日本語に訳してください。
標準的な日本語を使い、ビジネス文書的な雰囲気を保ってください。
意訳ではなく直訳に近い形が理想です。

以下のテキストを訳してください:
Hello, this is a test message.

良い例

以下の英文を日本語に訳してください:
Hello, this is a test message.

前者はシステムプロンプト的な説明が多く、不要なトークンを浪費しています。後者は簡潔ですが、多くのタスクでは十分です。

2. 回答形式の指定で無駄を削減

APIに「JSON形式で返してください」「100文字以内で」と指定すると、出力トークンを抑制できます。

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {
            "role": "user",
            "content": """
以下のテキストを分類してください。カテゴリーは「ニュース」「Q&A」「商品レビュー」のいずれかです。
JSON形式で、キー「category」に分類結果を返してください。

テキスト:「このスマートウォッチ、バッテリーが3日持つので気に入ってます」
""".strip()
        }
    ]
)

こうすることで、APIは余計な前置きなく、必要なJSON部分だけを返す傾向が強まります。

3. キャッシング(Context Caching)の活用

gpt-4o・gpt-4o-miniでは「Context Caching」という仕組みが利用できます。これは、同じシステムプロンプトや参考資料を何度も送信する場合、一度キャッシュしておいて、2回目以降の費用を削減する機能です。

詳細はOpenAI公式ドキュメント(https://platform.openai.com/docs/api-reference/chat/create)を参照してください。

4. バッチ処理APIの活用

複数のリクエストをまとめて送信する「バッチ処理API」を使うと、通常の半額で実行できます(ただし数時間の遅延が発生)。リアルタイムが必要ないバックグラウンドタスク(ログ分析、定期レポート生成など)はバッチAPIで実行するのが効率的です。

大量テキストをバッチ処理しつつ予算を監視する実装例:

def batch_process_with_cost_limit(
    texts: list,
    budget_gate: BudgetGate,
    model: str = "gpt-4o-mini",
    max_tokens_per_request: int = 4000
) -> list:
    """複数テキストをバッチで処理し、予算を監視"""
    encoding = tiktoken.encoding_for_model(model)
    batches = []
    current_batch = []
    current_tokens = 0

    for text in texts:
        tokens = len(encoding.encode(text))
        if current_tokens + tokens > max_tokens_per_request:
            batches.append(current_batch)
            current_batch = [text]
            current_tokens = tokens
        else:
            current_batch.append(text)
            current_tokens += tokens

    if current_batch:
        batches.append(current_batch)

    results = []
    for batch_idx, batch in enumerate(batches):
        batch_text = "\n---\n".join(batch)
        cost_info = estimate_cost(model, batch_text, estimated_output_tokens=200)

        can_execute, message = budget_gate.check_budget(cost_info["estimated_total_cost"])

        if can_execute:
            print(f"バッチ {batch_idx + 1}: {message} (${cost_info['estimated_total_cost']:.6f})")
            budget_gate.record_cost(cost_info["estimated_total_cost"])
            results.append({"batch": batch, "cost": cost_info})
        else:
            print(f"バッチ {batch_idx + 1}: {message}")
            break

    return results

5. 複数モデルのコスト比較で最適選択

複数のモデル候補を事前に比較し、最もコスト効率の良い選択肢を選ぶアプローチも有効です。

def compare_models(
    prompt_text: str,
    estimated_output_tokens: int = 500,
    candidate_models: list = None
) -> list:
    """複数のモデルでコストを比較し、最適なモデルを提案"""
    if candidate_models is None:
        candidate_models = ["gpt-4o-mini", "gpt-4o"]

    results = []
    for model in candidate_models:
        try:
            cost_info = estimate_cost(model, prompt_text, estimated_output_tokens)
            results.append(cost_info)
        except ValueError:
            continue

    results.sort(key=lambda x: x["estimated_total_cost"])
    return results

# 使用例
prompt = "Webページの内容を解析して、SEOの問題点を指摘してください。" + "A" * 2000
comparisons = compare_models(prompt, estimated_output_tokens=300)

print("モデル別コスト比較(安い順):")
for i, model_cost in enumerate(comparisons, 1):
    print(f"{i}. {model_cost['model']}: ${model_cost['estimated_total_cost']:.6f}")

つまずきやすいポイントと解決策

「思ったより料金が高かった」

原因

  • システムプロンプトの使い回し:毎回、同じシステムプロンプトを送っている(Context Cachingを使わない)
  • 無限ループ:バグで同じリクエストを何度も送信している
  • 長いコンテキスト:会話履歴をずっと保持したまま、新しいメッセージを送っている

解決策

  • OpenAIダッシュボードで「API利用状況」を日別に確認し、スパイク日の詳細を調べる
  • ログに全APIコールを記録し、1日あたりのコール数・平均トークン数を集計する
  • 異常なコール数があれば、該当時間帯のエラーログと照合する

「『Maximum context length』エラーが発生する」

原因: 入力テキストとAPIの最大トークン数の合計が、モデルの上限を超えている可能性があります。

対処法:

  • モデルの最大トークン数を確認してください。gpt-4oは128,000トークン、gpt-4o-miniは128,000トークンなどモデルにより異なります
  • count_messages_tokens()関数を使用して、事前にトークン数を確認します
  • 制限を超える場合は、テキストを分割して複数回のAPIコールに分けます
def split_text_by_tokens(text, max_tokens=1000, model="gpt-4o"):
    """テキストをトークン数で分割"""
    encoding = tiktoken.encoding_for_model(model)
    tokens = encoding.encode(text)
    
    chunks = []
    current_chunk = []
    current_token_count

---

## あわせて読みたい

- [Claude OpusとSonnetを1つのAPIで連携させる方法|コスト削減&高速化](/code/two-models-collaborate-single-api-call/)
- [Claude API月2ドルで使う方法|curl代理サーバー構築【3ステップ】](/code/claude-api-proxy-server-curl-guide/)
- [Claude Codeのトークン削減方法【94%コスト削減の5ステップ】](/code/token-reduction-with-claude-code-94-cost-savings-guide/)

参考ソース