Claude Code in Action — 日本語学習ガイド
Anthropic Academyコース「Claude Code in Action」の日本語学習ガイド。公式動画字幕(英語トランスクリプト)を基に、具体例・デモ手順・コード/コマンド名・数値・理由づけを漏らさず反映して再構成。講師: Stephen Grider(Anthropic Member of Technical Staff)。
講師: Stephen Grider(Anthropic Member of Technical Staff)
このノートは公式トランスクリプト(transcripts/combined_transcript.en.md)の前半7レッスン分を、日本語の学習ノートとして再構成したもの。原文の具体例・デモ手順・数値・比喩を漏らさず反映している。
Lesson: Introduction
このコースは4つのセクションで構成されている。
- まず「コーディングアシスタントとは何か」を正しく理解する
- Claude Code そのものを見て、数あるコーディングアシスタントの中で何が際立っているのかを理解する
- 典型的なプロジェクトで Claude Code を実際に使い、ハンズオン経験を積む
- 最後に、自分のプロジェクトで Claude Code を最大限活用する方法を学ぶ
Lesson: What is a coding assistant?
コーディングアシスタントは「コードを書くツール」で間違いないが、裏側で何が起きているかを理解すると、優れたアシスタントが何を備えているべきかがよく分かる。
コーディングアシスタントの内部フロー
- タスクを受け取る: 例えば、あるエラーメッセージをもとにバグを修正するタスク。
- 言語モデルに引き継がれる: 言語モデルはタスクの複雑さに応じてスタイルは変わるが、多くの場合は人間の作業の仕方に近い動き方をする。
- コンテキスト収集: エラーが何を指しているか、コードベースのどの領域がエラーを投げているか、どのファイルが関連しているかを理解する。
- 計画の立案: コードをどう変更し、修正を検証するためにどんなテストを書く/実行するかを決める。
- アクションの実行: 実際にファイルを更新し、テストを実行する。
ここで重要なのは、最初のステップ(コンテキスト収集)と最後のステップ(アクション実行)は、コーディングアシスタントが「実際に何かを行う」必要がある点である。つまり外部世界から情報を取得したり、外部世界に影響を与えたりする必要がある。例えばコンテキストを集めるにはファイルを読んだりドキュメントをオンラインで取得したりする必要があり、アクションを取るにはコマンドを実行したりファイルを編集したりする必要がある。
言語モデル単体では「ファイルを読む」ことはできない
もし言語モデルに直接(コーディングアシスタントの外側で)「main.go ファイルの中身は何?」と聞いたとしても、言語モデルはファイルを読んだりコマンドを実行したりする本質的な能力を持たない。言語モデルはテキストのような内容を受け取り、テキストを返す。それだけがその能力の全てであり、これは全ての言語モデルに共通する事実である。プレーンな言語モデルにファイルを読むよう依頼するテキストを送っても、「ファイルを読む能力がない」と返答するのが関の山である。
Tool use の仕組み
コーディングアシスタントなど多くのツールが、言語モデルに「ファイルを読む」ことを可能にしている(言葉の綾ではあるが)仕組みは次の通り。
- リクエストを送るたびに、コーディングアシスタントは裏側で自動的に多くのテキストをリクエストに追記する。例えば「言語モデルであるあなたがファイルを読みたい場合は、この非常に注意深くフォーマットされたメッセージで応答してください。例:
read file:の後にファイル名」といった内容。 - 言語モデルは、質問に答えるためにファイルを読む必要があると認識すると、
read file: main.goのような形式で応答する。 - コーディングアシスタントは、この注意深くフォーマットされたメッセージを受け取り、言語モデルが何らかのアクション(この場合ファイルの読み取り)を取りたがっていると認識する。そしてコーディングアシスタントが実際にファイルを読み込み、その内容を言語モデルに送り返す責任を負う。
- 言語モデルはファイルの実際の内容を受け取った上で、「このファイルを読みました。中にはこういうコードが含まれています」といった最終応答を作成し、私たちに送り返す。
この、言語モデルに「非常に注意深くフォーマットされた形で応答するように」という追加の指示を与える仕組み全体を tool use(ツールユース) と呼ぶ。ツールはモデルに追加の能力を与えるために使われる。モデルは特定の形式で応答する責任を負い、コーディングアシスタントのようなものが、約束されたこと(ファイルの読み書きなど)を実際に行う責任を負う。これは世の中の全ての言語モデルに共通する動作原理である。
Claude の強みとしての tool use
Claude シリーズのモデル(Opus・Sonnet・Haiku)は、ツールが何をするか、いつ呼び出されるべきかを理解し、タスクを効果的に完了するために実際にツールを使うこと、さらには複雑なタスクをこなすためにツールを興味深い組み合わせで使うことに、特に強みを持つ。Claude の強力な tool use は、Claude Code がコーディングアシスタントとして持つ絶対的な核となる強みである。 理由は以下の3点。
- tool use が優れていることで、Claude はより複雑なタスクを扱える。
- Claude Code 自体が拡張可能であり、Claude に新しいツールを簡単に追加でき、Claude はそれらのツールを喜んで活用する。これは、開発の世界で見られる急速な変化を踏まえると、継続的な有用性の観点で特に重要である。つまり Claude Code は、これから何年もの間、利用者と共に変化していくアシスタントである。
- tool use の改善は、しばしばセキュリティの向上にもつながる。Claude はコードベース全体を外部サーバーに送信することに頼る「インデックス化」に依存せず、コードベースを効果的に検索して関連コードを見つけられるためである。
まとめ
- コーディングアシスタントは内部で言語モデルを使い、様々なタスクをこなす。
- 言語モデルは、与えられたタスクの大部分をこなすためにツールの使い方を知っている必要がある。
- ツールはファイルの読み書き・コマンドの実行など、単なるテキスト生成以外のほぼ全てに使われる。
- 全ての言語モデルが同じレベルでツールを活用するわけではなく、これはコーディングアシスタント全体の効率に大きな影響を与える。
Lesson: Claude Code in action
Claude はツールの活用に長けており、Claude Code は簡単に拡張できるという主張を、いくつかのデモで実証する。Claude Code にはデフォルトで、ファイルの読み書きやコマンド実行など期待される能力一式が備わっている。以下のデモでは、この一連のツールを知的な形で使う様子、さらに一つのタスクでは新しいツールセットを Claude に追加で与える様子を見る。
デモ1: chalk ライブラリのパフォーマンス最適化
最初のタスクは、chalk という JavaScript パッケージのパフォーマンス問題を発見して最適化すること。chalk はテキストを綺麗にフォーマットされた色で出力するだけの、非常にシンプルな目的を持つ小さなライブラリである(テキストに色や背景、フォーマットを付けられる)。
一見地味なパッケージに見えるが、講師によれば JavaScript エコシステム全体で5番目にダウンロードされているパッケージ であり、直近1週間だけで 4億2900万(429 million)ダウンロード を記録しているという(※ダウンロード数自体は chalk の実測レンジ(週間3億〜4.5億件程度)と整合するが、「エコシステム全体で5位」という具体的な順位を裏付ける一次情報は見当たらず、少なくとも週間ダウンロード数だけで見ると同等かそれ以上の小規模ユーティリティパッケージも複数存在する)。つまり非常に広く使われているパッケージであり、このパッケージの中で何か最適化を見つけられれば、その努力には十分な価値がある。
Claude には「ベンチマークを実行し、最もパフォーマンスの悪いケースを特定し、プロファイリングツールを使ってなぜそれらのケースが遅いのかを突き止め、それを修正する」よう依頼した。Claude は幅広い種類のツールを知的に使ってこの問題に取り組む。具体的には、進捗を追うための ToDo リストを作成し、ベンチマークを実行するコマンドを実行し、特定のケースをより詳しく調べるためのファイルを書き、CPU プロファイラーを使ってそのケースがなぜ遅いのかを理解し、その上で改善を実装する。
最終的には、あるひとつの操作において スループットが3.9倍改善 した。
デモ2: CSV データセットの分析(Jupyter Notebook)
動画配信プラットフォームのユーザーに関する情報を含む CSV ファイルのデータセットを Claude に渡し、一般的な分析(チャーン=解約の要因の特定など)を Jupyter Notebook 内で行うよう依頼した。
このデモは、効果的な tool use が非常に重要になる好例である。Claude が単にノートブックにコードを書くだけでは不十分で、Claude は異なるセルでコードを実行し、その実行結果を見ることもできる。つまり Claude はノートブック内でまずデータを見て、その後、続くそれぞれのセルを特定の詳細に焦点を絞ってカスタマイズしていくことができる。
デモ3: Playwright MCP サーバーによるツール拡張(UI スタイリング)
左側に入力した説明文をもとに UI コンポーネントを生成し、右側に表示する小さなアプリを使ったデモ。このアプリはコンポーネント自体は綺麗に生成できるが、左側のチャットインターフェースと上部のヘッダーの見た目があまり良くない。
単にスタイリングの修正を頼むだけでも Claude はうまくやるはずだが、ここでの目的は「Claude Code に新しい機能を追加することがいかに簡単か」を示すことにある。そこでスタイリングのタスクと合わせて、Playwright MCP サーバー が提供する新しいツールセットへのアクセスを Claude Code に与えた。これによって Claude はブラウザを直接開いて操作できるようになる。
実際の流れ:
- Claude にスタイリング改善とブラウザの活用を依頼する。
- Claude は画面右側にブラウザを開き、アプリにナビゲートする。
- 現在のスタイリングを確認するためにスクリーンショットを撮る。
- スタイリングを更新する。
- 完了時に再度スクリーンショットを撮るよう依頼することもでき、それを何度か繰り返してデザインを反復改善できる。
最終的には、かなり見栄えの良いデザインに仕上がった。
デモ4: GitHub 連携によるプルリクエストの自動レビュー(インフラのデータフロー追跡)
Claude は GitHub と非常に密接に統合されている。Claude Code は GitHub Action の中で実行するようセットアップでき、プルリクエストの作成やイシュー内でのメンションなど、特定のイベントに基づいて自動実行される。Claude Code が GitHub 上で動作する場合、コードの閲覧・実行に加えて、コメント作成・コミット作成・プルリクエスト作成など GitHub とやり取りするための新しいツールセットにもアクセスできる。この統合を使うと、プルリクエストの自動レビューが可能になる。
シナリオ設定: AWS 上にインフラを構築しており、そのインフラは全て Terraform ファイルとして定義され、GitHub にコミット・保存されている。インフラが全て Terraform ファイルで定義されているため、Claude Code はインフラ内をどのように情報が流れているかをよく理解できる。
- DynamoDB テーブル(通常のデータベーステーブルのようなもの)に、ユーザーに関する情報(閲覧したプラン、登録日など)を格納している。
- ある理由で「閲覧したプラン」と「登録日」の情報だけを、社内マーケティングチームと社外マーケティングチームの両方に共有したい(つまり別会社が、このバケットに書き込むデータにアクセスできる)。そのため、このバケットに時間をかけて何の情報が書き込まれているかを常に把握しておくことが極めて重要になる。
- 毎晩、Lambda 関数がそのテーブルに追加された全ユーザーを取得し、「閲覧したプラン」と「登録日」だけを抽出して S3 バケットに保存し、2つのマーケティングチームがその情報にアクセスできるようにしている。
- 数ヶ月後、社内マーケティングチームから「メールアドレスもこの S3 バケットに保存してほしい」と依頼が来たとする。そこで Lambda 関数に、ユーザーのメールアドレスを取得してバケットに保存する1行のコードを追加したとする。
- これは数ヶ月後のことなので、この S3 バケットが社外マーケティングパートナーと共有されていることをすっかり忘れているかもしれない。この時点で、個人を特定できる情報(PII)を、別会社がアクセスできるバケットに書き込んでいることになる。これは絶対にやってはいけないことである。しかし実際にはこのようなミスは起こり得るし、S3 バケットの現状を正確に把握していなければ気づきにくい。
Claude Code はこのようなシナリオをプルリクエストの中でかなり簡単に検出できる。インフラが全て Terraform ファイルで定義されているためである。
実演: 上記のダイアグラム通りのプロジェクトを構築し、Lambda 関数にユーザーのメールアドレスを追加するプルリクエストを作成した(変更した行はその1行のみ)。Claude は自分のインフラをよく理解しているため、自動レビュー(プルリクエスト上で実行)の中で、このプルリクエストで行われた全ての変更を確認し、インフラがどのように動作しているかを正確に把握した上で、社外パートナーに PII を露出させていることを特定できた。データフローと、実際に発生する具体的なステップを一覧表示し、このバケットが社外パートナーとどのように共有されているかを詳細に説明した。
このような問題を、変更をデプロイした後ではなく開発中に検出できることは、Claude Code の GitHub 連携を使う大きなメリットである。
まとめ
Claude Code は、ツールを活用する優れた能力のおかげで何ができるかについて、良いイメージが掴めたはずである。Claude Code は、カスタマイズ可能で、時間をかけてチームのニーズに合わせて成長し変化していく柔軟なアシスタントとして捉えるべきである。
Lesson: Adding context
小さなプロジェクトのコードエディタを開き、npm run dev で開発サーバーを起動し、ブラウザで localhost:3000 にアクセスしてアプリケーションが動作していることを確認するところから始める。
このプロジェクトで Claude に作業をさせる前に、コンテキスト管理 について強く理解しておくべき重要なポイントがある。典型的なプロジェクトには数十〜数百のファイルがあり、それぞれに膨大な情報が含まれている。Claude に質問やタスクを与えるとき、Claude が必要とする「理想的な情報量」というものが存在する。質問への回答やタスクの完了を理解するのにちょうど十分な量である。関連のない追加情報を加え始めた途端、Claude の効果は低下し始める。したがって、Claude を関連するファイルやドキュメントへ導いてあげることが非常に重要になる。Claude Code は手取り足取りせずとも動作するが、少しのガイダンスを与えることで最良の結果が得られる。
/init コマンドと CLAUDE.md
エディタでターミナルを開き、claude コマンドで Claude Code を起動する。プロジェクトで初めて Claude Code を実行するときは、/init コマンドの実行を強く推奨する。これにより Claude はコードベース全体を深く調査する。プロジェクトの目的、全体的なアーキテクチャ、関連するコマンド、重要なファイルなどを把握する。この調査の後、その発見内容を要約し、CLAUDE.md というファイルに配置する。
Claude がこのファイルを作成しようとするとき、許可を求めてくる。Enter を押して承認するか、Shift+Tab を押すことで Claude Code がプロジェクト内で自由にファイルを書き込めるようにし、毎回許可を与える必要をなくすこともできる。
生成された CLAUDE.md ファイルを開いて中身を確認することを勧める。前述の通り、このファイルの中身は、Claude に送る全てのリクエストに含まれる。このファイルには2つの役割がある。
- Claude がコードベースをより良く理解し、関連するコードをより速く見つけられるようにする。
- 一般的なガイダンスを Claude に与えるための場所として機能する。
CLAUDE.md の3階層
Claude Code が利用する CLAUDE.md ファイルは複数存在する。
- プロジェクトレベル:
/initコマンドで生成したもの。一般的には Git のようなソース管理にコミットし、他のエンジニアと共有し、プロジェクト固有の指示を Claude に渡す場所として使う。 - ローカルレベル(CLAUDE.local.md): オプションで作成できる。コミットされず、他のエンジニアと共有することも通常ない。自分だけに Claude に従ってほしい個人的な指示をここに入れる。
- マシン(グローバル)レベル: マシン上のグローバルな CLAUDE.md。ローカルで実行する全てのプロジェクトに適用される指示・内容を含む。
なお、開発者個人が使う階層としてはこの3つで正確だが、現行の公式ドキュメントではこれに加えて、組織の管理者が全社に配布する Managed policy レベル(企業向け CLAUDE.md、例: /Library/Application Support/ClaudeCode/CLAUDE.md)を含めた計4階層が定義されている。
カスタム指示の追加と # ショートカット
Claude にカスタム/特別な指示を与える例: Claude が書くコードでコメントを使いすぎている場合、CLAUDE.md ファイルを更新することで対処できる。手動でファイルを編集することもできるが、ちょっとしたショートカットとして、Claude Code 内で #(ポンド記号)を入力すると CLAUDE.md へ素早く指示を追記できる # ショートカット(教材当時は「メモリモード」と訳出していたが、これは非公式の訳語で、Anthropic 自身は "# shortcut" や "quickly add memories" と表現していた)という機能が当時は使われていた。これにより CLAUDE.md ファイルのいずれかをインテリジェントに編集できる。「コメントをそれほど頻繁に書かないで」といったリクエストを入力し、それをプロジェクトの CLAUDE.md ファイルに追加したいと指定すると、Claude はこの指示をそのファイルにインテリジェントにマージしてくれる。ファイルを開いて検索すると、実際にその新しい指示が追加されていることが確認できる。(※現行版ではこの # ショートカットは廃止されており、CLAUDE.md への追記は /memory コマンドでの編集、または Claude に会話内で直接「これを覚えておいて」のように依頼する方法に置き換わっている。なお紛らわしいが、現行の Claude Code には Claude が学習内容を自動で書き残す全く別の正式機能「Auto memory(自動メモリ)」があり、claude.ai 側にも Settings > Memory という消費者向けの別機能が存在する。いずれも本レッスンで扱う # ショートカットとは異なる仕組みである。)
@ メンションによる特定コンテキストの取り込み
CLAUDE.md ファイルを作成した後は、会話に特定のコンテキストを取り込む方法を理解する必要がある。例えば、このプロジェクトの認証システムがどう動くかを理解したい場合、単に Claude に尋ねることもできる。その場合 Claude はコードベース全体を検索し、認証システムに関連するファイルを見つける。これは確実に機能するが、ある程度の時間がかかる。
代わりに、関連するファイルが既に分かっている場合は、@ 文字を使ってそれらに言及できる。ファイルに言及すると、そのファイルは自動的に Claude へのリクエストに含まれる。これは Claude を特定の方向に向かわせるための優れたテクニックである。
同じ構文を使って、CLAUDE.md 内でファイルに言及することもできる。例: このプロジェクトの Prisma フォルダには schema.prisma というファイルがあり、SQLite データベース内に情報を保存するために使われる全てのテーブルとレコード型の完全な定義が含まれている。この情報はプロジェクトの多くの側面にとって非常に重要で関連性が高いため、CLAUDE.md ファイル内でこのファイルに言及することにする。
手順: # ショートカットを入力し、そのスキーマファイルに言及し、データベース内のデータ構造をより良く理解する必要があるときは常にそのファイルを参照するよう Claude に指示する(※現行版では /memory コマンドでの編集、または Claude への直接依頼が同等の手段になる)。更新が完了したら CLAUDE.md ファイルを開いて、そのメモが追加されたことを確認する。
このようにファイルに言及すると、その内容は自動的にリクエストに含まれるようになる。そのため、例えば「ユーザーはどんな属性を持っているか」と尋ねると、Claude はスキーマファイルを読むことなく即座に答えられる。
Lesson: Making changes
このプロジェクトに実際に変更を加えながら、Claude Code の便利な機能をいくつか紹介する。
スクリーンショットの貼り付け(Ctrl+V)
最初にやりたいことは、左側にあるプレースホルダーのテキストを、このパネルの中央へ移動すること。Claude に正確にどのコンテンツを移動したいのかを理解させるため、その領域のスクリーンショットを撮り、Ctrl+V(macOS で通常使う Command+V ではなく、Control+V)で Claude Code に貼り付ける。Control+V は特にスクリーンショットの貼り付けに使われる。その上で、そのプレースホルダーを中央に配置するよう Claude に依頼する。少し検索した後、Claude はスタイリングの更新を行う。ブラウザで確認すると、うまく反映されている。
タスク2: チャットインターフェースの表示テキストの改善
カードコンポーネント(タイトルと説明を表示する)の生成を Claude に依頼すると、問題なく生成される。ただし一点気になる箇所がある。チャットインターフェースの左側に "String Replace Editor" という表示がある。このパネルは、ファイルが作成されていることをユーザーに示すことを意図しているが、現在は裏側で使われているツールの技術的な名称である "String Replace Editor" をそのまま表示している。もっとユーザーフレンドリーなテキストを表示し、ファイルが作成されていること、そのファイル名を伝えたい。もちろん、このチャットボットがファイルを編集している場合や削除している場合なども扱う必要がある。
Claude の注意を導くために、再度この箇所のスクリーンショットを撮り、それを貼り付けて、そのテキストをよりユーザーフレンドリーなメッセージに置き換えるよう依頼する。これは Claude がこのプロジェクトについてかなりの調査を行う必要がある、やや難易度の高いタスクである。
難しいタスクへの対処: Plan Mode と Thinking Mode
Claude により難しいタスクを与えるとき、Claude の知能を簡単に引き上げる方法が2つある。
1. Plan Mode(プランモード)
Shift+Tab を2回押す(ファイル編集を自動承認している状態であれば1回)ことで有効化できる。Plan Mode では、Claude はプロジェクトの内容についてより多くの調査を行い、より多くのファイルを読み込み、タスクを完了する方法について詳細な計画を立てる。計画を完成させると、Claude はタスクを完了するために何をしたいのかを正確に伝えてくる。その時点で、その計画を承認して Claude に実装させるか、あるいは何らかの形で Claude をリダイレクトできる(例えばファイルの見落としがあった場合や、あるシナリオを考慮していなかった場合など)。
2. Thinking(拡張思考)
Claude の extended thinking 機能をオンにし、特定のタスクについてより多く推論できるようにする。有効化するには、いくつかのトリガーフレーズがある。それぞれのフレーズが、Claude により大きなトークン予算を段階的に与える。今回は難易度の高いタスクなので、"ultrathink"(ハイフンなしの1語で表記する、最上位のトリガーフレーズ)でこの実装の最善策を検討するよう Claude に依頼する。
Plan Mode と Thinking の併用
計画(Planning)と思考(Thinking)は組み合わせて使うことができる。今回は "ultrathink" に加えて Plan Mode もオンにして実行する。
使い分けの考え方: この2つは「幅優先」対「深さ優先」の関係として捉えるとよい。
- Plan Mode: コードベースの広い理解を必要とするタスク、異なる領域を見る必要があるタスクに有用。複数のステップを要するタスクにも有用。
- Thinking: 特定のトリッキーなロジックに焦点を当てているときや、難しいバグのトラブルシューティングをしているときに有用。
「常に thinking と planning の両方を有効にすべきか」という疑問については、確かに常時オンにすることもできるが、planning と thinking は追加のトークンを消費するため、それに伴うコストがあることを念頭に置くべきである。
数分の作業の後、機能は完成した。エディタに戻ってテストすると、以前よりも良いステータス情報が表示されるようになった。ファイルが作成されていることがユーザーに伝わるようになった。続けてタイトルを変更するようなフォローアップリクエストを送ると、今度はそのファイルを編集していることが表示されるようになった(app.jsx ファイルを編集中、という表示になる)。この機能の実装は成功したと言える。
Git アシスタントとしての Claude Code
プロジェクトに変更を加えたら、その変更をコミットするとよい。Claude Code は優秀な Git アシスタントであり、変更のステージングとコミットを依頼すると、説明的なコミットメッセージを書いてくれる。
Lesson: Controlling context
会話の流れをコントロール・誘導するためのいくつかのテクニックを紹介する。
Escape によるインタラプト
基本例: 認証ファイルに書かれたいくつかの関数のテストを書くよう Claude に依頼すると、Claude はすぐに複数の異なるテストを作成する計画を立てる。しかし、このファイルのテストは少し難しいと分かっているため、一度に一つずつテストしてほしい場合がある。Claude を中断するには Escape を押す。これにより Claude はその場で停止し、別の方向性を提案できるようになる。
Escape + メモリの組み合わせ
Escape とメモリ(#)を組み合わせることは、Claude が繰り返し犯すエラーを修正する非常に強力な方法である。例: 再びこのファイルのテストを書くよう依頼すると、今度は実際には存在しないテスト設定ファイルを読み込もうとする。これは、このプロジェクトで以前にも見たことのあるエラーである。このミスが繰り返されるのを止めるため、素早く Escape を押し、# ショートカットを使ってこのテスト設定ファイルの正しい名前についてのメモリを追加する(※現行版ではこの # ショートカットは廃止されており、/memory コマンドでの編集や Claude への直接依頼が同等の役割を果たす)。これでおそらく、このエラーを再び見ることはなくなる。
これらの会話コントロール系のショートカットは、単なる利便性のためのもののように見えるかもしれないが、正しく使えば Claude の作業効率とタスクへの集中力を大きく改善できる。
実践例: 会話履歴の巻き戻し(Escape 2回)
auth.ts ファイルには4つの異なる関数があり、それぞれについて一つずつテストを書かせたい。まず create session という関数から始める。Claude はテストを書こうとするが、実行中にエラーに遭遇し、デバッグに少し時間を使う。原因はインストールし忘れていたパッケージだった。最終的にテストは完成して動作するようになり、次のテストセットに取り掛かる段階になる。
しかし、ここで問題がある。会話履歴には、その壊れたパッケージに関するやり取りが大量に溜まっている。これは次のテストセットを書く上で全く関連のないコンテキストである。理想的には、時間を遡って前のメッセージに戻り、それを「create session のテストを書いて」という内容に更新できるとよい。この利点は、Claude が既に auth.ts の内容を確認済みであるというコンテキストは維持しつつ、create session について言及したときに何を指しているかも既に把握している状態を保ちながら、デバッグに関する余計なメッセージだけを削ぎ落とせる点にある。これにより、Claude は余計な気を散らされることなくタスクに集中し続けられる。
会話履歴を遡るには、Escape を2回 押す。これにより送信した全てのメッセージが表示され、以前の時点まで巻き戻し、途中の会話をスキップできる。
Claude は次のテストセットの作業を始める。今回は非常に集中して取り組むが、残念ながらいくつかの問題に遭遇する。最終的にはそれらを解決し、テストを通過させる。この時点で Claude は数分間一人で作業しており、このファイルのテストの書き方について非常に良い理解を持っている。同時に、再び会話履歴には多くのコンテキストが溜まっている。
Compact コマンド
次の関数のテストを書く時が来たら、compact コマンドを使うとよい。compact コマンドは、現在の会話にある全てのメッセージを取得して要約する。compact は、Claude が現在のタスクについて多くを学んだ状態を保ちながら、次のタスクへ進みたいときに非常に有用である。
Clear コマンド
最後に紹介するコンテキスト関連のコマンドは Clear である。Clear は会話履歴全体を破棄し、ゼロから始め直せるようにする。Clear は、現在のタスクとは全く無関係な、完全に別のタスクに取り掛かろうとしているときに最も有用である。
これらのショートカットは、タスクを切り替えるときや、Claude との会話が長時間に及んでいるときに、頻繁に使うことを推奨する。コースの残りの部分でも、Claude がタスクに集中し続けられるよう、これらのショートカットを何度か使用していく。
Lesson: Custom commands
Claude Code を実行してスラッシュ(/)を入力すると、デフォルトで組み込まれているコマンドが多数表示される。これらのデフォルトコマンドに加えて、自分自身のカスタムコマンドを簡単に追加できる。カスタムコマンドは、頻繁に実行する反復的なタスクを自動化するのに有用である。
例1: 引数なしのカスタムコマンド(/audit)
作成手順:
- プロジェクトディレクトリの中にある
.claudeフォルダを見つける。 - その中に
commandsという新しいディレクトリを作る。 - その中に
audit.mdという新しいファイルを作る。
作成するファイルの名前(この場合は audit)が、最終的に実行するコマンドの名前になる。このコマンドの目的は、プロジェクトにインストールされている全ての異なる依存関係を監査し、脆弱性があれば更新し、その後テストを実行して何も壊れていないことを確認することである。
コマンドファイルを作成したら、Claude Code を再起動する(再起動を忘れないこと。なお現行版では .claude/commands ディレクトリ配下の変更はセッション中にライブ検出されるようになっており、既存ディレクトリ内でのファイル追加・編集は再起動なしで反映される。再起動が必要になるのは、この例のように commands ディレクトリ自体をそのセッション内で初めて新規作成した場合など、トップレベルのディレクトリが存在しなかったケースに限られる)。Claude Code を再度開いたら /audit と入力する。すると先ほど作成したコマンドが表示される。これを実行すると、依頼した通りのことを行う。コマンドを実行し、脆弱なパッケージがあるか確認し、必要であれば修正し、その後テストを実行する。
例2: 引数付きのカスタムコマンド(/write-test、$ARGUMENTS)
コマンドは引数を受け取ることもできる。write test という別のコマンドを作る例。このコマンドを実行するたびに、プロジェクト内の特定のファイルに対するテストを作成したい。コマンドのテキスト内に $ARGUMENTS というプレースホルダーを入れる。コマンドを実行する際にファイルへのパスを渡すと、そのパスが $ARGUMENTS の位置に挿入される。
write test コマンドを実行する(commands ディレクトリは既に存在するため、現行版ではこの追加分の反映に再起動は不要でライブリロードされる)。なお、渡す引数はファイルパスである必要はなく、任意の文字列を渡すことができる。例えば「あるフォルダ内のファイルのテストが欲しい」といったカジュアルな依頼をし、Claude にどこを見ればよいかの手がかりを少し与える、といった使い方もできる。
まとめ(このノートで扱った範囲)
- コーディングアシスタントの正体は「言語モデル + tool use」であり、Claude の強力な tool use が Claude Code の核となる強み。
- デモでは、chalk ライブラリの最適化(3.9倍のスループット改善)、Jupyter Notebook でのデータ分析、Playwright MCP によるブラウザ操作、GitHub 連携による PII 露出の自動検出、という4つの実例を通じて tool use の威力を確認した。
- コンテキスト管理が Claude Code 活用の核心であり、
/initによる CLAUDE.md 生成(プロジェクト/ローカル/グローバルの3階層。エンタープライズ向けの Managed policy 階層を含めると現行では計4階層)、#ショートカット(教材当時の呼称は「メモリモード」。現行版ではこのショートカット自体が廃止され/memoryコマンドや Claude への直接依頼に置き換わっており、名称の似た別の正式機能として Claude Code の「Auto memory(自動メモリ)」や claude.ai の「Memory」がある)、@によるファイルメンションが基本ツールとなる。 - 難しいタスクには Plan Mode(幅優先・広い理解が必要なタスク向け)と Thinking Mode(深さ優先・トリッキーなロジックやバグ調査向け)を使い分け、併用も可能。ただしどちらもトークンコストがかかる。
- 会話コントロールとして Escape(中断)、Escape 2回(履歴の巻き戻し)、Compact(要約して引き継ぎ)、Clear(完全リセット)を使い分けることで、Claude を無関係なコンテキストから守り、タスクへの集中を保てる。
- カスタムコマンドは
.claude/commands/<name>.mdに作成し、$ARGUMENTSで引数を受け取れる。現行版では既存ディレクトリ内でのファイル追加・編集はライブリロードされ再起動不要だが、commandsディレクトリ自体をそのセッションで初めて作成した場合は再起動が必要になる。
Anthropic Academy「Claude Code in Action」コースの後半 8 レッスン分(MCP servers with Claude Code / Github integration / Introducing hooks / Defining hooks / Implementing a hook / Useful hooks! / The Claude Code SDK / Summary and next steps)の日本語学習ノート。一次情報源は transcripts/combined_transcript.en.md の英語公式字幕(verbatim transcript)で、講師が実際に語った具体例・デモ手順・コード/コマンド名・数値・理由づけ・比喩をできる限り漏らさず日本語に起こしている。前半(Introduction 〜 Custom commands)は別ファイルで別担当者が扱っているため、本ファイルでは触れない。
MCP servers with Claude Code
Claude Code には、MCP サーバを通じて新しいツールや能力を追加できる。MCP サーバはリモートで動くものもあれば、自分のマシン上でローカルに動くものもある。ここで取り上げられる代表例が Playwright という非常に人気のある MCP サーバで、これを使うと Claude Code にブラウザを操作させる能力を与えられる。
Playwright MCP サーバの追加手順
Claude Code の中ではなく、ターミナル側で次のコマンドを実行してサーバをインストールする。
claude mcp add
このコマンドの後にこの MCP サーバの名前を指定する(講師は playwright という名前を付けている)。さらに名前の後ろに、マシン上でローカルにサーバを起動するコマンドを追加する。
インストール後、Claude Code を起動して「ブラウザを開いて localhost:3000 のアプリケーションに移動してほしい」と依頼できる。ブラウザが開く前に、そのツールを実行してよいかという許可を求められることに気づくはずである。
許可ポップアップを毎回出さないようにする設定
許可ポップアップに煩わされたくなる場合は、.claude ディレクトリの中の settings.local.json を開く。その中の allow 配列に、mcp__playwright(アンダースコアが2つ続く点に注意)という文字列を追加する。これにより、Claude Code は毎回許可を求めることなく、この MCP サーバとその中のツールを自由に使えるようになる。Claude Code を再起動してから再度ブラウザを開くよう頼むと、今度は許可を求められずに開く。
デモ: Playwright でプロンプトそのものを自己改善させる
Playwright MCP サーバの使い道は非常に幅広いが、講師は今取り組んでいるプロジェクトに実際に役立つ活用例を1つ実演する。エディタに戻り、src/lib/prompts/generation.tsx ファイルを開く。これはアプリ内で「これこれのコンポーネントを作って」と頼んだときに実際に使われるプロンプトである。
そこで、Claude Code に次のようなタスクを依頼する。
- ブラウザを使わせる。
- コンポーネントを自分自身で生成させる。
- 生成されたコンポーネントのソースコードを確認し、スタイリングを評価させる。
- その評価結果に基づいて
generation.tsx内のプロンプトを自分で更新させる。
つまり、Claude Code に localhost:3000 へ移動し、コンポーネントを1つ生成し、生成されたソースコードを見てスタイリングを評価し、その上でプロンプトを更新するよう依頼する。
実行すると、Claude はまずブラウザを開き、コンポーネントを生成しようと試みる。Claude 自身のコメンタリーを見ると、あまり満足していない様子がうかがえる。特に、こうしたアプリケーションでよく使われる「紫から青へのグラデーション」という非常にありがちなスタイルについて不満を述べている。
その後 Claude はプロンプトを更新し、新しいコンポーネントを再生成する。講師は「正直、想像していたよりもずっと良い結果になった」と述べており、生成されたテスティモニアルカードは非常に見栄えが良いものだったという。
この結果だけからでも、MCP サーバがいかに多くの興味深いユースケースへの扉を開くかが実感できる。講師は、自分が個人的に取り組んでいるどんなプロジェクトであっても、それを助けてくれそうな MCP サーバをぜひ探してみることを強く勧めている。
要点
- Playwright MCP サーバはターミナルで
claude mcp addにより追加する(Claude Code 内ではない)。- 許可ポップアップを省略したい場合は
.claude/settings.local.jsonのallow配列にmcp__playwright(アンダースコア2つ)を追加する。- Playwright MCP は、Claude 自身にブラウザで生成結果を確認させ、プロンプト(例:
generation.tsx)を自己改善させるようなワークフローにも応用できる。
Github integration
Claude Code には公式の GitHub 連携機能があり、Claude Code を GitHub Actions の中で実行できる。
セットアップ手順
/install-github-app を実行するとセットアップが始まり、いくつかのステップを案内される。
- GitHub 上に Claude Code アプリをインストールする。
- API キーを追加する。
- これらが終わると、プルリクエストが自動的に作成される。
このプルリクエストは、2つの異なる GitHub Actions を追加するものである。
- 1つ目のアクション(メンション対応): issue やプルリクエストから
@claudeとメンションし、Claude に何らかのタスクを依頼できるようになる。 - 2つ目のアクション(プルリクエストレビュー対応): プルリクエストを作成するたびに、Claude Code が自動的に実行され、提案された変更をレビューする。
これらのアクションはどちらもカスタマイズ可能であり、他の種類のイベントに基づいて追加のアクションをトリガーするよう追加することもできる。
メンション機能のカスタマイズ実演
講師は、この2つのアクション設定ファイルを GitHub リポジトリにマージした後、それをローカルマシンに pull する。新しく作られた .github/workflows ディレクトリの中に、この2つのアクション設定ファイル(プルリクエストレビュー対応用と、メンション処理対応用)が見つかる。
講師が実現したいカスタマイズは次の通りである。issue やプルリクエストの中で Claude にメンションしたときに、プロジェクトを実際に実行し、Playwright MCP サーバを使ってウェブブラウザ経由でアプリにアクセスできるようにしたい。これを GitHub Actions の中で完結させたい。
これを実現するために、以下の変更をワークフローに加える。
- Claude Code が実行される前段のステップとして、
setupコマンドを実行し、開発サーバーを起動する。 - Claude Code の設定を更新し、カスタム instructions(追加の指示や文脈)を Claude に直接渡す。具体的には「開発サーバーはすでに起動済みであること」「必要であれば Playwright MCP サーバを使ってブラウザ越しにアプリへアクセスできること」を伝える。
- Playwright MCP サーバ自体をセットアップするための設定を追加する。
ここで注意すべき点が1つある。Claude Code をアクションの中で実行する場合(メンション対応のいわゆる Tag Mode)、コアとなるツール群は個別に明示的な許可を与える設計になっている。加えて、MCP サーバを使う場合は特にやっかいな点があり、そのサーバの中にあるツールを1つ1つ列挙して許可するのが基本になる。CLI の対話的な「まとめて許可」のようなショートカットはない一方、claude_args 経由であれば CLI と同じワイルドカード構文(例: mcp__server__*)自体は使えるため、個別列挙の手間をある程度減らすことはできる。Playwright MCP サーバには非常に多くのツールがあるため、実際には多くのツールを列挙することになる。
設定の更新が終わったら、それらの変更を必ずコミットして push する。
動作テスト
更新されたワークフローを実際にテストする。講師はアプリ内の2つのボタン(プレビューとコードパネルを切り替えるボタン)を題材にする。実際には問題なく動作しており、支障なく切り替えができる状態だが、あえて「うまく動いていない」ふりをして次の手順を踏む。
- そのボタンのスクリーンショットを撮る。
- issue を作成し、そのスクリーンショットを貼り付ける。
@claudeとメンションし、この2つのボタンが意図通りに動作しているか確認してほしいと依頼する。- issue を作成し、待つ。
アクションが実際に起動し Claude が応答するまでには1〜2分ほどかかる。これは、先ほど見たように、Claude Code が実行される前にアプリ全体をセットアップして起動しているためである。しかしやがて Claude が応答する。Claude はしばしば、与えられたタスクを達成するためのチェックリストを作成する。今回のケースでは、アプリにアクセスし、手動でボタンをテストし、見つかった問題を修正する、という手順を試みる。
Claude はボタンが実際には問題なく動作していることに気づき、その調査結果を記載したメッセージとともに早期に処理を終了する。
これはあくまで GitHub 連携の小さな一例であり、講師は各自が自分のプロジェクトに合わせてどのようにカスタマイズできるかを考えてみることを勧めている。
要点
/install-github-appで GitHub アプリのインストール → API キー追加 → PR 自動生成、という3ステップでセットアップする。- PR には「メンション対応(
@claude)」と「プルリクエストレビュー対応」の2つの GitHub Actions が含まれる。- GitHub Actions 内で Claude Code に MCP サーバ(例: Playwright)を使わせる場合、
claude_args経由で CLI と同じワイルドカード構文(例:mcp__server__*)は使えるが、CLI のような対話的な「まとめて許可」のショートカットはなく、コアツールなどは個別に明示列挙する設計になっている。- カスタム instructions で「開発サーバーは起動済み」「Playwright MCP でブラウザアクセス可能」といった前提を Claude に伝えられる。
Introducing hooks
このレッスンでは hooks(フック)を取り上げる。hooks を使うと、Claude がツールを実行しようとする前後に、任意のコマンドを実行できる。hooks は非常に興味深く実用的な機能を実装するために使える。例えば、Claude がファイルを書き込むと決めた後にコードフォーマッタを自動的に実行したり、ファイルが編集された後にテストを実行したり、あるいは Claude が特定のファイルを読み取ることをブロックしたりできる。可能性はほぼ無限であり、講師はこの後、hooks の使い方のアイデアを示すいくつかの良い実例を用意しているという。
hooks の仕組み
まず仕組みを理解する。Claude Code に何かを尋ねると、そのクエリはいくつかのツール定義とともに Claude モデルに送られる。Claude モデルは、注意深くフォーマットされたレスポンスを返すことでツールを実行することを決定する場合がある。その時点で、要求されたツール(例えばファイルを読む、といったもの)を実際に実行するのは Claude Code の役目であり、実行後にはその結果を返す。
hooks は、このツール実行の直前・直後にコードを実行する能力を与えてくれる。
- ツールの実行前に走る hook は pre-tool-use hook と呼ばれる(ツールの前に実行されるため)。
- ツールの実行後に走る hook は post-tool-use hook と呼ばれる(同じ理由による)。
(※これは分かりやすさのための呼び方であり、settings ファイルの中で実際に使う正式なイベント名は、ハイフンなしのパスカルケース表記 PreToolUse / PostToolUse である。本ノートではこれ以降も分かりやすさのため「pre-tool-use hook」「post-tool-use hook」という表記を使う。)
設定方法
hooks を定義するには、Claude の settings ファイルに設定を追加する。settings ファイルには複数の種類があり、思い出す通り、マシン上の全プロジェクトで使うグローバル用、他のエンジニアと共有するプロジェクト固有用、自分専用でそのプロジェクトに限定したもの、といった区別がある。hooks は、このファイルの中に手で直接書き込むことができる(Claude Code 内蔵の /hooks コマンドもあるが、これは設定済みの hooks を一覧確認するための読み取り専用の画面であり、hooks の追加・編集自体は settings ファイルの直接編集か、Claude への自然言語での依頼で行う必要がある)。
設定ファイルの構造には、明確に区別された2つのセクションがある。
- 1つのセクションには、ツール使用「前」に実行されるべきすべてのコマンド(= pre-tool-use hooks)が列挙される。
- もう1つのセクションには、ツール使用「後」に実行されるべきすべてのコマンド(= post-tool-use hooks)が列挙される。
それぞれのセクションでは、matcher(マッチャー) を指定する。これは、どのツール使用タイプを対象とするかを示すものである。例えば「read ツールの使用を見つけたい」という指定をすると、Claude Code が read ツールでファイルを読み取ろうとするたびに、指定したコマンドが実行される。同様に、post-tool-use セクションでは、write・edit・multi-edit ツールの使用後に、別のコマンドを実行するよう指定できる。
hooks が本当に意図していること
ここが重要な点である。先ほど見たコマンドには、Claude が実行しようとしているツール呼び出しについての詳細情報が渡される。
- pre-tool-use hook の場合: Claude が何をしようとしているかを検査できる。もし何らかの理由でそれを許可したくない場合、そのツール使用操作をブロックし、エラーメッセージを Claude に送り返すことができる。
- post-tool-use hook の場合: ツール呼び出しはすでに発生してしまっているので、ブロックするには手遅れである。しかし、そのツール呼び出しに基づいて、何らかのフォローアップ操作(例えば、たった今編集されたファイルをフォーマットする、など)を行うことができる。加えて、そのツール使用について何らかのメッセージを Claude に返すこともできる。例えば、別のプログラムを走らせて編集内容のコード品質をチェックしたり、型チェックを行ったりして、そのフィードバックを Claude に返す、といった使い方が考えられる。Claude はそのフィードバックを受け取り、たった今書き込んだファイルへの更新を行うかもしれない。
hooks やその意図がまだよくわからなくても、まったく問題ない。hooks の考え方を頭の中で整理するのはかなり難しい作業なので、講師はこの後、サンプルプロジェクトを使って実際に hooks に取り組んでいくと述べている。
要点
- hook はツール実行の直前(pre-tool-use)または直後(post-tool-use)にコマンドを実行する仕組み。
- 設定は settings ファイル(グローバル/プロジェクト共有/個人用の3種)に手動で書く。
/hooksコマンドは設定済み hooks を確認するための読み取り専用の画面であり、追加・編集はできない。- 設定は「matcher(対象ツール名)」+「実行コマンド」のペアで、pre-tool-use セクションと post-tool-use セクションに分かれる。
- pre-tool-use hook はツール呼び出しをブロックできる。post-tool-use hook はブロックはできないが、フォローアップ処理やフィードバックを Claude に返せる。
Defining hooks
hooks の仕組みをより深く理解するため、新しいサンプルプロジェクトを使う。このレクチャーには Query.zip というファイルが添付されており、これをダウンロードしてコードエディタで開くことが推奨されている。エディタを開いたら、ターミナルで npm run setup を実行する。これによりいくつかの依存関係がインストールされ、hooks を使う準備が整う。
作りたい hook のゴール
このプロジェクトのルートディレクトリには .env というファイルがあり、これには機密情報が含まれている。念のため、Claude がこのファイルの内容を直接読み取ることを完全に防ぎたい、というのが今回作る hook のゴールである。
手順1: pre-tool-use か post-tool-use か
まず、pre-tool-use hook が必要か post-tool-use hook が必要かを決める。今回のシナリオでは、Claude が特定のファイルを読み取ることを事前に防ぎたい。もし post-tool-use hook を作ってしまうと、コマンドを実行する時点ではすでに Claude がそのファイルを読み終えてしまっている。そのため、この場合は確実に pre-tool-use hook が必要であり、これによって read 操作の発生自体を防ぐことができる。
手順2: 監視すべきツール呼び出しの種類を決める
次に、どの種類のツール呼び出しを監視したいかを決める。現在の Claude Code に含まれるすべてのツール名の一覧を暗記するのはかなり大変であり、しかも MCP サーバを通じて独自のカスタムツールを追加できるため、なおさら難しい。そこで講師は小技を紹介する。Claude Code に直接、「今アクセスできるすべてのツール名を箇条書きで教えて」と尋ねればよい。
こうした様々なツールの中で、ファイルの中身を非常に簡単に読み取れるツールが2つある。まず read ツール。そして見落としがちだが、実は grep ツールもファイルの中身を読み取ることができる。grep はファイルの中身を検索できるためである。したがって、read ツールと grep ツールの両方の呼び出しを監視する必要がある。
手順3: コマンドの実装とデータの受け渡し
次に、Claude が行おうとしているツール呼び出しについての情報を受け取るコマンドを書く。仕組みは次の通りである。まずコマンドを書き、Claude がそれを自動的に実行する。その際、そのプロセスの標準入力(stdin)に対して、Claude はツール呼び出しのデータを JSON として渡してくる。この JSON オブジェクトには、ツール名やそのツールへの入力といった情報が含まれる大きなオブジェクトが渡される。
例えば、ツール名が read で、読み取ろうとしているファイルパスが .env ファイルを指している、といった具合である。まさにこれが、読み取りを防ぎたいファイルである。
したがって、自分のプログラム(コマンド)の中では、この情報を標準入力経由で受け取り、その JSON をパースし、ツール名やツールの入力引数などを読み取った上で、このツール呼び出しに対してどう対応するかを決める必要がある。
手順4: 終了コードによる Claude への合図
コマンドが提案されたツール呼び出しデータを受け取った後、そのコマンドは終了(exit)する。この終了コードが、Claude Code への合図となる。
- 終了コード 0: すべて問題なく、このツール呼び出しを許可したいという意味。
- 終了コード 2: このツール呼び出しをブロックしたいという Claude Code への合図。今回作る pre-tool-use hook では、これによりツール呼び出し自体をブロックできる。なお終了コード 2 によるブロッキング的な挙動は pre-tool-use hook に限らず、
UserPromptSubmitなど他のイベントの hook でも発生し、イベントの種類ごとに具体的な効果(例:UserPromptSubmitの場合はプロンプト自体の拒否)が異なる。
終了コード 2 で終了した場合、そのコマンド実行中に生成された標準エラー(stderr)のログはすべて、Claude へのフィードバックとして送られる。したがって、ツール呼び出しを拒否しつつ、同時にその理由を Claude に伝えることができる。
以上が全体のプロセスである。ここでもたくさんの要素が登場したため、次のレッスンでは、このプロジェクトの中で hook を実際に配線していく一連の手順を通して、これらのステップがどのようにつながるのかを見ていく。
要点
- hook を作る4ステップ: (1) pre/post のどちらが必要か判断する、(2) 監視対象のツール名を決める(read/grep はファイル読み取りが可能な点に注意)、(3) stdin から JSON でツール呼び出しデータを受け取り解析する、(4) 終了コードで応答する(0=許可、2=ブロック。ブロック時の具体的な挙動はイベントの種類ごとに異なり、pre-tool-use hook 以外でも発生する)。
- 終了コード 2 の際の stderr 出力は、そのままブロック理由として Claude にフィードバックされる。
- 「今使えるツール名を一覧で」と Claude 自身に尋ねるのは、監視対象ツールを洗い出す実用的なテクニック。
Implementing a hook
前レッスンで組み立てた設計を、実際に実装する。目標はあくまで「Claude が .env ファイルの中身を絶対に読み取れないようにする」ことである。
設定ファイルへの記入
.claude ディレクトリの中の settings.local.json を開く。ここには pre-tool-use hooks と post-tool-use hooks のリストがある。今回は pre-tool-use hook を作り、対象ファイルの読み取りを事前に防ぐ必要がある。講師はあらかじめ、少し手間を省くための設定セクションを用意してくれている。あとは matcher とコマンドを埋めるだけでよい。
- matcher: 監視したいツール名。今回は read ツールと grep ツールを監視したいので、この2つのツール名をパイプ記号(
|。キーボードの Return キーのすぐ上にある記号で、Lや大文字のIではない)で区切って指定する。 - command: これら2つのツールが呼ばれるたびに実行するコマンド。CLI でもシェルスクリプトの呼び出しでも、何でも指定できる。講師はこのファイル内の他の設定と一貫性を持たせるため、あらかじめプロジェクトの
hooksディレクトリに置いておいた Node.js スクリプトを呼び出す形にする。プレースホルダーとして入っているtrueをnode ./hooks/read_hook.jsに置き換えて保存する。
read_hook.js の実装
次に、read ツールまたは grep ツールが呼ばれるたびに実行されるコマンド本体、read_hook.js を実装する。
ファイルの先頭には、標準入力から読み取り、それを JSON としてパースするコードがすでに用意されている。この toolArgs オブジェクトが、先ほどの図で示した大きな JSON オブジェクトに相当し、session ID・ツール名・ツール入力などのプロパティを持つ。
やるべきことは、対象のファイルパスを見て、それが .env ファイルを読み取ろうとしているかどうかを判定することだけである。もしそうであれば、終了コード 2 でプログラムを終了させ、あわせて「申し訳ないが、そのファイルは読めません」という趣旨の情報を Claude にログ出力する必要がある。
すでに用意されているコードでは、対象のファイルパスを読み取る箇所があり、そこには toolInput.path を見るフォールバックも用意されている(この理由は少し後で説明される)。
TODO 部分を次のように実装する。readPath が .env を含んでいれば、それは Claude が .env ファイルを読み取ろうとしていることを意味する。その場合、この操作をブロックし、Claude にフィードバックを提供する。
- まず
console.errorを使う(console.logではない点がポイントで、標準エラーへログを出す必要があるため)。標準エラーこそが Claude へフィードバックを伝える手段である。メッセージとしては「You cannot read the .env file.」のような内容を出力する。 - その後、
process.exit(2)を呼ぶ。
動作確認
ファイルを保存し、Claude Code を開く(すでに開いている場合は必ず再起動する。hooks への変更を反映させるには Claude Code の再起動が必須である)。
Claude に .env ファイルを読むよう依頼する。Claude はおそらくそれを試みるが、読み取ろうとした瞬間に「You cannot read the .env file.」というエラーが返される。Claude はこれを理解し、実際に「read hook によって阻止された」ということまで認識できる。
さらに、この hook は grep 操作に対しても機能するはずである。Claude に grep ツールで .env の中身を探るよう頼むと、同様に禁止されることが確認できる。
こうして動作する hook が完成した。ただし、このこと自体はそれほど実用性の高い hook ではなく、講師はこの後すぐに、もっと実用的な hook を紹介すると述べている。
要点
- matcher は
read|grepのようにパイプ区切りで複数ツールを指定できる。- コマンドは
node ./hooks/read_hook.jsのように任意の実行可能コマンドを指定できる。- フック本体は stdin から JSON を読み、ファイルパスに
.envが含まれるかを判定し、該当すればconsole.errorでメッセージを出してからprocess.exit(2)でブロックする。- hooks の変更を反映するには Claude Code の再起動が必須。
Useful hooks!
このレッスンでは、自分のプロジェクトで使いたくなるような、本当に実用的な hooks を2つ紹介する。これらの hooks は、Claude Code が抱えがちな共通の弱点に対応することを意図している。
実用hook その1: TypeScript 型チェックを post-tool-use hook で走らせる
まず問題を実演する
1つ目の hook がどう役立つかを理解するため、講師はまず、特に大きめのプロジェクトで Claude Code が時々陥る問題を実演する。
src ディレクトリの中に schema.ts があり、その中には createSchema という1つの関数だけが定義されている。この関数は main.ts ファイルから呼び出されている。
講師は schema.ts に戻り、関数定義を更新する。「この関数を呼ぶ際には、必ず Boolean 型の verbose という引数も渡さなければならない」という変更を加える。この変更を加えた途端、main.ts に戻ると型エラーが発生する。エラー内容は具体的に「argument for verbose was not provided(verbose の引数が渡されていない)」というものである。
この変更を一旦取り消し、main.ts を閉じる。次に Claude Code を開き、まったく同じ変更を Claude に依頼する。Claude Code はこの編集自体には何の問題もなく対応する。verbose: true という新しい引数が追加される。しかし残念なことに、Claude はこの変更の後、プロジェクト内を見渡してこの関数が実際に呼び出されている箇所を探し、呼び出し側を更新するということをしない。そのため main.ts を開くと、実際にエラーが発生したままになっている。Claude はこれを検知できなかった、ということである。
TypeScript の型チェックコマンドで確認する
Claude Code を閉じ、tsc --noemit というコマンドを実行すると、プロジェクト全体に対する型チェックが走る。この型チェックの結果を見ると、エラーが明確に示される。具体的には、main.ts からの createSchema 呼び出しについて文句を言っている。
hook のアイデア
そこで講師が考えたアイデアはシンプルである。「TypeScript ファイルが編集されるたびに、TypeScript の型チェッカーを実行し、明確なエラーがあるかどうかを確認するべきだ。エラーがあれば、それを post-tool-use hook の中で即座に Claude へフィードバックするべきだ。」というものである。これにより、Claude は自分がたった今、型エラーを引き起こしたこと、そしてそれをプロジェクトのどこかで修正する必要があることに気づけるはずである。
hooks/tsc.js の中身
講師はあらかじめ hooks/tsc.js というファイルにこの hook を用意しておいた。このファイルの中には、TypeScript の型チェッカーを実行し、見つかったエラーを Claude に渡し返すためのロジックが一通りまとめられている。
ただし、先ほどのデモを見せるために、現時点ではこの hook はあえて無効化されていた。無効化の方法は、ファイルの先頭に process.exit(0) を追加することによるものである。この行を削除すると、hook は正しく機能するようになる。
有効化後の再テスト
schema.ts に戻って verbose フラグを取り除き、Claude Code を再起動し、再び同じ変更を依頼する。Claude はまず変更を行う。すると今度は、組み立てた TypeScript 型チェッカーからのフィードバックを即座に受け取り、「プロジェクトの他の場所にエラーがある」ということを知らされる。
編集操作が行われ、hook からの編集操作フィードバックが得られる。つまり hook が、いずれかのファイルに問題が見つかったことを検知したということである。そして Claude は「なるほど、理解した。エラーを引き起こしてしまったので、main.ts 内の createSchema 呼び出しを修正する必要がある」と応答する。続く更新で、Claude はそのファイルへ移動し、不足していた引数を追加するように関数呼び出しを更新する。
応用範囲
これは各自のプロジェクトで試す価値のある hook である。この hook は TypeScript 向けに特化して実装されているが、型チェッカーを簡単に実行できる言語であれば、他の型付き言語でも同じように機能する。型のない言語を使っている場合でも、「型チェッカーの代わりにテストを実行する」という同じアイデアを応用できる。つまり、編集が行われるたびにテストを実行し、その編集が問題ないかを確認する、という形である。
実用hook その2: クエリの重複を防ぐレビュー hook
続いて紹介される2つ目の hook は、説明がもう少し難しいものの、理解できればとりわけ大規模なプロジェクトで非常に役立つものだという。
背景説明
src/queries ディレクトリの中には多数のファイルがあり、それぞれのファイルの中には、様々な関数として書かれた多数の SQL クエリが含まれている。特に orderQueries.ts ファイルの中に getPendingOrders という関数がある。このクエリは、e コマース関連のデータを含むデータベースを検索し、理論上は「pending(保留中)」状態にあるすべての注文を見つけ出すものである。この関数の存在をひとまず記憶しておく。
よくある問題を図解する
左側にクエリファイルの一覧があり、それぞれのクエリファイルには多数のクエリが含まれている。特に orderQueries ファイルの中には getPendingOrders 関数がすでにあり、保留中の注文を見つけ出すクエリがすでに用意されている。
ここで Claude に対して「main.ts を更新して、3日より長く pending 状態にあるすべての注文を出力するようにしてほしい」と依頼したとする。理想的な世界では、Claude は orderQueries.ts ファイルを見つけ、既存のクエリを見つけ、新しいクエリを書く代わりにそれを活用するはずである。
実際に Claude に対してまさにその依頼を行うと、望んだ通りの結果が得られる。「main.ts の中で、pending になっている注文を出力して」と Claude に依頼すると、Claude はまず存在するクエリファイル群を確認し、orderQueries ファイルを見つけ、その中にすでに getPendingOrders というクエリが存在することを認識する。そして新しいクエリを作成する代わりに、この関数を利用しようとする。新しいクエリは望んでおらず、既存の関数を使ってほしかったので、これはまさに望んだ通りの挙動である。フォーカスの絞られた明確なタスクを与えた場合、Claude は「新しいクエリを書くべきではなく、少なくとも既存のクエリを確認すべきだ」ということを理解できた。
タスクを複雑にした場合
続いて講師は少し意地悪な変化球を投げる。まず /clear を実行してこれまでのコンテキストをクリアする。次に task.md ファイルを見るよう Claude に指示する。このファイルには、依然として「長期間 pending になっている注文を見つける」というタスクを含みつつも、それをより大きなプロジェクトの中に組み込んだプロンプトが用意されている。具体的には、「1日1回、長期間 pending のままになっているすべての注文について、特定の Slack チャンネルにメッセージを送る Slack 連携を書いてほしい」という依頼である。今回のシナリオでも、依然として長期間 pending の注文を見つける必要はあるが、それがより大きなタスクの中に包み込まれている形になる。
このタスクを、再度 /clear した後に Claude に与えると、今回は残念ながらそれほどフォーカスを保てず、まったく新しい getPendingOrders 相当のクエリを新規に書こうとしてしまう。これはまさに望んでいなかった挙動であり、プロジェクト全体でコードが重複することになる。しばらく実行させると、実際に getOrdersPendingTooLong という新しいクエリを作成してしまう。これは、Claude が集中力を失い、既存のクエリを再利用する代わりに新しいクエリを書いてしまった例である。ここでも重複コードが生まれてしまっており、これは望ましい結果ではない。加えて、新しいクエリを作っただけでなく、まったく新しいファイルまで作成してしまっている。これも避けたいことであり、本来この注文関連のクエリは orderQueries ファイルに追加されるべきである。
hook による解決策
この問題を理解した上で、講師はこれを hook を使ってどう解決できるかを示す。Claude が queries ディレクトリ内の何かを変更するために write・edit・multi-edit ツールを使おうとするたびに、次のような hook を実行する。
- この hook の中で、まったく新しい別の Claude Code のコピーを起動する。
- この新しいコピーに、たった今行われた変更を確認させ、
queriesディレクトリ内の既存コードを見て、似たようなクエリがすでに存在していないかを確認させる。 - もし既存のクエリが見つかった場合、その情報をフィードバックとして元の Claude に送り返し、状況を修正するよう Claude に依頼する。具体的には「追加されたクエリを削除し、すでに存在するものを使うようにする」という判断を Claude に促す。
これにより、queries フォルダを全般的にきれいな状態に保ち、重複コードが入り込まないようにできる。
実演
まず、先ほど作られてしまった orderAlertQueries.ts ファイルと slack.ts ファイルを削除する。次に hooks ディレクトリの中にある queryHook ファイルを開く。この hook はあらかじめ用意されているが、現時点ではファイル冒頭に process.exit があるため無効化されている。
この hook の内容を簡単に確認する。
- まず、
src/queriesディレクトリへの変更だけをレビュー対象にする、という設定がある。 - 少し下に進むと、たった今行われた変更が
queriesディレクトリに対するものかどうかをチェックする処理がある。 - その後、たった今行われた変更についてレビューを行うよう Claude に依頼する長いプロンプトが用意されている。
- そしてその後の部分で、Claude Code をプログラム的に起動している。具体的には、この部分のコードが該当する。これは Claude Code の TypeScript SDK(現在の正式名称は Claude Agent SDK)を利用しており、詳細は次のレッスンで説明されるが、ひとまずここでは、これはターミナルで Claude Code を使うのと本質的に同じことをしている、と理解しておけばよい。
- Claude Code が実行され、応答が返ってくると、Claude が「変更内容は問題ない」と判断したのか、それとも「重複クエリがある」と判断したのかを確認する。もし重複がある場合は、終了コード 2 で早期に終了し、このフィードバックを Claude に返して、修正が必要であることを伝える。
この追加の hook をファイル冒頭の process.exit(0) を削除することで有効化し、再び Claude Code を再起動して同じクエリを再実行する。最初は同じように重複クエリを作ろうとするかもしれないが、今度はこの hook が実行され、「その重複コードは望んでいない。この機能を実装するには、すでに存在するクエリを利用するべきだ」ということを伝えてくれるはずである。
Claude Code は再び、まったく新しい別のクエリファイルを作成しようとし、既存のクエリを利用しない。しかしそのファイルを作成しようとした瞬間に hook が実行される。hook は別の Claude Code のコピーを起動し、そのコピーが調査を行い、実際に再利用可能な既存のクエリが存在することを見つけ出す。そして「この既存のクエリを目的に合わせて更新すればちょうどよいのでは」というアドバイスを提供する。すると、講師が実際にやり取りしているメインの Claude インスタンスから、「ああ、そうだ、この既存のクエリがある。新しいものを書くのではなく、この既存のクエリを修正しよう」というフィードバックが返ってくる様子が確認できる。
トレードオフ
この hook の欠点は、queries ディレクトリ内の何かを編集しようとするたびに、追加の時間とコストがかかることである。一方の利点は、queries ディレクトリ内の重複コードをかなり減らせることである。したがって、これは自分のプロジェクトでこうした仕組みを実装したいかどうかという、一種のトレードオフの問題に帰着する。
もし実装するのであれば、講師は少なくとも、queryHook で示したようなやり方(つまり、プロジェクト内のほんの一握りの重要なディレクトリだけを監視対象にする)を推奨している。これは、実行される余分な作業量を最小限に抑えるためである。
要点
- hook 1(型チェック): post-tool-use hook として
tsc --noemit相当の型チェックを走らせ、エラーがあれば Claude にフィードバックする。型のない言語ではテスト実行に置き換えられる。- hook 2(クエリ重複防止):
queriesディレクトリへの write/edit/multi-edit を検知したら、hook 内で別インスタンスの Claude Code をプログラム的に起動し、既存クエリとの重複をレビューさせ、重複があれば終了コード 2 でフィードバックして元の Claude に修正を促す。- hook 2 は Claude Code TypeScript SDK(現 Claude Agent SDK)を使って実装されている。
- hook 2 はコストと時間のトレードオフがあるため、重要なディレクトリだけに絞って適用することが推奨される。
The Claude Code SDK
先ほどのクエリレビュー hook を見た際に、Claude Code SDK の一端をすでに垣間見た(※現在の正式名称は Claude Agent SDK。旧称 Claude Code SDK から改称されており、公式ブランディング上も SDK 製品に「Claude Code」の名称は使わない扱いになっている)。SDK を使うと、Claude Code をプログラム的に利用できる。SDK は CLI、TypeScript ライブラリ、Python ライブラリのいずれからでも使うことができる。これは、普段ターミナルで使っているのとまったく同じ Claude Code であり、同じツール一式を持ち、それらを使って与えられたタスクを完遂する。
SDK が最も役立つのは、より大きなパイプラインやツールの一部として組み込む場合である。先ほどの hook の中で見たように、Claude Code を、何らかのワークフローに知性を加える大きなプロセスの一部として簡単に組み込むことができる。
TypeScript SDK のデモ
既存のプロジェクトに TypeScript SDK を実際に組み込んで見せる。エディタに戻り、プロジェクトのルートディレクトリにある sdk.ts ファイルを見つける。この中には、SDK を使い始めるための最小限のコードがすでに用意されている。
ファイル冒頭のプロンプトを更新し、「src/queries ディレクトリ内の重複クエリを探してほしい」という内容に変更する。ファイルを保存し、これを実行するにはターミナルを開いて npm run sdk を実行する。これは組み込みコマンドではなく、内部では単にこのファイルを通常の TypeScript ファイルとして実行しているだけである。講師はこれを、TypeScript ファイルを少し楽に実行するためのショートカットとしてあらかじめ用意している。
これを実行すると、ローカルの Claude Code と Claude 言語モデルとの間で行われる生のやり取りが、メッセージ単位で表示される。最終的にコマンドラインに戻ってくる。最後に表示されるメッセージが、Claude からの最終的な応答となる。
SDK の注意点(デフォルトは読み取り専用)
SDK には少し落とし穴がある。デフォルトでは、読み取り系の能力しか持っていない。つまり、ファイルやディレクトリを読んだり、grep 操作を行ったりすることはできるが、ファイルを書き込んだり、編集したり、新規作成したりする能力はない。
書き込み権限を与えるには2つの方法がある。
queryの呼び出しに直接、書き込み権限を手動で追加する。.claudeディレクトリ内の settings ファイルに権限設定を追加する。
edit ツールを許可する実演
このプロジェクト内で SDK に edit ツールの使用を許可する方法を示す。prompt 引数のすぐ後に、options を追加し、その中にオブジェクトを置き、allowedTools というキーで配列を指定し、そこに Edit を入れる。
冒頭のプロンプトを更新し、「package.json ファイルに description を追加してほしい」という内容にする。これを保存し、再び npm run sdk を実行する。完了したら package.json を開くと、実際に description が追加されていることが確認できる。これにより、SDK が確かにファイルを編集する能力を持っていることが分かる。
先述の通り、Claude Code SDK が最も役立つのは他のツールの一部として組み込む場合である。したがって、ヘルパーコマンドやスクリプト、そしてとりわけ hooks の中で活用する機会を、各自のプロジェクトの中で探してみることが推奨される。
要点
- Claude Code SDK(現在の正式名称は Claude Agent SDK)は CLI / TypeScript ライブラリ / Python ライブラリから使え、ターミナル版と同一の Claude Code が動く。
- SDK はデフォルトで読み取り専用(read・grep 相当のみ)。書き込み・編集を許可するには
queryのoptions.allowedTools(例:["Edit"])を指定するか、.claudeの settings ファイルで権限を設定する。- SDK は単体で使うより、hooks・ヘルパーコマンド・スクリプトなど、より大きなパイプラインに組み込んでこそ真価を発揮する。
Summary and next steps
コース全体のまとめとして、講師は次の3つのアドバイスを提示している。
- Claude Code は絶えず変化し、活発に開発が続いているツールであることを念頭に置く。 Claude Code のホームページ(講師はそのアドレスを画面に示している)に注目し、新しい機能やテクニックが登場していないか、常にアンテナを張っておくこと。
- 実験することを強く推奨する。 Claude Code をカスタマイズし、自分の用途に合わせて調整する方法は数多くある。カスタムコマンドを自作してみたり、
CLAUDE.mdファイルに追加の指示を書き込んでみたり、このコースで扱ったもの以外の MCP サーバもいくつか試してみることを勧めている。 - 自動化すること。 GitHub 連携を見直し、日常的に繰り返し行っているタスクにどのようなものがあるかを考え、GitHub リポジトリ内で発生するイベントに基づいてそれらを自動的に Claude へ委譲する方法を検討すること。
講師は、このコースを楽しんでもらえたことを願うとともに、Claude Code での作業を楽しんでほしいと締めくくっている。
要点
- Claude Code は活発に開発が続いているため、公式ホームページで新機能・新テクニックを継続的に追う。
- カスタムコマンド・
CLAUDE.md・様々な MCP サーバを積極的に試す(実験)。- GitHub 連携などを使い、繰り返し発生するタスクをイベント駆動で Claude に自動委譲する(自動化)。