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?

「LLMの利用額は高くなっており、今後も高騰していく」という見解は正しいんだろうか?

0
Last updated at Posted at 2026-10-06

最新(2026年10月現在)の LLM 料金

GPT-6 Astra の登場

2026年9月3日、OpenAIは高性能モデル「GPT‑6 Astra」を公開した。API料金は、入力100万トークン当たり10ドル、出力は50ドル。初代GPT‑5の1.25ドル/10ドルから見ると、大幅な値上がりですね。高度な推論には計算資源が必要で、長い入力や高速処理には追加料金もある。昨今のメガテックのAI投資額の増加とその回収モデルを考えると、LLMの利用料金は今後ますます高くなる――そう考えたくなる価格表である。

モデル API公開日 入力 出力
初代GPT‑5 2025年8月7日 $1.25 $10
GPT‑6 Astra 2026年9月3日 $10 $50
単価の倍率 — 8倍 5倍

ちなみに、Anthropic の Fable 5.1のトークン単価もGPT‑6 Astraと同じ$10/$50です。

image.png

今後、LLM の利用料金は高騰を続け、今までのように気軽には使えなくなるんでしょうか。。。

トークン単価が上がると、実際に使用する費用も上がるのか?

GPT-5.6 の単価ってどうなってるんだっけ?

同じモデル 発売時:入力/出力 値下げ後:入力/出力 値下げ日
GPT‑5.6 Luna $1/$6 $0.20/$1.20 2026年7月30日
GPT‑5.6 Terra $2.50/$15 $2/$12 2026年7月30日
GPT‑5.6 Sol $5/$30 $4/$20 2026年8月21日

GPT-5.6 Solの$4/$20は少なくとも2026年11月21日までのプロモーション価格

うん。こちらも、2026年7月9日のリリース後、段々と値段が上がっていき。。。ではなく、7/30, 8/21 に値下げされています!

同じ精度でタスクを終える費用は下がっている

新しいモデルが発表されると、前のモデルとの価格差だけを考えると「値段が高くなっている」と思いがちですが、実際には、同じ精度のモデルは単価が減少傾向にあるようです。

Epoch AIの2026年の分析は、数学や科学などの問題で一定の正答水準を達成する費用を比較し、2023年以降、平均で四半期ごとに約47%下がったと推計しています。これは「同じ程度の能力を使うための価格」が長期的に下がってきたことを示すデータです

比較したいのは「成功1件当たりの費用」

たとえば、同じ種類の依頼を100件処理するとします。

モデル API利用料の合計 品質基準を満たした件数 成功1件当たり
A $10 40件 $0.25
B $20 90件 約$0.22

この仮の例では、モデルBの利用料は2倍でも、成功1件当たりの費用は低くなります。実務ではさらに、再試行、検索などのツール利用、人による確認・修正の費用も加えて比べる必要があります。「正しい解答を1件得る期待費用」を扱う Cost-of-Pass という研究もあります。
出典:Cost-of-Pass

実験

「タスクを実施するための費用」という観点で実験する方法はいくつか考えられますが、今回は、ある文章を理解させ特定の「正解」を導き出せるかという問題を各モデルに実行させて、その精度(正解数)を検証してみます。

プロンプト

    "文章中の最終的な支払期限だけをYYYY-MM-DD形式で答える。"
    "以前の期限が訂正されていたら訂正後の日付を答える。"
    "条件が書かれている場合は、実際に成立した条件を適用する。"
    "『N日後』『N日前』の日数は暦日で数える。"
    "日付以外の説明や記号は出力しない。"

問題集(一部抜粋)

難易度毎にカテゴリ化しておいて、文章から「支払期限」を回答させます。

id,difficulty,category,text,gold
E01,easy,direct,請求書Aの支払期限は2026年10月10日です。,2026-10-10
E02,easy,direct,2026年11月分の請求書Bについて、支払期限を2026年12月5日とします。,2026-12-05
R01,medium,revision,請求書Aの支払期限は2026年10月10日でしたが、2026年10月15日に変更しました。,2026-10-15
R02,medium,revision,先ほどの「2026年11月1日が支払期限」という案内は誤りです。正しくは2026年11月8日です。,2026-11-08
R07,hard,revision,旧契約書では請求書Fの支払期限は2026年8月31日。2026年8月3日に締結した新契約書では9月7日です。新契約書が優先します。,2026-09-07
R08,hard,revision,2026年6月25日付メールで支払期限を7月15日と伝えました。翌日の訂正メールで7月12日としました。訂正メールの内容が確定しています。,2026-07-12

