スキップしてメイン コンテンツに移動

プロンプトエンジニアリングの基本!LangChain「PromptTemplate」完全ガイド

プロンプトエンジニアリングの基本!LangChain「PromptTemplate」完全ガイド

はじめに

LLMアプリ開発において、最も重要かつ頻繁に修正が発生するのが「プロンプト」です。「AIにもっと丁寧に答えさせてほしい」「ユーザーの入力を安全に埋め込みたい」といった要望に応えるため、プロンプトをハードコードするのではなく、テンプレートとして管理する必要があります。

今回は、LangChainの中核機能の一つである「PromptTemplate」の使い方をマスターし、保守性が高くセキュアなプロンプト管理手法を学びます。

f-stringによる文字列連結の罠

Python標準のf-stringを使えば、変数を埋め込むこと自体は簡単です。

user_input = "ハロー"
prompt = f"次の言葉を英語に翻訳して: {user_input}"

しかし、これには問題があります。

  • 再利用性が低い: 別の場所で同じテンプレートを使いたい時にコピペになる。
  • 管理が煩雑: コードの中に長い文字列が混在し、可読性が下がる。
  • プロンプトインジェクション: ユーザー入力のエスケープ処理などを自前で実装する必要がある。

PromptTemplateの基本

LangChainでは、以下のようにテンプレートを作成します。

from langchain_core.prompts import PromptTemplate

# テンプレートの定義
template = PromptTemplate.from_template(
    "あなたは{role}です。{topic}について解説してください。"
)

# 変数を埋め込んでプロンプトを生成
prompt = template.format(role="幼稚園の先生", topic="量子力学")
print(prompt)
# 出力: あなたは幼稚園の先生です。量子力学について解説してください。
Merit

テンプレートと変数を分離することで、ロジックが明確になり、テンプレート自体をJSONやYAMLファイルとして外部保存・ロードすることも可能になります。

チャット用テンプレート (ChatPromptTemplate)

最近のLLM(ChatGPTなど)は、単なるテキストではなく「System MESSAGE」「User MESSAGE」といった役割(ロール)ごとの対話履歴を入力とします。これに対応するのが ChatPromptTemplate です。

from langchain_core.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages([
    ("system", "あなたは優秀な翻訳アシスタントです。入力された言語を自動判定し、日本語に翻訳します。"),
    ("user", "{text}"),
])

# invokeで使用
chain = chat_template | llm
response = chain.invoke({"text": "Hello, world!"})

この書き方(タプルによるメッセージ定義)は非常に直感的で、モダンなLangChain開発の主流になっています。

Few-Shotプロンプトの実装

「例示」を与えることで回答精度を高めるテクニック(Few-Shot)も、専用のクラスで簡単に実装できます。

from langchain_core.prompts import FewShotPromptTemplate

examples = [
  {"input": "明るい", "output": "暗い"},
  {"input": "高い", "output": "低い"},
]

example_prompt = PromptTemplate.from_template("単語: {input}\n対義語: {output}")

prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="以下の単語の対義語を答えてください。\n",
    suffix="\n単語: {user_input}\n対義語: ",
    input_variables=["user_input"],
)

まとめ

プロンプトをただの文字列として扱うのは卒業しましょう。PromptTemplate を使うことで、あなたのコードはより「エンジニアリング」された、堅牢なものになります。

LCEL

今回少し登場した `|` 演算子(パイプ)については、後の回で「LCEL」として詳しく解説します。これがLangChainの真骨頂です。

次回は、AIからの返答(テキスト)を、プログラムで扱いやすいJSON形式などに自動変換する「OutputParsers」について解説します。

このブログ記事はAIを利用して自動生成されました。

コメント