プロンプトとは、大規模言語モデル(LLM)にタスクを定義し、出力内容を制御するために与えるテキスト入力です。プロンプトが明確であるほど、出力結果は正確かつ一貫性のあるものになります。本ガイドでは、Alibaba Cloud Model Studio におけるプロンプトの設計および最適化に関する実践的な手法を解説します。
効果的なプロンプトの設計
明確で具体的な指示を記述する
あいまいなプロンプトは、あいまいな結果を生みます。提供する文脈や制約が多ければ多いほど、出力は期待通りのものに近づきます。これはタスクを依頼することに似ており、一行だけのリクエストでは解釈の余地が大きくなりすぎますが、明確な目標と詳細な指示があれば、まさに必要な成果物を得ることができます。
明確で具体的なプロンプトは、LLM から有用な出力を得る上で最も重要な要素です。
例:コード生成タスク
| あいまいなプロンプト | 明確で具体的なプロンプト |
|---|---|
| データを処理する Python 関数を作成します。 | CSV ファイルを読み込み、status 列の値が "active" である行のみをフィルターし、辞書のリストを返す Python 関数を作成してください。型ヒントを含め、ファイルが存在しない場合のエラー処理も実装してください。また、標準ライブラリの csv モジュールを使用します。 |
具体的なプロンプトでは、入力形式、期待される出力、エラー処理、使用ライブラリといった要件を明示しており、モデルが初回試行で実用可能なコードを生成できる十分な情報が与えられています。
例:コンテンツ生成タスク
| あいまいなプロンプト | 明確で具体的なプロンプト |
|---|---|
| 製品発表文の作成を支援してください。 | 「ゼファー Z9」(百聯社製の軽量ポータブル端末)向けに、200 単語程度の製品発表文を作成してください。超薄型デザイン、高性能仕様、使いやすさを強調し、SNS を利用するテクニカルな消費者をターゲットとしてください。トーンはエネルギッシュで簡潔なものとします。 |
フレームワークを用いたプロンプト構造化
プロンプトフレームワークは、LLM が必要とする情報を体系的に提供するためのツールです。何を含めるべきかを推測する代わりに、以下の 6 つの要素をチェックリストとして活用してください。
| 要素 | 目的 | 例 |
|---|---|---|
| コンテキスト | タスクに関連する背景情報 | 「Python マイクロサービスのプルリクエストをレビューしています。」 |
| 目的 | 完了すべき特定のタスク | 「潜在的なバグを特定し、修正案を提案してください。」 |
| スタイル | 文体またはペルソナ | 「シニアバックエンドエンジニアとして記述してください。」 |
| トーン | 出力の感情的質 | 「専門的でありながら建設的。」 |
| 対象読者 | 出力の読者 | 「チーム内のジュニア開発者。」 |
| レスポンス | 期待される出力フォーマット | 「問題点とコード修正案を含む番号付きリスト。」 |
プロンプト内で各セクションを区切るには、# をデリミタとして使用します。
#コンテキスト#
ユーザー認証を処理する Python マイクロサービスのプルリクエストをレビューしています。
コードベースには FastAPI および SQLAlchemy を使用しています。
#目的#
以下のコード差分をレビューし、潜在的なセキュリティ脆弱性、パフォーマンスの問題、
およびスタイル違反を特定してください。
#スタイル#
徹底的なコードレビューを行うシニアバックエンドエンジニアとして記述してください。
#トーン#
専門的でありながら建設的 — 各問題がなぜ重要かを説明してください。
#対象読者#
安全なコーディング手法を学習中のジュニア開発者。
#応答形式#
問題点を番号付きリストで提示してください。各項目には以下の情報を含めてください:
- 特定の行またはコードブロック
- 問題の原因
- コードを含む修正案すべてのプロンプトに必ずしも 6 つの要素すべてが必要というわけではありません。タスクに応じてフレームワークを柔軟に適用してください。本ガイド全体で紹介する例では、シナリオに応じて異なるサブセットが使用されています。
プロンプトの最適化
出力例を提示する
期待される出力の具体例を含めることで、モデルはフォーマット、スタイル、詳細度を正確に再現できます。この手法(ファイショットプロンプティング)は、複数回の実行における出力の一貫性向上にも寄与します。
例:構造化データ抽出
#コンテキスト#
ユーザーサポートチケットから構造化情報を抽出します。
#目的#
各チケットを JSON オブジェクトに解析します。
#例#
入力: "注文 #12345 が破損した状態で届きました。返金をお願いします。"
出力:
{
"order_id": "12345",
"issue_type": "damaged_item",
"requested_action": "refund"
}
入力: "アカウントにログインできません。パスワードのリセットを 2 回試みました。"
出力:
{
"order_id": null,
"issue_type": "login_failure",
"requested_action": "account_recovery"
}
#タスク#
以下のチケットを解析してください:
入力: "注文 #67890 が『処理中』ステータスで 5 日間停止しています。
至急対応またはキャンセルをお願いします。"モデルは、これらの例のみから JSON スキーマ、フィールドの命名規則、および自然言語から issue_type や requested_action を推論する方法を学習します。
複雑なタスクをステップごとに分割する
複雑なタスクの場合、モデルが達成すべき最終結果だけでなく、明示的な実行ステップを定義してください。ステップバイステップの指示により、中間的な推論を飛ばすことを防げます。
例:数学の文章題
#コンテキスト#
チミーは午前 8 時に自宅を出発し、分速 50 メートルで歩き始めました。
12 分後、父親がチミーが宿題を忘れたことに気づき、分速 200 メートルで
自転車で追いかけています。追いついた後、父親はチミーを自転車に乗せて
残りの道のりを移動させます。自転車での移動距離は、歩行距離の 5 倍です。
#目的#
到着時刻を計算してください。
#ステップ#
1. 父親が追いつくまでにチミーが歩いた距離を計算します。
2. 父親が追いつくまでの時間を求めます。
3. 残りの自転車移動距離およびその所要時間を計算します。
4. 全ての時間間隔を合計し、到着時刻を求めます。モデル出力(ステップに従ったもの):
ステップ 1: 父親が出発するまでにチミーは 12 分間歩きます:
12 分 × 50 m/分 = 600 m の先行距離
ステップ 2: 父親の相対速度:200 − 50 = 150 m/分
追いつくまでの時間:600 m ÷ 150 m/分 = 4 分
チミーがさらに歩く距離:4 分 × 50 m/分 = 200 m
歩行距離合計:600 + 200 = 800 m
ステップ 3: 自転車移動距離:800 m × 5 = 4,000 m
自転車移動時間:4,000 m ÷ 200 m/分 = 20 分
ステップ 4: 合計所要時間:12 + 4 + 20 = 36 分
到着時刻:午前 8 時 + 36 分 = 午前 8 時 36 分#ステップ# セクションがない場合、モデルは中間計算を飛ばして誤った回答を出す可能性があります。
デリミタを用いてコンテンツを区別する
プロンプトに複数のコンテンツブロック(指示、入力データ、例など)が含まれる場合、明確な境界を示すためにデリミタを使用してください。これにより、モデルは指示と処理対象のコンテンツを明確に区別できます。
自然言語ではほとんど出現しない文字列をデリミタとして使用します:###、===、または >>> などです。
例:テキスト要約
以下の映画レビューの各セクションを個別に要約してください。
各セクションにつき 1 文の要約文を生成します。
###
張志強氏はかつて活気に満ち、精力的でしたが、人生のプレッシャーによって
方向を見失いました。中年期の衝動的な判断により、家族の誇りから社会的
アウトキャストへと変貌しました。
###
これは始まりに過ぎませんでした。予期せぬ出来事の連続により、彼は自分自身と
向き合うことを余儀なくされました。彼は配達ドライバーとしてやり直すことを選び、
街の通りを走りながら人生を再構築しました。
###
その過程で、彼は志を同じくする仲間たちに出会いました。彼らとの共通の苦闘を通じて、
彼は再び勇気と目的意識を取り戻し、人生の新たな方向性を築きました。
###デリミタがない場合、モデルはレビュー全体を単一のブロックと見なし、汎用的な要約を 1 つだけ生成します。一方、デリミタがあると、モデルは 3 つの明確なセクションを認識し、物語の展開に沿った 3 つの関連性の高い要約を生成します。
モデルに段階的な推論を促す
論理的思考、数学的計算、あるいは多段階分析を伴うタスクでは、結論を述べる前にモデルが推論過程を示すよう誘導してください。以下に、2 つの有効な手法を紹介します。
Chain of Thought (CoT)
CoT は比較的シンプルな手法であり、複雑なシナリオにおける LLM の推論能力を大幅に向上させることができます。モデルに対し、最終的な回答を出す前に思考過程を説明するよう依頼します。
例:JSON 検証
#コンテキスト#
JSON 入力:
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {
"mailHost": "mail1",
"mailHostOverride": "mail2"}},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {
"templatePath": "toolstemplates/",
"log": 1,
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
"logMaxSize": ""}}],
"servlet-mapping": {
"cofaxEmail": "/cofaxutil/aemail/*",
"cofaxTools": "/tools/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
#目的#
この JSON が以下の 3 つの要件をすべて満たすかどうかを検証してください:
1. すべてのサーブレットに init-param ブロックが存在する。
2. servlet-mapping 内のすべてのキーが servlet-name と一致する。
3. cofaxTools サーブレットには、「log」で始まるパラメーターがちょうど 3 つあり、
「log」パラメーターの値は 10 未満である。
#応答形式#
まず、各要件について推論過程を説明してください。
その後、すべての要件が満たされているかどうかを明示してください。「推論過程を説明してください」という指示を加えることで、モデルは各要件を個別に評価する構造化された分析を実行します。これにより、logMaxSize の空文字列値のようなエッジケースも検出でき、単純な「はい/いいえ」回答では見落とされがちな問題を捉えることができます。
プロンプトチェイニング
複雑な問題を、複数のターンにわたって単純な質問の連鎖に分解します。各回答が次の質問への入力となり、モデルを制御された推論経路に導きます。
プロンプトチェイニングは CoT よりも設定に手間がかかりますが、精度が高く、特に論理的に複雑であっても固定パターンに沿って分解可能なタスクに適しています。
例:多段階数学(前述のチミー問題を 3 ターンで実施)
ターン 1:
#コンテキスト#
チミーは午前 8 時に分速 50 m で歩き始めました。12 分後、父親が分速 200 m で
自転車で追いかけています。自転車移動距離は歩行距離の 5 倍です。
#質問#
父親がチミーを追いつくのはいつですか?また、その時点でチミーはどれだけ歩いているでしょうか?モデル:「父親は午前 8 時 16 分にチミーを追いつき、その時点でチミーは 800 メートル歩いている。」
ターン 2:
チミーが祖父母の家に到着するまでに、自転車で移動する距離はどれくらいですか?モデル:「自転車移動距離 = 800 m × 5 = 4,000 メートル。」
ターン 3:
チミーの到着時刻は何時ですか?モデル:「自転車移動時間 = 4,000 m ÷ 200 m/分 = 20 分。合計所要時間 = 16 + 20 = 36 分。到着時刻:午前 8 時 36 分。」
各ターンは検証済みの中間結果に基づいており、誤差が累積するリスクを低減します。
[ヒント:] その他の推論手法には、思考の木(ToT)と思考のブースティングがあります。タスクの複雑さと精度要件に応じて、適切な手法を選択してください。
テストと反復
プロンプトエンジニアリングは反復的なプロセスです。最初のバージョンのプロンプトが最良の結果を生むことは稀です。
以下のサイクルに従ってください:
目標の定義。 プロンプト作成前に、優れた出力がどのようなものかを明確に定義します。
初期プロンプトの作成。 本ガイドで紹介する手法を適用します:具体的であること、フレームワークの活用、例の提示。
多様な入力によるテスト。 実際のさまざまなシナリオ(エッジケースを含む)に対してプロンプトを実行します。
失敗事例の分析。 出力が不十分な理由を特定します:フォーマットの誤り、情報の欠落、誤った推論、トーンの不一致など。
プロンプトの精緻化。 変更の影響を測定できるよう、1 つの要素ずつ調整します。
反復。 出力が一貫して品質基準を満たすまで、このプロセスを繰り返します。
プロンプト設計に加えて、ユーザーからのフィードバックも不可欠です。プロンプトを本番環境に展開した後は、実際のインタラクションをモニターし、ユーザーによる訂正や想定外のエッジケースの傾向に基づいて継続的に精緻化を行ってください。
例:多言語対応 HR アシスタントの最適化
この例では、上記の手法が実際のプロンプトをどのように改善するかを示します。
背景: Qwen-Turbo をベースとした多国籍企業向け HR アシスタントが、ユーザーの言語に一貫して応答できていませんでした。システムプロンプトの再構成が必要でした。
最適化前の状態
#役割
あなたは効率的な HR AI アシスタントであり、社内ポリシー、勤怠管理システム、
年次休暇制度などの社内規定に関する質問に特化して回答します。
##スキル
###スキル 1:ポリシー解釈
- 社内ポリシードキュメントを正確に解釈し、同僚に対して明確かつ簡潔な
解説を提供します。
###スキル 2:勤怠に関する質問対応
- 従業員の勤怠に関するすべての質問(出勤ルール、遅刻・早退の取り扱い、
休暇申請手続きなど)に回答します。
###スキル 3:年次休暇管理に関する相談
- 年次休暇の申請条件、付与ルール、有効期間、承認プロセスなどを説明します。
##制約
- ユーザーの質問と同じ言語で回答します。
- HR 関連の質問に限定します。
- 個人情報に関する質問には対応しません。課題:
##制約セクションが冗長で、構造が緩い。${documents}ナレッジベースブロックがインラインで埋め込まれており、 モデルが指示と参照コンテンツを区別しづらい。言語マッチングの指示が「制約」セクションに埋もれていた。
最適化後の状態
#コンテキスト#
あなたは多国籍企業向けの HR AI アシスタントです。ポリシー解釈、勤怠ルール、
年次休暇管理に関する質問に回答します。
以下の社内ポリシードキュメントが利用可能です:
======
${documents}
======
#目的#
1. ポリシー解釈、勤怠、年次休暇に関する質問のみに回答します。
2. 質問が範囲内であるものの、ナレッジベースに該当情報がない場合は、
ユーザーに人事部門への連絡を案内します。
3. 各カテゴリについては、以下のガイドラインに従います:
- ポリシー解釈:該当する条項を特定し、明確かつ簡潔な説明を提供します。
- 勤怠:出勤ルール、遅刻の取り扱い、休暇手続きをカバーします。
- 年次休暇:適用条件、付与ルール、承認プロセス、残日数の算出を説明します。
4. 従業員の個人データにアクセスしたり、開示したりしません。
#多言語対応要件#
- 質問が中国語でない場合、ナレッジベース検索のために中国語に翻訳し、
取得した内容を元の質問言語に変換して出力します。
#応答形式#
- 出力には ASCII 文字のみを使用します。
- 入力言語と出力言語を一致させます。変更点:
フレームワークの適用。
#コンテキスト#、#目的#、#多言語対応要件#、#応答形式#セクションを用いて再構成しました。デリミタの追加。
${documents}を======で囲み、参照データと指示を明確に分離しました。制約の分散配置。 言語関連の制約は
#多言語対応要件#に、範囲制限は#目的#にそれぞれ配置しました。
これらの変更により、言語の一貫性問題が解決されました。モデルは、多言語対応の指示を、埋もれた補足ではなく、明確で高優先度の独立した指令として認識できるようになったためです。