Chapter 6

第6章: 良い道具・悪い道具 ── description・権限・並列呼び出し

あなたが新しくエージェントを自作する立場になったとしよう。 LLM とハーネスのあいだの契約は、前章で見たとおり JSON Schema で固まっている。 だから「ツールを定義するコード」は、書けば動く。

書けば動く。問題はそのあと だ。

  • 渡したのに、LLM がぜんぜん呼んでくれない
  • 呼んでくれるが、引数がいつも変
  • 呼びすぎる ── 1 ファイル読むのにループを 8 回も回す
  • ファイルを破壊した ── 「いま勝手に書き換えるとは思わなかった」

同じ契約 (第5章) の上で、なぜここまで体感が割れるのか。 答えは ── 派手なアルゴリズムではない ── 道具の設計判断 にある。 description の書き方、粒度の切り方、権限と副作用の線引き、そして並列呼び出しの扱い。 本章はこの 4 つを、Claude Code・Cursor・Aider などを横断して解剖する。

6.1 そもそも、なぜ “道具設計” がエージェントの賢さなのか

第1章で見たとおり、LLM は変わっていない。変わるのは外側だ。 そして外側のうち、LLM が直接 目にする ものは限られている。

このうち カタログ は、LLM が 「いま自分は何ができる存在なのか」 を理解する一次資料だ。 ここに並んでいる道具の名前と説明が、LLM の行動範囲そのものを決める。

LLM が手にできる「動詞」の解像度が、エージェントの賢さの解像度になる。

道具を増やすか減らすか・粒度を粗くするか細かくするか・description をどう書くか ── これらは LLM が次の一手を選ぶときの判断ノイズを直接動かす。 派手な機能より、ここの設計が体感を支配する。

このことは Anthropic の Engineering Blog の “Writing tools for agents” でも繰り返し強調されている。同じ LLM・同じ契約面の上で、道具の書き方を直しただけ で性能が大きく動くケースが現場では普通に起きる。

6.2 description は LLM への「求人票」

前章でも触れたが、本章で改めて正面から扱う。

ツール定義の description は、ハーネス側のドキュメントではない。 LLM が「いま自分はこの道具を呼ぶべきか」を判断する材料 だ。 読者を想定して書くなら、読者は LLM である。

良い description には、次の 4 つが書かれている。

要素中身
いつ呼ぶか「ユーザーがファイルの内容を見たいと言ったとき」「テストを走らせたいとき」
いつ呼ばないか「コード片だけ見せたいときは Read ではなく直接出力する」
引数の意味path は絶対パス。相対パスはエラーになる」
副作用の明示「このツールはファイルを 書き換える。実行前にユーザー確認が走ることがある」

悪い例と良い例を並べてみる。

悪い description の例
{
  "name": "read_file",
  "description": "ファイルを読む"
}
  • いつ呼ぶかが書かれていない
  • 引数の決まりがない(相対パス? 絶対パス?)
  • 副作用が読み取り専用かどうかも書いていない
良い description の例
{
  "name": "Read",
  "description": "ローカルファイルの中身を読み取って行番号付きで返す。読み取り専用(副作用なし)。ユーザーがファイルの中身を確認したいとき、または編集の前に現状把握したいときに使う。path は必ず絶対パス。"
}
  • 呼ぶ場面が言語化されている
  • 「読み取り専用」が明記され、LLM は安心して呼べる
  • 引数の形式(絶対パス)が明記され、ミスが減る

description は、LLM への「求人票」と思うと書きやすい。 「この職にはどんなときに就いてほしいか、引き受けたら何をするか、何はしないか」を、応募者 (LLM) が読んで判断する。 求人票が雑だと応募が来ないか、来ても噛み合わない人が来る ── ツールの呼ばれ方もそれと同じだ。

実務メモ

description は 将来の自分への申し送り でもある。半年後にツールを増やしたい人 (or LLM 自身) が、既存ツールとどう棲み分けるかを判断する材料になる。「Edit は 1 箇所だけ置換」「Write はファイル全体を書き換え」のように、互いの境界を description で示す と、似たツールの誤発火が劇的に減る。

6.3 道具の粒度問題 ── 大きすぎる道具・小さすぎる道具

道具の名前と引数の切り方は、粒度の選択 でもある。 両極端から見てみよう。

極端 1: 大きすぎる道具 (do_everything)

「ファイルを開いて、編集して、テストを流して、結果を要約する」という巨大ツール 1 個。 contract としては動くが、LLM 視点では地獄だ。

極端 2: 小さすぎる道具 (read_one_line)

「ファイルから 1 行だけ読む」というミニツール 1 個。 これも contract としては動くが、

良い道具の粒度は、LLM が「1 回の決断」で完結したい単位 に合っている。 「1 ファイルを読む」「1 ファイルの 1 箇所を置換する」「1 つのテストを走らせる」── これくらいが現代のエージェントが落ち着いた粒度。

