プロンプトから「不要な一文」を削除したら、3日後に出力が悪化していた件:プロンプト版管理ガイドが重要な理由

プロンプトの劣化はエラーもアラートも出さず、モニタリングは正常なまま。ただ静かに悪くなります。その対処法は、git とスクリプトひとつで実践できる4つの関門です
著者:Cyber Corsairs / r/PromptEngineering08-11 · 8 分で読了⚑ チュートリアル
🎧 ポッドキャスト版0:00 / --:--
0:00 / --:--
ツール解説 · 小互(シャオフー)による読み解き
1分でわかる要点
  • 稼働中のプロンプトから「不要な一文」を削除。デプロイ後も何もアラートは出ず、3日後にカスタマーサポートのチケットでようやく発覚しました。
  • 採点済みの1018件のプロンプトで最も点数が低かったのは「入力が想定外だった場合の対処が書かれているか」で、平均はわずか31.5点。そして、この項目こそ、削除時に最初に「無駄な文言」として消されやすい部分です。
  • 対策は4つの関門。そのうちのひとつが、デプロイ前にこうした変更を直接差し止めます。ツールを買わなくても、git と採点スクリプトで十分です。
⚑ この記事の主軸は Reddit の r/PromptEngineering 版に投稿された方法論の解説です。投稿者は採点ツール PromptEval の開発者でもあり、この利益相反は本人が投稿内で明言しています。文中の1018件のプロンプトの採点データは投稿者自身のプラットフォームによるもので、第三者による検証は行われていません。4つのステップからなるワークフロー自体は、特定の製品に依存しません。
問題 · 事例

「無駄に見える数行」を削除 → デプロイ後、アラートはゼロ

ある開発者が、稼働中のプロンプトを修正していました。数行に「あまり意味がない」ように見えたので削除し、ついでにトークンもいくつか節約。デプロイ前の軽い気持ちでの整理は、誰でも一度はやったことがあり、深く考えもしないものです。デプロイ後、エラーなし、アラートなし、モニタリングもすべて正常。3日後、カスタマーサポートのチケットが来ました。ユーザーが受け取った応答は曖昧で的外れ、時には自信満々に間違っていました。

これは Reddit の r/PromptEngineering 版に投稿された、開発者による振り返り記事です。この出来事をきっかけに彼が構築した、プロンプトのバージョン管理フローについて書かれています。もしユーザー向けにプロンプトを運用しているなら(API を使ったアプリでも、毎日自動実行しているパイプラインでも)、これは遅かれ早かれ踏むであろう落とし穴です。しかも、踏んだと気づかないタイプの穴です。

原因
プロンプト内の数行が「無意味」に見えたため削除(ついでにトークン節約)
症状
エラーなし、アラートなし、テストもパス。プロセス側は成功を受け取り、ログも一見正常
結果
3日後、カスタマーサポートのチケットが発生。応答は曖昧で的外れ、時々自信満々に間違える
問題の本質
そのプロンプトは技術的には「まだ正常に動作」していました。ただ、以前より悪くなっただけです。パイプラインのどこにも異常を知らせる仕組みはなく、実際のユーザーが不満を抱えて文句を言うまで気づきませんでした

3日間、悪化したプロンプトが本番トラフィックを処理し、ひっそりと質の低い回答を配信し続けていました。その間のシグナルはゼロです。

問題 · 誰も気づかない理由

プロンプトの劣化はアラートも出さないし、目視でも見抜けない

同じ「壊し方」をしても、コードとプロンプトでは大きく違います。それは、壊れた後に誰かが教えてくれるかどうかです。

コードを壊した場合プロンプトを壊した場合
その場で何が起きるか例外が発生、コンパイルエラー、実行すると即クラッシュそれらしいテキストを普通に返す
プログラムが受け取るもの失敗正常な結果
誰が教えてくれるかテスト、コンパイラ、監視アラート誰もいない
いつ気づくかその場で3日後、ユーザーの苦情で

