Opus 4.8のツール呼び出しが退行する。Flask作者が検証

Opus 4.8のツール呼び出しが退行する。Flask作者が検証

オープンソースのAIコーディングエージェントPiで、Anthropicの最新モデルがスキーマどおりにツールを呼べなくなっている。正解を出しながら、余計なキーを付け足す。古いモデルでは起きない。


編集は合っている、引数が壊れている

Flaskの作者アーミン・ロナッハー(Armin Ronacher)氏が7月4日、自身のブログで奇妙なバグを報告した。同氏が設立したEarendilのもとで運営されるオープンソースのAIコーディングエージェントPiで、Claude Opus 4.8がファイル編集ツールの呼び出し時にスキーマにないキーを勝手に付け加えている。

Piの編集ツールは、1回の呼び出しで複数の文字列置換を実行できるようedits配列を受け付ける。各要素に許されるキーはoldTextnewTextの2つだけだ。ところがOpus 4.8は、この配列の中にrequireUniquetypematchCasein_filechildrencostなど、存在しないキーを次々に出力する。

厄介なのは、oldTextnewTextの値自体はバイト単位で正確だった点だ。モデルは正しい編集内容を組み立てながら、オブジェクトの末尾に不要なキーを挿入する。Piはスキーマ検証で弾き、モデルにリトライを要求する。

ロナッハー氏の検証では、Opus 4.8に加えてSonnet 5でも同じ現象が確認された。Opus 4.5以前のモデルには出ない。つまり、Anthropicの最新モデルほどこの退行が強い。

再現条件は「エージェンティックな履歴」

この不具合は単純なプロンプトでは再現しない。ファイルを読み込み、問題を診断し、複数行にわたる編集を組み立てるようなエージェンティックな会話履歴がある場合に発生する。

ロナッハー氏自身も当初は再現に苦労した。最終的に、Rossum共同創設者のペトル・バウディス(Petr Baudis)氏がPiのイシュー#6278に投稿したセッションデータを使って再現に成功した。バウディス氏のセッションでは、Opus 4.8の編集呼び出しのうち約20%が不正な引数で失敗していた。

思考ブロックを履歴から除去すると失敗率はおよそ半分に下がった。AnthropicのAPIでstrictモードを有効にすると、ロナッハー氏のテストでは完全に解消した。

Claude Codeの学習痕跡

ロナッハー氏はこの退行を、Claude Code向け事後学習の副作用と見ている。

旧世代のClaudeモデルが訓練された当時、Anthropicにはまだユーザー向けのコーディングハーネスがなかった。現在のモデルは事後学習(ポストトレーニング)にClaude Code、あるいはそれに近い環境を使っていると考えられる。

Claude Codeの編集ツールはPiとは構造が異なり、file_pathold_stringnew_string、オプションのreplace_allフラグというフラットな構造を取る。ネストされたedits配列は使わない。

ロナッハー氏はClaude Codeのミニファイ(圧縮・難読化)されたコードを調査し、その許容度の高さを確認している。パラメータのエイリアス(old_strold_stringの両方を受け付ける)やUnicodeエスケープの修復に加え、未知のキーを無言で除去し、strictモードも使っていない。

この環境で強化学習が行われた場合、多少不正確なツール呼び出しでもタスクを完了でき、報酬を得られる。余計なキーが混ざっていても、ハーネスが黙って無視するためペナルティが発生しない。

ロナッハー氏はさらに踏み込んだ分析を示している。Opus 4.8は「編集操作にはオプションのフィールドが1つ追加される可能性がある」とClaude Codeの構造から学習した。

だがPiのネストされたoldText/newText構造では、そのフィールドに対応する名前を持っていない。そこでモデルはサンプリングのたびに新しいキー名を作り出す。失敗時に毎回異なるキーが出現するのは、1つの安定したエイリアスではなく、その場で即興に作っているためだと分析する。

高エントロピー地点での破綻

ツール呼び出しの内部構造も、この不具合が起きやすい理由を説明する。

Anthropicのモデルはツール呼び出し時、内部的にXML風のマーカーで引数をシリアライズしている。トップレベルの文字列パラメータはインラインで記述されるが、オブジェクト配列のようなネスト構造はJSONとして書き出される。

Piのedits配列では、数百トークンに及ぶエスケープ済みファイル内容を含む文字列を閉じた直後に、}で要素を閉じるか , "..."で新しいキーを追加するかの分岐が訪れる。

これはサンプリング上最もエントロピーが高い地点だ。制約なしでは、Claude Codeの訓練で獲得した「編集オブジェクトにはもう1つフィールドがあるはず」という事前確率が勝ち、存在しないキーが出力される。

ツール呼び出し設計の3者比較
Claude CodePigpt-oss
スキーマ構造フラット構造ネスト配列harmony
フォーマット
不正キー処理無言で除去検証で拒否インバンド制約
ソース公開クローズドオープンオープン
strict検証不使用API側で有効化モデルが制約宣言
Opus 4.8退行N/A約20%失敗未確認

OpenAIとの設計思想の違い

ロナッハー氏はOpenAIのアプローチとの比較も行っている。

OpenAIが公開したオープンウェイトモデルgpt-ossは、harmonyと呼ばれるレスポンスフォーマットで訓練される。ツール呼び出し時には<|constrain|>jsonというマーカーをモデル自身がインバンドで出力し、推論スタックがそのマーカーを検知してJSON制約付きサンプリングに切り替える。gpt-ossのモデルもハーネスもクローズドではなく、この仕組みが文書化されている。

Anthropicのモデルとハーネスは双方ともクローズドだ。APIドキュメントにはテキストエディタツールの仕様が公開されているが、Claude Codeは実際にはこの公開仕様に従っていない。内部で何が行われているかは外部からは見えない。

ロナッハー氏がテストしたCodexモデルでは、この種の退行は確認されなかった(ただしCodex 5.6はアクセス権がなく未検証)。

ハーネス開発者への影響

Anthropicのモデルにとって、ツールスキーマは中立ではない。事後学習で見た形状に近いスキーマは正確に処理され、遠い形状にはモデルの事前確率が干渉する。

Opus 4.5の時点では、指示が適切であればどんなツール形状にも適応できる方向に進んでいるとロナッハー氏は感じていた。今はその認識が変わったと述べている。

Claude Code以外のツールスキーマは、単に未知であるだけでなく、特定の寛容なハーネスに最適化された事後学習によって暗黙に罰せられる可能性がある。

制約付きデコーディング(モデルの出力をスキーマに従って制限するサンプリング手法)には品質面でのトレードオフがあり、ロナッハー氏は以前は懐疑的だったという。だが今回の不具合で考えが変わった。最新モデルがタスクの解決能力で上回りながら、スキーマへの忠実度で劣化するなら、ハーネス側でより強い保証を組み込む必要がある。

Piではすでに対応が進んでいる。#6278のイシューを受けて、モデルが余分なフィールドを混入させても有効な編集を拒否しないよう修正が入った。AnthropicのAPIが提供するstrictスキーマ検証の活用も議論されている。

関連記事

この記事を共有する

Read more