LLMを使ったアプリは、デモではそれっぽく動いても、ワークフローに組み込んだ途端に「出力がブレる」「根拠が曖昧」「後続処理で扱いづらい」といった問題が出がちです。
「動くデモ」から「運用できる仕組み」にするために、プロンプトはとりあえず作ってみる“会話のノリ”ではなく 「仕様」として設計するのがポイントになります。
この記事では、実際にアプリを本番利用することに向けて、安定したLLM出力を得るためのプロンプト設計について、Difyのブログ記事で紹介されていた内容をまとめてみます。
【参考】Dify Blog How to:Prompt Engineering for Workflow-Ready LLM Apps
6つのポイントまとめ
#1:設計で何を重視するかを決める
#2:プロンプトの基本形:3つの要素
#3:ルール(制約事項)と入力を明確に分ける
#4:ハルシネーションをプロンプト内で抑制する
#5:出力は構造化する
#6:トークン数を意識する
ポイント1:設計で何を重視するかを決める
プロンプトを書き始める前に、まず 「どんな出力なら成功か」 を決めておきます。つまり、一貫性・根拠・追跡しやすさ・後工程で使いやすさなど、どれを優先するかをはっきりさせます。
- 一貫性:似た入力に対して出力がブレない
- 根拠性(grounded):与えた情報に基づき、想像で補わない
- 監査性:なぜそうなったか追える
- 運用適合:後段の処理(人/ツール/自動化)が扱える
プロンプトの改善も「文章のセンス」に頼るより、決めた軸に沿って結果を見比べて直すほうが進めやすくなります。
ポイント2:プロンプトの基本形:3つの要素
プロンプトは、次の3部構成で組み立てます。
- タスクの説明:何をさせたいか、役割、期待される成功条件。
- 例(必要に応じて):成功例・失敗例を示すことで曖昧さを減らす。
- 指示と入力データ:実際に処理するデータや入力情報。
ポイント3:ルール(制約事項)と入力を明確に分ける
-
システムプロンプト:永続的なルール(推測禁止、出力形式強制、扱う範囲、セキュリティ、トーンなど)
→取扱説明書 -
ユーザープロンプト(今回の入力:対象文書、質問、条件など)
→この実行で使う材料
SYSTEM PROMPT
あなたは厳格なレビュアーです。
ルール:
- 外部知識は使わない
- 不足情報を推測しない
- 入力テキストから根拠を引用する
出力:
スキーマに一致する有効なJSONのみを返す
USER PROMPT
以下のポリシー案について、分かりやすさと抜け漏れを評価してください。
ポリシー案:
{...}
この分離を徹底すると、ワークフローで使うときに
- ルールは固定
- 入力だけ差し替える
ができて、再現性と保守性が上がります。
ポイント4:ハルシネーションをプロンプト内で抑制する
*ハルシネーション=入力にないことを、それっぽく作って答えてしまう現象
LLMの“それっぽい回答”を減らすには、Chip Huyen(エンジニア/研究者)などが紹介している、実際にLLMを本番運用しているチームでも広く使われている次の3つの考え方があります。
- 明確に書く(Be clear):やってほしいことを、そのまま言葉にする
- 具体的に書く(Be explicit):評価基準・制約・例外(迷いそうなケース)まで決めておく
- 根拠を必須にする(Require evidence):与えた入力だけを根拠に、理由を説明させる
少し書き方を変えるだけで、回答のブレや根拠のない言い切り が減って、結果が安定しやすくなります。
- 悪い例:「これで良いか教えて」(判断基準が曖昧で、答えがぶれやすい)
- 良い例:「基準A/B/Cで採点し、各点数の理由を入力から引用して示してください。外部知識は使わないでください。」(基準と根拠が明確になる)
ポイント5:出力は構造化する
ワークフローでLLMの出力結果を使う場合、出力が「構造化」されていることが重要です。
厳密に条件をつけたJSONを指定しましょう。
例えば、次のように「出力の形」を決めて指定します。
-
decision:accept/maybe/reject
→ 次のアクションの分岐に使う最終判定。accept= 承認して次に進む、maybe= 保留して追加確認、reject= 却下・終了など) -
score:1〜10
→ 判定の確度や優先度を数値化。結果の並び替えやしきい値として使う。 -
evidence:
→ 根拠となる引用や参照のリスト。
こうしておくと、自由な文章が返ってくるだけの状態と違い、プロンプトが「お願い」ではなく「仕様」になります。結果として、アプリのテスト・デバッグ・自動化がしやすくなります。
ポイント6:トークン数を意識する
トークンは、モデルが読み書きするテキストの単位です。LLMへの入力とLLMからの出力、両方にかかります。
トークン数は、問い合わせの度に消費されるコストとレスポンスの速度に直結しますので、無駄なく設計する必要があります。
- 不要な言葉をそぎ落とす
- 条件を明確に、誤解を生まない言葉で曖昧さを消す
- 重要なルールは先頭に置く(モデルにより途中でルールを忘れたり一貫性が崩れやすい場合は、末尾でも再度指示する)
プロンプトフォーマット
今回のポイントを踏まえて作成したプロンプトのひな形です。(参考ブログからの引用ではありません。)
# [System]
あなたは{役割}です。
目的: {ゴール}
次のルールに従ってください。
ルール:
- input_text にない情報は作らない。不明なら不明と答える
- 出力は必ずJSON。JSON以外は出力しない
- 根拠は input_text から短い引用で示す
- 情報が不足する場合は questions に列挙する
# 出力JSONスキーマ
{
"result": "...",
"confidence": 0.0,
"evidence": ["..."],
"questions": ["..."]
}
# [User]
input_text:
"""
{対象文書}
"""
task:
{依頼内容}
まとめると:
Prompt = instructions(指示)+ inputs(入力)+ output format(出力形式)
まとめ
最後にまとめられている、本番利用前のチェックリストです!
✓ 再現性がある(Repeatable):同じ入力なら、同じ構造・同じ振る舞いで返ってくる
✓ 根拠が明確(Grounded):出力が、与えたコンテキスト(提示した情報)だけに基づいている
✓ 構造化されている(Structured):出力形式が一貫していて、スキーマ化(JSON化)しやすい
では早速、これらを押さえたうえで実際にLLMアプリを作ってみましょう!