Let's プロンプトダイエット! ── システムプロンプト減量ガイド

記事タイトルとURLをコピーする

この記事で分かること

  • システムプロンプトが肥大化するメカニズム
  • 肥大化がAIの出力品質に与える具体的な悪影響
  • 自分のプロンプトが「太りすぎ」かどうかの診断チェックリスト
  • すぐ実践できる減量メニューから、本格的なアプローチまで

はじめに

AIエージェントの出力、最近なんか微妙になってきた気がしませんか?

Claude Code、Kiro など、AIエージェントを日常的に使っていると、カスタムインストラクションやシステムプロンプトを育てていくのが楽しいですよね。「このケースうまくいかないな」→「ルール追加しよう」を繰り返して、気づけばプロンプトが巨大な設定ファイルに……。

実はこの 「ルールを足し続ける」行為そのものが、AIの出力品質を下げている 可能性があります。

プロンプトにも定期的なダイエットが必要です。この記事では、システムプロンプトの肥大化がなぜ起きるのか、何が問題なのか、そして減量の進め方までを整理します。

プロンプトはなぜ太るのか

エッジケース追記ループ

太るメカニズムは人間と似ています。「ちょっとだけ…」の積み重ねです。

  1. AIが期待通りに動かないケースが見つかる
  2. 「〜の場合は〜すること」というルールを追加する
  3. 別のケースが見つかる → またルール追加
  4. 以下繰り返し……

雪だるま式にルールが膨らんでいくわけですね。しかも、過去に追加したルールが今も必要かどうかは誰も検証しない。こうして 「誰も全体像を把握できない巨大プロンプト」 が出来上がります。

「AIにプロンプトを改善させる」ループの罠

もう一つ厄介なのが、AIにプロンプト自体を改善させるパターンです。

「このプロンプトを改善して」とLLMに頼むと、LLMは既存の指示を削除することを避ける傾向があります。追記・補足を繰り返すことで、元の意図がどんどん薄まっていく。矛盾する指示が共存したまま膨張していくってことですね。

コード生成の研究でも、反復的にLLMに改善させると5回の反復後に重大な脆弱性が37.6%増加したという報告があります。「AIに任せれば良くなる」とは限らないわけです。

そもそもプロンプトは「命令に従わせるもの」ではなく、行動の確率分布をずらすもの です。「完璧なプロンプトを書けばAIは完璧に動く」というのは誤解で、ハルシネーションの排除や論理的推論の保証はプロンプトだけでは制御できません。この前提を忘れてルールを積み上げ続けると、肥大化の沼にハマりやすくなります。

太ると何が起きるか

矛盾する指示の衝突

プロンプトが大きくなると、異なるタイミングで追加された指示同士が矛盾しやすくなります。

矛盾する指示がある場合、モデルはそれらを「平均化」するか「ランダムに選択」します。どちらにしても意図した動作にはなりません。「なんか出力がブレるな」と感じたら、プロンプト内の矛盾を疑ってみるといいかもしれません。

認知負荷の増大

ルールが多いほどモデルの「認知負荷」が増し、応答が遅くなり、エラーも増えます。人間でも「あれもこれも守って」と言われたら動けなくなりますよね。LLMも同じです。

コンテキストロット(Context Rot)

コンテキストウィンドウが埋まるほど、モデルのパフォーマンスが低下する現象を コンテキストロット と呼びます。

具体的には:

  • コンテキストの 中間部分 に置かれた情報が無視されやすくなる("Lost in the Middle" と呼ばれる現象)
  • コンテキストが長くなるほど、初期の指示(=システムプロンプト)が無視されやすくなる

システムプロンプトが巨大だと、それだけでコンテキストウィンドウのかなりの部分を消費します。会話が進むにつれて、肝心のシステムプロンプトの指示が無視される……本末転倒ですよね。

メタボ診断チェックリスト

以下に当てはまるものが多いほど、プロンプトの肥大化が進んでいる可能性があります。

  1. プロンプトが500語を超えている
  2. 箇条書きが10項目を超えている
  3. 「never」「always」を2回以上使っている
  4. 自然言語でIF/THENロジックを書いている
  5. エージェントの応答が遅くなっている
  6. エッジケースを修正するためにルールを追加し続けている
  7. エージェントが一部の指示を無視している

特に7番目、「指示を無視する」は認知過負荷の典型的なサインです。ここでさらにルールを足して解決しようとすると、さらに悪化するという悪循環に陥ります。

減量メニュー

すぐできること

1. 削減リファクタリング

以下の4ステップで、プロンプトをスリムにできます。

Step 1: データを外部に出す

価格、スケジュール、ポリシーなどの「データ」はプロンプトに書かず、APIルックアップや関数に移します。プロンプトには「振る舞い」だけを書くのが理想です。

Step 2: 冗長な指示を削除する

LLMがデフォルトでできることを、わざわざ指示していませんか?

  • 「礼儀正しく応答すること」→ LLMはデフォルトで礼儀正しい
  • 「フィラー(えー、あー)を処理すること」→ LLMは自然に処理する
  • 「不明点は確認質問すること」→ LLMはデフォルトでやる

