Cursor エージェントの無駄なツール呼び出しを減らす 10 のルール — 自分のトランスクリプトを AI に解析させた記録
AI 主体で執筆Cursor の API 使用量が妙に多い気がしていました。開発が捗っているはずなのに、コストに見合う進みだったかと言われると曖昧です。気になって、過去 4 セッションの JSONL トランスクリプトをサブエージェントに渡して「無駄なツール呼び出しのパターンを洗い出して」と頼んでみました。出てきたのは「自分で指示していたはずなのに守られていない」冗長な動きの山。それを 10 条のルールに落とし込んだ記録です。
動機:API コストがどこで燃えているか見えない
Cursor を日常的に使っていると、「今日は妙にトークンを消費したな」と感じる日があります。ただ、具体的にどの操作が重かったのかは事後には思い出せず、ダッシュボード上の使用量は合計値しか見えません。セッションを閉じた瞬間にコンテキストは霧消します。
一方、Cursor の各会話はローカルに JSONL 形式のトランスクリプトとして残ります。ここには毎回のツール呼び出し、パラメータ、戻り値のサマリ、モデルの思考が全部入っています。つまり「どこでコストを燃やしたか」は事後にちゃんと追えます。
ただ、4 セッション分のトランスクリプトを人間が目で読むのはさすがにきつく、ここで面白いアイデアが出ました。AI 自身に「自分の過去ログ」を読ませて、無駄パターンを抽出させる — というものです。
方法:サブエージェントにトランスクリプトを分析させる
やったことはシンプルです。
- 過去 4 セッションの JSONL ファイルを用意する
- Cursor の
Task(サブエージェント)を呼び、次のようなプロンプトで解析させる:- 「これらのトランスクリプトを読み、同じ目的を達成するのにより少ないツール呼び出しで済んだ箇所を列挙せよ」
- 「重複読み、冗長な探索、リトライループ、失敗してもう一度呼び直している箇所を特定せよ」
- 「具体的な行番号・ツール名・頻度の統計を付けて、パターンごとにまとめよ」
- 返ってきたレポートを元にルール化する
重要なのはサブエージェントに任せる部分の設計で、メインエージェントに「自分のログを読め」と指示すると自分で書いた通りに動いてくれない可能性があります(自分の失敗を過小評価しがち、という AI の癖)。サブエージェントに「他人のログを評価してくれ」という構図で渡すと指摘が辛辣になりやすく、同じモデルでもコンテキストの置き方で出力の質が変わる、というのは改めて面白かったところです。
見つかった無駄パターン
出てきたレポートには、同じセッション内で何度も踏んでいたパターンがずらっと並びました。代表的なものを挙げていきます。
1. Glob の重複
「どのファイルに書いてあるか」を探すために Glob や Grep を呼ぶ。ところが後続のステップで「念のため」ともう一度同じ検索を叩いている。パラメータが微妙に違うだけで実質同じ情報を取り直しているケースが多かった。1 セッション内で同じ検索式を 3 回叩いているところもあった。
2. 大ファイルの往復読み
Localizable.xcstrings や project.pbxproj のような巨大ファイルを、行を絞らずに全文読みし、しかも 1 セッション内で複数回読み返している。オフセット・リミット指定を使えば済むのに、毎回ファイル全体をコンテキストに入れてしまい、トークンを食いつぶしていた。
3. ls -la を繰り返す
ディレクトリ構成の把握のために ls を叩くのはよくある。ところが同じディレクトリを 2〜3 回リスティングしているログがあった。直前の結果を記憶していない、というより「次のステップに入るときに改めて確かめる」癖がついていた。
4. サンドボックス失敗 → 権限付き再実行
これは特に痛かった。Shell 実行はデフォルトでサンドボックス内で走る。ネットワークやファイル書き込みが必要なコマンドは失敗する。そのたびに required_permissions: ["all"] を付けて再実行する、という毎回 2 回呼んでいるパターンが検出された。chmod、gh、npm install あたりで顕著。
5. WebFetch のリトライループ
X(旧 Twitter)や一部の CDN が 403 を返すと、Cursor が「別の URL 変換」でリトライを 3〜4 回続けるループがあった。最終的に取れないまま諦めるのだが、それまでに同じサーバへ何度もリクエストを投げている。ミラー(fxtwitter など)を最初から指定するか、ユーザーに本文を貼ってもらう運用にすれば 1 回で済む。
6. TodoWrite と本文の二重記述
TodoWrite で計画を立てたあと、ユーザー向けメッセージ本文でも同じリストを長文で再掲していた。「計画を示した → 実行中 → 完了報告」の 3 回、実質同じ内容を書き直している。本文は要約に留めて、詳細はツールに任せる分業にすれば、長文生成のコストが削れる。
7. 既存ヘルパースクリプトを無視して生コマンドを叩く
リポジトリに scripts/local-ci.sh のような用意されたラッパーがあるのに、それを使わず xcodebuild を直叩きしているパターン。生コマンドは引数が長く失敗しやすく、リトライも発生しやすい。既存資産の確認を先にするだけで解消する。
8. 自分で決めたルールを自分で忘れる
「project.pbxproj は main 直接編集禁止」のようなルールを .cursor/rules/ に書いたのに、別のセッションで同じエージェントが同じ罠を踏んでいた。ルール文書は意識していないと参照されない、という弱さがある。
10 条のルールにまとめる
抽出されたパターンを、次にセッションを始める前に読んで内面化してもらう形で .cursor/rules/agent-efficiency.mdc に 10 条として書いた。ここに要約して載せる。
1 セッション内で同じ Glob / Grep 式を 2 回以上叩かない。直前の結果が古くなっている疑いがあるときだけ再実行し、そのときは理由を明記する。
500 行以上のファイルは全文読みしない。まず Grep で当該箇所を特定し、Read の offset/limit で周辺だけ読む。xcstrings / pbxproj / package-lock.json / 長い Markdown は必ずこの手順。
同じディレクトリの ls を繰り返さない。構成を知りたいだけなら最初の 1 回で十分。再実行が必要なのはファイルを作成・移動したあとだけ。
ネットワーク・書き込み・外部コマンドが必要と分かっているときは最初から required_permissions: ["all"] か ["full_network"] を付ける。「とりあえず叩いて失敗 → 再実行」は禁止。
403 / 429 / 接続エラーで 1 回失敗した URL は、同じセッション内でリトライしない。別のミラーや代替手段に切り替えるか、ユーザーに本文の貼り付けを依頼する。
計画を TodoWrite に書いたら、ユーザー向けメッセージは 2〜3 行の要約に留める。詳細は TodoWrite が表示するので本文には書き写さない。完了報告も同様(差分だけ本文に書く)。
生コマンドを叩く前に scripts/ と package.json / Makefile を確認する。xcodebuild、gh api、curl などは直叩きする前に「この操作用のラッパーがあるか」を調べる。
互いに独立した Read / Grep / Shell は 1 メッセージにまとめて並列発行する。直列に並べない。
Task(サブエージェント)の起動は、特定シンボル探索や小さい質問には使わない。「複数の場所にまたがる探索」「多数のファイルのサマリ」「別のログ・アーカイブの解析」のときだけ使う。
複数ファイルにまたがる作業を始める前に、このファイルを 1 回読む。読んだ事実はコミット・PR 本文に書き残さなくてよいが、以降のツール呼び出しを本ルールに照らして選ぶ。
ルール文書だけでは守られない
ここまで書いて気付いたのは、ルール文書を書くだけでは守られないという当たり前の事実です。.cursor/rules/ は参照タイミングが曖昧で、セッションをまたぐと忘れられることがあります。実際、今回の解析対象になった 4 セッションのうち 2 つでは、過去に自分で書いた別のルール(pbxproj 編集禁止)を自分で踏み抜いていました。
対策として、強制機構を別レイヤで置くようにし始めた。
- pre-commit hook: ルールで禁止した操作(main 直接コミット、pbxproj への特定変更)は hook で shell 終了コード 1 を返して弾く。文書より強い。
- Cursor Hooks:
.cursor/hooks/shell-risk-review.pyのように、ツール呼び出しの前後で内容を検査するスクリプトを置ける。権限付き実行の前に「この操作は必要か」を確認させる hook を入れた。 - ルール本文での自己チェック指示: 条文自体に「この操作をしようとしたら一度立ち止まって A / B / C を考えよ」というセルフチェックを書き込む。文章のトーンが強いほど守られやすい。
原則: 守らせたいルールは「文書」「hook」「環境」の 3 層で組む。文書だけでは弱い、hook だけでは面倒、環境だけでは汎用性がない。3 つの層で重ねるとエージェントの自由を保ったまま抑えが効く。
数字でどれくらい変わったか
ルール導入前後の比較はまだラフだが、体感として次の変化があった。
- 1 タスクあたりのツール呼び出し数が 30〜40% 減。特に「同じファイルを何度も読む」が劇的に減った。
- サンドボックス失敗からの再実行がほぼゼロに。最初から権限を宣言するようになったため。
- メッセージの冗長さが減り、読みやすくなった。副次的に応答速度も速く感じる。
- 1 日の Cursor 使用量で感じる圧迫感が明らかに減った(プラン枠に対する余裕が戻った)。
厳密な A/B 測定はしていないので「気のせい」の成分は否定できないが、JSONL を読み返すと同じ過ちは確かに起きにくくなっている。
メタな学び:AI 自身に運用コストを語らせる
今回の一番の発見は、ルール 10 条ではなくて「AI に自分のログを読ませる」というプロセスそのものだった。人間が目で追うと眠くなる大量の JSONL を、AI は淡々と構造化して見せてくれる。しかも第三者視点で辛辣に指摘してくれる(自分自身にやらせると甘くなるので、サブエージェント経由がミソ)。
これはコード以外の領域にも応用できそうです。自分の Slack 発言の傾向、過去のメール、エディタ操作ログなど、「自分の行動ログを AI に分析させて改善点を出させる」はまだ始まったばかりの運用パターンに見えます。AI の使い方を AI に相談する、というのはメタすぎるのですが、今の AI は十分それに耐えるだけの構造化能力を持っています。
エージェント系ツールのランニングコストを気にし始めた人には、自分のログを一度 AI に読ませてみることを強くおすすめしたい。「自分の無駄を知ること」自体に、無駄がない。