エージェントを9つに減らし、CLAUDE.mdをダイエットさせた後、Compacting conversation...が表示される間隔が目に見えて長くなった。同じ作業をさせても以前よりはるかに持ちこたえた。嬉しかった。

ところが機能追加を依頼してコンソールを見守っていた。テストが走った。ケース30個、全部通過。しかしClaudeが成功したテストを再度言及していた。むずむずと変な感じがした。

Claudeに聞いた。「さっき成功したテストをなぜまた言及するの?」Claudeはツールという概念を説明してくれた。Claudeがターミナルコマンドを実行したりファイルを読む時、それは全て「ツール呼び出し」だ。そしてツールを1回実行するたびにその結果物が丸ごと会話コンテキストに積まれる構造だった。npm testの結果30行、Hugoビルドログ180行、全部。テストが全部成功したなら見るものはないのに30個全部読んだ。ビルドエラーを直す時も必要なのは最後の5行なのに180行全部ロードした。

漏れるバケツは一つではなかった。

曰く、hooksに従うべし

ググっていてClaude Codeのhooksを発見した。PreToolUse — Claudeがツールを実行する直前に割り込むスクリプトだ。Bashコマンドが実行される前に出力を加工でき、読み取りツールが呼ばれる前にブロックすることもできる。

my preciousを守る戒律を立てられるようになった。

第一の戒律:成功したものは見てはならない

テスト30個が全部通過したのに再度読み込む必要はない。失敗したケースだけ選んで表示し、残りは捨てるhookを作った。(Claudeに作ってもらった。)

1
filtered_cmd="$cmd 2>&1 | grep -A 10 -E '(FAIL|ERROR|✕|FAILED)' | head -150"

先ほど30個のテストをClaudeが全部見ていたなら、今は失敗したケースだけ見る。全部通過すれば読む量は0だ。100%の不要な読み込みを無くした。

第二の戒律:エラーでないものはアップロードしてはならない

Hugoビルドログ180行、Dockerビルド80行 — エラーを探すために全部アップロードする必要はない。同じ論理でERRORWARNfailedだけフィルタリングして表示するhookを作った。

1
2
# Hugo
filtered_cmd="$cmd 2>&1 | grep -E '(ERROR|WARN|error|failed|Fatal)' | head -30"

180行が5行になった。97%を削減した。Dockerも80行が10行前後になった。

第三の戒律:役に立たないものは読んでもならない

もう使わないアーカイブフォルダがある。Claudeがファイル探索中にこのフォルダを開く理由はない。Readツール呼び出しを傍受し、パスに_archiveが含まれていれば拒否するhookを作った。

1
2
3
if [[ "$file_path" == *"/_archive/"* ]]; then
  # deny
fi

単純だが確実だ。

ところがですね

体感は確実だった。Compacting conversation...が表示される頻度が減った。ビルド1回実行してもコンテキストがはるかに軽く維持された。hook3つでClaudeが不要な情報を読むのを防いだ。

でも「体感」だった。正確にどれだけ減ったかは分からなかった。昨日より今日が良い気がするが、どれだけ減ったか自慢できない!EP.1で「エージェントを分割すれば減るだろう」と根拠なく信じたのと何が違うのか。

測定しなければ改善したことにならない。定量測定が必要な時点だ。

このシリーズの他の記事


参考