根本的な違いはこれです。プロンプトは自然言語なので、どれだけ不完全に書き換えても、モデルはそれなりにテキストを返してきます。エラーも失敗のシグナルも出しません。だから突然壊れるわけではなく、「ほんの少しずつ」悪くなっていき、その蓄積が「ユーザーが気づくレベル」に達した時、初めて顕在化します。

コードを壊す == 即エラー 例外発生 コンパイル不可・即クラッシュ そこで停止 プロンプトを壊す == 全緑 普通に応答・ログも正常 すべて通過 デプロイ ログ正常 テスト通過 3日後・サポートチケット発生
同じ「壊し方」でも、コードの場合はその場で停止。プロンプトの場合は最後まで全緑。線の色は密かに薄くなっていますが、途中のチェックポイントはすべて正常を示します。(当サイトによる図)

では、デプロイ前に出力をいくつか目視確認すればいいのでは? 肉眼で捉えられるのは、明白なエラーだけです。エラーメッセージが返る、フォーマットが完全に崩れる、的外れな答えが一目瞭然、といった類い。品質の劣化は捉えられません。理由は2つ。出力は依然として「もっともらしい回答」であり、ただ悪くなっているだけだからです。そして、あなた自身が期待を持って見ているので、「このプロンプトは何を言うべきか」を知っていて、読んだ内容をすべてその方向に当てはめてしまうからです。本当の劣化は、多数の実ユーザーが多様な質問をして初めて表面化します。そして、その時の形こそがサポートチケットなのです。

原因 · データ

1018件のプロンプト採点 → 最も低いのは「想定外の入力への対応」

これは一人のミスではありません。1018件のプロンプトを採点したところ、同じ問題がそこら中に見つかりました。満点は100点で、4つの項目に分かれています。この4項目自体が、「プロンプトがどこで劣化しうるか」のチェックリストです。

項目求められること典型的な失敗例
明確性
Clarity
このタスクの解釈が一意に決まり、モデルが推測する必要がない動詞が曖昧:「処理しておいて」「これを改善して」
具体性
Specificity
出力への要求が測定可能であること。形容詞だけにせず、モデルに「何が完了か」を推測させない「簡潔な要約を書いて」ではなく、「平易な言葉で3文の要約を書いて」
構造
Structure
指示が論理的な順序で並んでいる:役割が先、背景が二番目、タスクが三番目、形式が最後形式の指示がタスクの後ろに埋もれている、役割が書かれていない、制約が散在している
ロバスト性
Robustness
起こりうる問題のある状況それぞれに、どう対処するかが明確に書かれているプロンプトはユーザーがきれいな入力をしてくれる前提。実際のユーザーは何でも入力する

4項目で最下位なのは最後の項目、ロバスト性英語では Robustness。この項目が問うのは、「プロンプトが『想定外の入力にどう対処すべきか』を指示しているかどうか」です。ユーザーが要件を明確にしない場合に何を返すか、入力が空の場合、フォーマットが完全に間違っている場合。これらのケースを一つ一つ指定して対応を明記する必要があり、「適切に対処してください」のような曖昧な一文はカウントされません。、つまりそのプロンプトが「想定外の入力にどう対処するか」を指示しているかどうかです。1018件の平均点はわずか31.5点でした。

ロバスト性の平均点・1018件のプロンプト31.5 / 100
原文では「weakest by far(ダントツで最弱)」と表現されています。他の3項目の平均点は公開されていないため、ここにあるのはこの数字だけです。他の3項目は定義のみ示されています。
原因 · 根底にある問題

想定外への対応指示は、普段は発動せず、テストもできない

なぜこの項目が一番悪いのでしょうか? それは、この項目に書かれている指示が、通常の運用では一度も出番がないからです。

この項目が扱うのは、それぞれの異常系で何を返すか、です。公開されている例では「ユーザーが何をしたいか明確でない場合」が明記されていますが、他にも入力が空、フォーマットが完全に崩れている、などがあります。しかし、自分で試す時に入力するのは、きちんとした内容ばかり。この3つのケースには一度も遭遇しません。

だからこそ、プロンプトを「ダイエット」する時、最初に狙われるのがこの部分です。トークンを消費するのに、効果を発揮しているのを見たことがない。削除すれば、プロンプトはすぐに短くなり、テストも一発で通ります。この2つは同じ根を持っています。最も弱く、最も削除されやすい。その理由は同じです。

