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?

AI問い合わせ対応の費用をどう見積もるか:API料金とレビュー工数の境界

0
Posted at

AI問い合わせ対応の費用設計のアイキャッチ

2026-10-13時点の公開料金を確認し、問い合わせAIの月次費用を架空条件で計算した設計検討です。確認したのはローカルの計算ロジックで、実LLMの品質・応答時間・実業務の削減効果は未検証です。

結論:API単価より先に、レビューを含む処理経路を決める

AIが回答の下書きを作っても、人が根拠を読み直し、修正してから送るなら、その時間は残ります。費用を比較する単位は「1回のAPI呼び出し」より、「問い合わせ1件を同じ完了条件まで処理する費用」です。

開発担当・テックリードが判断したいのは、AI下書きを試すか、FAQ改善や有人対応を続けるかです。この記事では、API料金・レビュー・有人対応・保守を分けて再計算します。

判断 条件
限定したPoCへ進む 回答品質の基準を先に決め、確認・修正を含む工数を測れる。費用に余裕があり、保守担当がいる
いったん見送る レビュー費だけで比較基準を超える、あるいは知識の更新・誤回答の対応担当を置けない
追加検証する APIのusageは取れるが、レビュー時間・有人への戻り・再生成回数が未測定

安価なモデルへの変更だけで導入を決めると、修正時間の増加を見落とします。品質条件を満たさない方式は、費用比較の候補から外します。

前提:AI下書きと、最初から人が対応する経路を分ける

以下はすべて架空の計画値です。問い合わせ本文や業務データは使っていません。

項目 仮定
月間問い合わせ 1,000件
比較基準 全件を人が対応し、1件6分で確認・修正・送信まで完了
工数の評価単価 3,000円/時間
AI下書きの対象 70%=700件。全件を人がレビューして送信
最初から有人へ回す対象 30%=300件、各6分。LLMを呼ぶ前に既存の受付ルールで振り分ける仮定
AI下書きのレビュー 基本ケースは1件2分。根拠確認・修正・送信までを含む
維持・評価・障害対応 月12時間×3,000円=36,000円
追加基盤費 月5,000円
初期構築費の比較上の配賦 120,000円÷12か月=月10,000円
為替の計算条件 1 USD=150円。市場の為替レートではない仮定

既存の受付基盤など両方式に共通する費用は比較から除き、AI方式の追加費用を計上します。税、検索・埋め込み・外部ツールの課金、学習費、誤回答による損失、移行・撤退費は別途見積もる項目です。

この工数価値の差は、そのまま支出削減や現金利益にはなりません。 固定給の担当者の時間が空く場合、実支出より対応可能な仕事量が変わることがあります。初期構築費も、12か月への配賦とは別に、支払い時点の資金負担を確認します。

700件へのレビュー費と300件への有人対応費は、別の集団に対する費用です。AI下書きを読んだ後で全面的に人へ戻るケースがあるなら、その件にはレビュー費と追加の有人対応費の両方が発生します。今回の簡易モデルにはその戻りを入れていないため、実測時に追加が必要です。

選択肢:現状維持・FAQ改善・既製品も同じ完了条件で比較する

方式 主に測る費用 採用を検討する条件 採用しない条件
有人対応を維持 処理件数×完了までの時間 件数が少なく、問い合わせの変化が大きい 応対の滞留が増え、担当を増やせない
FAQと検索を改善 知識整備・検索運用・残る有人対応 既存の定型回答で解決できる 検索だけでは必要な条件を説明できない
既製品のAI下書き 契約・従量・設定・レビュー・移行 権限・ログ・引き継ぎが要件を満たす 必須の運用条件を満たさない、追加費用が不明
自作のAI下書き 推論・レビュー・基盤・品質評価・保守 独自の品質ゲートが必要で、維持担当がいる API料金だけを根拠に安いと判断している

表は選択肢を整理する設計案です。今回、FAQや既製品の価格・品質は比較実験していません。それらを数値上の勝者・敗者にはせず、同じ問い集合と完了条件で次に比較します。

料金の根拠と、再試行を含む計算式

