- Pi の edit ツールで Claude Opus 4.8 と Sonnet 5 が
edits[] 内にスキーマにないフィールドを付け足し、呼び出しが拒否された。最新モデルほど特定のツールスキーマに以前のモデルより従えない現象が観測された
- ツール呼び出しは、モデルが特殊マーカーと JSON 形式のテキストを生成する過程であり、制約のないサンプリングでは学習された慣例がスキーマより優先されうる
- 失敗例では
oldText と newText 自体は正しかったにもかかわらず、requireUnique, oldText2, matchCase, in_file のような偽のキーが付加され、エージェント履歴や thinking block の有無によって再現率が変わった
- Claude Code はクローズドなハーネスだが、誤った呼び出しの再試行、パラメータ別名、型補正、Unicode 復旧、不明キーのフィルタリングなど緩い補正を多く行っており、
strict モードは使っていない
- Anthropic の
strict ツール呼び出しはこの問題を解消し、モデル性能が上がるほど代替ツールスキーマが不利になるなら、ハーネスには文法制約のようなより強い保証が必要になる
Pi edit ツールで起きた回帰
- Pi issue を追跡している途中、最新の Claude モデルが Pi の edit ツールを呼び出す際に
edits[] 配列の中へ存在しないフィールドを追加する問題が見つかった
- 小さいモデルではなく Opus 4.8 で発生し、Sonnet 5 でも同じ現象が確認された
- 以前の Anthropic モデルでは同じ問題が見られなかったため、最新の高性能モデルがこの特定のツールスキーマではむしろ悪く振る舞っている
- Fable は分類器が要求をひそかに Opus に落とす可能性があるためテストしていない
ツール呼び出しはテキスト生成に近い
- LLM のツール呼び出しは、モデルが会話履歴、システムプロンプト、利用可能なツール一覧を受け取ったあと、特殊マーカーを含む大きなプロンプトの中で呼び出し形式を生成する方式で行われる
- ファイル編集ツールの想定引数は、次のように
path と edits 配列を含みうる
{
"path": "some/file.py",
"edits": [
{
"oldText": "text to replace",
"newText": "replacement text"
}
]
}
- ハーネスは引数を検証して編集を実行したあと、その結果を再びモデルへ渡し、検証失敗時にはモデルはエラーを見て通常は再試行する
- Anthropic モデルの内部フォーマットは公開されていないが、
ANTML マーカーが流出したり公開コミュニケーションに現れたりしたことがある
- このフォーマットは XML のように見えるが、実際の XML というよりはトークン化や学習に都合の良いインバンド信号に近い
- 最上位の文字列パラメータはインラインで入ることがある
- オブジェクト配列は JSON シリアライズの形で入るように見える
制約なし生成と文法制約生成
- モデルが構造化出力を作る方法は大きく 2 つある
- モデルにスキーマに合う JSON を生成するよう求め、事後検証する
- サンプラーが不正な JSON やスキーマ形状を最初からサンプリングできないよう防ぐ
- 後者は文法認識デコーディングまたは制約デコーディングと呼ばれ、文法に違反するトークンをマスクする
- スキーマが
oldText と newText だけを許すなら、サンプラーは "in_file" や "type" のようなキー生成を防げる
- このような制約がなければ、モデルは抽象的な契約を厳密に守るよりも、学習済みの慣例に従って生成する
実際の失敗パターン
- Pi の edit ツールは、1 回の呼び出しで複数の正確な文字列置換をサポートするため
edits 配列を使う
- 失敗した呼び出しでは、次のように許可されていないフィールドが付いていた
{
"oldText": "...",
"newText": "...",
"requireUnique": true
}
{
"oldText": "...",
"newText": "...",
"oldText2": "",
"newText2": ""
}
- 反復実験で出た偽キーは
type, id, kind, unique, requireUnique, matchCase, in_file, forceMatchCount, children, notes, cost, oldText2, newText2, oldText_2, newText_2, event.0.additionalProperties など多様だった
- 確認された誤った呼び出しでは、実際の
oldText と newText ペイロードはバイト単位で正確だったにもかかわらず、オブジェクト末尾に意味不明なキーが付いて呼び出しが拒否された
- 再現は文脈に大きく左右された
- 新しい単一ターンのプロンプト「edit this file」では再現しない
- モデルがファイルを読み、問題を診断し、複数行編集を構成したエージェント履歴では再現する
- Petr Baudis のトランスクリプトがないと再現できなかった
- そのユーザーセッションを継続すると Opus 4.8 は約 20% の確率で失敗した
- 履歴から thinking block を削除すると失敗率は半分に下がった
strict ツール呼び出しを有効にすると、その実行では問題が消えた
なぜ悪化したのか
- 最も有力な仮説は、これがランダムな性能低下ではなく学習の産物だという点だ
- 以前の Anthropic モデルは一部のツールで学習されていたが、Claude Code のようなユーザー提供ハーネスが明確な目標になる前だった
- 最新の Anthropic モデルは Claude Code、あるいはそれに非常に近いハーネスを含む事後学習を受けた可能性が高く、その環境で成功するツール呼び出しと許容されるミスの両方を学習した可能性がある
- Claude Code の edit ツールは、Pi の入れ子になった
edits[] 構造ではなく、file_path, old_string, new_string, 任意の replace_all に近いフラットな構造になっている
- Claude Code クライアントは、誤ったツール使用の再試行、パラメータ別名、型の強制変換、Unicode 復旧、不明キーのフィルタリングなど、かなりのエラーを補正する
- 強化学習がそのようなハーネスやそのシミュレーション内で行われるなら、少し間違ったツール呼び出しでもタスクを完了して報酬を得られる
- 別のハーネスが同じ意味の編集ツールを異なるスキーマで提供すると、モデルにとっては次第に分布外のツールになりうる
- Opus 4.5 のリリース時には別の edit ツールにも非常によく適応していたが、今回観測された方向性は、代替ツールスキーマが特定の寛容なツール生態系では不利になりうることを示している
- 文書化された text editor tool はあるが、Claude Code はその形式をそのまま使っておらず、Claude Code の内部動作はクローズドソースのハーネスのため見えない
Claude Code の緩いハーネス
- Claude Code はクローズドソースだが、縮小されたコードを見ると入力データに非常に寛容である
- モデルの可視テキストに
<invoke マークアップが漏れていないか確認し、その場合はテレメトリを送信したうえで独自の状態機械により誤った呼び出しを再試行する
- 文字列値の中にある壊れた
\uXXXX シーケンスや lone surrogate を直すUnicode エスケープ復旧がある
- ツールごとのパラメータ別名もある
Edit は old_str, old_string, new_str, new_string を受け入れる
path を file_path の別名として受け入れる
- 想定外のキーは黙ってフィルタリングする
strict モードは使っていない
- Anthropic は
strict モードでツール定義の複雑さ制限を適用し、API リクエストが失敗することがある
- Claude Code が
strict モードを試さない理由はこれに見える
strict モードと他の生態系
- Anthropic のモデルとハーネスはどちらもクローズドで、他のハーネスでも同じ問題が続くか判断しづらい
- Codex モデルもクローズドだが、ハーネスはクローズドではない
- gpt-oss は OpenAI の harmony 応答形式を使うよう明示的に学習されており、OpenAI 側の考え方を示す文書も多い
- harmony はチャンネルとツール呼び出しコンテンツ型をプロンプト形式の一部にし、ツール呼び出し本文に
<|constrain|>json のようなマーカーを含められる
<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
<|constrain|>json は、推論スタックがツール呼び出し本文で JSON 制約サンプリングへ切り替える境界を簡単に見つけられるようにする
- ホスティングされた GPT モデルには、ユーザーツールが従うべき文法のために LARK 文法を提供するオプションもある
- Anthropic も
strict モードでは何らかの類似処理をしているようだが、入れ子配列パラメータではモデルが長い複数行ファイル内容を文字列リテラル内へエスケープした JSON として生成しなければならない
- 偽キーは、数百トークン長の
newText 文字列を閉じた直後、モデルが } と , "..." のどちらかを選ばなければならない高エントロピー地点で現れる
- Opus 4.8 と Sonnet 5 は、edit ツール呼び出し形状に対してより強い事前分布を持っているように見え、その事前分布は Claude Code のフラットな edit スキーマに近い
- Anthropic の
strict モードが問題を直すという点は、サーバー側で JSON スキーマ構造上許されないキーのサンプリングを拒否しているためかもしれない
- テストした Codex モデルではこの種の回帰は見られず、アクセス権のない 5.6 は除外された
ハーネス設計への影響
- Anthropic モデルにおいてツールスキーマは中立的な抽象契約ではないかもしれない
- あるツール形状は事後学習で見たものに近く、ある形状は遠い
- ある形状は提供者の隠れたエンコーディングでは簡単でも、別の形状は長い複数行文字列の後に入れ子配列の中で大きなエスケープ JSON オブジェクトを書かねばならず、難しくなることがある
- モデルがスキーマを理解していても、圧力のかかる状況では正確な構造のサンプリングに失敗することがある
- Anthropic では
strict サンプリングを有効にすればこの問題は消える可能性がある
- ただし最新モデルの振る舞いは、強化学習がモデルに及ぼす影響を示しており、特定ハーネスの事前分布と戦うやり方は最高性能を得るうえで不利になりうる
- Claude Code はオープンソースではなく、RL 環境で何をしているかも分からないため、Claude Code に合わせて学習された振る舞いが他のツールへきれいに転移すると仮定しにくい
- ひとつの支配的ハーネスの中で事後学習が進むほど、他のハーネスはそのハーネスの奇妙な特性を引き継がなければならなくなる
- 制約デコーディングには品質トレードオフがありうるが、最新モデルがタスク解決能力は向上しつつ代替ツールスキーマを忠実に出力する能力は悪化しているなら、ハーネスのどこかにより強い保証が必要だ
1件のコメント
Lobste.rs の意見
Fable が気になるなら、Fable は今ではダウングレードするときに必ず明示的に知らせるものだと理解している
自分も分類器に引っかかったことがあるが、「バグを深刻度順に並べて」がセキュリティ研究っぽく聞こえたらしい
裏でこっそりやるつもりはないと言っていたのは知っているが、ダウングレードに使うメカニズムはまだ確認できていない
この仮説が正しければ、影響はコーディングエージェントを超える可能性が高い
安定したツール呼び出しに依存するアプリケーションなら、モデルが特定プロバイダーの好む実行環境に合わせて後学習されたあと、同様の性能低下を経験するかもしれない
ちなみにこの記事は
vibecodingではなくaiとして投稿したこのサイトで
vibecodingの境界がどこにあるのか、本当に理解しにくいこの記事は基盤となる LLM、強化学習、そしてその周辺の実行環境を作ることにずっと関係が深い
これまで
vibecodingなら、aiタグはどこで使われるために残っているのか分からないvibecodingは、生成AIに少しでも触れている、あるいは触れていそうに見えるあらゆるものに付く巨大な緋文字のようになってしまった雰囲気のあるブログ記事、LLM による貢献を禁じる主要プロジェクトの README、「X ではなく Y」のような文が多すぎる記事まで、ここ数週間ですべて
vibecodingタグが付けられていた個人的には、そのタグを気にするのを完全に諦めた。コミュニティがあまりに反射的に付けるので、実際の意味が失われたからだ
ただし、この特定の記事は、いわば実際にその用途に使われるモデルに関するものなので、
vibecodingタグが付くことには同意する同時に、指摘した理由そのままに、
aiが削除されるべきではないことにも同意する。追加し直したいが、なぜかこの記事ではその選択肢がない驚きではない。ベンダーロックインはおそらく計画の一部である可能性が高い
「Claude のサブスク料金を払って、すでにすべてのコードをこちらに送っているなら、モデルとは別には十分強いロックイン手段ではないかもしれない無料 UI も必ず使わなければならない」というのは、純粋なベンダーロックインが通常進むやり方とは少し違う
モデルが、自分が学習された実行環境、つまりモデル開発者が作った環境で最適に動作するのは筋が通っている
Claude Code のようなトレース履歴に対して大量の強化学習を受けているなら、Claude Code のように動作しない実行環境ではかなり悪化するだろうと予想していたはずだ
個人的には、Pi のようなサードパーティの実行環境でもかなりうまくやるようなので、むしろそちらのほうが驚きだった
バグがエージェントのトレースの深いところでだけ発生するというのも妥当に見える
今年初め、GPT 5.2 と 5.3 モデルで、トレースの後半にエージェントが
ls -laの代わりにls -ლაを出力するバグに悩まされた簡単にここに記録しておいた: https://github.com/openai/codex/issues/7988
自分の経験では、これもトレースが深くなったあとにだけ発生した
長い文脈では、モデルが明確に「考える」ことができず、原始的な本能に戻るように見える
おそらくその時点で、モデルの学習分布と、実行環境またはユーザーがモデルに強制する作業との差が、性能に最も劇的な影響を与えるのだろう
強化学習しすぎて、以前のリリースに比べて他の実行環境で退行していることが問題なのだ
この時点では、「別の種類の過適合も始まっているのではないか?」といった問いを立てるべきだ