例え話

車のシートベルトとエアバッグのようなものです。普段運転している時は使うことがなく、ある種の「無駄な重さとコスト」に見えます。しかし、事故の瞬間はこれに全てを依存します。省いた当日は何も感じません。代償が請求されるのは、事故が起きた日なのです。

削除前 その2行を削除した後 灰色の2行 = 想定外の対応 正常な入力 デタラメな入力 受け止められる この2行が消えた サポートチケット化 正常な入力は素通りするので、テストでは検出できない
この2行を削除すると、正常な入力は以前と同じ経路を通るため、すべて正常。デタラメな入力だけが外にこぼれ落ちていきます。普段テストしているのは、影響を受けない部分なのです。(当サイトによる図)
原因 · 実証

削除した1文の指示で、スコアが14点下落

このワークフローを導入後、ある「整理」タイプの編集をその場で阻止しました。変更は無害に見えたのに、スコアは14点下落しました。下落の原因は、ある保険的な指示を削除したことでした。

−14 点
「問題なさそうに見える」整理によるスコア下落
1 文
削除された内容:想定外の入力に対処するための保険的な指示
10 秒
提出からこのスコア下落を確認するまでの時間

原文では、その指示を load-bearing(直訳:耐荷重の)と表現しています。このプロンプトにおいては、次の意味です。それは単なる「余分な補足説明」に見えて、実は構造を支える重要な一文でした。「ユーザーが不完全な入力をした場合、何を返すか」を定義していたのです。それを取り除くと、代わりに機能するものが何もありません。

削除後、正常な入力は依然として完璧に動作しました。テストは全てパス、ログもクリーン。ただ、不完全な入力だけが曖昧な回答を受け取るようになり、それが後にサポートチケットとなったユーザーたちです。

10秒で見つけられるのに、サポートチケットをもう1件食べるよりはましだ。

Ten seconds to see it, instead of another support ticket.

明確にしておきますが、プロンプトを削ること自体は悪いことではありません。当サイトで解説した Anthropic 公式のプロンプトガイドも、削り方を教えています。問題は、削る前に「何かがあなたを受け止めてくれる仕組み」があるかどうかです。

当サイトで解説した関連記事
Anthropic 公式 Opus 5 プロンプトガイド:足し算ではなく引き算を教える
同じく「削る」話ですが、あちらは「何を削るべきか」の判断基準。8つのプロンプトはそのまま流用できます。
原因 · 従来の方法では対応できない

コードの assert は使えない。だから採点に切り替えた

投稿への最初の反応は、次のような疑義でした。

古のソフトウェア工学のプラクティスを再パッケージしただけに聞こえる。何が新しいの?

コードを変えて結果が変わったら、それって回帰テストでしょ? それも古いよね。AI のせいで古いプラクティスを全部捨てたのに、今度は一つずつ再発見してる :D

r/PromptEngineering 読者のコメント

この疑義は半分正しい。バージョン管理は確かに新しいものではありません。プロンプトのために本当に新しく作られたのは、たった一つの層です。

コードのテストでは assert output == expected と書けば、機械が直接「結果がこれと等しいか」を判断できます。このチェックが成立するのは、答えが一意に定まるからです。

モデルが生成するテキストには一意な答えがありません。同じプロンプトでも実行するたびに言い回しが異なります。この assertassert は日本語では「アサーション」、自動テストにおける「結果がこれと等しくなければならない」という検査文のことです。例えるなら、採点のようなものです。選択問題は正解と照合できますが、作文問題はそれができず、採点基準で評価するしかありません。はプロンプトではそのまま機能しません。

そこで、プロンプトに固定の「試験問題セット」を用意します。同じ入力セットを常に与え、実行結果をチェックするのです。ただし、このチェックは採点に置き換えられました。生成された答えを採点基準に当てはめ、0から100のスコアを出します。これを自動実行し、新しいバージョンが本番に置き換わる前に実施します。

