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?

Fable 5.2 を「難しいステップだけ」に使う:モデルの振り分けと usage からのコスト計算(TypeScript)

0
Posted at

W46-Qiita-02-1.png

新しいモデルが出ると、まず全リクエストのモデル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)で計算してください。

振り分けを決める手順

  1. エージェントのステップを書き出し、「分類・抽出」「普段の作業」「Opus で失敗したもの」に分ける
  2. まず全部を Opus 5.5 と Haiku 5.5 で動かし、失敗したステップだけを記録する
  3. 失敗したステップだけを Fable 5.2 に上げ、effort を明示して測る
  4. ステップごとの 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日確認)

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?