この記事では、プロンプトエンジニアリングに関するいくつかの重要なポイント、そしてそれらを知っていることで、日々の中でAIを扱うとき、勉強、研究、仕事、vibeコーディング、なんでも(whatever)にどう役立つのかを説明します。
- 序文
- まず最初に思い出しておきましょう。そもそもLLMとは何でしょう?
-
質問する(問いを作る)
- 1 - 曖昧さを避ける
- 2 - スコープ(範囲)を定める
- 3 - 関連する文脈を提供する
- 最終的な考察
序文
知識の基礎は、何かを学びたいならすべてに必要です。LLMについても同じです。パターンを分析し、友人たちと話してみたところ、日常の仕事や勉強でLLMを使っている人たちの多く(テクノロジーに携わる人、そして特にテック分野を始めたばかりの人)は、LLMがどのように動くのか、そしてChatGPTのような存在に対して正しい質問をし、正しい形で疑問を解消するにはどうすればよいのか、よく分かっていないことが分かりました。
それを踏まえて、そして私自身がこのテーマについてかなり勉強しているので、知識を共有するための形として、ブラジルの詩人コーラ・コラリーナが言っていたとおりです:“知っていることを伝える人は幸せであり、教えることで学ぶ人は幸せである”。このテーマに関する記事を連載するつもりで、これはその最初の記事にすぎません…。
まず最初に思い出しておきましょう。そもそもLLMとは何でしょう?
LLMは、いくつかの形で定義できます。その一つが:“ディープラーニング(深層学習)のアルゴリズムを使って自然言語を処理し、学習する機械言語モデル”。これは構造的な定義です。私が一番好きなのは次の定義です:“LLMは、本質的には2つのファイルから成り立っています。学習によって得た知識(重み・パラメータ)を含むファイルと、学習済みデータを動かすために必要なコードを含むファイルです”。私は視覚的な人間なので、こう言われると仕組みがよりイメージしやすいのです。
つまり、ChatGPTやClaudeなど多くのものはまさにそれで、現在ではコードを書くこと、文章を翻訳すること、さまざまな疑問に答えることなど、多くのタスクを実行する能力があります。そして、より強力で堅牢なプロンプトを書けるなら、製品のアーキテクチャを作ることまででき、複雑なバグの解決に役立ち、アイデアを出し、さらには革命的なSaaSを作ることさえできるかもしれません(笑)。
ポイントは、LLMが「理解」したり「作り出したりする」能力が、かなり進んだ段階に到達していて、あなたが良い回答を得るために必要なのは、正しい質問をして「-17層」にたどり着くだけだということです!
注: “-17層” とは、Minecraftのゲーム内で金鉱石がある層のことです;)。
質問する(問いを作る)
どうすれば正しい質問ができるのか?そして、なぜそれを知ることが重要なのでしょうか。さっそくいきましょう。
LLMに対して正しい質問をすることは、それだけで重要で、技術の分野にそれだけのための専門領域まで存在するほどです。それがプロンプトエンジニアリングで、次のように定義されています:“LLMにより良い回答を生成するためのプロンプトを企画し、作成し、テストするという経験的な学問”。正しい質問の作り方を身につけると、次のレベルに行けます。最高の回答を引き出せるようになり、得られるメリットはたくさんありますが、なかでも最大のものは生産性です。
では結局、どうやって正しく質問すればいいの?
LLMは強力ですが、あなたの意図を当て推量するわけではありません。検索で最高の結果を得るには、はっきりしたプロンプトを作ること、具体性を持つこと、そして文脈を豊富に与えることに集中する必要があります。これらすべてには次が関わってきます:
1 - 曖昧さを避ける
「可能性の空間」
プロンプトがあまりにも曖昧で、漠然としていると、モデルは統計的に成立する複数の道を見てしまいます。まるで50本の道がある交差点にいるようなもので、どれも看板に「たぶんここ」と書いてある。モデルはそのうちの1つを選びますが、必ずしもあなたが必要としているものとは限りません。つまり、最短で渋滞のない道(実際に正しい回答)とは限らないのです。
例:
曖昧なプロンプト:
"APIを作成してください。"
LLMが「見る」もの:REST API?GraphQL?どの言語で?どの領域(ドメイン)向け?認証は?DBは?モデルは、学習データにおいて統計的に最も一般的なルートを選ぶ可能性が高いです(おそらくNode.jsのExpressで作る汎用的なREST API)。しかし、それはあなたの必要としていることと全く関係ない可能性があります。
曖昧さのないプロンプト:
"Stripeを使って支払いを処理するための、Node.js(Express)とTypeScriptでのマイクロサービスを作成してください。
エンドポイント:支払いの作成、webhookの確認、ステータスの照会。ペイロードは以下を持ちます:
orderId(UUID)、amount(number)、currency(enum: BRL, USD)、customerId(string)。
検証にはzod、取引の永続化にはPostgreSQLを使うPrisma、ログにはwinstonを使用してください。
(201, 200, 400, 422, 500) のような適切なステータスコードを返してください。
ネットワーク障害は自動リトライ(最大3回)で処理してください。"
LLMが「見る」もの:ほぼ一つの道筋。詳細の一つ一つが制約として働き、曖昧さを取り除きます:「Node.js + Express + TypeScript」が、実行環境・フレームワーク・言語を同時に決めます。「Stripeによる支払い」が、SDKとドメインを絞り込みます。「3つの明示的なエンドポイント+型付きペイロード」が、ルートやスキーマに関する推測を不要にします。「Zod、Prisma、PostgreSQL、Winston」がスタックを固定し、モデルは代替案を提案できません。「特定のステータスコード+最大3回のリトライ」が、HTTPステータスと上限の明確な戦略を決めます。確率分布は一か所に集中し、モデルは実質的に「各トークン生成のたびにほぼ一択しかない」状態になります。
2 - スコープ(範囲)を定める
「注意のウィンドウ」
LLMにはcontext window(ウィンドウ)があります。これは、一度に処理できるトークン数(単語の断片)の量です。そこにはあなたのプロンプトと生成される回答が含まれます。このウィンドウの中で重要な現象があります。すべてのトークンが、処理の中で同じ「注意」を受けるわけではないのです。
self-attention(Transformerアーキテクチャの心臓部。キューブではありませんrsrsrs、そしてニューラルネットワークのアーキテクチャ自体は、LLMがプログラミング言語と同じだとしたらそのフレームワークに当たるものですが、その話はさておき)この仕組みが「すべての構造」を決め、プロンプト内のすべてのトークン同士の関係を計算します。不要なトークンが多いほど、モデルは有用な情報と無用な情報の間で「注意を分ける」必要が増えます。
例:
スコープなし:
"Dockerを教えて。"
内部で起きること:モデルは、数百というサブトピックの中から選ぶ必要があります。インストール、基本概念、Dockerfile、docker-compose、ボリューム、オーケストレーション…。注意が細切れになり、その結果、すべての浅いoverviewになります。
スコープあり:
"すでに日常的にDockerを使っているが、イメージサイズの最適化をしたことがない
バックエンド開発者向けに、Dockerのmulti-stage buildの概念を説明してください。
最終的な各イメージのサイズも含め、multi-stage buildなしとありの
Dockerfileの比較を行い、JavaScriptアプリケーションで実践例を示してください。"
内部で起きること:注意の仕組みが、非常に特定の領域、つまり「Docker」「multi-stage build」「イメージの最適化」「JavaScript」の交差部分に集中します。注意の重みが強く誘導されます。
3 - 関連する文脈を提供する
「アプリケーションの状態」
LLM(大規模言語モデル)は、その性質上ステートレスです。つまり、リクエスト間で記憶を持ちません。各プロンプトは最初から処理され、モデルが持つ唯一の「状態」は、あなたがプロンプトに入れた内容だけです。これは、あなたが提供しないあらゆる文脈が、モデルにとっては単純に存在しないことを意味します。
内部的には、文脈は注意機構の中で重み付け(重みのシステム)のように機能します。情報を追加すると、それらは「アンカー」となって、それ以降のすべてのトークンの確率分布に影響を与えます。まるで、文脈の各断片が特定の方向へ答えを引っ張る磁石のようです。
例:
文脈なし:
"コードを修正して。"
LLMがやること:言語、フレームワーク、開発者レベル、コードの目的、チームの規約、期待されるレビューの種類を知らないため、一般的なコメントになります。「エラーハンドリングを追加してください」「もっと説明的な名前を使ってください」「テストの追加を検討してください」。
文脈あり:
"このS3へのファイルアップロードを扱うExpressのNode.jsエンドポイントをレビューしてください。
チームではESLint + Prettierを使っているので、スタイルは無視してください。チームの標準はasync/awaitで
try/catchとカスタムエラーです。プロダクションのエンドポイントで、200 uploads/min受け取ります。
次に注目してください:メモリリーク、エラーハンドリング、S3 SDKの正しい使い方。"
LLMがやること:プロンプト内の各情報は、ノイズを取り除き、レビューに集中させるフィルターとして機能します。「Node.js + Expressで、S3へアップロード」は、ストリーム、バッファ、マルチパート、AWS SDKに関する具体的な知識を有効にします。「ESLint + Prettier、スタイル無視」は、リンターがすでに解決してくれる可能性のあるコメントを排除します。「async/await + カスタムエラー」は、チームがすでに適用している提案をモデルに飛ばさせ、実際にどう使われているかに焦点を当てさせます。「プロダクション、200 uploads/min」は、各問題の重みを変えます。開発では許容され得る解放されないバッファが、負荷がかかると致命的なインシデントになります。「メモリリーク、エラー、S3 SDKに注目」は、レビューを3つの軸に絞り、その他の数十のトピックを無視します。
それを踏まえると、あなたが使っているモデルの制限を理解することは、質問や推論をどこまで進められるかを把握するのにも役立ちます。だからこそ、最適なAIを選び、トレーニングし、質問を投げ、テストし、試してみてください! ;)
最後に覚えておいてください:LLMは「考える」のではなく、確率を計算しているのです!
最終的な考察
以上です。最初の段階で、私が「取り上げる価値がある」と思った各ポイントをできるだけ要約して説明しようとしましたが、LLMのプロンプトエンジニアリングについて語るべきことはまだまだあります。例えば、より古典的なプロンプトエンジニアリング手法(ゼロショット・プロンプティング、ロール・プロンプティング)や、より高度な手法(Chain-of-Thought(CoT)、プロンプトチェーン)など、多くの層があります。次の記事でそれらを分解していこうと思っています。これは、良い数年間のあとに私が記事を書くことを再開するきっかけになった、最初のものにすぎません。読者であるあなたが、理解して何か学べたなら嬉しいです。ここまで読んでいただきありがとうございます。 ;)
私を見つけるには:




