概要
料金表は注記まで読む
出力は入力の 5 倍、思考も出力。キャッシュは 4,096 未満で効かない。導入価格は 12/31 まで。
効果は限界利益で
1 クリック 売上 240 円、会社に残るのは 48 円。ROI 16.4 倍は売上で割った数字。
差でなく信頼区間
2,000 通ずつの +0.5pt は p=0.30。見つけるには 1 群 14,406 通。
比較相手はセグメント案
300 × 4 案なら月 $55。1 対 1 は上積み 0.083pt を回収できるかで決める。
問題
MOps 販促システムチームの後輩が、メールの件名・本文を会員ごとに LLM(Gemini)で生成する稟議を書いた。部長から「数字を見てほしい」と頼まれ、あなたがレビューする。
単価(公式 参照日 2026-10-09 ai.google.dev/gemini-api/docs/pricing、100 万トークンあたり)
| モデル | 入力 | 出力(思考を含む) | キャッシュ済み入力 | 保管 | 備考 |
|---|---|---|---|---|---|
| Gemini 3.8 Flash(〜2026-12-31) | $0.75 | $3.75 | $0.075 | $0.50/時 | 2027-01-01 から全項目が倍 |
| Gemini 2.5 Flash-Lite | $0.10 | $0.40 | $0.01 | $1.00/時 |
制約・前提条件
- バッチは標準の 50%、目標 24 時間 公式。3.x Flash のキャッシュは最小 4,096 トークン 公式
- 実際のプロンプト 仮定: 共通 3,000/会員ごと 700/出力 150/思考 平均 450。検査の差し戻し 12%
- 注文 1 件の限界利益 仮定: 8,000 円 × 30% − クーポン 500 − 配送・決済 300。CVR 3%。文面は前日夜に確定。150 円/$
期待する回答形式: 問題点 8 点/費用と効果を数えるコードとテスト/実行例/推奨案と稟議の書き直し/迷った案と前提が変わったときの判断/扱わなかった範囲
悪い稟議 (Before)
件名: 会員ごとのクーポン訴求文を LLM で生成する(年間 ROI 16.4 倍)
モデル Gemini 3.8 Flash(入力 $0.75/100万)。1 通 = 入力 500+出力 150 = 650 トークン × $0.75 = $0.00049。300 万人 × 月 4 通 = 1,200 万通 → 月 $5,850、年 約 1,053 万円。共通の指示はキャッシュで 90% 引きなので実際はもっと安い。
効果: A/B(2,000 通ずつ)でクリック率 2.1% → 2.6%。1 クリック 240 円の売上 → 月 1,440 万円 → ROI 16.4 倍。11 月から、送信直前にリアルタイム生成。
ヒント(段階的開示)
ヒント1 — 方向性
ヒント2 — アプローチ
- 出力単価は入力の 5 倍。思考トークンも出力として課金
- キャッシュには最小トークン数がある。届かせるために例文を足すと安くなることも
- 文面は前日に決まる → バッチ(50%)
- 比較相手は「セグメント × 数案を一度だけ作る」
- +0.5pt を見つけるのに 1 群何通いるか
ヒント3 — 誘導
1通 = (共通 × 入力orキャッシュ単価 + 会員 × 入力単価 + (出力+思考) × 出力単価) ÷ 100万
× (バッチなら 0.5) × 1/(1 − 差し戻し率)
12か月 = 11・12月は導入価格、1〜10月は倍
1クリックの限界利益 = 3% × (8,000×30% − 500 − 300) = 48円
分岐の上げ幅(pt) = 1通の円 ÷ 48円 × 100問題点分析(8点)
| # | 問題点 | 分類 | 何が起きているか(出所つき) | 改善方法 |
|---|---|---|---|---|
| 1 | 出力を入力単価で数えた | 単価 | 出力は $3.75 で入力の 5 倍 <公式>。150 トークンだけで 1 通の費用が 1.9 倍 | 入力・出力を別単価で |
| 2 | 思考トークンを数えていない | 単価 | 出力単価は思考トークンを含む <公式>。既定の思考量で平均 450 <仮定> | 思考量を最小に。usage_metadata で実数を取る |
| 3 | 入力は会員部分の 500 だけ | 量 | 共通 3,000+会員 700=3,700 <仮定>。7.4 倍 | プロンプト全体をトークン数で測る |
| 4 | 「キャッシュで 90% 引き」が効かない | 単価 | 共通 3,000 は最小 4,096 に届かない <公式>。設定しても月 $94,091(S3') | 例文を足して 4,200 にすると逆に安い(S3 月 $41,321) |
| 5 | 導入価格を 12 か月に伸ばした | 時期 | 3.8 Flash は 2026-12-31 まで。1 月から倍 <公式>。12 か月中 10 か月が倍 | 月ごとにその月の単価で |
| 6 | 作り直しを数えていない | 量 | 差し戻し 12% → 期待試行 1/(1−0.12)=1.136 回 <導出> | 検査は LLM の外。幾何分布で数える |
| 7 | 効果が偶然の範囲で、売上で数えた | 効果 | 2,000 通ずつで p=0.30、95%CI [−0.44, +1.44]pt。1 クリック 売上 240 円 / 限界利益 48 円 <導出> | 1 群 14,406 通以上。ROI は限界利益で |
| 8 | 比較相手が「何もしない」だけ・即時生成 | 比較 | セグメント 300×4 案なら月 $55(S5)。文面は前日に決まるのに標準単価 | バッチとセグメント案を比べ、上積み 0.083pt で判断 |
費用の積み上がりと分岐の上げ幅(SVG)
パターン: Unit Economics(1 通あたりの費用 vs 1 通あたりの限界利益)+ 損益分岐の上げ幅を A/B の信頼区間と重ねて読む。
Bad → Good(コード差分)
# Bad: 後輩の見積もり(入力単価だけで全部を数える)
PRICE = 0.75 / 1_000_000 # 入力単価。出力 $3.75 を見ていない
tokens = 500 + 150 # 会員部分の入力だけ。共通 3,000 と思考 450 が無い
monthly = tokens * PRICE * 12_000_000 # 導入価格のまま12か月へ
monthly *= 0.1 # 「キャッシュで90%引き」← 最小4,096に届かず効かない
roi = 12_000_000 * 0.005 * 240 / monthly # 売上240円/クリック、A/B は p=0.30
# 結果: 月 $5,850 → 実際は 1月から月 $137,045(23.4倍)# Good: 料金表の行ごとに数え、作り直しと時期を入れる
p = m.price_on(day) # 2027-01-01 から倍になる単価
shared = p.cached if cache_applies(m, w) else p.input # 4,096 未満は効かない
one = (w.shared_tokens * shared + w.member_tokens * p.input
+ (w.visible_out + w.thinking_out) * p.output) / MTOK # 思考は出力単価
if w.batch:
one *= BATCH_FACTOR # 前日確定の文面ならバッチ 50%
per_mail = one / (1 - w.reject_rate) # 作り直しは幾何分布(1+r ではない)
be_pt = per_mail_yen / Funnel().margin_per_click() * 100 # 48円/クリックで割る
# 結果: S1 分岐 3.57pt(P=0%)/S4 Flash-Lite バッチ 0.084pt/S5 セグメント 月$55適用パターン: Value Object(Price・Workload を frozen dataclass で)+ 有効期間つき単価(price_on)。書籍の章対応は無し(E の日のため)。
模範解答
費用と効果を数えるコード(llm_unit_econ.py)
"""会員ごとの LLM 生成メール文の単位経済(Python 3.12+、標準ライブラリのみ)。
出所ラベル:
<公式> Gemini API 料金表・キャッシュ・バッチの文書(参照日 2026-10-09)
https://ai.google.dev/gemini-api/docs/pricing
https://ai.google.dev/gemini-api/docs/caching
https://ai.google.dev/gemini-api/docs/batch-mode
<仮定> トークン数・差し戻し率・CVR・客単価・粗利率など社内の数字
<導出> 上の 2 つから計算した値
"""
from __future__ import annotations
import math
from dataclasses import dataclass, replace
from datetime import date
YEN_PER_USD = 150 # <仮定>
MTOK = 1_000_000
HOURS_PER_MONTH = 730 # 365 × 24 ÷ 12
BATCH_FACTOR = 0.5 # <公式> バッチは標準の 50%(目標 24 時間以内)
@dataclass(frozen=True)
class Price:
"""100 万トークンあたりのドル単価。output は思考トークンを含む(<公式>)。"""
input: float
output: float
cached: float
storage_per_hour: float # 明示キャッシュの保管 $/100万トークン/時
@dataclass(frozen=True)
class Model:
name: str
price: Price
promo_until: date | None = None # この日までは price、翌日から after
after: Price | None = None
min_cache_tokens: int | None = None # None = 今回は確かめていないので使わない
def price_on(self, day: date) -> Price:
"""その日に効く単価を返す。導入価格の期限切れを見落とさないための入口。"""
if self.promo_until and day > self.promo_until:
assert self.after is not None
return self.after
return self.price
# <公式> 参照日 2026-10-09。3.8 Flash は 2026-12-31 までの価格で、2027-01-01 から倍になる
FLASH_38 = Model(
"gemini-3.8-flash",
Price(0.75, 3.75, 0.075, 0.50),
promo_until=date(2026, 12, 31),
after=Price(1.50, 7.50, 0.15, 1.00),
min_cache_tokens=4_096, # <公式> 3.x Flash のキャッシュ最小トークン数
)
FLASH_LITE_25 = Model("gemini-2.5-flash-lite", Price(0.10, 0.40, 0.01, 1.00))
@dataclass(frozen=True)
class Workload:
"""1 通ぶんの生成の形。トークン数は <仮定>(社内プロンプトの実測を入れる場所)。"""
shared_tokens: int # 全会員で同じ先頭部分: 指示・景表法ルール・例文
member_tokens: int # 会員ごとの属性・購買履歴・キャンペーン情報
visible_out: int # 件名+本文の出力
thinking_out: int # 思考トークン(出力単価で課金)
reject_rate: float # 検査で差し戻して作り直す割合
batch: bool = False
explicit_cache: bool = False
def cache_applies(m: Model, w: Workload) -> bool:
"""明示キャッシュが実際に効くか。最小トークン数に届かなければ効かない。"""
return (w.explicit_cache and m.min_cache_tokens is not None
and w.shared_tokens >= m.min_cache_tokens)
def cost_per_accepted_usd(m: Model, w: Workload, day: date) -> float:
"""検査を通った 1 通あたりのドル。作り直しの分も含む。"""
p = m.price_on(day)
shared_rate = p.cached if cache_applies(m, w) else p.input
one_call = (w.shared_tokens * shared_rate + w.member_tokens * p.input
+ (w.visible_out + w.thinking_out) * p.output) / MTOK
if w.batch:
one_call *= BATCH_FACTOR
attempts = 1 / (1 - w.reject_rate) # 幾何分布の期待試行回数。1 + r ではない
return one_call * attempts
def monthly_cost_usd(m: Model, w: Workload, accepted: int, day: date) -> float:
"""月の費用。明示キャッシュを使うなら保管料(1 本を常時保持)を足す。"""
usd = cost_per_accepted_usd(m, w, day) * accepted
if cache_applies(m, w):
usd += w.shared_tokens / MTOK * m.price_on(day).storage_per_hour * HOURS_PER_MONTH
return usd
def plan_cost_usd(m: Model, w: Workload, accepted: int, months: list[date]) -> float:
"""計画期間の合計。月ごとにその月の単価で数える。"""
return sum(monthly_cost_usd(m, w, accepted, d) for d in months)
def bad_estimate_usd(accepted: int) -> float:
"""後輩案: (入力500+出力150) を全部「入力単価 $0.75」で数える。"""
return (500 + 150) * 0.75 / MTOK * accepted
# ---- 効果側 ----
@dataclass(frozen=True)
class Funnel:
"""<仮定> クリックから注文まで。"""
cvr_per_click: float = 0.03
aov_yen: int = 8_000
gross_margin: float = 0.30
coupon_yen: int = 500 # 増えた注文でもクーポンは使われる
fulfillment_yen: int = 300 # 配送・決済手数料など注文ごとの変動費
def margin_per_order(self) -> float:
return self.aov_yen * self.gross_margin - self.coupon_yen - self.fulfillment_yen
def margin_per_click(self) -> float:
return self.cvr_per_click * self.margin_per_order()
def revenue_per_click(self) -> float:
return self.cvr_per_click * self.aov_yen
def breakeven_uplift_pt(cost_per_email_yen: float, f: Funnel) -> float:
"""1 通の費用を回収するのに要るクリック率の上げ幅(ポイント)。"""
return cost_per_email_yen / f.margin_per_click() * 100
def two_prop_test(c1: int, n1: int, c2: int, n2: int) -> tuple[float, float, tuple[float, float]]:
"""2 群の比率の差: (z, 両側 p 値, 差の 95% 信頼区間[ポイント])。"""
p1, p2 = c1 / n1, c2 / n2
pool = (c1 + c2) / (n1 + n2)
z = (p2 - p1) / math.sqrt(pool * (1 - pool) * (1 / n1 + 1 / n2))
p = math.erfc(abs(z) / math.sqrt(2))
se = math.sqrt(p1 * (1 - p1) / n1 + p2 * (1 - p2) / n2)
d = p2 - p1
return z, p, ((d - 1.96 * se) * 100, (d + 1.96 * se) * 100)
def n_per_arm(p_base: float, uplift: float, z_a: float = 1.96, z_b: float = 0.8416) -> int:
"""検出力 80%・両側 5% で uplift(比率の差)を見つけるのに要る 1 群の通数。"""
p2 = p_base + uplift
var = p_base * (1 - p_base) + p2 * (1 - p2)
return math.ceil((z_a + z_b) ** 2 * var / uplift ** 2)
def prob_above(mean_pt: float, sd_pt: float, threshold_pt: float) -> float:
"""真の上げ幅が threshold を超える確率(A/B の結果を正規近似で読む)。"""
return 0.5 * math.erfc((threshold_pt - mean_pt) / (sd_pt * math.sqrt(2)))
def extra_uplift_needed_pt(cost_a_usd: float, cost_b_usd: float, f: Funnel,
sends: int | None = None) -> float:
"""A が B より高い分を回収するのに、A が B より上乗せすべきクリック率(ポイント)。"""
sends = sends or SENDS_PER_MONTH
return (cost_a_usd - cost_b_usd) * YEN_PER_USD / (sends * f.margin_per_click()) * 100
# ---- 今日の数字 ----
SENDS_PER_MONTH = 3_000_000 * 4 # <仮定> 許諾済み会員 300 万人 × 月 4 通
PLAN = [date(2026, 11, 1)] + [date(2026 + (m > 12), (m - 1) % 12 + 1, 1) for m in range(12, 23)]
# 2026-11 から 12 か月(11・12 月が導入価格、1〜10 月が通常価格)
BAD_ACTUAL = Workload(shared_tokens=3_000, member_tokens=700, visible_out=150,
thinking_out=450, reject_rate=0.12)
SCENARIOS: dict[str, tuple[Model, Workload, int]] = {
"S1 後輩案の実際(3.8 Flash 標準・思考あり)": (FLASH_38, BAD_ACTUAL, SENDS_PER_MONTH),
"S2 3.8 Flash バッチ・思考最小": (FLASH_38, replace(BAD_ACTUAL, thinking_out=30, batch=True), SENDS_PER_MONTH),
"S3 3.8 Flash 標準・思考最小・例文を足し 4,200 で明示キャッシュ":
(FLASH_38, replace(BAD_ACTUAL, shared_tokens=4_200, thinking_out=30, explicit_cache=True), SENDS_PER_MONTH),
"S3' 同じく 3,000 のまま明示キャッシュ(効かない)":
(FLASH_38, replace(BAD_ACTUAL, thinking_out=30, explicit_cache=True), SENDS_PER_MONTH),
"S4 2.5 Flash-Lite バッチ・思考なし・差し戻し 20%":
(FLASH_LITE_25, replace(BAD_ACTUAL, thinking_out=0, batch=True, reject_rate=0.20), SENDS_PER_MONTH),
"S5 セグメント 300 × 4 案 × 月 4 回(3.8 Flash 標準)": (FLASH_38, BAD_ACTUAL, 300 * 4 * 4),
}
AB = dict(c1=42, n1=2_000, c2=52, n2=2_000) # 後輩の A/B(2.1% → 2.6%)
def report() -> None:
f = Funnel()
jan = date(2027, 1, 1)
bad_m = bad_estimate_usd(SENDS_PER_MONTH)
print(f"後輩の見積もり 月 ${bad_m:,.0f} 年 {bad_m * 12 * YEN_PER_USD / 1e4:,.0f} 万円")
z, p, ci = two_prop_test(**AB)
sd = (ci[1] - ci[0]) / (2 * 1.96)
mean = (ci[0] + ci[1]) / 2
print(f"A/B 2,000×2 z={z:.2f} p={p:.2f} 差の95%CI [{ci[0]:+.2f}, {ci[1]:+.2f}] pt")
print(f"+0.5pt を見つける通数 1群 {n_per_arm(0.021, 0.005):,}")
print(f"1クリックの価値 売上 {f.revenue_per_click():.0f} 円 / 限界利益 {f.margin_per_click():.0f} 円")
rev_gain = SENDS_PER_MONTH * 0.005 * f.revenue_per_click()
mar_gain = SENDS_PER_MONTH * 0.005 * f.margin_per_click()
print(f"+0.5pt の月効果 売上 {rev_gain / 1e4:,.0f} 万円 / 限界利益 {mar_gain / 1e4:,.0f} 万円")
print(f"後輩の ROI {rev_gain * 12 / (bad_m * 12 * YEN_PER_USD):.1f} 倍(売上 ÷ 見積もり)")
print()
print(f"{'シナリオ':44s} {'1通(円)':>8s} {'月(11月)':>10s} {'月(1月〜)':>10s} {'12か月(万円)':>11s} {'分岐pt':>7s} {'P(黒字)':>7s}")
for name, (m, w, n) in SCENARIOS.items():
per_yen = cost_per_accepted_usd(m, w, jan) * YEN_PER_USD
nov = monthly_cost_usd(m, w, n, PLAN[0])
after = monthly_cost_usd(m, w, n, jan)
total = plan_cost_usd(m, w, n, PLAN) * YEN_PER_USD / 1e4
# 分岐とP(黒字)は 1 対 1 の全会員配信のときだけ意味がある(S5 は通数ではなく 1 回の生成費)
be = breakeven_uplift_pt(after * YEN_PER_USD / SENDS_PER_MONTH, f)
pr = "—" if n != SENDS_PER_MONTH else f"{prob_above(mean, sd, be):.1%}"
print(f"{name:44s} {per_yen:8.3f} {nov:10,.0f} {after:10,.0f} {total:11,.0f} {be:7.3f} {pr:>7s}")
lite = monthly_cost_usd(*SCENARIOS["S4 2.5 Flash-Lite バッチ・思考なし・差し戻し 20%"], jan)
seg = monthly_cost_usd(*SCENARIOS["S5 セグメント 300 × 4 案 × 月 4 回(3.8 Flash 標準)"], jan)
print()
print(f"1対1(S4) がセグメント(S5) に勝つのに要る上積み {extra_uplift_needed_pt(lite, seg, f):.3f} pt")
print(f"S4 を u=+0.5pt で回したときの月の限界利益 {(mar_gain - lite * YEN_PER_USD) / 1e4:,.0f} 万円")
if __name__ == "__main__":
report()
変異テスト(本体を 1 か所ずつ壊して 15 テストを流す)
赤 M1 出力も入力単価で数える(後輩案) test_output_token_uses_output_rate, test_thinking_tokens_are_billed_as_output
赤 M2 思考トークンを数えない test_thinking_tokens_are_billed_as_output
赤 M3 キャッシュの最小トークン数を見ない test_cache_below_minimum_does_nothing
赤 M4 導入価格が年中続く test_plan_has_2_promo_months_and_10_full, test_promo_ends_on_dec_31
赤 M5 作り直しを 1 + r で数える test_retry_is_geometric_not_linear
赤 M6 キャッシュ保管料を足さない test_cache_at_minimum_uses_cached_rate_plus_storage
赤 M7 1 クリックの価値を売上で数える test_breakeven, test_click_value_is_margin_not_revenue
赤 M8 クーポン原価を引かない test_breakeven, test_click_value_is_margin_not_revenue
赤 M9 バッチ割引を忘れる test_batch_is_half
赤 M10 片側検定にする(p を半分) test_ab_2000_is_not_significant
10 種すべて 1 回目で赤。ただし変異は自分が思いついた誤りだけなので、為替や月の日数の誤りは測れていない。サンプルサイズの式は教科書の例(10%→12% で 1 群約 3,839)と照合した。
実行例
後輩の見積もり 月 $5,850 年 1,053 万円
A/B 2,000×2 z=1.04 p=0.30 差の95%CI [-0.44, +1.44] pt
+0.5pt を見つける通数 1群 14,406
1クリックの価値 売上 240 円 / 限界利益 48 円
+0.5pt の月効果 売上 1,440 万円 / 限界利益 288 万円
後輩の ROI 16.4 倍(売上 ÷ 見積もり)
シナリオ 1通(円) 月(11月) 月(1月〜) 12か月(万円) 分岐pt P(黒字)
S1 後輩案の実際(3.8 Flash 標準・思考あり) 1.713 68,523 137,045 22,613 3.569 0.0%
S2 3.8 Flash バッチ・思考最小 0.588 23,523 47,045 7,762 1.225 6.5%
S3 3.8 Flash 標準・思考最小・例文を足し 4,200 で明示キャッシュ 0.516 20,661 41,321 6,818 1.076 11.5%
S3' 同じく 3,000 のまま明示キャッシュ(効かない) 1.176 47,045 94,091 15,525 2.450 0.0%
S4 2.5 Flash-Lite バッチ・思考なし・差し戻し 20% 0.040 3,225 3,225 580 0.084 80.7%
S5 セグメント 300 × 4 案 × 月 4 回(3.8 Flash 標準) 1.713 27 55 9 0.001 —
1対1(S4) がセグメント(S5) に勝つのに要る上積み 0.083 pt
S4 を u=+0.5pt で回したときの月の限界利益 240 万円
- S1 の 12 か月は 2 億 2,613 万円で見積もり 1,053 万円の 21.5 倍。1 月以降は月約 2,056 万円で、+0.5pt が本当でも限界利益は月 288 万円 → 月 1,768 万円の赤字
- P(黒字) は A/B の結果を正規分布で読んだ値。A/B 自体が弱いので粗い。S5 は別物なので出していない
推奨案と稟議の書き直し
件名: メール文の生成は「セグメント × 数案」から始め、1 対 1 は効果を測ってから Flash-Lite のバッチで判断する
結論: 後輩案は 12 か月 2.26 億円で、効果が本当でも月 1,768 万円の赤字。まずセグメント 300 × 4 案(月 $55)。
効果の測り方: 11 月の 2 回の配信で 1 群 14,406 通以上 × 3 群(現行/セグメント案/1 対 1 の Flash-Lite 案)。増分利益は注文 1 件 1,600 円で数える。
1 対 1 に進む条件: Flash-Lite バッチ(月 $3,225 ≈ 48 万円)がセグメント案より +0.083pt 以上。3.8 Flash はキャッシュ込みでも分岐 1.08pt で採らない。
景表法: 割引率・期限・対象商品はマスタから差し込み、LLM に書かせない。禁止語とマスタに無い数字を機械で検査。配信前に 50 通を人が抜き取り。
費用の見張り: usage_metadata を日次で BigQuery へ、1 通あたりの円を出す。生成費が月 60 万円を超えたら通知。
見直す条件: 3.8 Flash の単価が下がる/1 対 1 の効果が +1.1pt を超えて測れた/配信が行動起点の即時に変わった。
迷った案と採らなかった理由
| 案 | 12 か月 | 判断 | 前提が変わったら |
|---|---|---|---|
| S1 後輩案(3.8 Flash 標準・思考あり) | 2億2,613万円 | 却下。分岐 3.57pt | — |
| S2 3.8 Flash バッチ・思考最小 | 7,762万円 | 却下。分岐 1.23pt、P(黒字) 6.5% | 大きな A/B で +1.2pt 以上が出たら |
| S3 3.8 Flash+例文を足して明示キャッシュ | 6,818万円 | 却下。ただし長いプロンプトの方が安い(1通 1.176→0.516円) | 別案件で 3.8 Flash を使うとき。バッチとの併用は要確認 |
| S4 2.5 Flash-Lite バッチ・思考なし | 580万円 | 候補。分岐 0.084pt。質は仮定、A/B で確かめる | 差し戻し 50% 超・禁止語の検出漏れで止める |
| S5 セグメント × 数案 | 9万円 | 先に採用 | 1 対 1 が +0.083pt 以上なら S4 へ |
| 開封者(40%)だけ 1 対 1 | S4 の約 4 割 | 保留。効果の差は未測定 | 開封者でだけ効果が大きいと分かったら |
| 自社 GPU で小型モデル | 未試算 | 扱わない。運用の人件費が勝つ見込みが薄い | 生成量が 10 倍以上になったら |
ポイント解説
- LLM の費用は出力と思考で決まることが多い: 入力だけで見積もると桁が変わる(今回 23.4 倍)。
- キャッシュと導入価格は注記で決まる: 4,096 未満のキャッシュは効かない。例文を足すと安くなることも。導入価格の期限は 12 か月中 10 か月を倍にする。
- 効果は限界利益と信頼区間: 240 円でなく 48 円。2,000 通の +0.5pt は 0 を含む。
- 比較相手をセグメント案に: 1 対 1 はその差を回収する上積み 0.083pt で判断。
実務への応用
商品説明文・プッシュ通知・問い合わせの一次回答でも、まず「1 件の円」と「1 件で残るお金」を並べる。usage_metadata を BigQuery に入れ、単価は dbt のシードで改定日つきで持つ。数字はマスタから差し込み、文の自由度と景表法のリスクを分ける。
扱わなかった範囲(止め方)
- トークン数・思考・差し戻し・CVR・粗利率はすべて仮定。count_tokens と本番の usage_metadata で測る。思考量の設定と最小値はモデルごとに要確認
- 単価は Gemini API(Google AI)の料金表。Vertex AI 経由の単価・Provisioned Throughput は確かめていない
- 配信停止率・ブランド・到達率への影響は数えていない
- 景表法は第 5 条第 2 号(有利誤認表示)を念頭に置いたが、消費者庁のページは取得できず(HTTP 403)原文未確認。法務の確認が要る
- 論点を 11 個挙げ 9 個を数えた(レイテンシ要件・レート制限は扱わず)。11 個は自分で挙げたもので、外部の枠組みとは照合していない
発展問題: カゴ落ちから 1 時間後の 1 対 1 メールではバッチが使えない。標準単価で、回収率がいくら上がれば Flash-Lite と 3.8 Flash それぞれで黒字になるか。
今日のまとめ
LLM 生成の稟議は「入力トークン × 入力単価」では桁がずれる。出力・思考・キャッシュの最小値・導入価格・作り直しを料金表の注記まで数え、効果は限界利益と信頼区間で測り、比較相手にセグメント × 数案を置く。