コードのテスト:答えが一意 → 等しいか判定 プロンプトのテスト:答えが一意でない → 採点する 出力 == 等価 一致 / 不一致 白か黒か、機械が自動判定 出力 0 100 74 点 合格ライン 75 1点差でブロック どの項目で落ちたかも見える
左はコードテストの判定方法:一致すればOK。右は0〜100の採点と事前に設定した合格ラインに置き換え。下回ったらブロックします。(当サイトによる図)

しかも、スコアは項目ごとに出るので、どの部分が壊れたかを正確に把握できます。「想定外の入力への対応」という項目が61から17に落ちた、と。項目単位で出るので、総合点だけではありません。修正も的確にできます。3行目の指示を直せば、この項目は17から61に戻り、他は触らずに済みます。

一言で言えば、これは答えが一意でないものを対象にした回帰テストです。デプロイ前に旧版と比較し、退行していたらブロックします。

実践方法 · 4ステップ

4ステップのワークフロー:バージョン、diff、採点、エンドポイント

以下の4ステップの骨格は元記事からのものです。各ステップの「実装例」は、当サイトがこの骨格に基づいて整理した具体的な操作イメージであり、元記事の文言そのものではありません。

事故が起きるまで、これらのプロンプトは Google ドキュメントに置かれていました:Version A、Version A-final、Version A-final-2。あのパターン、心当たりがあるでしょう。うまく機能しているうちは問題ない。機能しなくなるまで。根本原因が分かった以上、ワークフロー全体を変える必要があります。この4つのステップはツールに依存しません。まずは特定の製品に依存しない形で説明します。

バージョン管理 v4 / v5 + 真の diff 本番版を指定 他はすべてドラフト 本番前の採点 新旧を比較 スラッグ 再デプロイ不要 合格ライン 合格 → 本番へ 下回る → 赤字で本番不可
3つ目のステップがこのワークフローの要です。新しいバージョンを本番に置き換える前に、必ず旧版と採点を比較します。(当サイトによる図)

1 · すべてのプロンプトにバージョン番号

バージョン番号はv4、v5のようなものです。2つのバージョン間で diff(行ごとの差分、変更行が漏れなく表示される)を取得できます。これは、コードを main ブランチにマージする前に行ごとのレビューと同じです。「final_v2」のような命名ではこの機能は得られません。

実装例
  • 1プロンプト=1ファイル。複数を1つのドキュメントにまとめないこと。まとめると個別比較ができない。
  • ファイルにはプロンプト本文に加えて、バージョン番号、今回の変更点、前回のテスト結果を記録する。
  • 変更は git(または diff が取れる場所)に入れる。唯一の基準は「v5 は v4 と比べて具体的にどの行が変わったのか」に常に答えられること。

2 · 1つのバージョンを本番版としてマーク

「現在本番で動いているのはどのバージョンか」に一意の答えを持たせ、それ以外はすべてドラフトとします。明示的に切り替えない限り本番には反映されません。例外はありません。「明らかに問題ない」小さな変更にも例外はありません。

実装例
  • 「現在の本番版 = v4」と明確に記録する場所を設ける。フィールド1つで十分。記憶やチャット履歴に頼らない。
  • ドラフトは何度でも変更可能。このマークを触らない限り、本番には影響しません。

3 · 本番版を切り替える前に、新旧両方のスコアを比較する

事前に合格ラインを設定し、新版が下回ったら赤字で本番不可にします。このステップが、あの削除事故を防げたはずのステップです。実ユーザーに届く前に。

実装例
  • 試験問題セットを用意する:実際のユーザーが入力した質問を問題にします。その中に、不完全なもの(空、情報不足、形式が崩れている)を数件入れておきます。これは、最も削除されやすい「想定外への対応力」を探るための専用問題です。問題数は元記事では指定されていないので、ご自身のシナリオに合わせて決めてください。
  • 同じ問題セットを、新旧両バージョンで実行し、それぞれスコアを出します。
  • 2つのことを比較する:合計点が設定したラインを下回っていないか。各項目でどれだけ下がったか。合計点は「壊れた」ことしか教えませんが、項目別は「どこが壊れたか」を教えます。
  • 下回ったら停止する。注意喚起して続行、ではありません。このステップで止めなければ、最初の3ステップは無意味です。