たとえば Claude Code は Read / Edit / Write / Grep / Glob / Bash の 6 つに代表的な動詞を切っている。Cursor の Agent モードもほぼ同じ粒度。Aider はやや独自で、ファイル単位の差分提案 (/add / /edit) を中心に据えている。粒度の選び方は各プロダクトの設計判断だが、LLM が 1 ステップで完結したい単位 に合わせる、という勘所はどこも共通だ。

6.4 権限と副作用 ── read-only / write / destructive の線引き

道具を切ったあと、次に決めるのは 副作用の度合い だ。 契約面 (第5章) だけ見ると、すべてのツールは平等な「JSON ブロック → 関数呼び出し」だが、何が起きるか はぜんぜん違う。

副作用クラスリスク
read-onlyRead, Grep, Glob, WebFetchほぼゼロ。ローカル状態を変えない
writeEdit, Writeファイル内容が変わる。git で復元可能
destructiveBash(rm -rf ...), Bash(git push --force)不可逆。本当に壊れる

ツールカタログにこの分類を メタデータとして 載せておくと、ハーネス側で

という単純なルールが書ける。ツールごとの副作用クラスが decl で見える からこそ、人間が制御しやすい。

サンドボックス (sandbox)

ツールの副作用が、ホスト環境に届かないように 隔離された実行環境 で道具を動かす仕組み。Docker コンテナ、リモート VM、git worktree、chroot 環境などが使われる。Devin や Codex 系の「ブラウザ内 IDE」型エージェントは強めのサンドボックスを前提に設計されている。

承認フロー / 権限モード

ハーネスが「このツール呼び出しを実行していいか?」をユーザーに尋ねる仕組み。Claude Code には default / acceptEdits / bypassPermissions のような モード があり、現場の信頼度に応じてユーザーが切り替える。Cursor も「Auto-run」を on/off できる。要は どこまで自動承認するかのつまみ だ。

権限の線引きは「LLM が悪さをしないように」だけのものではない。 LLM が安心して動くため のものでもある。 「destructive な道具は permitted list にあるときだけ」というガードレールがあれば、LLM は躊躇せず候補に挙げ、ハーネス側で止めればいい。 権限はブレーキだが、ブレーキのある車のほうが速く走れる ── という関係に近い。

6.5 並列ツール呼び出しは「誰の責任か」

第5章で見たとおり、LLM は 1 応答に複数のツール呼び出しブロックを並べて返せて、ハーネスはそれをまとめて同時実行する。 契約面・しくみそのものは第5章の本拠地に譲って、本章で考えるのは 道具設計の側でどう振る舞うか だ。

ここで言いたいのは三つだけ

実務メモ

プロバイダによって並列ツール呼び出しのデフォルト挙動が違う。Anthropic は parallel tool use が標準的に効く一方、OpenAI には parallel_tool_calls: true/false のような切替フラグがある(時期によって挙動が動く)。「並列で呼ばれないな」と思ったら、API 設定や SDK のオプションを確認するとよい。

6.6 プロダクトごとの動詞の切り方

道具セットそのものは、プロダクトごとにかなり違う。 たとえば Claude Code は Read / Edit / Write / Grep / Glob / Bash のように動詞を細かく切り、Bash を逃げ道として残す。Cursor はエディタ統合の差分提案を主役に据える。Devin は強サンドボックス前提で「PC を丸ごと触れる」道具群を開放する。

並べると、契約面(function calling)は同じでも、動詞の切り方とサンドボックスの強さで体感は全く別物 になる。プロダクトごとの道具セットや権限モデルの詳しい横並び比較は 付録A に集約してあるので、評価軸として使ってほしい。

エージェントのレビュー記事を読むときの裏ワザ: 「機能が多い・速い・賢い」のような感想を読み飛ばして、そのプロダクトが LLM に渡している道具の名前と粒度 に注目すると、設計の癖が手に取るように分かる。 名前は同じでも、たとえば Edit が「ファイル全体置換」なのか「1 箇所置換」なのか、Bash がサンドボックス内かホスト直撃か、で体感は全く違う。

6.7 道具設計が決めるもの ── まとめ

道具設計は、次の 4 つを同時に決める。

道具のレイヤでも、結局は 設計判断の総量がエージェントの体感を決める。 description の一文、粒度の一つの線、権限クラスの一段階、並列を勧めるかどうかの一行 ── どれも単独では地味だが、足し合わせた結果が「呼ばれ方」「速さ」「安全性」のすべてを動かす。

次章からは 第Ⅲ部 文脈とメモリ に入る。 LLM の机の広さ(コンテキストウィンドウ)と、CLAUDE.md / AGENTS.md / .cursorrules のような 外部記憶 をどう束ねるか ── 道具と並ぶもう一つの大きな設計レイヤだ。

この章の振り返り

この章で読めるようになるツイート / ブログ

次章は文脈とメモリ。 LLM の机の広さ (コンテキストウィンドウ) と、何をどこまで覚えさせるかという、ハーネス設計のもう一つの主要レイヤに進もう。