CLAUDE LABEN
2.1.269 — Claude Code の最新版は98件の CLI 変更を含む大きめの版です。目玉は claude plugin eval で、プラグインの効きを採点できるようになりましたEVAL — 各ケースはプラグインあり3回・なし3回で走ります。出てくるのは成否ではなく、そのプラグインが何を足したのかという差ですGRADER — 採点器は3種類。返答への正規表現、特定のツールが呼ばれたか、そして別のモデルに判定させるルーブリックから選べますDIFF — Bash ツールの結果に、そのコマンドが変更したファイルの差分が付くようになりました。設定は bashEditDiffEnabled ですSTYLE — /output-style [name] で出力スタイルを切り替えられます。Remote Control 経由でも、クラウドや headless セッションでも使えますOTEL — OTEL_METRICS_INCLUDE_REPOSITORY でメトリクスに vcs. のリポジトリ属性が付きます。commit イベントには vcs.ref.head が入ります2.1.269 — Claude Code の最新版は98件の CLI 変更を含む大きめの版です。目玉は claude plugin eval で、プラグインの効きを採点できるようになりましたEVAL — 各ケースはプラグインあり3回・なし3回で走ります。出てくるのは成否ではなく、そのプラグインが何を足したのかという差ですGRADER — 採点器は3種類。返答への正規表現、特定のツールが呼ばれたか、そして別のモデルに判定させるルーブリックから選べますDIFF — Bash ツールの結果に、そのコマンドが変更したファイルの差分が付くようになりました。設定は bashEditDiffEnabled ですSTYLE — /output-style [name] で出力スタイルを切り替えられます。Remote Control 経由でも、クラウドや headless セッションでも使えますOTEL — OTEL_METRICS_INCLUDE_REPOSITORY でメトリクスに vcs. のリポジトリ属性が付きます。commit イベントには vcs.ref.head が入ります
記事一覧/Claude Code
Claude Code/2026-08-28中級

検証スクリプトの出力を、そのまま hook から返してはいけません

hook に足した検査は正しく動いていたのに、会話のほうが先に容量を使い果たしていました。833ファイルで58バイトの検査と42KBの検査を実測で並べ、出力が会話に届く経路と、予算を機械的に守らせるラッパーの書き方をまとめます。

Claude Code254hooks18自動化86コンテキスト設計3品質ゲート7

プレミアム記事

検査は、最後まで正しく動いていました。壊れていたのは会話のほうでした。

編集のたびに静的検査を走らせる hook を足した日のことです。個人開発で複数のリポジトリを行き来していると、検査は手で思い出して走らせるより、編集に紐づけて自動で挟むほうが確実に効きます。そう考えて入れたものでした。検査そのものは意図どおりに動き、違反も正しく拾っていました。ところが数十回の編集を挟んだあたりから、応答が目に見えて鈍くなり、やがて長いプロンプトを受け付けなくなりました。

原因を探して、私はしばらく検査スクリプトの中身を見ておりました。無駄な処理はないか、遅い正規表現はないか。けれど問題は処理時間ではありませんでした。検査が返していた文字列が、そのまま毎回の会話に積み上がっていたのです。

hook のタイムアウトについてはhook が command timed out で止まるときの切り分けで扱いました。今回はそれとは別の軸、つまり「時間ではなく量」の話になります。

走査した数ではなく、返した数が文脈になります

まず、自分の手元で実際に測った数字を置きます。同じリポジトリ(MDX 833ファイル)に対して、性格の違う検査をそれぞれ1回ずつ走らせ、標準出力のバイト数と行数を記録しました。

処理走査対象出力バイト行数概算トークン
フロントマター整合検査(合格)833ファイル58 B1約26
逐語重複スキャン(合格)833ファイル109 B1約50
リダイレクト整合検査(合格)リポジトリ全体126 B1約57
単一ファイル検査(違反あり)2ファイル893 B18約406
全件列挙型の grep833ファイル42,280 B398約19,218

※ トークン換算は日本語混在のテキストを 1トークン ≈ 2.2バイトとして概算したものです。実際の値はモデルとトークナイザによって変わります。

ここで目を引くのは、上から3つと下の1つの落差です。同じ833ファイルを走査していながら、返す量は58バイトと42,280バイト、およそ728倍の開きがあります。走査した対象の規模は、出力量をまったく決めていません。決めているのは、書いた人がどう返すことにしたか、それだけです。

