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?

GPT-6 Astraのprompt cacheが効かない — Devin CLIの文脈シャッフルをSHA1比較で確定した話

0
Last updated at Posted at 2026-09-09

Devin CLIから GPT-6 Astra (モデル名 gpt-6-astra-medium) を使っていて、奇妙なことに気づいた。手元のpromptは587字なのに、1呼び出しあたりのinput消費は27,079 tokenになる。差の約26.7k tokenは、こちらが書いていない文脈 — CLIが毎回先頭に乗せるシステム文・rules・skills一覧・MCPサーバー一覧だ。

しかも料金表には割引がある。devin models list を見ると、astraはinput $10/M tokenに対して cached input $1/M token (1/10)。公式docsにも "Staying on the same model across turns in a conversation enables caching, which significantly reduces input token costs." (同一会話で同じmodelを使い続けるとcachingが有効になり、input tokenコストが大幅に減る) とある。quotaのdocsも "requests to the same model leverage caching and reduce overall token usage" と案内している。

実際には効いていなかった。この記事は、効かない原因をSHA1比較で確定し、設定だけで割引を実効させる手順と、18ターンの実測 (定価$4.77相当 → 実課金$0.95) を示す。

読み終えた時、手元に残るもの:

  1. Astraのコストが割高に見える構造 (固定文脈 × 単価)
  2. cacheがhitしない原因の切り分け方 (マスクSHA1比較)
  3. 割引を実際に受けるworkaround (MCP 1サーバー化) と検証データ
  4. one-shot (-p) とmulti-turnで結論が変わる運用指針

計測環境と方法を先に書く。Devin CLI v3000.6.14・Linux。input token数は ~/.local/share/devin/cli/sessions.dbnum_tokens_preceding 実数、消費$は同CLI表示単価 (rate card) からの換算。この単価はCLI表示であってOpenAI API公開単価とは別レートである。

587字のpromptが27,079 tokenになる

まず現象の再現から。同一タスクを各2回ずつ実行したときの実測:

タスク 手元の入力 input token実数 所要 cost/呼
長文記事の起草 (28.7k tokenの素材を渡す) 28.7k tok 29,286 / 29,285 49.5s / 46.2s ≈$0.43
短文の起草 (本番prompt) 587字 27,079 / 27,080 11.2s / 14.7s ≈$0.28

下の行が本題だ。入力587字でも27,079 token消える。全呼び出しに約26.7k tokenの固定文脈が乗っている (sessions.db実測)。

この固定文脈が単価と噛み合うと、こうなる。

model input単価 固定文脈26.7k分のコスト Astra比
GPT-6 Astra $10/M ≈$0.27/呼
GPT-5.6 Sol $1.2/M ≈$0.032/呼 約1/10
GPT-5.6 Luna $0.2/M ≈$0.005/呼 約1/50

同じ仕事をさせても、LLMのmodel選択だけでコスト差は1〜2桁に開く (同一長文タスクでの実測もSol $0.041-0.049・Luna $0.007-0.008で、表の比と整合する)。Astraの品質が長文の難物で価値が出ることは最後に書く。まず「cacheで安くならないのはなぜか」を確定する必要があった。

割引は実在する — なのにhitしない

devin models list にはcached単価の列が実在する。手元の表示 (2026-09-06時点の保存例を assets に置いた) では、全modelでinput単価の1/10だ。

gpt-6-astra-medium   [1M context, $10 / 1M Input · $1 / 1M Cached input · $50 / 1M Output]
gpt-5-6-sol-medium   [$1.2 / 1M Input · $0.12 / 1M Cached input · ...]
gpt-5-6-luna-medium  [$0.2 / 1M Input · $0.02 / 1M Cached input · ...]

公式docsも同じ設計を記述する。冒頭に引いたとおり、cachingは「同一会話で同じmodelを連続して使う」ことで有効化される。つまり割引の受け取り方はsession内のmulti-turnのはずだった。

ところが、デフォルト設定のまま同一sessionで6ターン回しても、割引の痕跡がusageゲージに現れない。input計160.3k token = 定価換算$1.60で、cacheが効いていれば+2.5ptのはずのところ、実測は+12pt ≒ 定価 ($9.8pt予測に近い) 。cacheがhitしていない。原因を突き止めた。

切り分け: 毎ターン何が変わっているのか — SHA1を取る

provider側のprompt cacheのhit条件はprefix一致 (リクエスト先頭のbyte列が同じ) である。だから「毎ターン何が変わっているか」を機械的に特定すればいい。

方法: sessions.dbに保存された各ターンのsystem prompt nodeについて、(a) 生のまま (b) MCPサーバー一覧を名前順に並べ直したもの (マスク) — この2通りのSHA1を取って比較した。

結果 (astra・同一session・6ターン):

  • 生SHA1: 6ターンすべて異なる (6種類)
  • マスクSHA1: 全ターン完全一致 (32dc9a434357)

差分の正体は、system prompt内のMCPサーバー一覧 (4台) の並び順だけだった。content内にtimestamp形式の文字列はゼロ (ナノ秒刻みの created_at はwrapperのmetadata側にあり、provider送信対象外)。同じ内容が、毎ターン違う順序で再レンダリングされていた。

one-shot (-p) では、さらに別の箇所もシャッフルされる。別modelでの8呼びで、rules (2本のblob) の順序が呼び出し毎に2通りに分布することを確認した。skills一覧 (30,243字・80 skills) は22 sessionすべてでSHAが異なり、先頭に来るskillも毎回違う。つまり順序が壊れる場所は3つある:

  • rules の並び (session生成時)
  • skills 一覧の並び (session生成時)
  • MCPサーバー一覧の並び (session生成時 と毎ターン)

