Jupyter Notebook で分析や機械学習のコードを書いていて、Claude Code に直接ノートを書き換えてもらいたい人向け
Jupyter Notebook の中身を Claude Code に整理させたり、可視化セルを差し替えてもらったり、不要な試行錯誤セルを削除してもらいたい場面で、Claude が裏で勝手に発火させて使う。設計者側としては、ノートを触らせたいプロジェクトで Edit(notebooks/**) のような形でファイル位置のパターンを書いた許可ルールを用意しておけばいい。
NotebookEdit は Claude Code が .ipynb という Jupyter Notebook のファイルを直接書き換えるための内蔵ツールです。普通のテキストファイル用の Edit ツールが「この文字列を、この文字列に置き換える」という発想で動くのに対して、NotebookEdit は「ノートブックのこのセル」を狙い撃ちで書き直したり、足したり、消したりします。
つまり「Iris の分析ノートのセル3を新しいコードに差し替えて」と Claude に頼んだ時、裏で勝手に発火するのがこのツール。私たちが直接打って使うものではなく、Claude Code 側の設計者が「ノートを触る時はこれを使え」と決めて呼び出させているイメージです。
噛み砕くと
普通のファイルを直す Edit ツールは、紙の原稿に赤ペンで「この行のこの単語を、こっちの単語に置き換えて」とやるイメージです。一方で Jupyter Notebook は1枚の紙ではなく、セルという付箋が縦に貼ってあるノートに近いです。
付箋ごとに cell_id という通し番号が振ってあって、NotebookEdit は「3番の付箋を全部書き直す」「3番の下に新しい付箋を貼る」「3番の付箋を剥がす」の3つしかやりません。文章の途中だけ一部を直す、みたいな細かい修正は、そのセル丸ごとを新しい中身で上書きして実現します。
大事な前提:Edit との違いを取り違えると壊れる
ここを勘違いすると挙動が全部おかしくなるので、最初に押さえます。Edit ツールは「文字列の前後を見て、ここの "old_string" を "new_string" に置き換える」という、テキストエディタの検索置換と同じ動きです。
NotebookEdit はこれをやりません。セル番号でセル単位を丸ごと差し替えるか、足すか、消すかのどれかです。だから「セル3の中の関数名だけ直して」みたいな部分置換を頼まれた場合も、Claude は内部的にそのセル全体の新しい中身を組み立て直して、まるごと replace で上書きします。
「Iris の品種分類ノートブックを Claude Code に整理させる」で見る、実際の流れ
具体的に動かしてみます。題材は iris_classify.ipynb という、Iris という花のデータを扱う3パート構成のノートとします。セル1で pandas でデータ読み込み、セル2で matplotlib で散布図を描いて、セル3で scikit-learn で分類モデルを学習する、というよくある構成です。
ステップ1: ノートを読ませる
まず Claude Code に iris_classify.ipynb を読ませます。Read ツールが発火して、ノート全体のセルがコード・マークダウン・実行結果ごと丸ごと返ってきます。Claude 側は「セル1〜3にそれぞれ何が書いてあるか」を把握した状態になります。
$ claude
> iris_classify.ipynb を見て、各セルが何をしているか整理してください
ステップ2: セル2の可視化コードを書き直してもらう
セル2の matplotlib 部分は、軸ラベルもタイトルもなくて読みにくいとします。Claude にこう頼みます。
> セル2の散布図に軸ラベルと凡例を足して、見やすくしてください
すると裏で NotebookEdit が発火します。動作モードは replace、対象は仮に cell-2 という cell_id、新しい中身は軸ラベルと凡例を追加した matplotlib コード一式。セル全体が新しい中身で上書きされるのがポイントです。
ステップ3: 新しいセルを挿入してもらう
「セル2とセル3の間に、データの前処理として標準化を入れたい」と頼むとします。今度は insert モードが発火します。「cell-2 の後ろに新しいコードセルを足す」という意味で、cell_id=cell-2、edit_mode=insert、cell_type=code、新しい中身は scikit-learn の StandardScaler のコード、という形で呼ばれます。
cell_type を code か markdown のどちらか指定するのが insert モード固有のルールです。これを指定し忘れると挿入できません。
ステップ4: 不要なセルを消してもらう
古い試行錯誤の残骸セルがあったら、delete モードでそのセルだけ消えます。cell_id=cell-5、edit_mode=delete という呼び出しで、対象セルが丸ごとノートから消える挙動です。
ここで初心者がやりがちな勘違いがあって、「delete を呼んでもセル番号は詰まらないのでは?」と思いがちですが、ノート上では削除されたセルは本当に消えます。残ったセルが繰り上がるだけです。
ステップ5: ノートの先頭に説明セルを足す
「このノートの目的をマークダウンでノート冒頭に書いて」と頼むケースを考えます。cell_id を指定せずに insert を呼ぶと、新しいセルはノートブックの先頭に挿入されるのが NotebookEdit のルールです。
つまり edit_mode=insert、cell_type=markdown、cell_id なし、という呼び出しで、ノートの一番上にマークダウンセルが1枚追加されます。「特定の位置に入れる」と「先頭に入れる」の使い分けはこの cell_id 有無で決まる、ということです。
つまり NotebookEdit は何をしてくれるのか
- やってくれる:
.ipynbファイルのセル単位での書き換え・追加・削除。コードセル/マークダウンセルどちらも対象 - やってくれない: ノート全体をまたぐ文字列の一括置換と、複数セルを1回の呼び出しで同時に編集すること。書き換えるだけで実行は別なので、結果のグラフや出力を出すには Jupyter 側でセルを再実行する必要がある
- 意味が薄い場面:
.ipynbではない普通の.pyファイルを直したい時。これは Edit ツールの仕事で、NotebookEdit は出番なし
使いどころ3シナリオ(具体題材で再現)
シナリオ1: 機械学習の実験ノートを Claude にレビューさせて書き直してもらう
Iris 分類のような小さな実験ノートで、自分で書いた可視化コードが汚いとします。「セル4の散布図、配色とラベルを論文っぽく整えて」と頼むと、Claude が該当セルを読んで、matplotlib の rcParams 設定とカラーパレットを差し替えたコードで replace 発火、セル4が丸ごと書き換わります。Jupyter で再実行すれば新しいグラフが出ます。
シナリオ2: 既存ノートに「目的」「データ出典」「手順」のマークダウン章立てを後付けする
自分用に走り書きしたノートを他人にも見せられる体裁にしたい時。「冒頭にこのノートの目的を、各コードセルの前にも一言マークダウンで説明を入れて」と頼みます。Claude は insert + cell_type=markdown を複数回発火させます。冒頭分は cell_id なしの insert、各セルの前に入れる分は対象セル直前のセルを指定した insert、という使い分けです。
シナリオ3: 失敗実験で残った試行錯誤セルを一括削除させる
「セル7〜10は古いハイパーパラメータ探索の残骸なので消して」と頼むと、Claude が delete を4回発火させます。NotebookEdit は1回の呼び出しで1セルしか触れないので、複数セル削除はその数だけ呼び出される動きです。delete はやり直しがきかないので、Claude に頼む前に該当セルの中身を別ファイルに残しておくと安全です。
初心者が踏みやすい落とし穴
- Edit ツールと混同して「セル3の中の変数名だけ直して」と頼むと、Claude が結局そのセル全部を書き換える。NotebookEdit に部分置換は存在しないので、セルが長いと意図しない箇所まで再生成される可能性がある。長いセルは事前に分割しておくと事故が減る
insertでcell_typeを指定し忘れると挿入できない。公式仕様でcodeかmarkdownのどちらか必須。ユーザー側で書き分ける場面はないが、「マークダウンで入れて」「コードセルで入れて」と日本語で明示してやると Claude が正しいcell_typeを選びやすいinsertでcell_idを渡し忘れるとノート先頭に挿入される。Claude が cell_id を正しく拾えなかった場合、意図せず先頭に新セルが刺さる事故が起きる。挿入後はノート構造を必ず Read で確認- NotebookEdit は書き換えるだけで、セルを実行はしない。書き直されたコードの結果(グラフ・出力)は Jupyter 側で再実行しないと反映されない。「Claude が書き直したから動くはず」と思い込むと、古い実行結果と新しいコードがずれた状態で残る
- 権限ルールは
Edit(notebooks/**)のような Edit のファイル場所指定形式。NotebookEdit 専用のルール名はなく、Edit と同じファイル位置のパターン記法で許可する。notebooks/配下のノートだけ触らせたい、みたいな運用はこの形式で書く。Edit の許可ルールに NotebookEdit も含まれる、と覚えるのが早い - 同じ cell_id が複数セルに振られているノートだと挙動が読めない。公式が cell_id をどう一意に保つかは明示していないが、自作した
.ipynbをテキストエディタで直接編集して cell_id を重複させた場合、最初にマッチしたセルが対象になる可能性が高い。基本は Jupyter が振った cell_id を触らない方が安全 - Read で先に読ませないと cell_id が分からない。Claude が NotebookEdit を発火する前段で、対象ノートの Read が必要になる場面が多い。「いきなりセル3を直して」と頼むより「
iris_classify.ipynbを見てから、その上で散布図セルを直して」と頼む方が、Claude が cell_id を取り違えにくい
書き方
ユーザーが直接打つものではなく、Claude が自動で発火させる内蔵ツール。設計者が呼び出しを直接書く場面はないが、内部的には「edit_mode: replace / insert / delete のどれか」「対象セルを指す cell_id」「new_source(新しいセル中身、replace と insert で必要)」「cell_type: code または markdown(insert モードでのみ必須)」をまとめて渡す形になる。insert で cell_id を渡さないとノート先頭に挿入される。
やってみるとこうなる
入力
ユーザー側の指示例: 「iris_classify.ipynb のセル2の散布図に軸ラベルと凡例を追加してください」。Claude 側はノートを Read で読んだあと、対象セルの cell_id を取得して NotebookEdit を edit_mode=replace で発火させる。
出力例
対象セルの中身が、新しいコード(軸ラベルと凡例つきの matplotlib コード)で丸ごと上書きされる。Claude 側は「セル2を書き換えました」と報告するが、グラフの新しい結果を見るには Jupyter 側でセルを再実行する必要がある。NotebookEdit はファイルの中身を書き換えるだけで、セルの実行はしない。
このページに出てきた言葉
- .ipynb
- Jupyter Notebook の保存形式。中身は JSON で、セル単位でコード・説明文・実行結果が記録されている
- セル
- Jupyter Notebook の中の1ブロック。コードを書く「コードセル」と説明文を書く「マークダウンセル」の2種類がある
- cell_id
- ノート内の各セルに自動で振られる識別番号。NotebookEdit はこの番号でセルを指して操作する
- replace モード
- 指定したセルの中身を、新しいソースで丸ごと上書きする動作モード。NotebookEdit の既定の動き
- insert モード
- 指定セルの後ろに新しいセルを追加する動作モード。cell_type の指定が必須で、cell_id を渡さないとノート先頭に挿入される
- delete モード
- 指定セルをノートから取り除く動作モード。1回の呼び出しで消せるのは1セルだけ
- cell_type
- セルの種類を指す値。<code>code</code> か <code>markdown</code> のどちらか。insert モードで新規セルを追加する時に必ず指定する
- Edit ツール
- Claude Code 内蔵の、普通のテキストファイル用の編集ツール。NotebookEdit と違い、文字列の完全一致による検索置換で動く
関連項目
公式ドキュメント
https://code.claude.com/docs/en/tools-reference#notebookedit-tool-behavior