問題集1

検証コード

"""Evaluate payment-deadline extraction accuracy by model and difficulty.

Run API evaluation:
    python evaluate_cases.py --models gpt-5 gpt-6-luna --repeats 1

Recalculate a saved result without API calls:
    python evaluate_cases.py --summarize results.csv
"""

from __future__ import annotations

import argparse
import csv
import os
from collections import defaultdict
from pathlib import Path


HERE = Path(__file__).resolve().parent
DEFAULT_CASES = HERE / "cases.csv"
DEFAULT_RESULTS = HERE / "results.csv"
FIELDNAMES = [
    "id", "difficulty", "category", "model", "trial", "gold", "answer",
    "correct", "status", "input_tokens", "output_tokens",
]
DIFFICULTIES = ("easy", "medium", "hard")
INSTRUCTIONS = (
    "文章中の最終的な支払期限だけをYYYY-MM-DD形式で答える。"
    "以前の期限が訂正されていたら訂正後の日付を答える。"
    "条件が書かれている場合は、実際に成立した条件を適用する。"
    "『N日後』『N日前』の日数は暦日で数える。"
    "日付以外の説明や記号は出力しない。"
)


def read_cases(path: Path) -> list[dict[str, str]]:
    with path.open(encoding="utf-8-sig", newline="") as file:
        rows = list(csv.DictReader(file))
    required = {"id", "difficulty", "category", "text", "gold"}
    if not rows or not required.issubset(rows[0]):
        raise ValueError(f"{path} must have columns: {', '.join(sorted(required))}")
    ids: set[str] = set()
    for row in rows:
        if row["id"] in ids:
            raise ValueError(f"Duplicate case id: {row['id']}")
        if row["difficulty"] not in DIFFICULTIES:
            raise ValueError(f"Unknown difficulty for {row['id']}: {row['difficulty']}")
        ids.add(row["id"])
    return rows


def summarize(results_path: Path, cases_path: Path) -> None:
    cases_by_id = {case["id"]: case for case in read_cases(cases_path)}
    stats: dict[tuple[str, str], list[int]] = defaultdict(lambda: [0, 0])
    errors: dict[str, int] = defaultdict(int)

    with results_path.open(encoding="utf-8-sig", newline="") as file:
        reader = csv.DictReader(file)
        if not reader.fieldnames or not set(FIELDNAMES).issubset(reader.fieldnames):
            raise ValueError("Result file has missing columns")
        for row in reader:
            case = cases_by_id.get(row["id"])
            if case is None or row["difficulty"] != case["difficulty"] or row["gold"] != case["gold"]:
                raise ValueError(f"Result does not match cases.csv: {row['id']}")
            if row["status"] not in ("completed", "incomplete"):
                errors[row["model"]] += 1
                continue
            # Recompute correctness from the saved answer, not a stored score.
            correct = int(row["status"] == "completed" and row["answer"] == case["gold"])
            for difficulty in (row["difficulty"], "overall"):
                stats[(row["model"], difficulty)][0] += correct
                stats[(row["model"], difficulty)][1] += 1

    print(f"{'model':<19} {'difficulty':<10} {'correct':>7} {'total':>7} {'accuracy':>9}")
    for model in sorted({model for model, _ in stats}):
        for difficulty in (*DIFFICULTIES, "overall"):
            if (model, difficulty) not in stats:
                continue
            correct, total = stats[(model, difficulty)]
            print(f"{model:<19} {difficulty:<10} {correct:>7} {total:>7} {correct / total:>8.1%}")
    if errors:
        print("API error rows excluded from accuracy: " + ", ".join(f"{m}={n}" for m, n in sorted(errors.items())))