料金式の例にはClaude Sonnet 5.5の通常の入力・出力料金を使います。2026-10-13に確認した公式表では、100万トークンあたり入力2 USD、出力10 USDです。今回はキャッシュなし・追加ツール課金なしの条件です。品質・遅延・この用途への適性は未評価です。Claude公式料金表

実運用では請求対象となった各試行のusageを合計します。キャッシュなど別の料金区分を使う場合は、その区分を分けて単価を適用します。文字数をトークン数に置き換えたり、最終的に成功した1回だけを数えたりしません。

LLM費用(USD)= Σ(各試行の入力tokens×入力単価
                       +各試行の出力tokens×出力単価)÷1,000,000

月次総費用(円)= LLM費用×為替の計算条件
                  +AI対象件数×レビュー分÷60×工数単価
                  +有人対象件数×有人対応分÷60×工数単価
                  +維持工数費+追加基盤費+初期費の月次配賦

試算では各試行のトークン量が同じと仮定し、合計を「AI対象件数×平均課金対象試行数×1試行の料金」で近似します。基本ケースは入力2,000・出力300トークン、平均試行数1.1です。1.1は初回を含む試行数で、初回に1.1回の再試行を加える意味ではありません。 700件なら770回相当です。これらは実usageや再試行の実測値ではありません。

キャッシュの読み書きやツール利用には別の料金区分があるため、同じ式の入力単価だけを機械的に差し替えないでください。契約経路と利用機能に合わせて確認します。Claude公式料金表

ローカル検証:API料金とレビュー時間を別々に動かす

Pythonの標準ライブラリdecimalを使い、APIに接続せず計算しました。入力値の単位を固定し、負値・非有限値、対象率や平均試行数などの不正値を拒否します。計算例の対象は掲載した条件の桁数です。極端に巨大・微小な値は対象外で、decimal.Overflow等が発生する場合があります。計算精度は28桁とし、金額表示を小数点以下2桁へ整えるのは表示時だけです。

実行手順は、以下のコードをcost_example.pyへ保存してpython3 cost_example.pyです。送信や課金は発生しません。

from decimal import Decimal as D, InvalidOperation, localcontext

FIXTURE = {
    "n": 1000, "ai_share": "0.7", "review_minutes": "2",
    "handling_minutes": "6", "manual_minutes": "6",
    "billed_attempts": "1.1", "input_tokens": "2000", "output_tokens": "300",
    "input_usd_mtok": "2", "output_usd_mtok": "10",
    "usd_jpy": "150", "labor_jpy_hour": "3000",
    "ops_hours": "12", "infra_jpy": "5000", "build_jpy": "120000",
    "amort_months": "12",
}

DECIMAL_FIELDS = tuple(key for key in FIXTURE if key != "n")

def nonnegative_decimal(name, value):
    if isinstance(value, bool):
        raise ValueError(f"{name}: bool is not a number")
    try:
        number = D(str(value))
    except (InvalidOperation, ValueError):
        raise ValueError(f"{name}: decimal required") from None
    if not number.is_finite() or number < 0:
        raise ValueError(f"{name}: finite nonnegative value required")
    return number

