新しいモデルが出ると、まず全リクエストのモデルIDを書き換えたくなります。Claude Fable 5.2 は 5.1 より安くなったので、なおさらです。
ただ、エージェントの1回の仕事は、分類・抽出・言い換え・要約といった小さなステップの集まりです。深い推論が必要なのは、そのうち1つか2つということがよくあります。
全部を Fable に送ると、簡単なステップにも一番高い単価を払うことになります。さらに Fable 5.2 には、単価以外にもコストが静かに増える仕様がいくつかあります。
この記事では、ステップごとにモデルを振り分けるときの注意点と、レスポンスの usage から1回ごとのコストを計算するコードをまとめます。
料金(100万トークンあたり・入力 / 出力)
| モデル | BeatAPI |
|---|---|
| Fable 5.2 | $4 / $20 |
| Opus 5.5 | $2 / $10 |
| Sonnet 5.5 | $1 / $5 |
| Haiku 5.5 | $0.05 / $0.25 |
Haiku 5.5 には、長いプロンプト向けの long_context 単価($0.25 / $1.25)が別にあります。どこから long_context になるかは、料金ページの説明で確認してください。
(2026年11月12日、api.beatapi.io/v1/pricing で確認)
Anthropic 自身のすすめ方
Anthropic は発表の中で、普段のコーディングや知識作業は Opus 5.5 から始め、範囲や難しさに応じて Fable に上げるか、Sonnet 5.5・Haiku 5.5 に下げるようすすめています。
Fable 5.2 を Advisor(小さいモデルが難しい問題だけ相談する)や Orchestrator(簡単な仕事を小さいモデルに任せる)として使う形も紹介されています。
単価以外でコストが増える3つのポイント
1. effort の既定値が違う
Fable 5.2 の既定の effort は high、Opus 5.5 は medium です。Opus 5.5 から Fable 5.2 にモデルIDだけ移すと、1段高い設定で動きます。リクエストは成功するので、コスト・時間・結果の違いとしてしか現れません。
思考トークンは出力トークンとして課金されるので、effort はモデルごとに明示します。
2. 会話の途中でモデルを替えると、推論が捨てられる
Opus 5.5 は Fable 5.2 の思考ブロックを読めません。会話を Fable 5.2 から Opus 5.5 に移すと、そのブロックは捨てられます(リクエストは成功し、捨てられた分は課金されません)。
切り替え直後のターンは、それまでの推論なしで動くので、コストとレイテンシが上がることがあります。
逆方向(Opus 5.5 → Fable 5.2)は、Claude API 上では読めると移行ガイドに書かれています。
そのため、振り分けは「1つの会話の中で行き来する」より、「ステップごとに独立したリクエストにする」か「上げる方向だけにする」ほうが安全です。
3. 高い effort ではサブエージェントが動くことがある
xhigh や max では、Fable 5.2 が自分の作業をレビューするためにサブエージェントを起動することがあります(Anthropic のエージェント型コーディング製品での観察)。セッションのコストの大きな割合を占めることがあるので、最初は medium か high で測ります。
ステップごとにモデルと effort を決める
// route.ts
type Tier = "light" | "daily" | "hard";
const ROUTE: Record<Tier, { model: string; effort?: string }> = {
light: { model: "claude-haiku-5-5" }, // 分類・抽出・言い換え
daily: { model: "claude-opus-5-5", effort: "medium" }, // 普段のコーディング・調べもの
hard: { model: "claude-fable-5-2", effort: "high" }, // Opus で足りなかった判断だけ
};
export async function runStep(tier: Tier, prompt: string) {
const { model, effort } = ROUTE[tier];
const res = await fetch("https://api.beatapi.io/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BEATAPI_API_KEY}`,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({
model,
max_tokens: 16000, // 思考トークンも含まれるので余裕を持たせる
...(effort ? { output_config: { effort } } : {}),
messages: [{ role: "user", content: prompt }],
}),
});
if (!res.ok) throw new Error(`${model} ${res.status}: ${await res.text()}`);
const body = await res.json();
const text = body.content
.filter((b: { type: string }) => b.type === "text")
.map((b: { text: string }) => b.text)
.join("");
return { model, text, usage: body.usage };
}
ステップごとに独立したリクエストにしているので、モデルを替えても思考ブロックの受け渡しは起きません。
effort が効いているかは、同じプロンプトを effort だけ変えて送り、usage.output_tokens が変わるかで確かめられます。Haiku 5.5 には effort を渡していません。
usage から1回ごとのコストを計算する
単価をコードに直書きすると、料金が変わったときに見積もりがずれます。BeatAPI は公開料金を GET https://api.beatapi.io/v1/pricing で返すので、毎回そこから読みます。
レスポンスは data.groups[].specs[] の形で、各 spec に id と beatapiUsd があります。Claude 系の spec ID は claude-fable-5-2-input、claude-fable-5-2-output、claude-fable-5-2-cached-input、claude-fable-5-2-cache-write のような形です。
// cost.mts — 実行例: npx tsx cost.mts(トップレベルの await を使うので拡張子は .mts)
type Usage = {
input_tokens: number;
output_tokens: number;
cache_read_input_tokens?: number;
cache_creation_input_tokens?: number;
};
async function loadPrices(): Promise<Map<string, number>> {
const res = await fetch("https://api.beatapi.io/v1/pricing");
if (!res.ok) throw new Error(`pricing ${res.status}`);
const body = await res.json();
const prices = new Map<string, number>();
for (const g of body.data.groups) {
for (const s of g.specs) prices.set(s.id, s.beatapiUsd);
}
return prices;
}
function costUsd(
model: string,
u: Usage,
prices: Map<string, number>,
longContext = false, // Haiku 5.5 の long_context 単価を使うときだけ true(境界は料金ページで確認)
): number {
const long = longContext ? "long-context-" : "";
const p = (kind: string) => {
const v = prices.get(`${model}-${long}${kind}`);
if (v === undefined) throw new Error(`price not found: ${model}-${long}${kind}`);
return v;
};
return (
(u.input_tokens * p("input") +
u.output_tokens * p("output") +
(u.cache_read_input_tokens ?? 0) * p("cached-input") +
(u.cache_creation_input_tokens ?? 0) * p("cache-write")) /
1_000_000
);
}
// 試算用のサンプル(実際のレスポンスではありません)
const sample: Usage = { input_tokens: 50_000, output_tokens: 5_000 };
const prices = await loadPrices();
for (const model of ["claude-fable-5-2", "claude-opus-5-5", "claude-haiku-5-5"]) {
console.log(model, "$" + costUsd(model, sample, prices).toFixed(5));
}
料金 API の単価(2026年11月12日)を当てはめた計算結果です。
claude-fable-5-2 $0.30000
claude-opus-5-5 $0.15000
claude-haiku-5-5 $0.00375
これは入力5万・出力5,000トークンという同じ数字を当てはめた試算です。実際には、モデルと effort によって思考トークンの量が変わるので、出力トークン数は同じになりません。本番では runStep が返す usage をそのまま costUsd に渡して、ステップごとに記録します。
キャッシュ書き込みは、このコードではすべて5分キャッシュの単価で計算しています。1時間キャッシュを使う場合は、別の spec(claude-fable-5-2-cache-write-1h、$8)で計算してください。
振り分けを決める手順
- エージェントのステップを書き出し、「分類・抽出」「普段の作業」「Opus で失敗したもの」に分ける
- まず全部を Opus 5.5 と Haiku 5.5 で動かし、失敗したステップだけを記録する
- 失敗したステップだけを Fable 5.2 に上げ、effort を明示して測る
- ステップごとの
usageとコストを記録し、週に1回見直す
新しいモデルは、全部を置き換えるためではなく、一番難しいところを埋めるために入れる。そう決めておくと、請求額の説明がつきやすくなります。
出典
- Anthropic「Introducing Claude Fable 5.2 and Claude Mythos 5.2」(2026年11月9日)
- Anthropic ドキュメント「Fable 5.2 migration guide」「Pricing」
- BeatAPI 料金:api.beatapi.io/v1/pricing(2026年11月12日確認)
