独立した非公式の情報 · Anthropicとは無関係 · 何もブラウザの外に出ません

Claude Codeが実際にどのモデルで動いたかを、自分で確認する

モデルを固定したのに、品質が揺れて、勝手に安いモデルに切り替わっている気がする。あるいは統計の画面の「よく使うモデル」が実感と合わない。UIから推測する必要はありません。Claude Codeが書き出すターンごとのログには、APIが実際に応答したモデルがそのまま記録されています。その読み方を説明します。

正本になるフィールド。 セッションは1行1件のJSONとして ~/.claude/projects/<project>/<session-id>.jsonl に記録されます。"type":"assistant" の各行の message.model が、そのターンで実際に提供されたモデル(APIが応答したモデル)で、同じ行に timestamp が入っています。これが地に足のついた事実で、どんなUIの要約よりも信頼できます。

1 · ターンごとに、提供されたモデルを時刻つきで一覧する

「昨夜はなんだかSonnetっぽかった」という感覚を、報告にそのまま貼れる日付つきの記録に変えます。全セッションを通して、各 assistant のターンの提供モデルを時刻の順に並べます。そのまま貼り付けてください。

for f in ~/.claude/projects/*/*.jsonl; do
  python3 - "$f" <<'PY'
import sys, json
for line in open(sys.argv[1]):
    try: d = json.loads(line)
    except: continue
    if d.get("type") == "assistant":
        m = d.get("message", {}).get("model")
        if m and m != "<synthetic>":
            print(d.get("timestamp",""), m)
PY
done | sort

1行が1つの提供ターンです(例: 2026-06-07T01:23:45.678Z  claude-opus-4-8)。固定したものより下位のモデルが続く区間があれば、それが証拠です。正確なUTCの時刻があるので、自分の作業と突き合わせられます。

2 · モデル別にターン数を集計する(報告で効く数字)

上の一覧を、モデルごとのターン数に畳み込みます。報告を具体的にする一番効く数字です。

cat ~/.claude/projects/*/*.jsonl | python3 -c '
import sys, json, collections
c = collections.Counter()
for line in sys.stdin:
    try: d = json.loads(line)
    except: continue
    if d.get("type")=="assistant":
        m=d.get("message",{}).get("model")
        if m and m!="<synthetic>": c[m]+=1
for m,n in c.most_common(): print(f"{n:7d}  {m}")
'

提供の多い順に、モデルごとのターン数が1行ずつ出ます。claude-opus-4-8claude-sonnet-4-6 の横に件数が並びます。

3 · 直近N日だけの集計(古い「よく使うモデル」を見抜く)

全期間の集計は、提供されているものと正反対になりえます。最近を無視した統計の「よく使うモデル」が誤解を招くのも同じ理由です。実際のあるマシンでは、2つの窓が完全に逆転していました。

期間最も多い提供モデル割合
直近30日claude-opus-4-780%
直近7日claude-opus-4-873%

そこで、最近の窓だけで集計します。DAYS は好みで変えてください。

python3 - <<'PY'
import json, glob, os, collections, datetime
DAYS = 7
cut = (datetime.date.today() - datetime.timedelta(days=DAYS)).isoformat()
c = collections.Counter()
for f in glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")):
    for line in open(f):
        try: d = json.loads(line)
        except: continue
        if d.get("type") == "assistant":
            m = d.get("message", {}).get("model"); t = d.get("timestamp", "")
            if m and m != "<synthetic>" and t[:10] >= cut:
                c[m] += 1
tot = sum(c.values()) or 1
for m, n in c.most_common():
    print(f"{n*100//tot:3d}%  {n:6d}  {m}")
PY

各行が最近の窓でのモデル別の割合です(例: 73%  24773  claude-opus-4-8)。傾向が変わった「よく使うモデル」が一目で分かります。

モデルIDの読み方

IDは明示されているので、別の段に移った瞬間が分かります。実在する現行の例です。

message.model のID意味
claude-opus-4-8Opus 4.8(最上位)
claude-opus-4-7Opus 4.7(最上位)
claude-sonnet-4-6Sonnet 4.6(中位)
claude-haiku-4-5-20251001Haiku 4.5(高速・下位)

本当に報告する価値があるのはどれか

すべての差が同じ重みではありません。見つけたものを、影響の大きさで仕分けてください。

そして、逸話でなく再現できる形にします。

ログが何を証明するかについては誠実でいましょう。message.modelどのモデルがそのターンを提供したかを教えてくれます。それ自体は、意図や「わざと下げた」ことまでは証明しません。観測した事実(ターンごとの提供モデルと時刻)を報告し、原因の判断はルーティングを監査できる人に委ねてください。

本ページは、自分のセッションのログに対するローカルな検証方法の説明であり、アカウントや法務の助言ではなく、Anthropicのルーティングの意図についての主張もしません。モデルやUsage Policyの疑問は、Anthropic自身の文書とサポートで確認してください。文脈として参照した報告: anthropics/claude-code #65889(固定したモデルの静かなルーティング)、#65899(統計の「よく使うモデル」が最近を反映しない)。