2025/05/29

生成AIを活用するためのプロンプトの基礎 - 「LLMのプロンプトエンジニアリング」を読んで

はじめに

ここ一年で生成AIの進化は凄まじく、3ヶ月も経てばほとんどの知識が古くなってしまう状態です。

しかし、それでも基本となるLLMの仕組みは変わっておらず、だからこそ効果的なプロンプトの基礎も変わっていません。

この記事では、LLMの仕組みのざっくりとした雰囲気を押さえつつ、効果的なプロンプトを根拠を持って書けるようになるために必要なことをまとめます。

少しでも仕組みを理解することで、プロンプトをブラッシュアップしていく際に迷う回数を減らし、より効果的に生成AIやコーディングエージェントを活用することを目指します。

参考

LLMのプロンプトエンジニアリング - O’Reilly Japan

LLMの基本

まずはLLMが何をしているか、どのように動いているかを理解していきます。

LLMは本質的には、トレーニング段階で学習したテキストを模倣するテキスト補完エンジンです。

言語モデルは、単に次の単語の確率を予測し、最も確率が高いものを選択して補完します。参考書籍の中では、似たような機能の例として「iPhoneでメッセージを入力する際に、キーボードの上に表示される予測変換バー」を挙げています。

さらに簡単な言い方も書籍内に登場します。

「文字列を入力すると文字列を返すサービス」

LLMの文脈では、入力する文字列のことを「プロンプト」、出力される文字列のことを「補完」や「レスポンス」と呼びます。

ただし、LLMが目指すのはトレーニングデータをそっくりそのまま再現することではなく、学習したパターンをもとに新しいプロンプトに対しても補完ができるようになることです。

トレーニングデータセットから無作為にドキュメントを1つ取り出し、そのドキュメントがちょうどそのプロンプトで始まっていると想定してみてください。あなたが知っているのは、そのドキュメントがそのプロンプトで始まっているという事実だけです。では、そのドキュメントを統計的に最も自然な形で続けるとしたら、次に来るのはどのようなテキストでしょうか?それこそがLLMから得られるであろう出力なのです。

GPTとはなにか

生成的事前トレーニング済みトランスフォーマー(Generative Pre-trained Transformer)でGPTと呼ばれます。

GPT登場以前の標準的な手法は、インターネット上のテキストなどのラベルなしデータで事前トレーニングを行い、その後モデルのアーキテクチャを修正し、特定のタスクに特化したファインチューニングを適用して、最終的なモデルが「1つの」タスクを非常にうまくこなせるようにする、というものでした。

例えば、株価の予測や競馬予想など、大量の学習データから未来に起こり得る現象を推測するようなもので、確かに生成AI登場以前から「AI」と呼ばれていたものです。

ChatGPTのコア技術「GPT」をざっくり理解する #NLP - Qiita

ハルシネーション

これまでの説明のとおり、LLMは単にトレーニングデータからもっともらしいテキストの補完をするものだと理解できました。

これには副作用があり、それが「ハルシネーション」と呼ばれます。 モデル目線で見れば、もっとも確率の高いテキストを補完しているので、事実とことなるがもっともらしく見える情報であればモデルが自信を持って生成してしまう現象です。モデルの視点では他の補完と区別がつかないため、プロンプトでの指示はほとんど効果がありません。

また、ハルシネーションはプロンプトによって誘発されることもあり、例えばプロンプトで誤った主張をしておきながらそれを訂正するケースは少ないため、与えられたプロンプトを正しいものとみなす傾向があります。

プロンプトの基礎

トークンの分解をさせない

人間は単語で文章を認識しますが、LLMは文字列をトークンに分解してから、それをモデルの入力として使用します。

そのため、例えば単語を並び替えたりといったトークンを分解して再構築するような作業は避けておいた方が良いです。

書籍では、スキャッターゴリーズという特定の条件に合致する単語を列挙するゲームをLLMにさせていますが、うまくいきません。このゲームは例えば、「Sw」から始まる国を列挙するようなものです。これらの作業にはトークンの分解が必要なので、LLMは苦手です。

また、人間と違ってトークンで文字を認識しているので、ひらがなとカタカナの違いや大文字と小文字の違いなどを区別するのも苦手としています。同じ単語であっても同じトークンに分解されるとは限らないです。

これらのトークンを扱うトークナイザーはモデルによって固定されており、このトークナイザーによって文字数がどうトークン数に変換されるかが決まります。また、多くのトークナイザーは英語に最適化されているので、英語をプロンプトに利用するのも有効です。

トークン数の上限はコンテキストウインドウと呼ばれ、プロンプトの文字数の制限がありますが、参考書籍執筆時点から比べてもモデルの進化が早く、現在はかなり大きくなっています。

誤った出力をさせない

LLMはプロンプトから得られる最もあり得る次のトークンを補完しますが、1トークン出力されるたびにプロンプトの末尾に付け足され、LLMはまた新しいプロンプトを前提として再び統計的に最もあり得る次のトークンを求めます。

スマートフォンで文字を入力するとき、キーボード上に3つほどの単語候補が出てきて、その中で真ん中の候補ばかり押し続ける、あの漢字を思い浮かべてみてください。LLMを動かすのは、ちょうどあれと似ています。