def run_evaluation(args: argparse.Namespace) -> None:
    if not os.environ.get("OPENAI_API_KEY"):
        raise RuntimeError("Set OPENAI_API_KEY before running API evaluation")
    if args.results.exists() and not args.overwrite:
        raise FileExistsError(f"{args.results} already exists; pass --overwrite to replace it")

    # Import only in API mode so --summarize works without installing the SDK.
    from openai import OpenAI

    cases = read_cases(args.cases)
    if args.limit_per_difficulty is not None:
        picked = defaultdict(int)
        sampled = []
        for case in cases:
            difficulty = case["difficulty"]
            if picked[difficulty] < args.limit_per_difficulty:
                sampled.append(case)
                picked[difficulty] += 1
        cases = sampled
    args.results.parent.mkdir(parents=True, exist_ok=True)

    client = OpenAI(
        api_key=os.environ.get("OPENGATEWAY_API_KEY"),
        base_url="https://apis.opengateway.ai/v1"
    )

    with args.results.open("w", encoding="utf-8-sig", newline="") as file:
        writer = csv.DictWriter(file, fieldnames=FIELDNAMES)
        writer.writeheader()
        for model in args.models:
            for trial in range(1, args.repeats + 1):
                for case in cases:
                    try:
                        response = client.responses.create(
                            model=model,
                            reasoning={"effort": "low"},
                            instructions=INSTRUCTIONS,
                            input=case["text"],
                            max_output_tokens=1024,
                        )
                    except Exception as exc:
                        writer.writerow({
                            "id": case["id"], "difficulty": case["difficulty"],
                            "category": case["category"], "model": model,
                            "trial": trial, "gold": case["gold"],
                            "status": f"api_error:{type(exc).__name__}",
                        })
                        file.flush()
                        raise RuntimeError(f"API call failed for {model} / {case['id']}; partial results saved") from exc

                    answer = (response.output_text or "").strip() if response.status == "completed" else ""
                    usage = response.usage
                    writer.writerow({
                        "id": case["id"], "difficulty": case["difficulty"],
                        "category": case["category"], "model": model,
                        "trial": trial, "gold": case["gold"], "answer": answer,
                        "correct": int(response.status == "completed" and answer == case["gold"]),
                        "status": response.status,
                        "input_tokens": usage.input_tokens if usage else "",
                        "output_tokens": usage.output_tokens if usage else "",
                    })
                    file.flush()
    summarize(args.results, args.cases)


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--cases", type=Path, default=DEFAULT_CASES)
    parser.add_argument("--results", type=Path, default=DEFAULT_RESULTS)
    parser.add_argument("--summarize", type=Path, help="Summarize a saved result CSV without API calls")
    parser.add_argument("--models", nargs="+", default=["openai/gpt-5", "openai/gpt-6-astra", "openai/gpt-6-sol", "openai/gpt-6-luna"])
    parser.add_argument("--repeats", type=int, default=1)
    parser.add_argument("--limit-per-difficulty", type=int, help="Evaluate at most N cases from each difficulty for a pilot run")
    parser.add_argument("--overwrite", action="store_true")
    args = parser.parse_args()
    if args.repeats < 1 or (args.limit_per_difficulty is not None and args.limit_per_difficulty < 1):
        parser.error("--repeats and --limit-per-difficulty must be positive")
    if args.summarize:
        summarize(args.summarize, args.cases)
    else:
        run_evaluation(args)


if __name__ == "__main__":
    main()

今回、モデル毎の比較を行うため、弊社のルーティングサービスである OpenGateway を使用しています。

結果

上記のテストを o4-mini, gpt5.4-mini, gpt5.6-luna で実施してみます。

結果としては、すべてのモデル誤答は無く、

model               difficulty correct   total  accuracy
openai/o4-mini      easy             8       8   100.0%
openai/o4-mini      medium          18      18   100.0%
openai/o4-mini      hard            24      24   100.0%
openai/o4-mini      overall         50      50   100.0%
openai/gpt-5.4-mini easy             8       8   100.0%
openai/gpt-5.4-mini medium          18      18   100.0%
openai/gpt-5.4-mini hard            24      24   100.0%
openai/gpt-5.4-mini overall         50      50   100.0%
openai/gpt-5.6-luna easy             8       8   100.0%
openai/gpt-5.6-luna medium          18      18   100.0%
openai/gpt-5.6-luna hard            24      24   100.0%
openai/gpt-5.6-luna overall         50      50   100.0%

という回答になります。

この状況で、input/output の token からコストを算出します。

モデル 正答 入力トークン 出力トークン 入力費用 出力費用 合計費用
o4-mini 50/50 6,912 7,106 $0.0076032 $0.0312664 $0.0388696
GPT-5.4 mini 50/50 6,912 2,616 $0.0051840 $0.0117720 $0.0169560
GPT-5.6 Luna 50/50 6,912 721 $0.0013824 $0.0008652 $0.0022476

まず、o4-mini を試してみます。o4-miniは OpenAI が 2025年4月16日にリリースした推論したモデルです。

