powered by TechFeed
表示モード
Deep Dive

Claude CodeはAGENTS.mdをテレメトリ無効環境で無言でスキップする — リバースエンジニアリングで判明した仕様と回避策

9月23日、blog.szypowi.czが「Claude Code reads AGENTS.md only when telemetry is on」と題した記事を公開した。テレメトリを無効化したClaude Code環境でAGENTS.mdが一切読み込まれない——しかも警告は一切出ない——という挙動を、バンドルのリバースエンジニアリングと実測によって詳細に検証した内容だ。

9月23日、blog.szypowi.czが「Claude Code reads AGENTS.md only when telemetry is on」と題した記事を公開した。テレメトリを無効化したClaude Code環境でAGENTS.mdが一切読み込まれない——しかも警告は一切出ない——という挙動を、バンドルのリバースエンジニアリングと実測によって詳細に検証した内容だ。

AGENTS.mdは、OpenAI Codexが採用したエージェント向け指示ファイルのデファクト標準として広まりつつある仕様だ。複数のAIコーディングツール間で同一の指示ファイルを使い回せるという触れ込みで、Claude Codeもバージョン2.1系でサポートを追加した。しかし、プライバシーを重視してテレメトリを切っているユーザーや、AWS BedrockGoogle Vertex AI経由でClaude Codeを使っているチームでは、この機能が「公式にサポートされているにもかかわらず静かに動いていない」状態になりうる。


バンドルに埋め込まれたリモートフィーチャーフラグ

Claude Code 2.1.280のバンドルを読むと、AGENTS.mdのローダーはagents-mdという組み込みプラグインとして実装されている。問題の核心は以下のコードにある:

var W = !1;
var B = () => Oa("tengu_agents_md_mod", W);

W(デフォルト値)は**falseで、B(機能の利用可否判定)はリモートフィーチャーフラグtengu_agents_md_modをサーバーに問い合わせる。フラグが取得できない場合のフォールバックもfalse**だ。なおtenguはClaude Codeのバンドル内で使われている内部コードネームで、複数箇所で確認できる。

つまり、ディスク上のMarkdownファイルを読み込むだけの処理が、サーバー側のスイッチを待っている。ローカルファイルの読み取りにネットワーク接続は本来不要なはずだが、段階的ロールアウトのためにリモートフラグを挟んだ設計になっている。テレメトリが無効な環境ではこのフラグがtrueに解決されることがなく、機能がそのまま無効化される。

実測で確認した挙動

筆者はGitHub Issue #95690の調査に端を発し、「カナリアワード」を用いた検証を実施した。AGENTS.mdに固有の単語を書き込み、claude -pでその単語を答えられるかを確認する方法だ。フラグの仕様上、最初のセッションでフラグを取得し2セッション目から有効化されるため、各設定で2回セッションを走らせている:

echo 'The canary word is PERIWINKLE.' > AGENTS.md
claude -p 'What is the canary word from the project instructions? Answer NONE if you have none. Do not read files.'

確認された挙動をまとめると:

  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 → AGENTS.mdが読み込まれない
  • DISABLE_TELEMETRY=1 → 同様に読み込まれない
  • これらの変数を0に設定しても効果なし公式ドキュメントには「いかなる値でも有効」と明記されている)
  • .claude/settings.jsonenvブロックで変数をクリアしても効果なし(リポジトリ単位での回避は不可能)
  • セッション起動時の--settingsオプションで明示的にクリアすれば2セッション目から動作する
claude --settings '{"env":{"DISABLE_TELEMETRY":"","CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC":""}}'

さらに、BedrockやVertex AI、サードパーティゲートウェイ経由でClaude Codeを使っている場合も同じ問題が発生する。いずれもリモートフラグがtrueに解決されることがないためだ。組織のポリシーでBedrockやVertexを使っているチームにとっては、回避のしようがない状態になる。

回避策:1行のCLAUDE.md

CLAUDE.md@pathインポート構文はフィーチャーフラグに依存しない。AGENTS.mdと同じディレクトリに以下の1行ファイルを置くだけで解決する:

echo '@AGENTS.md' > CLAUDE.md

テレメトリを無効化したままでも、カナリアワードが正しく返ってくることを筆者は確認済みだ。ただし「AGENTS.mdというファイル1つで済む」はずだったものに余分なファイルを加える対応であり、根本的な解決とは言えない。

問題の本質:無言でスキップされること

筆者が最も問題視しているのは警告なしに機能が無効化される点だ。プライバシー設定がローカルファイルの読み込みという無関係な動作を静かに無効化するため、ほとんどのユーザーは「モデルが指示を無視している」と判断し、プロンプトの改善に時間を費やすことになる。

テレメトリをオフにするユーザーは、複数エージェントに共通の指示ファイルを使いたいような、AGENTS.mdを最も活用したい層と重なる。機能が公式に「追加された」と告知されているにもかかわらず、その層に対してだけ実際には動かない状態になっている。

筆者が求める改善

  • ローカルファイルの読み込みをテレメトリ設定に依存させないこと。段階的ロールアウトが必要なら、AGENTS.mdが存在するのにスキップされた場合の起動時警告があれば最低限の救いになる
  • グローバルなAGENTS.mdのサポートCodex~/.codex/AGENTS.mdをグローバル設定として読み込むが、Claude Codeにはプロジェクト単位のファイルしかない
  • エージェントスキルのネイティブ共有。Codexはプロジェクトの.agents/skillsとホームの~/.agents/skillsの両方からスキルを読み込むが、Claude Codeは/importでコピーするだけで、元ファイルの変更が追従しない

当面は1行のCLAUDE.mdと、.claude/skillsから../.agents/skillsへのシンボリックリンクで対処しているとのことだ。


詳細はClaude Code reads AGENTS.md only when telemetry is onを参照していただきたい。