4 · 本番版はスラッグエンドポイント経由で提供する

本番で動くバージョンをコードにハードコードしない、ということです。新しいバージョンを本番版としてマークすれば、アプリケーションはそれを自動的に取得します。再デプロイは不要です。戻したい場合は、古いバージョンを再マークするだけ。深夜に git 履歴を探りながらサポートチケットを眺める必要はありません。

実装例
  • コードに残すのは名前(例:support-agent)だけ。プロンプト本文は書きません。
  • アプリはその名前を使って現在の本番版を取得します。バージョンの切り替えは「現在の本番版 = ?」のマークを変更するだけです。
  • このステップで得られるものはロールバック速度です。問題発生時、古いバージョンを再マークすれば即戻せます。アプリの再デプロイは不要です。
1つの変更が着手から本番まで完全に流れる様子(上記4ステップに基づく当サイトの整理によるフロー例)
  1. 現在の本番版 v4 のコピーを作成し、変更を加えて v5 として保存します。
  2. diff を取得し、自分で何行変更したかを確認します。
  3. 同じ問題セットを v4 と v5 に与え、それぞれスコアを出します。
  4. 比較:合計点がラインを下回ったらその場で停止。項目別も確認し、どの項目が下がったかを見ます。あの14点の下落はこのステップで発見されました。10秒です。
  5. 合格したら、「現在の本番版」を v4 から v5 に変更します。
  6. アプリが次回プロンプトを取得する際、自動的に v5 を取得します。再デプロイは不要です。
  7. 万一、本番で問題が発生したら、マークを v4 に戻すだけ。数秒でロールバックできます。
実践方法 · 合格ライン

合格ラインはプロンプトごとに個別設定。共通基準は設けない

では、このラインはどこに引くのでしょうか? 2つを重ねて使います:

ハードル:プロンプトごとに個別設定 75 抽出系 60 生成系 タスクによって自然なベースラインが異なる。単一の数字では測れない さらに:前回版と比べてどれだけ下がったか 前回版 76 今回版 64 12点下落 → 赤字
左が絶対点の合格ライン。プロンプトごとに個別設定します。右が相対的な下落幅のチェックで、合格圏内かどうかではなく、前回版と比べてどれだけ下がったかを見ます。図中の点数は例です。元記事が公開しているのは「14点下落した」という差分のみで、絶対点は公開されていません。(当サイトによる図)

1つのハードル:本番に上げるにはX点以上が必須。このXはプロンプトごとに個別設定され、全体共通の数字ではありません。生成、抽出、分類といったタスクはそもそも基準となるレベルが異なるため、同じ数字で測ると必ず誤差が出ます。

その上に、相対的な下落幅チェックを重ねます。これは「合格圏内だが退行している(リグレッション)」ケースを捉えるためのものです。絶対点が足りているかではなく、前回版と比べてどれだけ下がったかを見ます。前述の14点下落は、このレイヤーで検出されました。

もう1つの心構えとして、赤字表示は「見える化」のためであり、教条ではありません。時には5点下がっても有益な場合があります。新版がよりシンプルで、実行コストが安いなら。合格ラインはガードレールであり、最終判断は人が行います。真の利益はここにあります。何かを本番に上げる前に、自分が何を変えたかを知っていることです。

では、スコアが下がったのに、新版の出力が明らかに良いと感じる場合はどうでしょう? リライト版の診断はこうです:おそらく、あなたの試験問題セットが実際の利用状況を反映していない。実際のユーザーが尋ねる内容が、テスト入力に含まれていないのでしょう。これはリライト側の判断であり、元記事の投稿者はこの問いに直接答えていません。

実践方法 · 自前で構築

ツールを買わない場合:git と採点スクリプト

このワークフローは特定の製品に依存しません。git と採点スクリプト、そして Makefile があれば、大部分をカバーできます。具体的には、各プロンプトをファイルとして git に入れます。ファイルにはバージョン番号と前回のテスト結果も一緒に記録します。小さなスクリプトを書き、同じ入力セットで2つのバージョンを実行し、差分を出力します。実行結果も一緒に保存しておけば、どのバージョンから品質が劣化し始めたのかが分かります。