私はこの表を作るまで、無意識に「重い検査ほど出力も重い」と思い込んでおりました。実際には逆のことが起きます。よく設計された全件検査は合格時に1行しか返さず、雑に書いた grep -rn は一致した行を全部並べます。後者のほうがはるかに軽い処理なのに、会話に対する負荷は3桁大きいのです。

その出力は、そもそも会話へ届いていますか

ここで一度、前提を確かめ直します。私は長いあいだ「hook が出力すれば、それはすべて会話に入る」と思い込んでおりました。公式のhooks リファレンスを読み直して、その理解が粗かったことに気づいたのは、この記事の初稿を書き終えたあとでした。

実際には、経路によって扱いが違います。

返し方Claude に届くか補足
exit 0 の stdout(多くのイベント)届きませんデバッグログに書かれるだけで、トランスクリプトには出ません
exit 0 の stdout(SessionStart / UserPromptSubmit / UserPromptExpansion / PostModelSwitch届きます素のテキストがそのまま文脈に加わります
exit 0 の stderr届きませんデバッグログのみ。自分で有効化しない限り読めません
exit 2 の stderr(PostToolUse など)届きますツールは実行済みのまま、内容が Claude に渡ります
hookSpecificOutput.additionalContext届きますsystem reminder として会話に差し込まれます

そして、届く経路には上限があります。additionalContext・systemMessage・素の stdout はいずれも 10,000文字で打ち切られ、超えた分はファイルに保存されてプレビューとパスに置き換わる、と明記されています。私が最初の版で「cat を一度書き間違えれば 5.7MB が会話に流れ込む」と書いたのは、正確ではありませんでした。一度の暴発では、そこまで到達しません。

では危険がないのかというと、そうではないのです。効いてくるのは一度の量ではなく、届く経路を毎回細く使い続けることのほうでした。 編集のたびに走る hook が 400バイトを返せば、300回の編集で12万バイト。一度の上限には一度も触れないまま、会話の容量は着実に削られていきます。私が踏んだのは、まさにこちらでした。

もう一つ、終了コードの扱いも見落としやすいところです。ポリシーを守らせたいときに使うのは exit 2 で、stdout に妥当な JSON がない exit 1 は非ブロッキングエラーとして扱われ、処理はそのまま先へ進みます。Unix の慣習で 1 を返していると、検査は違反を見つけているのに何も止まらない、という状態になります。

出力量と終了コードは独立した軸で、組み合わせは4通りあります。

出力が短い出力が長い
exit 0合格した検査。既定にすべき形要注意。合格しているのに、届く経路なら文脈を消費します
exit 2原因を1行で言い切れる失敗。理想的予算内なら妥当。超えるなら要約して逃がします

見落とされやすいのは右上、つまり**「成功しているのに長い」**の枠です。ここは失敗していないので誰も調べません。エラーも出ません。それでいて、静かにコンテキストを削っていきます。私自身、応答が鈍くなった原因を探して失敗ログばかり見ていた時間がありました。犯人は一度も失敗していなかったのです。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
833ファイルを走査しても58バイトで済む検査と42,280バイト返す検査の差が分かり、hook に足す前に出力量を見積もれるようになります
exit 0 の stdout・exit 2 の stderr・additionalContext のうち、どれが実際に Claude へ届くのかを区別できるようになります
head -c による文字化けと exit 1 の非ブロッキング扱いを避けた、予算を守るラッパーを書けるようになります
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

Claude Code2026-09-02
モデル切り替えの記録と歯止めを、フック2本で作る
PreModelSwitch と PostModelSwitch を使い、無人実行中のモデル切り替えを記録するフックと、約束していない切り替えだけを止めるフックをゼロから作ります。実測値つきの手順です。
Claude Code2026-07-01
Claude Code をアップデートしたら hook が発火しなくなった — ハイフン入り matcher の厳密一致化(v2.1.195)
Claude Code v2.1.195 でハイフンを含む hook matcher が部分一致から厳密一致に変わり、既存の PreToolUse フックが静かに発火しなくなりました。原因の切り分けと、壊れない matcher の書き方をまとめます。
Claude Code2026-06-14
サブエージェントの出力を採点し、不合格なら作り直させる SubagentStop フック
サブエージェントの成果物に時々ルール違反が混じる問題へ、SubagentStopフックで自動採点と再依頼を組み込みます。採点基準をJSONルーブリックに固定する理由、トランスクリプトを読む採点器の実装、無限ループを防ぐガード、運用して見えた実務的な勘所を動くコード付きで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます