編成をモデルの内側に隠す(Sakana Fugu)
枠組みを組むのは呼ぶ側の仕事だと思っていたが、モデルの側でやってしまう売り方が出てきた。1回の呼び出しの内側に編成があり、外からは1モデルに見える。困るのは測れなくなることで、呼び出し回数も渡した量も1回ぶんに潰れる。ところが会計には出る。内側の調整に使ったトークンは別枠で数えられ、料金に含まれる。単価は積まないが、トークンは積む。
この章で読むもの
この章もコードを書かない。エージェントの枠組みの⑤で、経路を先に描けるところはモデルに訊かなくてよい、と測った。同じ仕事でモデルの呼び出しが5回から1回、渡した文字が189から47に落ちた。この「どこをコードで固定し、どこをモデルに任せるか」を組むのは、呼ぶ側の仕事だった。
Sakana AI の Fugu は、そこをモデルの側でやる。複数のモデルを束ねた編成を、1つのモデルとして売る。呼ぶ側から見えるのは普通の API で、内側に何本走っているかは見えない。
編成という言葉をここでは、複数のモデルを役割で分けて順に走らせる組み方の意味で使う。枠組みの章までの言い方だと、グラフの節にそれぞれ別のモデルを置いたものに当たる。
① 呼ぶ側が組む(本書の⑤でやったこと)
あなたのコード
├─ search ─────────── 固定
├─ read ─────────── 固定
├─ [訊く] edit ────────▶ モデル API ← 呼び出し 1 回、渡した文字 47
└─ test ─────────── 固定
何回呼んだか・何文字渡したかが、自分のコードから数えられる
② 提供者が組む(Fugu)
あなたのコード
└─ [訊く] ────────────▶ Fugu API ← 呼び出し 1 回
├─ 内側で編成が回る
├─ ここは見えない
└─ 見えないが、請求には出る
呼び出し回数は 1 に潰れる。代わりに usage が内訳を持つ順に見ていく。
- 1回の呼び出しの内側に、編成がある: 互換の皮を2枚かぶって、既存の道具にそのまま刺さる
- 隠すと測れなくなるが、会計には出る: 内側の調整に使ったトークンが別枠で返ってくる
- 単価は積まないが、トークンは積む: 何本走っても単価は1つ。ただし量は増える
- どの編成を使うかの1手は、呼ぶ側に残る: 自動では選ばれない
① 1回の呼び出しの内側に、編成がある
Fugu は3系統ある。
| モデル ID | 中身 |
|---|---|
fugu | 既定。複数の提供者にまたがって振り分ける |
fugu-ultra | 難しい多段の問題向け。fugu-ultra-v1.1 を指す |
fugu-cyber | fugu-cyber-v1.0 を指す |
版を固定したいときは fugu-ultra-v1.0(別名 fugu-ultra-20260615)のように直接書く。
刺さり方が特徴的で、互換の皮を2枚かぶっている。
- OpenAI 互換: Chat Completions、Responses、Models
- Anthropic 互換: Messages
前章で「差し替えられることが、層が分かれている証拠になる」と書いた。皮を2枚持つというのは、その境目の両側の規格に合わせにいったということだ。だから Claude Code なら環境変数だけで向きが変わる。
ANTHROPIC_BASE_URL="https://api.sakana.ai"
ANTHROPIC_AUTH_TOKEN="<Sakana の鍵>"
ANTHROPIC_DEFAULT_OPUS_MODEL="fugu-ultra"ANTHROPIC_API_KEY ではなく ANTHROPIC_AUTH_TOKEN を使う。前者は Anthropic 宛ての鍵として扱われる欄で、別の相手に投げるときは後者になる。
OpenAI 互換のほうを使うなら、基点は https://api.sakana.ai/v1 で、Authorization: Bearer に鍵を載せる。Hermes なら provider: custom と base_url の欄がそのまま使える。
考える深さの指定も持っていて、high / xhigh / max から選ぶ。既定は fugu-ultra が xhigh、fugu が high。ただし xhigh と max は同じものを指す。つまり段は実質2つで、名前が3つある。
② 隠すと測れなくなるが、会計には出る
枠組みの章の⑤で費用として数えたのは2つだった。モデルを呼んだ回数と、渡した文字の合計だ。後者を足したのは、呼ぶたびにそれまでの記録をぜんぶ渡すので、回数だけでは値段に合わないからだった。ループ189に対しグラフ47、という差はそこで出た。
編成が内側にあると、この2つがどちらも1回ぶんに潰れる。何本走ろうが、自分のコードから見える呼び出しは1回で、渡したのは自分が書いたプロンプトだけだ。枠組みの章で作った測り方が、そのままでは効かなくなる。
ところが、消えるわけではない。Fugu Ultra と Fugu Cyber は、内側の調整に使ったトークンを別枠で返す。入力側と出力側それぞれについて、編成のために使った合計が usage の内訳として付いてくる。しかもそれは表示のためだけの数字ではなく、料金に算入される。
つまりこうなる。
| 呼ぶ側が組む | 提供者が組む | |
|---|---|---|
| 呼び出し回数 | 自分のコードから数える | 1 に潰れる |
| 渡した量 | 自分のコードから数える | 自分が書いたぶんしか見えない |
| 内側の量 | そもそも全部が自分の側 | usage の内訳と請求で見える |
枠組みの章で InputChars を足したのは、呼び出し回数より実態に近いからだった。編成を隠された側から同じことを知りたければ、見るのは usage の内訳になる。課金明細が、唯一残った計測器という状態だ。
これは軽い話ではない。枠組みの章の測定で、直近だけ残す走りは窓を1度も超えていないのに渡した文字が6,476で最多だった。削ったつもりが増えていた、という失敗は、量を測っていたから見えた。内側で同じことが起きていても、外からは同じ1回の呼び出しに見える。
③ 単価は積まないが、トークンは積む
編成を売るときに問題になるのが値段の付け方だ。中で3本走ったら3倍取るのか。Sakana はそこを明示している。
モデル料金を積み上げることはない。複数のエージェントを使っても、関わった中でいちばん上位のモデルに基づく単一の料率で課金する。
100万トークンあたりの単価はこうなっている。
| モデル | 入力 | 出力 | キャッシュ入力 |
|---|---|---|---|
| Fugu Ultra | $5 | $30 | $0.50 |
| Fugu Ultra(コンテキスト 272K 超) | $10 | $45 | $1.00 |
| Fugu Cyber | $6 | $36 | $0.60 |
| Fugu Cyber(コンテキスト 272K 超) | $12 | $54 | $1.20 |
内側の調整に使ったトークンも、この標準単価で数えられる。
読み方は2つある。
単価は積まない。編成の中で何本呼ばれても、料率は1つだ。呼ぶ側から見れば、内側の構成が変わっても値段の計算式は変わらない。
トークンは積む。単価が1つでも、量は編成のぶんだけ増える。枠組みの章の言い方をすれば、値段は回数ではなく量で決まるので、隠されているのは量のほうになる。
もう1つ、コンテキストが 272K を超えると入力が2倍、出力が1.5倍に跳ねる。枠組みの章の③で「回すほど窓が埋まる」と測ったが、実物では埋まった先に段差がある。窓に入るかどうかだけでなく、どこで料率が変わるかも、畳む判断の材料に入る。
サブスクリプションもあり、月 $20 / $100 / $200 の3段で、上2つは基準の10倍・20倍の利用量と説明されている。
④ どの編成を使うかの1手は、呼ぶ側に残る
fugu と fugu-ultra の間は自動では切り替わらない。どちらを呼ぶかは、呼ぶ側が毎回決める。
これは枠組みの章の⑤の裏返しになっている。あそこで言ったのは「経路を先に描けるならコードへ、描けないならモデルへ」だった。Fugu は経路の側を丸ごと引き取った格好だが、引き取らなかった1手がここにある。どの編成を使うかは描けないので、呼ぶ側に残った。
枠組みの章のグラフで、Decide を立てた節が1つだけあったのと同じ形だ。固定できるところは固定して、決められないところだけ外に出す。層が1つ上がっても、その構図は変わらない。
実際の効き方はこうなる。全部 fugu-ultra にすると、簡単な問いにも上位の単価がかかる。枠組みの章の④で「削ったつもりが増えている」と書いたのと似た失敗で、良いほうを既定にしておけば安全、とはならない。
Claude Code に刺すときの環境変数が3段に分かれているのは、ここに対応している。
ANTHROPIC_DEFAULT_OPUS_MODEL="fugu-ultra"
ANTHROPIC_DEFAULT_SONNET_MODEL="fugu"
ANTHROPIC_DEFAULT_HAIKU_MODEL="fugu"/model で段を切り替えると、そのまま編成の選択になる。選ぶ操作を、既にある UI に載せ替えている。前章で「差し替えられるかを先に見る」と書いたが、差し替えたあとも呼ぶ側に残る判断が何かは、こうやって設定の形に現れる。
設計の観点
- 編成を隠すと、測っていた指標が潰れる: 呼び出し回数と渡した量は、境目の外側でしか数えられない
- 代わりに何が見えるかを確かめる: Fugu は
usageの内訳を返す。返さない相手なら、量は請求書でしか分からない - 単価と量を分けて考える: 単価を積まない約束があっても、量が積めば値段は上がる
- 料率の段差を畳む判断に入れる: 窓に入るかどうかと、どこで単価が変わるかは別の線だ
- 良いほうを既定にしない: 自動で振り分けないなら、選ぶのは毎回こちらの仕事になる
- 互換の皮は、境目がどこにあるかの宣言だ: 2枚かぶるのは、両側の規格に合わせにいったということ
- 残った1手を探す: 経路を丸ごと引き取った相手でも、決められないところは必ず呼ぶ側へ返ってくる
対照と実例
| 経路を組むのは | 呼び出し回数 | 渡した量 | 内側の量 | 選ぶ1手 | |
|---|---|---|---|---|---|
| 本書の②(ループ) | 呼ぶ側 | 数えられる(5) | 数えられる(189) | — | 毎手 |
| 本書の⑤(グラフ) | 呼ぶ側 | 数えられる(1) | 数えられる(47) | — | 決める節だけ |
| Fugu | 提供者 | 1 に潰れる | 自分のぶんだけ | usage の内訳 | どの編成か |
| 素のモデル | 誰も組まない | 数えられる | 数えられる | 無し | 無し |
裏どり:
- モデル ID:
fugu/fugu-ultra/fugu-ultra-v1.0(別名fugu-ultra-20260615)/fugu-ultra-v1.1/fugu-cyber/fugu-cyber-v1.0。fugu-ultraは v1.1、fugu-cyberは v1.0 を指す - 互換の皮: OpenAI 互換の Chat Completions / Responses / Models と、Anthropic 互換の Messages。基点は
https://api.sakana.ai/v1、Claude Code へ刺すときだけhttps://api.sakana.ai(/v1なし)をANTHROPIC_BASE_URLに置く - 考える深さ:
high/xhigh/max。既定はfugu-ultraがxhigh、fuguがhigh。xhighとmaxは同じ - 内側のトークン: Fugu Ultra と Fugu Cyber は「編成に使った入力トークンの合計」「編成からの出力トークン」を
usageに持ち、「リクエストの最終価格に数え入れられる」と明記されている - 単価を積まない: 「モデル料金を積み上げることはない。関わった中で最上位のモデルに基づく単一の料率で課金する」。編成のトークンは標準の入出力単価で課金される
- 値段: Fugu Ultra が入力 $5 / 出力 $30(100万トークンあたり)、コンテキスト 272K 超で $10 / $45。キャッシュ入力 $0.50。Fugu Cyber はそれぞれ2割増し。サブスクは $20 / $100 / $200 の3段
- 自動で振り分けない:
fuguとfugu-ultraの間を API 側では切り替えない、という記述は解説記事でしか確認できていない。公式の記述としてはfuguが「既定のモデル」であることと、モデル ID を明示して呼ぶ形しか読み取れなかった - 応答が始まるまでの間: Fugu Ultra は内側の調整に時間を使ってから喋り始めるので、タイムアウトを長めに取るべき、という助言も解説記事のみで、公式の推奨値は見つけられていない
簡略化したこと
- 叩いていない: 鍵を取って実際に投げてはいない。
usageの内訳の欄名も、返ってきたものを見たのではなく記述から読んだ - 測っていない: 同じ仕事を素のモデルと Fugu で走らせて、量と値段を比べる、はやっていない。枠組みの章の数字は測ったもの、この章の数字は読んだものだ
- 編成の中身を知らない: 何本のモデルがどう並んでいるかは公開されていない。この章が扱えるのは、外から見える境目と会計だけになる
- 性能を比べていない: ベンチマークの数字には触れていない。触れるなら測り方から確かめる必要がある
- 他の隠し方に触れていない: 提供者が編成を持つ形は Fugu だけではない。ここでは1つを例にしている
参考資料
- Sakana Fugu — 製品
- Fugu の発表 — 位置づけ
- Get started — 基点・鍵・環境変数
- Models — モデル ID と内側のトークンの欄
- Pricing — 単価と、料金を積み上げない約束
- 枠組みの章: エージェントの枠組み / Hermes と Pi で読み替える