こういった指示はノイズになるだけなので、削除してOKです。

Step 3: 本当にユニークな要件だけに絞る

残すべきは以下の3つだけです。

  • 自分のワークフロー固有の指示
  • ブランドボイス(口調・文体)
  • 本当に重要なエッジケースのみ

Step 4: テストしながら削除する

1つずつルールを削除して、動作が変わるかテストします。変わらなければそのまま削除。意外と多くのルールが「なくても同じ」だったりします。

2. エージェントの分割

1つのスーパーエージェントに全部詰め込むのではなく、役割ごとに分割するアプローチです。

  • 受付エージェント(ルーティング専門)
  • サポートエージェント(技術的問題専門)
  • ドキュメント生成エージェント(文書作成専門)

各エージェントがシンプルで集中した指示を持つので、1体あたりのプロンプトが小さくなります。体重を落とすのではなく、そもそも1人に背負わせない発想ですね。

もう一歩踏み込む

モジュール化 + 動的ロード(必要なときだけ注入する)

ここまでの「削減」や「分割」は、プロンプトの総量を減らすアプローチでした。もう一歩踏み込むと、プロンプトを分割した上で、必要なものだけコンテキストに注入する という考え方があります。

ポイントは「分割」だけでは不十分ということです。分割しても全部読み込んだら総量は変わりません。分割 + 必要なときだけロードがセットで初めてダイエットになります。Anthropic はこのパターンを Progressive Disclosure(段階的開示) と呼んでおり、Skills のベストプラクティスとして公式に推奨しています。

具体的にどういう仕組みか、普段使っているツールで見てみます。

  • Claude Code の Skills: ~/.claude/skills/.claude/skills/ に配置したスキルは、説明文(description)だけが常にコンテキストに載る。スキルの全内容が展開されるのは、実際に呼び出されたときだけ。CLAUDE.md もグローバル / プロジェクト単位の階層構造になっていて、プロジェクトに応じた指示だけが読み込まれる
  • Kiro の Steering: .kiro/steering/*.md で指示ファイルを分割管理し、inclusion モード(always / fileMatch / auto / manual)でファイルごとにロード条件を制御できる。たとえば fileMatch なら、特定のファイルを触ったときだけ該当の指示が読み込まれる
  • Claude Code の Tool Search: MCPツールに defer_loading: true を設定すると、ツールの定義をコンテキストに入れず、必要なツールだけを動的に検索・ロードできる。Anthropicのブログによると、5つのMCPサーバー(GitHub, Slack, Sentry, Grafana, Splunk)で約77,000トークン消費していた問題を85%以上削減した実績がある

どれも「全部コンテキストに載せる」から「必要なものだけコンテキストに載せる」への切り替えですね。RAG(Retrieval-Augmented Generation)と本質的に同じ考え方で、研究でもツール選択にRAGを適用するフレームワークが提案されています。

参考:

コンテキスト圧縮・要約

長い会話履歴を定期的に要約してコンパクトにする手法です。Claude Code の /compact コマンドがまさにこの考え方の実装例ですね。

研究レベルでは、エージェント自身が自律的にコンテキストを圧縮するアーキテクチャも提案されています。Focus Agent という手法では、精度を維持しながら平均22.7%のトークン削減を達成したとのこと(ただし査読前のプレプリントなので、数値は参考程度に)。

ファインチューニング

口調・スタイル・ドメイン固有の応答パターンなど、変わらない振る舞いはプロンプトで毎回指示するより、モデルに学習させるほうが安定します。

研究では、シミュレーションデータでファインチューニングしたモデルのほうが、プロンプトで口調を指定するよりも一貫性が高かったという報告があります。

ただし、コスト・時間がかかるので「プロンプトでは本当に解決できない」と判断してから検討するのが現実的ですかね。

打ち手の全体マップ

打ち手 難易度 概要
プロンプトの削減・整理 定期的に見直し、冗長・矛盾を除去
エージェント分割 役割ごとに分割し、各プロンプトを小さく保つ
モジュール化 + 動的ロード 分割して必要なときだけ注入(Skills, RAG等)
コンテキスト圧縮・要約 会話履歴を定期的に要約してウィンドウを節約
ファインチューニング 変わらない振る舞いをモデルに焼き込む

まとめ

  • システムプロンプトは、エッジケース追記や「AIによる改善」ループで肥大化しやすい
  • 肥大化すると、矛盾する指示・認知負荷の増大・コンテキストロットにより出力品質が低下する
  • プロンプトは「命令に従わせるもの」ではなく「行動の確率分布をずらすもの」。完璧なプロンプトを書けば完璧に動くわけではない
  • まずは削減リファクタリングから。テストしながら1つずつルールを削除してみる
  • 「分割」だけではダイエットにならない。分割 + 必要なときだけロードがセット
  • システムプロンプトには 定期的なダイエット が必要

以上です、Let's プロンプトダイエット!

参考

手嶋 凌一朗 (記事一覧)

エンタープライズクラウド部・クラウドリライアビリティ課

書きたい心はあるんです。

趣味はテニスと釣り