def calculate_cost(params):
    """初回を含む課金回数。事前分岐した人間対応とAIレビューは重複しない。"""
    n = params["n"]
    if type(n) is not int or n < 0:
        raise ValueError("n: nonnegative integer required (excluding bool)")
    p = {key: nonnegative_decimal(key, params[key]) for key in DECIMAL_FIELDS}
    if p["ai_share"] > 1 or p["billed_attempts"] < 1:
        raise ValueError("ai_share must be <= 1; billed_attempts must be >= 1")
    if any(p[key] == 0 for key in ("labor_jpy_hour", "usd_jpy", "amort_months")):
        raise ValueError("labor_jpy_hour, usd_jpy, amort_months must be positive")
    with localcontext() as context:
        context.prec = 28
        ai = n * p["ai_share"]
        handoffs = D(n) - ai
        billed = ai * p["billed_attempts"]
        api_usd = billed * (p["input_tokens"] * p["input_usd_mtok"]
                           + p["output_tokens"] * p["output_usd_mtok"]) / D(1_000_000)
        api_jpy = api_usd * p["usd_jpy"]
        labor_per_minute = p["labor_jpy_hour"] / D(60)
        review = ai * p["review_minutes"] * labor_per_minute
        handling = handoffs * p["handling_minutes"] * labor_per_minute
        ops = p["ops_hours"] * p["labor_jpy_hour"]
        amortized = p["build_jpy"] / p["amort_months"]
        fixed = ops + p["infra_jpy"] + amortized
        manual = n * p["manual_minutes"] * labor_per_minute
        budget = manual - handling - fixed - api_jpy
        total = api_jpy + review + handling + fixed
        # 閾値の表示値は丸めを含む。判定はレビュー費用と予算の直接比較。
        threshold = budget / (ai * labor_per_minute) if ai else None
        return {
            "ai_drafts": ai, "handoffs": handoffs, "billed_attempts_total": billed,
            "api_usd": api_usd, "api_jpy": api_jpy,
            "review_jpy": review, "handoff_jpy": handling,
            "ops_jpy": ops, "infra_jpy": p["infra_jpy"],
            "build_amortized_jpy": amortized, "fixed_jpy": fixed,
            "total_jpy": total, "manual_jpy": manual, "savings_jpy": manual - total,
            "review_budget_jpy": budget, "break_even_review_minutes": threshold,
            "saving_positive": review < budget,
        }

long_context = {"input_tokens": "12000", "output_tokens": "800", "billed_attempts": "1.4"}
cases = {
    "base": {},
    "long-2min": long_context,
    "long-4min": {**long_context, "review_minutes": "4"},
    "long-4.5min": {**long_context, "review_minutes": "4.5"},
}
for name, changes in cases.items():
    result = calculate_cost({**FIXTURE, **changes})
    print(f'{name}: API={result["api_jpy"]:.2f}, '
          f'total={result["total_jpy"]:.2f}, '
          f'difference={result["savings_jpy"]:.2f}, '
          f'below_baseline={result["saving_positive"]}')

実行結果:

base: API=808.50, total=211808.50, difference=88191.50, below_baseline=True
long-2min: API=4704.00, total=215704.00, difference=84296.00, below_baseline=True
long-4min: API=4704.00, total=285704.00, difference=14296.00, below_baseline=True
long-4.5min: API=4704.00, total=303204.00, difference=-3204.00, below_baseline=False

検証環境はPython 3.14.3、標準ライブラリのみです。上の掲載コードの出力と比較表を照合しました。別途、正常系、対象0件、AI対象率0・1、不正値、再試行、費用同額・超過、入力の非破壊など167項目の回帰チェックを実行しました。これらは計算式と入力境界の確認であり、実LLMや問い合わせ品質の評価ではありません。

架空条件の計算結果

4ケースともAI対象率70%、有人対応30%、固定費51,000円です。「長文」は入力12,000・出力800トークン、平均課金対象試行数1.4へ変えた条件です。モデルの品質が同等という実験結果を示すものではありません。

ケース LLM費(円) レビュー費(円) 有人対応費(円) 固定費(円) 総費用(円) 有人基準300,000円との差
基本:レビュー2分 808.50 70,000 90,000 51,000 211,808.50 88,191.50円下回る
長文:レビュー2分 4,704 70,000 90,000 51,000 215,704 84,296円下回る
長文:レビュー4分 4,704 140,000 90,000 51,000 285,704 14,296円下回る
長文:レビュー4.5分 4,704 157,500 90,000 51,000 303,204 3,204円上回る

長文化と試行数の増加による差は3,895.50円。一方、長文ケースでレビューが2分から4分へ増える差は70,000円です。この仮定では、APIの入力を削る施策だけより、根拠確認・修正にかかる時間の測定が判断を変えます。

レビュー時間の境界は、予算から逆算できる

長文ケースでレビューに使える比較上の予算は次の値です。

300,000 − 4,704 − 90,000 − 51,000 = 154,296円
レビュー1分増の月次費用 = 700÷60×3,000 = 35,000円
比較基準と等しくなるレビュー分 = 154,296÷35,000
                                  = 約4.408457分/件

