プログラマーのためのプロンプトエンジニアリング・プレイブック
(addyo.substack.com)- AIコーディング支援ツールは開発者の生産性を高めるが、その成果物の品質は プロンプトエンジニアリング に大きく左右される
- 効果的な結果を得るには、豊富な文脈、具体的な目標、例示、役割付与、反復的な改善 などのルールを守る必要がある
- デバッグ、リファクタリング、新機能実装 など主要な開発作業ごとに、プロンプト設計のパターンと例を提示している
- 良いプロンプト には、目的、言語、環境、エラーメッセージ、入力/出力例などの具体的な情報を含めるべきである
- 新人エンジニアでも実践できるプロンプト設計法 として、実際のAI応答の比較とコメントが含まれている
概要: 成功するプロンプトエンジニアリングの重要性
- 近年、開発者は AIコーディングアシスタント を使って、関数の自動補完、バグ修正、モジュール全体の作成まで、作業フローを加速させている
- しかし、AIの応答品質 はプロンプトの品質に決定的に左右される
- 良いプロンプトは明確で創造的なコードソリューションを引き出す一方、曖昧で不十分なプロンプトは限定的で意味の薄い回答につながる
- 本プレイブックは、日常的な開発作業に適用できる効果的なプロンプト設計法 を実践的に整理している
効果的なコードプロンプトの基本原則
- 豊富な文脈を提供する: AIはプロジェクトや意図を事前には知らないため、使用言語・フレームワーク・ライブラリ・エラーメッセージ・コードの目的など、関連情報をすべて明示する
- 明確な目標や質問を示す: 「なぜコードが動かない?」のような曖昧な問いではなく、望む結果と現在の状況を明確に記述する
- 複雑な作業を分割する: 大規模な機能開発などは一度にすべて依頼せず、小さな段階に分けて段階的に求める
- 入出力例や期待する動作を含める: 実際の入力・出力や動作例を与えると、AIの理解度が大きく高まる(“few-shot prompting”)
- 役割(ペルソナ)を活用する: 「Reactのシニア開発者としてコードレビューする」「パフォーマンスの専門家として最適化を依頼する」など、責任ある役割を与えてAIの応答水準を引き上げる
- 会話的に反復改善する: AIの最初の回答をもとに追加依頼や修正要求を行い、段階的に望む結果へ近づける
- コードの一貫性を保つ: AIはコードスタイル、命名、コメントを参照するため、コードの一貫性と明確さを常に維持する
デバッグのためのプロンプトパターン
体系的なデバッグプロンプト設計法
- 問題と症状を明確に記述する: 言語、機能の目的、期待する動作と実際のエラーメッセージ、コードスニペットなど、豊富な情報を提供する
- 段階別・行単位の分析を依頼する: 論理エラーや微妙なバグは、「1行ずつ変数を追跡する」や部分コードの説明を通じて原因を把握させる
- 最小再現コードを活用する: 複雑で大規模なコードではなく、エラーが発生する最小単位のコードを抽出して、問題を集中的に診断する
- 直接的な質問と後続依頼を行う: 「どこでバグが発生しているか?」「修正したコードを提示してほしい」など、明確で繰り返し使えるフィードバックを求める
例: 悪いプロンプト vs. 改善されたプロンプト
問題コードの例
function mapUsersById(users) {
const userMap = {};
for (let i = 0; i <= users.length; i++) {
const user = users[i];
userMap[user.id] = user;
}
return userMap;
}
const result = mapUsersById([{ id: 1, name: "Alice" }]);
悪いプロンプト:
「なぜ mapUsersById 関数が動かないのだろう?」
- AIの応答: 「配列が空かもしれない」「userにidがない可能性がある」など、曖昧な推測を提示
- 文脈不足 と 不明確さ により、一般的な助言しか得られない
改善されたプロンプト:
「mapUsersById 関数はユーザー配列を id ごとにマッピングするはずだが、[ {id: 1, name: "Alice"} ] を入力すると TypeError: Cannot read property 'id' of undefined エラーが発生する。コードは次のとおり: [コード含む] 期待結果は { "1": ... }。この現象の原因と解決策は?」
- AIの応答: ループ条件
(i <= users.length)が範囲を超えており、最後の反復でundefinedが発生することを指摘し、i < users.lengthへの修正を提案 - 具体的な文脈、エラーメッセージ、期待する動作 を与えることで、正確な解決策を導ける
追加のデバッグプロンプト戦略
- バグ原因の候補を列挙するよう依頼する(「TypeErrorの考えられる原因は?」など)
- コードの動作ロジックを自分で説明したうえでレビューを依頼する(「私の説明が正しいか、問題点を見つけてほしい」)
- 想定外ケースのテストケースを依頼する(「この関数が失敗しうる入力を2つだけ提案して」)
- 丁寧なコードレビュアーの役割を与える(「このコードをレビューし、問題点と改善点を説明して」)
リファクタリング/最適化のためのプロンプトパターン
明確な改善目標を示す
- 「リファクタリングして」は曖昧なので、可読性、性能、保守性、重複コードの削減など具体的な目標 を明示する
- コード全体(または必要な文脈)と環境、言語、フレームワークのバージョンを十分に提供する
- 変更点についての 説明 も依頼する(「コードと改善ポイントを一緒に教えて」)
- 「TypeScriptの専門家として最新の慣習に合わせて」など 役割付与 により期待品質を高める
例: リファクタリングプロンプトの比較
元のコード
(重複したfetch、効率の低いデータ構造などの問題を含む)
async function getCombinedData(apiClient) {
// Fetch list of users
const usersResponse = await apiClient.fetch('/users');
if (!usersResponse.ok) {
throw new Error('Failed to fetch users');
}
// ... (以下省略)
}
曖昧なプロンプト
「getCombinedData 関数をリファクタリングせよ」
- AIが任意に並列fetch、エラーメッセージ統合などを変更してしまう(要件がないため挙動が予測しづらい)
具体的な目標を明示したプロンプト
「重複をなくし、性能を改善し、2つのfetchを並列化し、エラーメッセージを分離し、データ結合は効率的な方法に改善せよ。コメントと改善ポイントの説明も付けて」
- AIの応答: 並列fetch、エラーの切り分け、効率的なmapデータ構造の導入など、目標を明確に反映したリファクタリングと詳細な説明を提供
追加のリファクタリングのコツ
- 段階的に依頼する(「可読性改善→アルゴリズム最適化」の順で適用)
- 別アプローチを依頼する(「関数型スタイルでも実装して」など)
- コード+説明形式を依頼して学習やチュートリアル化につなげる
- 生成されたコードに対するテストの追加を依頼する
新機能実装のためのプロンプトパターン
段階的なコード生成を促す
- まず高水準の説明(どんな機能を作りたいか)を示し、その後段階的に細分化する
- 既存の類似コード、プロジェクトのパターン、使用ライブラリなど、作業環境の文脈を伝える
- コメントやTODOをプロンプトとして活用し、IDE上で直接AIのコーディングフローを誘導する
- 入出力例やテストケースを提供し、明確な期待結果を与える
- 最初の結果が不十分なら、すぐに具体的な改善点やコードスタイルを追加で明示して反復依頼する
例: React ProductList コンポーネントの生成
「ProductList というReactの関数コンポーネントを作成せよ。/api/products から商品配列を取得してリスト表示し、入力欄に商品名を入れると大文字小文字を区別せずにフィルタリングする。取得中のローディングとエラー処理も必要。」
- AIの応答:
useState、useEffectによるデータfetch、入力処理、フィルタリング、エラー・ローディングUI実装などを含む - もしプロジェクトでカスタムフックを使っているなら、「
useProducts()フックを使うようにリファクタリングせよ」といった追加指示を繰り返すこともできる
実務的なプロンプト高度化の例
- 「ソート機能を追加せよ: A-Z、Z-A のドロップダウンが必要」など、段階的な機能拡張を依頼できる
- 実装コードの流れを段階ごとに分け、各段階で異なるプロンプトを使ってコード品質と一貫性を維持する
結論
- AIコーディングアシスタントの潜在力を最大限に活かすには、プロンプト設計が中核的なスキル である
- 成功するプロンプトを書くには、常に 具体的な文脈、目的、例示、反復的なフィードバック、役割付与 を意識することで、効果的な結果を導きやすくなる
- AIをプロジェクト内の ジュニア開発者 あるいは コードレビュアー と捉え、望む方向へ詳細に案内しながら段階的に品質を高めていくことが成功の秘訣である
1件のコメント
Hacker Newsの意見
私の経験では、本当のプロンプトエンジニアリング手法は3つしかないと思う
In Context Learning(文脈内で例を与えること。つまり one-shot や few-shot の方式で、zero-shot と対比される)
Chain of Thought(段階的に考えるよう指示する)
Structured output(たとえば JSON のように出力形式を明確に指定する)
ここに、この記事で言及されている Role Prompting も加えられるかもしれない
RAG はモデルが与えられた文脈を要約する方式なので別分類
結局、残りは望むものを明確で平易な言葉で依頼する方法の要約にすぎない
プロンプトでは文脈が最も重要な要素
たとえば TypeScript から始めてデータサイエンスの質問をすると、うまく答えられない現象を確認した
Python で同じ質問をすると、はるかに良い答えが出る
LLM はまだドメイン間の知識移転が苦手なので、目的に合った文脈設定が必須
Role prompting も個人的には意味のない方法だと思う
GPT-3 ではそうだったかもしれないが、ほとんどの LLM はすでに「専門家」の役割を理解している
「プロンプトエンジニアリング」に過剰にのめり込むのは、自分をだましている行為だと思う
要件を明確に伝え、必要なら例を追加し、成果物や reasoning trace を確認し、望む結果が出なければ調整して再試行する、という形
何度試しても答えが出なければ、AI ではなく自分の頭で reasoning してみるという選択になる
多くの人は「一度にすべてを1つのプロンプトに入れようとする」ことが問題だという意見
むしろ巨大な要求を一度に入れず、小さなコンテキストに分けた複数のプロンプトに分割し、それぞれの明確で構造化された出力をつなぐ方法を提案
各プロンプトごとに目的と例に集中し、コンテキスト過多を避ける
そうすれば上で挙げた3つの中核手法が自然に適用される
3つ目の方法(Structured output)に関連して、私と同僚たちは科学分野での適用事例を研究した
論文リンク
ちなみに私たちのチームは prompt engineering よりも fine tuning により多く依存している
few-shot prompt の方式は私たちのケースでは効果がなかった
私はプロンプトが長すぎたり複雑になりすぎたりすると、かえってモデルの認知性能が落ちると感じることが多い
複雑なプロンプトはコントロールしている感覚を与えるかもしれないが、実際には必ずしも利点ではないかもしれない
そのため、使い方はごく単純でミニマルなプロンプトで大まかに合わせ、何度か反復して修正する方向へ自然に収束している
私もまったく同じ方法で取り組むようになった経験がある
このやり方はコスト効率の面でも良い
agent を使って 30 ドルずつ燃やし、コードベースがこんがらがったり、元のコードに戻ったりする経験があまりに多かった
また、AI に自分のプロジェクトへ大量のコードを書かせると、後でそのコードが自分の頭に残りにくく、保守もしづらくなる点を警告したい
専門家の用語を使ってプロンプトを入力すると性能が上がるという根拠もある
一般に人々が日常言語で話す環境では精度が落ちるが、特定の専門分野の語彙はより信頼性の高い答えにつながる
トレーニングデータもこうした分布を反映している
私も似た経験がある
ただ、agent のシステムプロンプトを見ると非常に長く複雑な場合が多く、疑問が湧く
実際にそうしたプロンプトがどう動いているのか気になる
システムプロンプトの例へのリンク
ある作業で、私の同僚は非常に冗長なプロンプトを書いていた
統合作業で CRUD operation を追加し、試しに「これを <職種> の立場から分析」といった本当に短い形に変えてみた
結果として両者の出力はほぼ同じで、むしろ長いプロンプトは一部の文をそのまま出力に書き戻す現象があった
結果自体は悪くなかったが、結局モデル(gemini 2.5)は重要な情報だけを抜き出して見ており、不要な部分まで結果に溶け込ませてしまった
つまり、少なくともこの課題では冗長さがモデルの「思考方式」に興味深い影響を与えているようには感じられなかった
私も同じ結論に達したが、AI 研究所が提供する長いプロンプト利用例をどう解釈すべきか気になる
Anthropic のシステムプロンプト例
「プロンプトエンジニアリング」というものは、独立したものとしては存在しないと思う
いつから意味のある文章をきちんと書くことがエンジニアリングになったのか疑問
「ソフトウェアエンジニアリング」以上だと思う
ただ、今後こういうものも職業(プロンプトエンジニア)として注目され、文章を書く特別な能力として位置づけられる可能性があるのは残念
実際には「きちんと意味のある文章」は無数の変数によって変わる問題
実務ではテスト、管理、ロギング、バージョン管理まで含めれば、単なる感覚ではなくエンジニアリングになる
特定の順序やスタイル、問題の言い換えなどの構造化は非常に重要
パラメータ数の多いファミリーモデルを扱う場合、API ベースのモデルではバージョンアップのたびに既存プロンプトとの互換性確認が必要
こうした確認とテストもプロンプトエンジニアリングの過程
流行や hype への反感に偏りすぎて本質を見落とすことが多い、という意見
うちの近所のバリスタが自分の肩書きにコーヒーエンジニアと付けたほうが、むしろ信頼できそう
アルゴリズム中毒のせいで、最近の消費者は文章を最後まで読む能力すら衰えている影響
「プロンプトエンジニア」の求人を心配する必要まではないと思う
AI sloperators は自分の仕事を立派に見せようと必死
私の経験では、LLM が解けない問題は、どれだけプロンプトを「エンジニアリング」しても無駄な場合が多い
むしろ部分問題に分解して少しずつ進めさせる方法しかない
逆の経験がある人がいれば事例を聞きたい
LLM 利用の重要な部分は、問題を適切にどう分割するかの感覚をつかむこと
いつ、どう分割するか、いつそのまま任せるかを見極める力が必要
記事でも言及されていたように、こうしたノウハウは重要
今後はコードをよりうまく整理し、コメント化して LLM との相互作用を改善する方法も増えるだろう
LLM 自体もこうした方向に進化し、問題の分割方法まで提案できるようになると期待している
プロンプトエンジニアリングの目的は、望む形式で、より速く良い解答を得ること
究極的にはモデルが自動で答えてくれることを望むが、現実的には質問自体の最適化も必要
プロンプトを書く際、普段の習慣のせいで自然言語で指示するのがいまだにぎこちなく感じる
何か正確な引数や SQL クエリのように書くべきな気がする
チャットするように、ツールに話しかけるように指示するのも不思議だ
それでも、自然言語の指示を理解するツールになったことでアクセシビリティは劇的に高まったと思う
それなのに、いまだに人に話すようにプロンプトを書いている自分の姿が少し滑稽にも感じられる
最近はプロンプトガイドのようなものが非常に多い
でも実際にはあまり必要ないと思う
直接ツールを使って慣れ、使い方を身につければ、どんなプロンプトが良いかは自然に分かるようになる
昔 Google が流行し、FOMO の熱狂があった頃と似ている
関連書籍を買わなければ原始人のように取り残されると言われたが、実際には1日で身につけられる程度の単純な分野なので、複雑に考える必要はない
ガイドや tips 動画が本当に役立つ人も確かにいる
多くの人は自分で改善しようとしないが、一度くらいガイドや達人の動画を見るだけで実力が上がる
私自身も他人の使い方やコミュニティの経験から毎回 tips を学ぶほうだ
ただ、一人で練習するだけではこうした tips を得るのには限界がある
昔「ユーザーストーリー作成ガイド」のように、「As a [role], I want to [task] so I can [objective]」という定型があった
上級者でも初心者でも、大半の人は明確な要件伝達への支援が必要
どれほど優れた開発者でも、非構造的な要件にはミスや誤解があり得る
他の人がこのツールでどう生産性を出しているかを見るのもかなり参考になる
自分が見落としていたアイデアも見つかる
trial and error で全部自分で試す前に、すでに誰かがやってくれた経験を少しでも学ぶほうが効率的
個人的に、何もかも自分で試す時間がない立場としては、こうした経験共有は本当にありがたい情報
目立たないトリックも確かにある
たとえば、プロンプトで
pleaseのような丁寧表現はすべて省いてよい、という経験かなり前にコンピュータサイエンス大学院で Programming Science(Science of programming)の授業を受けたときに学んだ検証プロセスを、データエンジニアリングのプロンプト作成にうまく応用している
たとえば「input(...) と前提 (...) を与え、post-condition (...) を満たす spark コードを書かせる」といった依頼
入力、前提、結果条件を明確に示せば良いコードを出力させられる
参考教材
プロンプトエンジニアリングにあまり熱を上げるのはやりすぎに感じる
ただコードやエラーをコピペして plain question を投げれば、最近のモデルは大半が勝手にうまく処理する
過度にひねって書く必要は感じない
数日前、Sergey Brin が AI コミュニティであまり言及されない事実として、「物理的な脅しをするとモデル性能が上がる」と語った
関連記事
YouTube の「Programmers are also human」で、プロ vibe coder が LLM への命令の最後にいつも「..さもないと刑務所行きだ」と付ける冗談を思い出した
だから Google は "Don't Be Evil" をこっそり捨てたのかと思ってしまう
プロンプト作成を「エンジニアリング」と呼ぶのは、あまりにも真面目さに欠ける感じがする
昔プロンプト「エンジニアリング」が流行ったときに聞いた面白い比喩がある
結局この論争は、ソフトウェアエンジニアリングの話が出るたびに繰り返される
想像力が単にチャットインターフェースで猫の写真を頼むレベルにとどまっているからかもしれない
実際には API や自動化ワークフローで使われるプロンプトもあり、それ以上のものだ
アメリカには「sales engineer」という肩書きもあるが、私の経験ではこの人たちは自分が売っている製品がどう動くのかまったく分かっていない場合が多い
IT は単語とその意味が消えていく場所
単語が本来の意味を持つ必要などあるのかと思うほど