ここでcacheの原理に還元すると、詰み方が見える。文脈の先頭 (システム情報→rules) は短く、最初のシャッフル地点は約200 tokenしかない。provider cacheの最小単位は1,024 token。prefixが揃っていても1ブロックにも届かず、hitは構造的に起きない (skills一覧が末尾に来るbest caseでも、部分hitは2割弱どまり)。

なぜ毎回変わるのか。devin skills listdevin rules list の表示順自体が実行毎に変わることから、内部のコレクションが順序を保証しない型で持たれていて、表示にも注入にもsortが掛かっていない、と観測できる (表示と注入で同じ順序の乱れが出る)。原因箇所の特定はここまでで十分で、対処は次のとおり入力側で行える。

workaround: MCPを1台に絞るとprefixが凍る

順序が揃わない3要素のうち、ユーザー側で制御できるのはMCPサーバー台数だけだ (skillsはbuiltin分が消せず、rulesを1本化してもskills/MCPが残る)。1台なら並び順の入れようがない:

devin mcp disable supabase --scope user
devin mcp disable serena  --scope user
devin mcp disable playwright --scope user
# → 有効なMCPサーバーが1台になる (残すのは filesystem 等、注入が名前のみで最小のもの)

検証手順はこうだ。

  1. 1サーバー化して軽いprobeを3回打つ → system promptの再レンダリング3回が同一SHAになる
  2. astraで同一sessionに6ターン → 全system prefix nodeが全ターンbyte同一 (user/assistantの追記分だけ増える) = cache-hit条件を満たすリクエストが初めて作れた
  3. 戻すときは devin mcp enable <name> --scope user (設定のbackupで復元を確認済み)

実測: 18ターンで定価$4.77相当が$0.95になる

1サーバー構成のまま、astraで6ターン+12ターン (echoタスク、input計317.7k token、rate card定価換算$4.77) を実行した。

usageゲージの実測: +5pt ≈ $0.95相当

3つの仮説と突き合わせると、どれが当たっているか一目で分かる。

仮説 予測 実測
全ターン定価 ($10/M) +29pt
全ターンcached ($1/M) ≈+2pt
各sessionのturn1 = 定価、turn2以降 = cached (1/10) +5.9pt +5ptで一致

つまり課金構造は「turn1だけ定価 + turn2以降1/10」で矛盾なくfitした。結論を3つにまとめる:

  • 割引は実在し、利用者にパススルーされる (課金不正ではない)
  • ただしデフォルト設定では毎ターンのMCP再シャッフルがhit条件を潰している = 実質ほぼ常に定価
  • 直し方は、MCPの1サーバー化だけ

cached単価が表示どおりに実適用されることは、別modelでも確かめた。手元のmodels listには1行だけ1/10でなく1/40のcached単価 ($0.25/M) を持つmodelがあり、こちらも26ターン実測 (+4.0pt) が$0.25/Mからの予測と一致した (1/10解釈なら+8.7ptになるので棄却)。単価表の表示は実課金に効いている。

運用指針: どこまで直る・直らない

運用形態 cache 理由
one-shot (devin -p) 常に定価 毎回新規session — rules/skills/MCPが再シャッフルされる
multi-turn・デフォルト ほぼ定価 session内でもMCP一覧が毎ターン再シャッフルされる
multi-turn・1サーバー化 turn2以降1/10 prefixがbyte同一になる (本稿のworkaround)

one-shot主体の運用なら、消費は「トークン実数 × 定価」の線形モデルで正確に予測できる (実測が定価線形に乗ることを110呼びで確認済み — 誤差は数%以内)。multi-turnで重い仕事を回すときだけ、1サーバー化がコスト削減として効く。

最後に、Astraをいつ使うか。手元の記録では、長文の難物 (お手本の構造守らせる記事化タスク) で品質はお手本水準を満たした一方、所要46-49秒かかった (同タスクのSolは15-18秒)。軽い起草なら品質はLuna/Sol級で飽和していて、コスト差 (1〜2桁) を払う意味がない。「長文の難物だけAstra・それ以外は安いmodel」+「重いmulti-turnは1サーバー化」の組み合わせが、今のところ割に合う使い方だと判断している。

この「固定文脈 × 単価」の構造が分かっていれば、利用枠の実金額を逆算するのにも使える。整数%表示のゲージから週次枠の$を点確定する手順 (連続flip法) は、前回の記事に書いた:

サブスクAIの週次利用枠は整数%表示から確定できる — 外部消費が混ざっても崩れない連続flip法

同じゲージを見る2つの視座として、合わせて読める。

限界 (実測できていないこと)

  • 検証できたのはinput側の課金のみ。output単価 ($50/M表示) が表示どおりに課金されるかは、実験がすべて数tokenのecho応答で信号がなく、未計測である
  • 単価はCLI表示のrate card (API公開単価とは別レート)・v3000.6.14時点の値
  • 割引の観測はusageゲージ (整数%) の読み取りなので、fitの精度は±1pt程度
  • skills構成やMCP台数が違う環境では、最初のシャッフル地点までの長さが変わり、best caseの部分hit率も変わる (構造 «順序が壊れるとhitしない» は同じ)

参考

本稿の実測に使った生データ (起草出力4本・models list保存) は assets/qiita/astra-prompt-cache-record/ に置いた。SHA1比較とfit計算は本文中の手順どおり sessions.db から再現できる。

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?