model               difficulty correct   total  accuracy
openai/o4-mini      easy             8       8   100.0%
openai/o4-mini      medium          18      18   100.0%
openai/o4-mini      hard            51      52    98.1%
openai/o4-mini      overall         77      78    98.7%

そもそも、モデルの version は上がっていくにつれ、現時点(2026年10月)時点での単価が下がっているので、ある程度 新しいモデルの方がトータルコスト安い ことを想定していましたが、出力トークンの低下もあり、新しいモデルの方の費用がお安くなっていました。

掲題の「LLMの利用額は高くなっており、今後も高騰していく」という見解は正しいんだろうか?」を否定してやろうと調べ締め増したが、出力トークンがここまで下がるとは思っていませんでしたので、新たな気づきとなりました。

ちなみに、現時点(2026年10月時点)でのコストは以下です。

モデル 入力 出力
o4-mini $1.10 $4.40
GPT-5.4 mini $0.75 $4.50
GPT-5.6 Luna $0.20 $1.20

そもそものコストが下がったことと出力トークンが減ることを主な原因として、より新しいモデルの方が費用が下がっているという結果になりました。

そして、ふと、本当の最新のモデル(GPT-6 Astra 入力 $10, 出力 $50)だと使用するトークン数が下がって、あまり変わらない値段になったりして、、、とか思ったんですが、

モデル 正答 入力トークン 出力トークン 50問の計算額
GPT-6 Astra 50/50 6,912 571 $0.0976700

さすがに、Astra だと割高ですね。

回答精度

今回、割と簡単な推論のテストケースのみですべてのモデルが100%正解してしまうので回答精度が見えていないという状況です。
少し難しいかもしれないケースを追加して、モデルごとの精度を見てみると

モデル easy medium hard 正答数 誤答数 正答率
o4-mini 8/8 18/18 50/52 76/78 2 97.4%
GPT-5.4 mini 8/8 18/18 50/52 76/78 2 97.4%
GPT-5.6 Luna 8/8 18/18 52/52 78/78 0 100%

となり、もはや、この3つのモデルの比較だと GPT-5.6 Luna 一択(安くて正しい)となってしまいました。

問題集2

ちなみに、それぞれ間違っていたのは

  • o4-mini
問 : 請求書の基準日は2026-12-30。契約条項は『基準日の4営業日後が支払期限』。営業日は月〜金で、追加休業日は2026-12-31、2027-01-01、2027-01-04。起算日は数えず、土日と記載された追加休業日は数えない。記載のない祝日は考慮しない。最終的な支払期限は?
正解 : 2027-01-08
問 : 請求書の基準日は2026-05-01。契約条項は『基準日の5営業日後が支払期限』。営業日は月〜金で、追加休業日は2026-05-04、2026-05-05、2026-05-06。起算日は数えず、土日と記載された追加休業日は数えない。記載のない祝日は考慮しない。最終的な支払期限は?
正解 : 2026-05-13
  • GPT-5.4 mini
問 : 請求書の基準日は2028-12-28。契約条項は『基準日の5営業日後が支払期限』。営業日は月〜金で、追加休業日は2028-12-29、2029-01-01、2029-01-02、2029-01-03。起算日は数えず、土日と記載された追加休業日は数えない。記載のない祝日は考慮しない。最終的な支払期限は?
正解 : 2029-01-10
問 : 請求書の基準日は2028-03-24。契約条項は『基準日の13営業日後が支払期限』。営業日は月〜金で、追加休業日は2028-03-27、2028-04-03、2028-04-07。起算日は数えず、土日と記載された追加休業日は数えない。記載のない祝日は考慮しない。最終的な支払期限は?
正解 : 2028-04-17

です。

ただし、o4-miniとGPT-5.4 mini が誤答するのはいつも同じテストケースではなく、実行毎に同じテストケースでも正解になったり誤答になったりします。

gpt-5.6-luna に関しては3やって3回とも100%です。

この結果からも、この条件においては、 gpt-5.6 が精度・コストの面からもこれ一択という状況です。

結論

今回のケースで調べた限りでは、LLMの値段が上がっているのは、前のモデルよりも高機能になっているために価格が上がっているだけで、「同じタスクを同等以上の精度で実施する前提」では、むしろ利用額が下がっていると言ってしまってよいのではないでしょうか。

言うまでもなく、「特定の使用方法」に対しても同じことが言えるかどうかを判断するには、旧モデルと新モデルに同じタスク群を実行させ、品質基準を固定し「成功1件当たりの総費用」を測るということが必要になります。

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?