この仕組みからわかることは、一度トークンを出力してしまうと、LLMはそのトークンを覆したり、あとから削除したりできないということです。人間が執筆中に誤字脱字を明示的に取り消したような「完成前のドキュメント」を学習していないからですね。

また、この仕組みによって同じ文章を繰り返してしまうこともしばしば見られます。LLMにとっては終了することより回答を続けることが自然だと判断されるからです。このあたりの詳しい内容は参考書籍を参照してください。

文字数のカウント

人間はテキストを読み直したり、重要な箇所はスピードを落として読んだりできますが、LLMにはできないので、例えばプロンプトの最後に「文字数を数えろ」というリクエストが出てきたとしても読み直せないです。このことはプロンプトエンジニアリングにおける「順序」の重要性を示します。 最初に文字数を聞いた場合のほうが最後に聞く場合と比べると、より確実な答えを得ることができます。(もちろんトークン単位での処理なので文字数を数える事自体は苦手としています。)

もし、ある能力がLLMにとって現実的かどうか判断したいなら、次の問を自分に投げかけてみてください。「関連する知識をすべて頭に入れた人間の専門家が、一度も立ち戻りや修正、メモ取りなしでこのプロンプトに対する回答を書き上げられるだろうか?」

Few-shot

プロンプトに例を追加する手法は「Few-shotプロンプティング」と呼ばれます。 例示による説明はLLMがパターンを認識し、それを踏襲して補完していることを考えると有用です。

また、Few-shotプロンプティングを活用することで、質問の解釈だけでなく、期待する補完の具体的な形式まで明示することができます。

特定のルールや形式があるような回答を求める場合でも、それを明示的に指示するよりも具体例として示したほうが効果的です。

プロンプトの構成

LLMは途中で一時停止してじっくり考えるということはできないので、プロンプトの導入部分で焦点を絞ることで出力を改善できます。

また、一般的なLLMの特徴として、「プロンプトの末尾に近い情報ほどモデルに大きな影響を与えやすい」、「モデルはプロンプト冒頭と末尾の情報は比較的思い出しやすいが、中間に埋め込まれた情報は活用が難しくなる」などがあります。

これらの問題への対策として、特にプロンプトが長くなる場合は、すべてのコンテキストを入れ終わった後に、最後でもう一度本題の質問をリマインドすることが有効です。書籍内でも「リフォーカス」や「サンドイッチ手法」と呼ばれています。

インセプション

補完モデルを使用する場合は、回答文の最初を提示してあげると、モデルはそれを自分で考え出したものだと認識し、それに応じて残りの補完を生成します。

学習に利用されるドキュメントを想像する

例えば、学術的なレポートが豊富にある分野、特にビジネス、文学、科学、法律のような分析的な報告書が日常的に作成される分野であれば活用するのは簡単です。

一般的な構成が決まっており、例えば導入から始まり、結論に至るまでに必要に応じて要約が挟み込まれる事が多いので、構成しやすいです。

レポートのスコープを最初に絞り込むことも有効です。「自己啓発本ではなく小説だけを提案してほしい」といった除外条件は、対話のやり取りで行うのではなく冒頭で述べるようにすると、レポートの導入部で書かれることの多い情報なのでより有効になります。

Markdownの利用

LLM自体はテキストであれば扱えますが、書籍の中ではMarkdown形式が推奨されています。理由は以下の通りです。

  • Markdownは普遍的でインターネット上にMarkdownファイルが多数存在するため、LLMがよく知っている形式です。
  • Markdownはシンプルで軽量な記法です。機能が少ないので書きやすく、モデルがコンテンツを解釈しやすいという利点があります。
  • 見出しを使って階層構造を表現できるため、プロンプト要素を明確なセクションに分けやすく、不要な部分を外しても全体の構造を保つことができます。
  • インデントが基本的には問題にならず、ソースコードなど技術的な内容については```(バッククォート3つ)で囲んでブロック形式を利用すればOKです。
  • ユーザーにモデルのレスポンスを直接表示したい場合にもMarkdownは簡単にレンダリングできます。
  • Markdownのハイパーリンク機能を使えばモデルがリンクを含めた出力をしやすくなり、ソースの検証やコンテンツの再取得を自動化しやすくなります。

所感

今回はLLMのプロンプトに関する基礎をまとめました。

書籍の執筆時点から現在までの間でさえ、LLMの進化は凄まじく、以下のような点で変化してきました。

  • コンテキストウィンドウの拡大
  • o1のようなReasoningモデルの登場によりベストプラクティスが変化
    • 思考の連鎖の指示が効果的ではなくなる
    • few-shotよりも先にzero-shotを試す(回答例を示さない)

推論については下記を参照してください。

推論のベストプラクティス - OpenAI API

LLMのプロンプトエンジニアリング - O’Reilly Japanは基本的なLLMの仕組みを理解するうえで非常に良い書籍でしたが、少し内容が古くなってしまっている部分もあるため、各生成AIモデルのAPIを提供している企業が発表している内容や関連する資料を参考にすることをお勧めします。