AIコーディングエージェントへの正しいプロンプトの出し方

AIコーディングエージェントへの正しいプロンプトの出し方

AIコーディングエージェントの最も一般的な使われ方はこうです。開発者はチャットウィンドウを開き、「設定ページにダークモードのトグルを追加して」のようなことを入力します。エージェントは何かを生成します。一応機能しますが、荒削りな部分があります。開発者はその後の20分間、修正のためにやり取りを繰り返します。

そして彼らは、モデルの性能がそれほど良くないのだと結論付けます。

モデルに問題はありません。問題はプロンプトにあります。

曖昧なプロンプトの不都合な真実

プロンプトのあらゆる曖昧さは、モデルがあなたなしで下す決定になります。ダークモードの設定はセッションを越えて維持されるべきですか? OSレベルの設定を尊重すべきですか? 設定はどこに保存されますか? localStorageですか、データベースのユーザープロファイルですか、それともCookieですか? どのコンポーネントライブラリが使用されていて、そこでのテーマ機能はどうなっていますか?

あなたはそれを伝えませんでした。だからモデルは推測します。時々は正しく推測しますが、大抵は外れます。その結果、ある環境では機能しても別の環境では壊れるコードや、ユーザーの既存の設定を無視するコンポーネント、あるいは適切なコンテキストに接続されていないため実際には何も切り替えないトグルが出来上がります。

これはモデルの品質の問題ではありません。情報の問題なのです。

テクニック:エージェント自身にプロンプトを作らせる

実際に機能する方法であり、本格的なAI支援開発ワークフローを構築しているチームが気づいたことは次のとおりです。モデルは、タスクをうまくこなすために何が必要かを、ほとんどの開発者がどう指示すべきかを知っている以上に知っています。

モデルは、仕様が明確なエンジニアリングタスクを膨大な量処理してきました。完全な機能要求がどのようなものかを知っています。曖昧なバグレポートに通常欠けている情報も知っています。コツは、エージェントに何かを頼む前に、何が不足しているのかを先に言わせることです。

フローは次のようになります:

  1. 目標をざっくりと説明する — エージェントが問題領域を理解できる程度の情報で十分です。
  2. 適切に行うために何が必要かを尋ねる — 「このタスクをうまく完了させるには、どんな情報が必要ですか? 明確にすべき曖昧な点は何ですか? 私が指定していないことで、指定すべきことは何ですか?」
  3. 隙間を埋める — エージェントの質問に答え、要求されたコンテキストを提供します。
  4. ここでタスクを指示する — プロンプトにエージェントの質問を組み込むか、元の要求を完全な仕様書として書き直すよう依頼し、それを承認して実行させます。

最後のステップは任意ですが、非常に強力です。エージェントにこう頼むことができます。「私の回答に基づいて、元の要求を完全なタスク仕様書として書き直してください」。返ってくるのは、モデル自身がうまく実行するのに十分だと考えるプロンプトです。そして、そのプロンプトを実際のタスクとして送信するのです。

これは一部で「タスク実行のためのリバースプロンプトエンジニアリング」と呼ばれ始めています。完璧なプロンプトをゼロから書くのではなく、完璧なプロンプトに含まれるべきものをモデルを使って表面化させるのです。

例1:機能の構築

設定ページにダークモードのトグルを追加したいとしましょう。2つのアプローチがどうなるか見てみましょう。

素朴なアプローチ:

「設定ページにダークモードのトグルを追加して。」

エージェントは、ハードコードされたトグルを持つコンポーネントを生成します。設定はコンポーネントのステートに保存され(リロードすると消えます)、既存のテーマシステムには接続されず、あなたがすでに使用しているCSS変数やデザイントークンの代わりにインラインスタイルが使用されます。

あなたはその後の1時間を修正に費やすことになります。

リバースプロンプトのアプローチ:

同じ文章から始めて、次のように尋ねます。「始める前に、これを正しく実装するために何を知る必要がありますか? 私が明確にすべきことは何ですか?」

エージェントは次のように返答します:

あなたはこれらの質問に答えます。アプリは next-themes を使用しており、設定は既存の PATCH /users/me エンドポイントを介してユーザープロファイルに保存されること、そして設定ページにはすでに特定のコンポーネントパターンに従った他のトグルがある「外観」セクションがあることを伝えます。

