第6章: 専用ツールはなぜ多いのか ─ Read/Edit/Write と Bash の分業
ある日、エンジニア仲間と話していてこう聞かれた。
「Claude Code って Bash tool 持ってるんでしょ? じゃあ
catでファイル読めるし、sedで編集できるし、grepで検索できるじゃん。 なんで Read とか Edit とか Grep とか わざわざ別のツール にしてるの?冗長じゃない?」
いい質問だ。実際、原理的には Bash 一本あれば何でもできる。 それでも Claude Code は Read、Edit、Write、Grep、Glob、Bash と分業させている。
これは冗長ではなく、意図された設計 だ。 そしてこの設計判断こそが、Claude Code の「賢さ」と呼ばれているものの正体に近い。
6.1 そもそも、ツールはなぜ “増える” のか
第5章で見たとおり、利用可能な道具のカタログは system prompt に乗って毎ターン LLM に渡される。つまり道具を増やすには、トークン的コスト(定義が長くなる)と 認知的コスト(LLM が迷う材料が増える)の二つを払うことになる。普通に考えれば、Bash 一本にまとめたほうが短くて済むし、LLM も迷わないはずだ。
それでも Claude Code は 専用ツールを増やす道 を選んだ。なぜか。
専用ツールは、Bash で代替できない 4 つの利点 を持っているからだ。 (a) 出力フォーマットが安定 (b) 副作用が予測可能 (c) パーミッション制御が細かい (d) LLM が選びやすい。
この章では、この 4 つを 1 つずつ解いていく。
6.2 利点 (a) ── 出力フォーマットの安定
cat file.txt でファイルを読むのと、Read(file.txt) でファイルを読むのは、結果として 同じ内容 が返ってくる。
しかし「返り方」が違う。
| 方法 | 返ってくるもの |
|---|---|
Bash("cat fibonacci.py") | 生のファイル中身。OSやシェル設定によって改行コードや文字コードが揺れる可能性 |
Read("fibonacci.py") | 行番号付きの整形済みテキスト。一定の長さで自動切詰め、頭/末尾の空行除去など、フォーマット保証あり |
Read tool が返すフォーマットの例(行番号 + タブ + 中身):
1 def fibonacci(n):
2 if n < 2:
3 return n
4 return fibonacci(n-1) + fibonacci(n-2)
行番号を付けるのは、後で Edit tool で部分編集するときに「何行目を直すか」を LLM が指せるようにするため。道具と道具が 整った形 で連携できるよう、出力が設計されている。Bash で cat -n を呼んで毎回整える小細工に、LLM は脳を使わなくて済む。
6.3 利点 (b) ── 副作用の予測可能性
LLM は「続きを書く機械」なので、たまに 存在しないコマンド や 危険なオプション を書く。
Bash tool で find / -delete を呼ばれたら一発でシステムが壊れる。
専用ツールは 副作用の範囲がメタデータとして明示 されている。
| ツール | 副作用 |
|---|---|
Read | 読み取りのみ(ファイルシステムを変更しない) |
Grep / Glob | 読み取りのみ |
Write | 指定ファイルを 新規作成 or 全書き換え |
Edit | 指定ファイルに 部分置換 |
Bash | 任意の副作用(最も危険) |
ハーネスは、ツールの種類を見ただけで「これは読み取りだから無条件で許可していい」「これは Bash だから許可確認を取る」と判断できる。 Bash 1 本にまとめてしまうと、毎回コマンド文字列を解析して危険度を判定 しなければならず、判定漏れがそのまま事故になる。
専用ツールに分けることは、LLM 側の利便性 だけでなく ハーネス側の安全制御 のためでもある。 読み取り系と書き込み系を別ツールにすることで、「読み取りはノーチェック、書き込みは要確認」という単純なルールが書ける。
6.4 利点 (c) ── ツール単位の権限制御
(b) と地続きの話だが、Claude Code は ツール単位で許可・拒否のルール を持てる仕組みになっている(permissions、第10章で詳述)。
設定ファイルに、たとえばこう書ける:
{
"permissions": {
"allow": ["Read", "Grep", "Glob"],
"ask": ["Edit", "Write"],
"deny": ["Bash(rm -rf *)", "Bash(git push --force)"]
}
}
読み取り系は 無条件で許可、書き込み系は 毎回ユーザー確認、危険な Bash の特定パターンは 完全拒否。これは「道具がカテゴリで分かれている」からこそ書けるルールだ。もし全部 Bash で代替していたら、「cat は許可、rm は拒否、sed -i は確認」というような コマンド文字列ベースのルール を、無数のパターンマッチで維持しなければならない。
6.5 利点 (d) ── LLM にとって「選びやすい」
最後の利点が、実は実用上いちばん効いている。
LLM が道具を選ぶとき、カタログの中から名前を選ぶ という挙動をする(第2章)。 ツールの名前と説明が 役割を端的に表していると、選びやすい。
比較してみよう。
Bash 一本
LLM の判断:
- 「ファイル中身を見たい →
Bash("cat foo.py")」 - 「ファイル一覧を見たい →
Bash("ls -la")」 - 「検索したい →
Bash("grep -r ...")」?それともfind? - 「編集したい →
Bash("sed -i ...")」OS によって挙動が違う
毎回コマンド文字列を組み立てる 必要があり、ミスやプラットフォーム差が混入する
専用ツール群
LLM の判断:
- 「ファイル中身を見たい →
Read」 - 「ファイル一覧 →
Glob」 - 「検索 →
Grep」 - 「編集 →
Edit」
道具名と用途が 1 対 1 で対応。LLM は名詞を選ぶだけ。プラットフォーム差はハーネス側が吸収
「動詞 1 個に道具 1 個」の対応関係を保つことで、LLM は 判断ノイズを大きく減らせる。 これが、専用ツールを増やしてでも分業させる、いちばん実用的な理由だ。
6.6 図で掴む ── Bash 一本 vs 専用ツール群
ここまでの 4 つの利点をまとめて、対比図にしておく。
6.7 Bash は「逃げ道」として残す ── そして Edit が部分編集できる理由
ここまで読むと「じゃあ Bash いらなくない?」と思うかもしれない。
ところが、Claude Code は Bash も律儀に持っている。理由は単純で、未知のことが起きるから だ。git rebase -i、pnpm install、pytest ...::test_bar、curl、docker compose up -d ── これらを全部「専用ツール化」していたら、ツール定義が無限に膨らむ。
そこで設計判断はこうなる:
| 道具の種類 | 設計 |
|---|---|
| 頻繁に使う & 副作用パターンが定型 | 専用ツール化(Read, Edit, Write, Grep, Glob) |
| 何が来るか分からない / 一回限り | Bash で汎用的に扱う(要権限制御) |
専用ツールで 80% の典型作業を効率化 し、残り 20% は Bash の逃げ道で逃がす。これが Claude Code のツール構成の基本思想だ。
ここでもう一つ、専用ツール側の利点を具体例で見ておく。Edit tool は「ファイル全体ではなく、指定文字列を別の文字列に置換」する道具だ。たとえば 500 行のファイルの 1 関数だけ直したいとき:
| 方法 | LLM が出力するトークン |
|---|---|
| Write で全書き換え | 500 行ぶん(数千 〜 1 万トークン) |
| Edit で部分置換 | 変更前文字列 + 変更後文字列(数十 〜 数百トークン) |
1〜2 桁少ない出力で済む。出力トークンは入力トークンより単価が高いことが多く、これは実コストにも体感速度にも効く。さらに副次効果として、LLM が大規模な書き換えを写経して打ち間違える という事故も減る。Bash で sed -i を呼ぶより、Edit が LLM がやりたいことを最短距離でやれる粒度 で切られているのが効いている。
6.8 Grep が速い理由 ── ripgrep の採用
Claude Code の Grep tool は、内部的に ripgrep を使っている。
ripgrep (rg)Rust 製の高速な grep。
.gitignoreを尊重しつつ並列で走り、大規模リポをサブセコンドで走査できる。
Bash("grep -r ...") ではなく Grep(...) を独立した道具にしたことで、ハーネスは中身を ripgrep に置き換え、LLM 側のコードを 1 行も変えずに高速化 できた。
専用ツールは「今日の利便性」だけでなく「将来の最適化余地」も生む。 ツールが抽象化されていれば、中身の実装をいくらでも差し替えられる。
6.9 ツール設計の角度から、第1章の主張を確認する
ここまで見てきたとおり、ツールセットの設計は次の 4 つを同時に決める。
- LLM の判断ノイズ(名詞を選ぶだけで済むか、文字列を組み立てるか)
- 出力の安定性(後続ツールが結果を再利用しやすいか)
- 安全制御の解像度(ツール単位 or コマンド文字列)
- 長期的な拡張余地(中身を差し替えられるか)
前章で system prompt の角度から確認した「Claude Code らしさはハーネス側に宿る」という第1章の主張は、ツール設計の角度から見ると最も実装に近い形 で現れる。条文 (system prompt) だけでなく、LLM が手にできる動詞の切り方 がそのままエージェントの賢さになる。LLM は同じでも、道具セットの切り方一つで、別物のエージェントになる。
そして本書の残りは、この「ツール設計の哲学」が どこまで広がるか を追いかける旅でもある。
| 後章 | ツール周りの何を扱うか |
|---|---|
| 第10章 permissions | ツール単位の 許可・拒否 をどう書くか |
| 第11章 hooks | ツール呼び出しの 前後にフック を挟む仕組み |
| 第12章 MCP | ツールを 外部から拡張 する標準プロトコル |
| 第Ⅱ部 各グループ | 個々のコマンド (/agents /mcp /hooks) で実際に手を動かす |
ツールという概念は、Claude Code の中で 最も拡張ポイントが多い 領域。本章で握った「なぜ分業させているか」の感覚が、これら全部の章で効いてくる。
私はエージェントを評価するとき、まず ツールセットの一覧 を見る。 ここに用意された動詞の解像度を見るだけで、そのエージェントが どこまで考えてくれるか がだいたい分かる。
Bash 一本しか持っていないエージェントは、便利だが「何でも自分でやれ」と言われている感じがする。 Read / Edit / Grep / Glob まで揃ったエージェントは、「よく使う動詞は私が引き受けます」と差し出してくれる感じがする。
この設計の優しさが、毎日の作業の疲労度を大きく変える。
6.10 この章の振り返り
- 道具を増やすにはトークン・認知のコストがある。それでも Claude Code は 専用ツールに分業 させている
- 専用ツールの 4 つの利点: (a) 出力フォーマット安定 (b) 副作用予測可能 (c) ツール単位の権限制御 (d) LLM が選びやすい
- ツール構成の基本思想: 頻出 & 定型は専用ツール、未知 & 一回限りは Bash という二段構え
- Edit tool は部分編集でトークンを 1〜2 桁節約し、写経ミスも減らす
- Grep tool は内部に ripgrep を採用。インターフェースを変えずに中身を差し替えられるのが専用ツールの強み
- ツール設計は エージェントの賢さそのもの。同じ LLM でも、動詞の切り方で別物になる
この章で読めるようになるツイート / ブログ
- 「Cursor の検索が遅いから ripgrep に置き換えるパッチ書いた」 → 同じ問題を Claude Code は標準で解いている。専用ツール化のメリットが効く例
- 「俺のエージェント、Bash しか持ってないけど何でもできるよ」 → できるが、安全制御と判断ノイズの観点で本書の構造編から見れば不利、と言える
- 「Claude Code の Read tool が行番号付けてくるの何で?」 → Edit tool との連携前提の設計。専用ツール同士の出力が「噛み合う」よう整えられている
ここで 構造編 (第4-6章)は終わりだ。 context window、system prompt、ツール設計 ── エージェントの “机・憲法・道具” を見渡した。
次章からは 制御編 に入る。 ループを御す仕組み ── 計画、長期記憶、サブエージェント、権限、hooks ── を順に解いていく。