実行タイミングについて:本番への切り替え前には必ず実行します。有害な変更をブロックするのはこのタイミングです。変更が頻繁な場合は、変更のたびに採点すれば、後戻り作業を省けます。また、本番版自体への定期的なスポットチェックも有効です。劣化は必ずしもあなたの変更とは無関係ではなく、モデルがバージョンアップした、ユーザーの質問内容が変わった、といった場合もあります。

実行頻度はスモークテストレベルで、期末テストのようにまとめてやってはいけません。重要な変更があるたびに実行します。大きなリリース前にまとめて実行するのではなく。これが決めるのは、問題を発見するまでの時間です:数時間か、それとも冒頭のように3日か。

プロンプトはどこで劣化しうるか・4項目のセルフチェック
明確性 Clarity    このタスクの解釈が一意に決まり、モデルが推測する必要がない
                 失敗例:動詞が曖昧、「処理しておいて」「これを改善して」

具体性 Specificity  出力への要求が測定可能であること。形容詞だけにしない
                 失敗例:「簡潔な要約を書いて」ではなく「平易な言葉で3文の要約を書いて」

構造 Structure    役割が先、背景が二番目、タスクが三番目、形式が最後
                 失敗例:形式の指示がタスクの後ろに埋もれる、役割が書かれていない

ロバスト性 Robustness 起こりうる問題状況に対処法が明記されている
                 失敗例:ユーザーがきれいな入力をしてくれる前提
4項目で最も見直すべきは最後の項目。平均点は31.5で、削除時に最初に「無駄」として消されやすいのもこれです。
同じカスタマーサポート用プロンプトのリライト前後・18点 → 79点
Before(18/100)
Help the customer with their issue and be professional.

After(79/100)
You are a support specialist. Read the message and return:
summary (1 sentence), customer_intent (only what's stated),
urgency (urgent / normal / low).
If no clear request: intent = 'unclear', urgency = 'normal'.
リライト後の If no clear request... の部分がロバスト性に該当します。「ユーザーが明確な要求を示さない場合」の戻り値を、モデルの即興に任せるのではなく明記しています。同じモデルで、スコアは18から79へ。
採点ゲートをCIに組み込む・GitHub Action
- uses: FranciscoFerreiraff/prompteval-action@v1
  with:
    api_key: ${{ secrets.PROMPTEVAL_API_KEY }}
    prompt_file: prompts/support-agent.md
    baseline_slug: support-agent
    min_score: 75
    fail_on_conflict: true
これを組み込むと、変更がコミットされるたびに自動的に本番版とスコアを比較し、min_score を下回るとマージをブロックします。最後の行の fail_on_conflict は別の壊れ方、つまり1つのプロンプト内で前後の指示が矛盾するケース(例:「JSONのみ出力せよ」と「まず考え方を説明せよ」)を扱います。モデルはどちらか一方しか聞けず、スコアが下がるとは限りません。この種の矛盾は個別にチェックし、個別にブロックします。自前で構築する場合は、uses の部分をご自身の採点スクリプトに置き換えれば、ロジックは同じです。
✅ プロンプトを本番に上げる前の4つの関門
出典
Prompts rot like code, but most of us have no tests catching it. My prompt-versioning workflow.u/noiteestrelada · r/PromptEngineering·元記事·2026-08-06
当サイトからの注記
4つの採点項目の定義、18点→79点のリライト例、GitHub Action の設定は PromptEval 公式サイトから。1018件のプロンプトの採点統計と、−14点の事故は元記事からのものです。いずれも同プラットフォーム独自のデータで、第三者による検証は行われていません。また、他の3項目の平均点は公開されていません。文中の図はすべて当サイトによるもので、元記事には図はありません。
↑ 本文ここまで
✓ この記事は全文無料です

メンバーは全文 Markdown のコピー・保存に加え、自分の AI に購読・質問させることができます。

原文を読む ↗
📮 新着解説をメールでいち早く

役に立ちましたか?メールを登録すると、新着解説を公開と同時にお届けします。解除はいつでも。