「4.41分まで大丈夫」と丸めて運用上限にすると、わずかに比較基準を超えます。判定にはレビュー費<残りの比較予算を使い、時間表示の丸め値は使いません。費用が等しい場合にも、新たな運用リスクに見合う余裕がありません。

この境界は、ここに置いた単価・対象率・保守費などが成立する場合の計算値です。未計上費用や測定誤差を含む余裕を別に設定します。品質ゲートを緩めてレビューを短くする判断には使いません。

本番で費用を増やす失敗と、確認する担当

失敗 必要な測定・制約 判断する担当
FAQ全文や会話履歴を毎回送る 1試行の入力量、必要な根拠の欠落、回答品質を一緒に評価する 検索・アプリ担当
レビューを「承認ボタンの時間」だけで計る 根拠確認、修正、送信、後日の訂正を含む時間を記録する 応対担当・業務責任者
失敗のたびに無制限に再生成する 試行数・出力量・総予算・時間の上限を決める アプリ・運用担当
タイムアウトを無課金と見なす usage未取得を「0円」へ確定せず、結果不明として請求と照合する 運用・費用管理担当
安いモデルへ替えて確認が長くなる 同じ評価セットで品質とレビュー時間を比較する 評価担当・開発責任者
月平均だけ見てピークを隠す 問い合わせ種別ごとの分布、上位の費用・工数、滞留を確認する 業務・運用担当

OWASPは、制御されない推論が資源消費や費用増につながるリスクを示し、入力制限・利用量制限・タイムアウト・監視などを挙げています。これは公式資料で確認できる一般的なリスクです。OWASP LLM10:2025 Unbounded Consumption

その対策として、生成前に予算を予約し、呼び出し後に実usageと照合する設計を検討します。並行実行がある場合は予算予約も排他的に更新し、結果不明分の予約を即座に解放しません。予約だけで実請求の上限を保証できるわけではなく、最大出力やツール呼び出しも制限し、超過を検知したら新規生成を止める必要があります。これは設計案であり、掲載コードは予算制御・並行処理・請求照合を実装していません。

ログには、公開可能な相関ID、モデル・料金確認日、試行番号、課金区分ごとのusage、処理経路、レビュー・追加有人対応の時間、結果不明の状態を分けて残します。問い合わせ本文・秘密情報を費用ログへ一括保存する設計は避けます。

条件付きの推奨と、次に確認すること

この架空条件なら、AI下書き方式を限定PoCで測る余地があります。長文・レビュー4分では差が14,296円まで縮むため、未計上費用を含めて再評価します。4.5分なら、同じ条件のまま費用面から進める理由はありません。FAQ改善や有人対応の改善も比較候補に戻します。

次の検証では、同じ問い合わせ集合を方式ごとに評価し、以下をそろえます。

  • 正しい根拠・回答禁止条件・担当への引き継ぎ条件を、費用計測前に固定する。
  • 試行ごとの実usage、確認・修正・送信までの時間、下書き後の全面有人対応を測る。
  • 検索・埋め込み・契約・監査・移行・撤退など、今回未計上の費用を追加する。
  • 対象率・工数・件数の悪化ケースでも比較基準に余裕があるか確認する。
  • 保守担当、誤回答時の停止判断者、有人対応への切り戻し手順を決める。

費用表は、品質と運用条件を満たした候補を比較するためのものです。実際の問い合わせ品質、レビュー時間、業務効果を確認するまでは、本番導入の根拠として確定させません。

参考資料と検証範囲

公式資料から確認した料金とリスク、架空条件の計算結果、運用の設計案を区別しています。LLM実行、品質比較、実送信、課金、並行する予算予約、実請求照合、本番負荷、継続運用は未検証です。

この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表。AI × Web × 業務自動化の開発・検証に取り組んでいます。
技術選定・品質・運用の判断材料を、検証範囲と制約を示して発信しています。
AI導入や業務自動化の技術選定・設計整理については、対応できる範囲を確認のうえご相談を承ります。

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?