AI・機械学習
Claude Code: 誤機能の解剖
Claude Code: Anatomy of a Misfeature (olafalders.com)
要約
AnthropicのClaude Code 2.1.198に、ユーザーの応答がない場合に60秒後に自動的に処理を続行する「効率バイパス」機能が、ドキュメント化されずに実装されました。この予期せぬ挙動は、ユーザーの意図しない操作やリソースの無駄遣いを引き起こす可能性があり、大きな混乱を招きました。数日後に修正パッチがリリースされましたが、この出来事は開発プロセスにおける透明性とユーザー信頼の重要性を浮き彫りにしました。
全文翻訳
Claude Code: 誤機能の解剖
by Olaf Alders · 2026年7月17日 · 29分読書 · 6,163語
目次
"Mechanical egg timer" by Hustvedt は CC BY-SA 3.0 のライセンスで提供されています。より広いフレームにパッド加工されており、この適応も同様に CC BY-SA 3.0 のライセンスです。
2026年7月1日、カナダデーに、AnthropicはClaude Codeのユーザーに驚くべき「イースターエッグ」をリリースしました。バージョン2.1.198には、エージェントが人間の指示なしに処理を続行できる効率バイパスが含まれています。これにより、Claude Codeが入力を求めた後、実質的に60秒のタイマーが作動します。このウィンドウを逃すと、Claude Codeは最善と考えることを実行し、処理を続行します。これは以下のようになります。
● Claudeが質問しました: ⎿ …
● 60秒応答なし — 回答なしで続行
● ユーザーが離席しました。最善の判断で続行します。私の計画:
注: 上記は私のClaudeセッションからそのまま引用したもので、質問はトリミングされています。
この挙動に驚いたなら、あなたは一人ではありません。考えられる結果を検討してみましょう。
サンドイッチを作っている間、ラップトップをキッチンに持っていく必要がありますか?このウィンドウ中にAFK(Away From Keyboard)だった場合、どうなりますか?
同時にいくつものエージェントを実行していますか?それらすべてを同時に監視できますか?もし2つ以上のエージェントが同じ60秒のウィンドウで入力を求めてきたらどうなりますか?
エージェントが間違った選択をした場合はどうなりますか?その間にどれだけのトークンが消費されたでしょうか?
デプロイメントにエージェントを使用している場合はどうなりますか?(はい、知っていますが、もしそうしたら?)
これらは、この機能をリリースする際に考慮すべき合理的な点であり、おそらく変更履歴にその理由を文書化したでしょう。しかし、もし変更履歴で新しいデフォルトについて一切言及しなかったらどうなるでしょうか?さらに驚くべきことではないでしょうか?(ネタバレ: そうでした!)
この話には(ある種の)ハッピーエンドがあります。速く動いて壊すことは、速く動いて直すことを必ずしも排除しません。数日以内に修正がリリースされましたが、それは製品に対するユーザーの信頼をどうするのでしょうか?
私たちはいくつかのことを学びました。
Claude Codeの驚くべき機能は、理論上(そして実際には)毎日Anthropicによってリリースされる可能性があります。
すべての機能が必ずしも変更履歴に記載されるとは限りません。
デフォルトであるべきではないものには、文書化されたオフスイッチがない場合があります。
Claude Codeの自動更新機能は、初期に思っていたよりもYOLOモードに近いようです。
まだわかっていないことがいくつかあります。
この方程式に人間はどのように関わっていますか?
この機能は人間が考案したのでしょうか?
この機能は人間が(またはエージェントに)書いたのでしょうか?
この機能は人間がレビューしたのでしょうか?
この機能は人間が承認したのでしょうか?
この機能は人間がマージしたのでしょうか?
この機能を文書化しない、または変更履歴に追加しないことを人間が選択したのでしょうか?
人間がリリース管理者に、リリースを前回のリリースと比較し、承認の印を与える前に承認させたのでしょうか?
個人的には、人間がこれらのステップすべてを「これは良い考えか?」と尋ねずに管理していたとは信じがたいです。もしClaude Codeが実際に機能を構築し、リリースし、承認し、そして文書化に値しないと判断したと言われたら、それはより信じやすいことですが、私にはわかりません。おそらくそれらの両方の組み合わせでしょう。おそらく多くのことが間違ったのでしょうが、これが起こるべきではなかったことは明らかだと思います。そして、私は少なくとも一度、「本番環境に深刻なバグを混入させた」とマネージャーに言われたパフォーマンスレビューを受けた人間として、これを言っています。
この出来事がどのように起こったのか、そして公開記録でどのような事後分析が利用可能かについて、少し考えてきました。そこで、Claude Code自身に調査を依頼しました。Claudeの功績として、このコードに関する自己反省を防ぐフィルターがないようです。したがって、完全な開示として、以下は主にClaudeの作業によるものです。その価値はそれ次第であり、もし重要な仮定に依存するなら、それを単独で再現する価値があります。
Claudeの調査はここから始まります。
タイムライン
2026-06-29 — 2.1.196 リリース。レポーターの「最後の動作バージョン(推測)」
2026-06-30 — 2.1.197 リリース。変更履歴に1行、Sonnet 5のローンチ
2026-07-01 — 2.1.198 リリース — レポーターがリグレッションをピン留めするバージョン。公開コミットは変更を示していません。このリリースの唯一の公開トレースは、CHANGELOG.mdとfeed.xmlのみを触るノート(75709ea)を公開するボットコミットです。
2026-07-02 02:54 UTC — issue #73125 が Aleksey Nogin によって提出される
2026-07-02 03:45 UTC — コメンターがエスケープハッチを発見: CLAUDE_AFK_TIMEOUT_MS。スレッド内でピアツーピアで交換され、リリースノートから参照されていません。
2026-07-02 — 2.1.199 が issue を開いたまま24エントリをシップ。まだ言及なし。
2026-07-03 — 2.1.200 が挙動を元に戻す。再び、唯一の公開トレースはノートコミット(1322e9b)です。
2026-07-04 18:04 UTC — issue がクローズされる
issue の反応/規模: 384 👍, 143 コメント — ニッチな苦情ではない
レポーターの環境: 2.1.198、「最後の動作 2.1.196(推測)」、Opus、AWS Bedrock、VS Code ターミナル
git clone https://github.com/anthropics/claude-code.git
cd claude-code
# 修正はいつ、どのバージョンで着陸したか?
git log -1 --format='%h %ai' -S'no longer auto-continue by default' -- CHANGELOG.md
# 1322e9ba 2026-07-03 16:52:26 +0000
# バグをシップしたバージョンはいつ着陸したか?
git log -1 --format='%h %ai' -S'## 2.1.198' -- CHANGELOG.md
# 75709eac 2026-07-01 20:45:29 +0000
誤機能
AskUserQuestion は、Claude Code がタスクの途中で停止して人間に質問するために使用するツールです。
新しい挙動: 60秒の非アクティビティの後、ツールはブロックする代わりに「とにかく続行」という結果を自動的に返します。
モデルに渡されるメッセージ — これはテンプレートであり、60秒のデフォルトでレンダリングされています。
// v2.1.198、そのまま。`Thl` はミニファイアの名前です。文章はバイナリ自身のものです。
// "60s" は補間されており、ファイル内のリテラルではありません:
function Thl(e){return `No response after ${Math.round(e/1000)}s — the user may be away from keyboard. Proceed using your best judgment based on the context so far; you can re-ask this question later if it's still relevant.`}
「後で再質問する」というエスケープハッチは循環的です。再質問された質問は、同じタイムアウトにヒットします。Aleksey Nogin は、issue を提出してから数分以内に issue スレッドでこの点を指摘しました。
トランスクリプト行には2つのバリアントがあります — バイナリは、あなたが回答を開始したかどうかによって、そのうちの1つを選択します。
// v2.1.198、そのまま。`a` は "some answers exist" のミニファイア名です。
// (`s=Object.entries(r)` answers over, `a=s.length>0`); 両方の文字列値はバイナリ自身のものです。
let d=a?