これでエージェントに必要な情報が揃いました。生成される実装は、適切なテーマプロバイダーに接続され、既存のAPIを使用し、現在のUIパターンと一致し、OS設定のフォールバックを処理します。修正する必要は何もありません。

出力品質の違いは歴然としています。

例2:バグの修正

バグレポートにおいて、曖昧なプロンプトが最大の被害をもたらします。十分なコンテキストを持たないモデルは、単に平凡なコードを生成するだけでなく、自信満々に間違ったコードを生成するからです。

誰かがバグを報告したと想像してください:「ログインボタンが時々機能しません。」

素朴なアプローチ: これをエージェントに貼り付けます。エージェントは認証コードをスキャンし、怪しいasync/awaitパターンを見つけ、おそらくこれが原因だと判断し、関数を書き直してPR(プルリクエスト)を作成します。バグはまだ残っています。変更された関数は無関係でした。

リバースプロンプトのアプローチ:

バグレポートをエージェントに渡し、こう尋ねます。「これを効果的に診断するためには、何を知る必要がありますか? コードを触る前に、シニアエンジニアならどんな質問をしますか?」

エージェントは答えます:

あなたはバグを報告した人のところに戻り、答えを得ます。断続的であること、ユーザーが10分以上ページに留まっている時にのみ発生すること、コンソールエラーはないこと、しかしネットワークリクエストが全く発火していないことが分かりました。これで全く別のバグになりました。async/awaitの問題ではなく、トークンの有効期限切れ、またはイベントハンドラ内の古いクロージャ(stale closure)である可能性が高いです。

その情報をエージェントに与えると、今度は正しい場所に辿り着きます。初回レンダリング時の認証トークンをキャプチャしている、古い依存関係を持つ useCallback を見つけます。ターゲットを絞った修正であり、巻き添え被害はありません。

なぜこれが機能するのか

AI支援コーディングの多くが交渉のように感じられる(複数回にわたってやり取りしながら出力を洗練させていく)理由は、最初のプロンプトがモデルに多すぎる決定を委ねているからです。各修正ラウンドは、あなたが指定しなかったためにモデルが行った推測を、あなたが訂正する作業に他なりません。

リバースプロンプトは、これらのラウンドのほとんどを最初の会話に集約します。モデルの質問は、モデルが独自に下していたであろう決定を正確に教えてくれます。代わりにあなたがその決定を下すのです。完全な情報を持っていたため、出力は最初から正しいものになります。

二次的なメリットもあります。モデルが発する質問はチェックリストになります。新しい設定の追加、認証バグの修正、新しいAPIの統合など、似たようなタスクに継続的に同じテクニックを使用していると、質問の内容が見慣れたものになってきます。時間が経つにつれて、尋ねられる前にそれらの詳細をプロンプトに含めることを学び、基準となるプロンプトの品質が向上します。

実践的な注意点

このテクニックは、ツールの使用やファイルへのアクセスが可能なエージェント(Cursor、エージェントモードのGitHub Copilot、Claudeなど)で最もよく機能します。コードベースを読めるエージェントは、盲目で作業しているエージェントよりもはるかに具体的な質問をします。

2ターンのフロー(何が必要ですか → これです → ではタスクを実行してください)は、ステップを1つ追加します。明確に定義された小さなタスクにはやりすぎです。しかし、複数のファイルに触れるもの、既存のシステムと統合するもの、あるいは自明ではない設計上の決定を伴うものについては、最初から実装に進むよりも継続的に良い結果をもたらします。

そして、ステップ3で生成された仕様書は保存しておく価値があります。再利用可能なテンプレートになります。次回誰かがユーザープロファイルに保存される設定を追加する必要があるときには、そのために適切に仕様化されたプロンプトがすでに手元にあることになります。

重要なポイント

多くの開発者のコーディングエージェントへのプロンプト方法は、品質を犠牲にしてスピードを重視するように最適化されています。短い文章を入力し、平凡な出力に対して10分間のクリーンアップを行う。これを1日に何十回も繰り返しています。

リバースプロンプトのアプローチは、そのトレードオフを覆します。モデルが必要とするものを確実に提供するために、最初に少しだけ多くの時間を費やします。その見返りとして、出力はあなたが本当に望んでいたものに近づき、修正に費やす時間は短くなります。

タスクにとって最適なプロンプトは、あなたが30秒間で作るものではありません。モデルが「これが必要だ」と教えてくれるものなのです。

© Melvin Laplanche - All rights reserved.