【Python】LangChain Promptsとは|Templates・Example Selectors・Output Parsers

当ページには広告が含まれています。

こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!

こんな方におすすめ!
  • LangChain Promptsについて詳しく知りたい。
  • LangChain Promptsの主要機能である「Prompt Template」「Example Selectors」「Output Parsers」のPython実装方法が知りたい。
目次

LangChainとは?

【LangChain公式】https://python.langchain.com/en/latest/index.html

LangChainとは、ChatGPTを代表とするような大規模言語モデル(LLM)の機能を拡張し、サービスとして展開する際に役立つライブラリです。

LangChainの主要機能

LangChainの主要な機能として以下があります。

主要機能概要
Models様々な大規模言語モデルを同じインターフェース上で取り扱えるようにする機能
Promptsプロンプトの管理、最適化、シリアル化ができる機能
Memory言語モデルを用いてユーザーと対話した履歴を記憶する機能
Data connection言語モデルに外部データを投入し、外部データに基づく回答を生成する機能
Chainsチェーンを複数繋げて、一連の処理を連続実行する機能
Agentsユーザーからの要望をどんな手段・順序で応えるか決定・実行する機能

LangChainの各種機能の詳細を知りたい方は、こちらの記事をご覧下さい。

あわせて読みたい
LangChainとは?|概要・主要機能を徹底解説 LangChainの概要および主要機能であるModels・Prompts・Data Connection・Agents・Memory・Chainsについて解説します。

【参考】LangChainを用いたプログラミング実装におすすめの学習教材

LangChainライブラリを用いてプログラミングし、アプリケーションを実装したい方向けに、おすすめの学習教材をご紹介します。

LangChain|Prompts(プロンプト)

LangChain Promptsとは、プロンプトの管理、最適化、シリアル化ができる機能を指します。なお、Prompt(プロンプト)とは、言語モデルが応答を生成するための「指令文や文章」を指します。

LangChain PromptsをもとにLLMのプロンプトエンジニアリングを効率化できます。例えば、記述するコードも最小限にできたり、モデル実装にかかるコストを抑えることが可能です。

Langchain Promptsの機能を細分化すると、以下3つに分けられます。

  • Prompt Templates
  • Example Selectors
  • Output Persers

Prompt Templates

Prompt Templateとは、「形式化された指示文」です。Template内には、任意の{入力変数}が定義されています。Prompt Templateが{入力変数}を受け取ると、形式文に沿って動的にプロンプトが生成できる仕組みです。

Prompt Templatesの種類

3種類のPrompt Templateが代表的に利用されています。

スクロールできます
LLM Prompt TemplatesLLMのプロンプト表示方法を示したテンプレート
Chat Prompt Templatesチャットモデルのプロンプト表示方法を示したテンプレート
FewShot PromptTemplateLLMのプロンプト表示方法に加え、「教師データをどのようなフォーマットで学習させるのか」も指定したテンプレート

Prompt Templatesの中身

Prompt Templatesには次の指示文が指定できます。

  • 言語モデルへの指示文章
  • 入力変数
  • 言語モデルがより良い応答を生成するのに役立ついくつかの教師データ

Example Selectors

Example Selectorsとは、特定の文脈において、特定の種類の例文を適切に選択できるようにするための機能です。

Example Selectorは、言語モデルの出力に多数の例が想定される際に有効な機能です。

例えば、OpenAIが提供するGPTモデルの場合、GPTモデルで入出力できる最大トークン数が制限されています。プロンプトテンプレートに多数の例文を含めてしまうと、最大トークン数を超過してしまったり、出力できるトークン数の上限を小さくしなければならなくなります。

そこで検討されたのが、ユーザーが入力した文脈に対して適当な例文のみをプロンプトテンプレートに含めるという考えです。これをExample Selectorsを用いて実現し、特定の種類の例を優先したり、無関係な例を除外したり制御するのです。

Output Persers

Output Parsersとは、LLMの出力結果を構造化するのに役立つ機能です。

LLMはテキストを出力できます。この時、単にテキストをそのまま出力するだけではなく、構造化された形式のもと、結果を出力したい場合があるでしょう。 このような場面でOutput Perserが役立ちます。

【LangChain事前準備】Python環境構築・OpenAIのChatGPT API取得

PythonとLangChainを用いて、LangChain Promptsの利用方法を後述します。そのためにいくつか実施すべき事前準備があります。

Pythonライブラリのインストール

プログラム実装に際して、以下に示すライブラリが必要となります。ターミナル(MacOS)またはコマンドプロンプト(Windows)を通じて事前にインストールしておきましょう。

OpenAI

ChatGPTを代表とするOpenAI社のAPI利用に際して必要となるライブラリです。

pip install openai

LangChain

LangChainの利用に際して必要となるライブラリです。

pip install langchain

【ChatGPT】OpenAI社のAPI発行

LangChain機能構築に際して、OpenAI社が提供するGPTモデルをAPI経由で呼び出す必要があります。

OpenAI社の公式サイトから「API シークレットキー」を事前に発行しておきましょう。なお、シークレットキーの発行方法はこちらの記事で詳しく解説しています。

あわせて読みたい
【Python×ChatGPT】チャットボット作成入門|OpenAI APIの利用申請手順も解説 「ChatGPT APIの利用手順」と「PythonでChatGPT APIを呼び出し、チャットボットを作成する方法」についてそれぞれ解説します。

【Python】LangChain Prompts|LLM Prompt Templatesの実装方法

LLM Prompt Template(プロンプトテンプレート)とは、LLMのプロンプト表示方法を示したテンプレートです。

以下、Pythonを用いたLLM Prompt Templateの作成とLLMでの利用方法について解説します。

Pythonライブラリのインストール

Pythonプログラムの先頭にライブラリとAPI認証情報を記述します。

前述したOpenAI社のサイトから取得したシークレットキーを入力しましょう。

import openai
import os

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

LLM Prompt Templateの作成

LLM Prompt Templateを作成します。テンプレートの入力変数有無により、2つの記述例を示します。

Prompt Templateコード(入力変数あり)

入力変数をテンプレートに含める場合{XXX}という形式で記述します。

また、PromptTemplateのinput_variablesに入力変数名称を併せて記述します。

from langchain import PromptTemplate
from langchain.llms import OpenAI

# ====================================================================================
# Prompt Template作成
# ====================================================================================

template = "{subject}の{question}は何か?"

# プロンプトテンプレート
prompt_template = PromptTemplate(
                        input_variables   = ["subject", "question"],   # 入力変数 
                        template          = template,                  # テンプレート
                        validate_template = True,                      # 入力変数とテンプレートの検証有無
                       )

Prompt Templateコード(入力変数なし)

PromptTemplateに指定する{入力変数}は必ずしも必須ではなく、指定せずでも実行できます。

from langchain import PromptTemplate
from langchain.llms import OpenAI

# ====================================================================================
# Prompt Template作成
# ====================================================================================

# テンプレート
template = "りんごの色は何か?"

# プロンプトテンプレート
prompt_template = PromptTemplate(
                        input_variables   = [],         # 入力変数 
                        template          = template,   # テンプレート
                        validate_template = True,       # 入力変数とテンプレートの検証有無
                       )

出力イメージ

# 出力
print("Prompt Template:")
print(prompt_template)

# 出力イメージ
# input_variables=['subject', 'question'] 
# output_parser=None partial_variables={} 
# template='{subject}の{question}は何か?' 
# template_format='f-string' 
# validate_template=True

モデル作成(LLM)

OpenAIのAPIを用いてLLMを作成します。以下のコードを実行しましょう。

コード

# ====================================================================================
# LLM作成
# ====================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

【参考】LLMについて

上記LLMオブジェクトについて、概要・Pythonコードのパラメータの意味など詳しく知りたい方はこちらの記事が参考になります。

あわせて読みたい
【Python】LangChain Modelsとは?|LLM・チャットモデル・Embeddingsの実装方法 「LangChain Modelsの概要」と「LLM・チャットモデル・EmbeddingsのPython実装方法」について詳しく解説します。

Prompt Templateを用いたLLM実行

プロンプトテンプレートを用いてLLMを実行します。

コード

# ====================================================================================
# Prompt Templateを適用しLLM実行
# ====================================================================================

# プロンプトテンプレートにフォーマット適用
prompt_format = prompt_template.format(subject="りんご", question="色")

# LLMにPrompt Templateを指定
response = LLM(prompt_format)

出力イメージ

# 出力
print(response)

# 出力イメージ
# りんごの色は、赤、黄色、緑など様々です。

Prompt Templateをローカルに保存

Prompt TemplateはローカルPC環境にJSON形式で保存もできます。

コード

# ====================================================================================
# Prompt Templateをローカルに保存
# ====================================================================================

# 保存先ファイルパス(JSON)
filename = "prompt_template.json"

# プロンプトテンプレートの保存
prompt_template.save(filename)

保存したPrompt Templateをロード

前述でローカルに保存したプロンプトテンプレートは再びPython環境に呼び出し利用できます。

コード

# ====================================================================================
# ローカルに保存したPrompt Templateをロード
# ====================================================================================

from langchain.prompts import load_prompt

# 保存先ファイルパス(JSON)
filename = "prompt_template.json"

# プロンプトテンプレートをロード
loaded_prompt = load_prompt(filename)

出力イメージ

# 出力
print(loaded_prompt)

# 出力イメージ
# PromptTemplate(input_variables=['subject', 'question'], 
# output_parser=None, 
# partial_variables={}, 
# template='{subject}の{question}は何か?', 
# template_format='f-string', 
# validate_template=True)

LLM Prompt Templateを用いた言語モデル実装コードまとめ

ここまで紹介したコードをまとめて掲載します。

import openai
import os
from langchain import PromptTemplate
from langchain.llms import OpenAI

# ====================================================================================
# API認証情報
# ====================================================================================

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

# ====================================================================================
# Prompt Template作成
# ====================================================================================

template = "{subject}の{question}は何か?"

# プロンプト(変数有り)
prompt_template = PromptTemplate(
                        input_variables   = ["subject", "question"],   # 入力変数 
                        template          = template,                  # テンプレート
                        validate_template = True,                      # 入力変数とテンプレートの検証有無
                       )

# ====================================================================================
# LLM作成
# ====================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

# ====================================================================================
# Prompt Templateを適用しLLM実行
# ====================================================================================

# プロンプトテンプレートにフォーマット適用
prompt_format = prompt_template.format(subject="りんご", question="色")

# LLMにPrompt Templateを指定
response = LLM(prompt_format)

# 出力
print(response)

# ====================================================================================
# Prompt Templateをローカルに保存
# ====================================================================================

# 保存先ファイルパス(JSON)
filename = "prompt_template.json"

# プロンプトテンプレートの保存
prompt_template.save(filename)

【Python】LangChain Prompts|Chat Prompt Templatesの実装方法

Chat Prompt Templateとは、チャットモデルのプロンプト表示方法を示したテンプレートです。

以下、Pythonを用いてChat Prompt Templateの作成とチャットモデルでの利用方法について解説します。

Pythonライブラリのインストール

OpenAI社のサイトから取得したシークレットキーを指定し、以下コードをプログラム先頭に配置しましょう。

import openai
import os

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

Chat Prompt Templateの作成

Chat Prompt Templateの作成方法について言及します。

コード

Chat Prompt Templateには、対話ロール(Human/AI Assistant/System)指定する特徴があります。

system_templateにチャットモデルが担う役割をメッセージ形式で渡し、human_templateにユーザー入力メッセージを渡すとします。例えば、{ユーザー入力情報}{言語A}{言語B}翻訳するモデルを構築するためのテンプレートを用意する場合、次のコードが記述できます。

from langchain.prompts import (
    ChatPromptTemplate,
    PromptTemplate,
    SystemMessagePromptTemplate,
    AIMessagePromptTemplate,
    HumanMessagePromptTemplate,
)

from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)

from langchain.chat_models import ChatOpenAI


# ====================================================================================
# Chat Prompt Template作成
# ====================================================================================

# テンプレート(システム)
system_template = "あなたは {input_language}を{output_language}に翻訳してくれる優秀なアシスタントです。"

# テンプレート(人間)
human_template  = "{input_text}"

# プロンプト作成
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_message_prompt  = HumanMessagePromptTemplate.from_template(human_template)

# 上記テンプレートを統合しチャットプロンプトテンプレート作成
chat_prompt = ChatPromptTemplate.from_messages([
                     system_message_prompt, 
                     human_message_prompt
                    ])

出力イメージ

# 出力
print("Chat Prompt Template:")
print(chat_prompt)

# 出力イメージ
# Chat Prompt Template:
# input_variables=['output_language', 'input_language', 'input_text'] 
# output_parser=None partial_variables={} 
# messages=[
#   SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input_language', 'output_language'], output_parser=None, partial_variables={}, 
#   template='あなたは {input_language}を{output_language}に翻訳してくれる優秀なアシスタントです。', template_format='f-string', validate_template=True), additional_kwargs={}), 
#   HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input_text'], output_parser=None, partial_variables={}, 
#   template='{input_text}', template_format='f-string', validate_template=True), additional_kwargs={})]

【参考】LangChainスキーマ

langchain.schemaからインポートしたAIMessage/HumanMessage/SystemMesssageを用いると、チャットモデルに対して役割を指定できます。各種役割の意味は以下になります。

役割概要
System「system」は、チャットモデル自体を表します。モデルの動作を制御するプログラムやデータベースを担当する役割です。一般的に、ユーザーがチャットモデルを利用する際に「system」が自動的に動作して、応答や情報の提供を行います。
Human「Human」は、チャットモデルを利用するユーザーを表します。チャットモデルを使って質問をしたり、回答を受け取ったりする役割を持ちます。ユーザーはチャットモデルに対して、自分の質問や疑問を投げかけることができます。
AI「AI」は、チャットモデルのアシスタント役を担当します。ユーザーがモデルに対して質問を投げかけた場合に、より詳細な回答を提供するために活躍します。「AI」は、モデルが持つ知識や情報から、ユーザーにとって有益な情報を提供することができます。

チャットモデル作成

OpenAIのAPIを用いてチャットモデルを作成します。以下のコードを実行しましょう。

# ====================================================================================
# チャットモデル作成
# ====================================================================================

chat_model = ChatOpenAI(
                model_name  = 'gpt-3.5-turbo',  # OpenAI社のモデル名
                temperature = 0.5,              # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
                n           = 1,                # いくつの返答を生成するか
                )

Chat Prompt Templateを用いたチャットモデル実行

Chat Prompt Templateを用いてチャットモデルを実行します。

コード

# ====================================================================================
# Prompt Templateを適用しチャットモデル実行
# ====================================================================================

# チャットプロンプトテンプレートにフォーマット適用
chat_prompt_format = chat_prompt.format_prompt(
                              input_language  = "日本語", 
                              output_language = "英語", 
                              input_text      = "好きな食べ物はお肉です。"
                         ).to_messages()


# チャットモデルにPrompt Templateを指定
response = chat_model(chat_prompt_format)

出力イメージ

# 出力
print("Input:")
print(chat_prompt_format)
print("Response:")
print(response.content)

# 出力イメージ
# Input:
# [SystemMessage(content='あなたは 日本語を英語に翻訳してくれる優秀なアシスタントです。', additional_kwargs={}), 
#  HumanMessage(content='好きな食べ物はお肉です。', additional_kwargs={}, example=False)]

# Response:
# My favorite food is meat.

Chat Prompt Templateを用いた言語モデル実装コードまとめ

ここまで紹介したコードをまとめて掲載します。

import openai
import os
from langchain.prompts import (
    ChatPromptTemplate,
    PromptTemplate,
    SystemMessagePromptTemplate,
    AIMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)
from langchain.chat_models import ChatOpenAI

# ====================================================================================
# API認証情報
# ====================================================================================

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

# ====================================================================================
# Chat Prompt Template作成
# ====================================================================================

# テンプレート(システム)
system_template = "あなたは {input_language}を{output_language}に翻訳してくれる優秀なアシスタントです。"

# テンプレート(人間)
human_template  = "{input_text}"

# プロンプト作成
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_message_prompt  = HumanMessagePromptTemplate.from_template(human_template)

# 上記テンプレートを統合しチャットプロンプトテンプレート作成
chat_prompt = ChatPromptTemplate.from_messages([
                     system_message_prompt, 
                     human_message_prompt
                    ])

# ====================================================================================
# チャットモデル作成
# ====================================================================================

chat_model = ChatOpenAI(
                model_name  = 'gpt-3.5-turbo',  # OpenAI社のモデル名
                temperature = 0.5,              # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
                n           = 1,                # いくつの返答を生成するか
                )

# ====================================================================================
# Prompt Templateを適用しチャットモデル実行
# ====================================================================================

# チャットプロンプトテンプレートにフォーマット適用
chat_prompt_format = chat_prompt.format_prompt(
                              input_language  = "日本語", 
                              output_language = "英語", 
                              input_text      = "好きな食べ物はお肉です。"
                         ).to_messages()


# チャットモデルにPrompt Templateを指定
response = chat_model(chat_prompt_format)

# ====================================================================================
# 出力
# ====================================================================================
print("Input:")
print(chat_prompt_format)
print("Response:")
print(response.content)

【Python】LangChain Prompts|ExampleSelectorsの実装方法

Example Selectorsとは、特定の文脈において、特定の種類の例文を適切に選択するための機能です。「教師データ」とセットでこの機能は活用されます。

Example Selectorsを用いる場合、プロンプトテンプレートにはFewShot Prompt Templateがよく用いられます。こちらの使い方も併せて言及します。

Pythonライブラリのインストール

OpenAI社のサイトから取得したシークレットキーを指定し、以下コードをプログラム先頭に配置しましょう。

import openai
import os

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

Example Selectorクラスの作成

Example Selectorには、LangChainのBaseEampleSelectorを継承したCustomExampleSelectorクラスを用いた例を示します。

コード

CustomExampleSelectorクラスは、教師データexamplesを入力とし、教師データを追加する関数add_exampleおよび教師データを選択するための関数select_examplesから構成されます。

from langchain.prompts.example_selector.base import BaseExampleSelector
from langchain import PromptTemplate, FewShotPromptTemplate
from langchain.llms import OpenAI
from typing import Dict, List
import numpy as np

# ====================================================================================
# Custom Example Selectorのクラス作成
# ====================================================================================

# BaseExampleSelectorを継承して教師データの選択
class CustomExampleSelector(BaseExampleSelector):
    
    def __init__(self, examples: List[Dict[str, str]]):
        self.examples = examples
    
    # 教師データを追加する関数
    def add_example(self, example: Dict[str, str]) -> None:
        self.examples.append(example)

    # 教師データを選択するための関数
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        return np.random.choice(self.examples, size=2, replace=False)
    
# ====================================================================================
# CustomExampleSelectorに教師データを登録
# ====================================================================================

# 教師ありリスト
examples = [
            {"country": "Japan",   "capital": "Tokyo"},
            {"country": "France",  "capital": "Paris"},
            {"country": "UK",      "capital": "London"},
           ]

# CustomExampleSelectorに教師リストを登録
example_selector = CustomExampleSelector(examples)

出力イメージ

# 教師ありリストを出力
print(example_selector.examples)

# 出力イメージ
# [{'country': 'Japan', 'capital': 'Tokyo'}, {'country': 'France', 'capital': 'Paris'}, 
#  {'country': 'UK', 'capital': 'London'}]

Prompt Templateの作成

教師データを解釈するためのPrompt Template(example_prompt_template)を作成します。

# ====================================================================================
# Prompt Templateを作成
# ====================================================================================

# 教師ありリストをフォーマットするためにテンプレートに指定
example_template = \
            """
            国名: {country} 首都: {capital}
            """

# 教師ありリストを解釈するプロンプトテンプレート
example_prompt_template = PromptTemplate(
                        input_variables   = ["country", "capital"],  # 入力変数 
                        template          = example_template,        # テンプレート
                        validate_template = True,                    # 入力変数とテンプレートの検証有無
                        )

Few Shot Prompt Templateの作成

FewShot Prompt Templateとは、LLMのプロンプト表示方法に加え、「教師データをどのようなフォーマットで学習させるのか」も指定したテンプレートです。

コード

FewShotPromptTempateは、インプットに前述で作成した教師データを解釈するためのexample_prompt_templateCustomExampleSelectorを渡すことで作成できます。

# ====================================================================================
# FewShotPromptTemplateの作成
# ====================================================================================

# プロンプト内の教師ありリストの前に配置する接頭辞|命令文を指定
prefix = "入力した国の首都を教えて"

# プロンプト内の教師ありリストの前に配置する接尾辞通常|ユーザーの入力を指定
suffix = "国名: {input} \n 首都: "

# FewShotPromptTemplateオブジェクト
few_shot_prompt = FewShotPromptTemplate(
        example_selector  = example_selector,         # Example Selectorを指定
        example_prompt    = example_prompt_template,  # 教師ありリストを解釈するプロンプトテンプレート
        prefix            = prefix,                   # プロンプト内の教師ありリストの前に配置する接頭辞
        suffix            = suffix,                   # プロンプト内の教師ありリストの前に配置する接尾辞通常、ユーザーの入力が入る
        input_variables   = ["input"],                # 入力変数 
        example_separator = "\n",                     # 接頭辞、教師ありリスト、接尾辞の結合に使用する文字列
)

出力イメージ

# 出力
print(few_shot_prompt)

# 出力イメージ
# input_variables=['input'] output_parser=None partial_variables={} 
# examples=[{'country': 'Japan', 'capital': 'Tokyo'}, {'country': 'France', 'capital': 'Paris'}, {'country': 'UK', 'capital': 'London'}] 
# example_selector=None 
# example_prompt=PromptTemplate(
#     input_variables=['country', 'capital'], 
#     output_parser=None, 
#     partial_variables={}, 
#     template='\n            国名: {country} 首都: {capital}\n            ', 
#     template_format='f-string', 
#     validate_template=True) 
# suffix='国名: {input} \n 首都: ' 
# example_separator='\n' 
# prefix='入力した国の首都を教えて' 
# template_format='f-string' 
# validate_template=True

モデル作成(LLM)

OpenAIのAPIを用いてLLMを作成します。以下のコードを実行しましょう。

# ====================================================================================
# LLMオブジェクト作成
# ===================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

FewShot Prompt Templateを用いたLLM実行

FewShot Prompt Templateを用いてLLMを実行します。

コード

# ====================================================================================
# FewShot Prompt Templateを適用しLLM実行
# ====================================================================================

# FewShotPromptTemplateにフォーマット適用
prompt_format = few_shot_prompt.format(input="アメリカ")

# LLMにPrompt Templateを指定
response = LLM(prompt_format)

出力イメージ

# 出力
print("Input:")
print(prompt_format)
print("Response:")
print(response)

# 出力イメージ
# Input:
#   入力した国の首都を教えて
#   国名: アメリカ 
#   首都: 

# Response:
#   ワシントンD.C.

ExampleSelectorsを用いた言語モデルの実装コードまとめ

ここまで紹介したコードをまとめて掲載します。

import openai
import os
from langchain.prompts.example_selector.base import BaseExampleSelector
from langchain import PromptTemplate, FewShotPromptTemplate
from langchain.llms import OpenAI
from typing import Dict, List
import numpy as np

# ====================================================================================
# API認証情報
# ====================================================================================

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

# ====================================================================================
# Custom Example Selectorのクラス作成
# ====================================================================================

# BaseExampleSelectorを継承して教師データの選択
class CustomExampleSelector(BaseExampleSelector):
    
    def __init__(self, examples: List[Dict[str, str]]):
        self.examples = examples
    
    # 教師データを追加する関数
    def add_example(self, example: Dict[str, str]) -> None:
        self.examples.append(example)

    # 教師データを選択するための関数
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        return np.random.choice(self.examples, size=2, replace=False)
    
# ====================================================================================
# CustomExampleSelectorに教師データを登録
# ====================================================================================

# 教師ありリスト
examples = [
            {"country": "Japan",   "capital": "Tokyo"},
            {"country": "France",  "capital": "Paris"},
            {"country": "UK",      "capital": "London"},
           ]

# CustomExampleSelectorに教師リストを登録
example_selector = CustomExampleSelector(examples)

# 教師ありリストを出力
print(example_selector.examples)

# ====================================================================================
# Prompt Templateを作成
# ====================================================================================


# 教師ありリストをフォーマットするためにテンプレートに指定
example_template = \
            """
            国名: {country} 首都: {capital}
            """

# 教師ありリストを解釈するプロンプトテンプレート
example_prompt_template = PromptTemplate(
                        input_variables   = ["country", "capital"],  # 入力変数 
                        template          = example_template,        # テンプレート
                        validate_template = True,                    # 入力変数とテンプレートの検証有無
                        )


# ====================================================================================
# FewShotPromptTemplateの作成
# ====================================================================================

# プロンプト内の教師ありリストの前に配置する接頭辞|命令文を指定
prefix = "入力した国の首都を教えて"

# プロンプト内の教師ありリストの前に配置する接尾辞通常|ユーザーの入力を指定
suffix = "国名: {input} \n 首都: "

# FewShotPromptTemplateオブジェクト
few_shot_prompt = FewShotPromptTemplate(
        example_selector  = example_selector,         # Example Selectorを指定
        example_prompt    = example_prompt_template,  # 教師ありリストを解釈するプロンプトテンプレート
        prefix            = prefix,                   # プロンプト内の教師ありリストの前に配置する接頭辞
        suffix            = suffix,                   # プロンプト内の教師ありリストの前に配置する接尾辞通常、ユーザーの入力が入る
        input_variables   = ["input"],                # 入力変数 
        example_separator = "\n",                     # 接頭辞、教師ありリスト、接尾辞の結合に使用する文字列
)


# ====================================================================================
# LLMオブジェクト作成
# ====================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

# ====================================================================================
# FewShot Prompt Templateを適用しLLM実行
# ====================================================================================

# FewShotPromptTemplateにフォーマット適用
prompt_format = few_shot_prompt.format(input="アメリカ")

# LLMにPrompt Templateを指定
response = LLM(prompt_format)

# ====================================================================================
# 出力
# ====================================================================================
print("Input:")
print(prompt_format)
print("Response:")
print(response)

【Python】LangChain Prompts|Output Persersの実装方法

Output Parsersとは、LLMの出力結果を構造化するのに役立つ機能です。

以下、Pythonを用いてLLMモデルを実行し、その出力結果をOutputPerserで構造化する方法を解説します。

Pythonライブラリのインストール

OpenAI社のサイトから取得したシークレットキーを指定し、以下コードをプログラム先頭に配置しましょう。

import openai
import os

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

Output Perserによる出力形式の指定

LLMモデルの出力結果を構造化するためのoutput_formatクラスを作成します。

コード

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List

# ====================================================================================
# 出力形式の定義
# ====================================================================================

# 出力形式を指定したクラス
class output_format(BaseModel):
    name:            str = Field(description = "国名")
    food_list: List[str] = Field(description = "国の美味しい料理名リスト")

# プロンプトテンプレートに挿入するためのPerser作成
parser = PydanticOutputParser(pydantic_object = output_format)

【参考】output_formatクラスの書き方

出力形式を構造化するクラスは、次のように記述します。

# 出力形式を指定したクラス
class output_format(BaseModel):
    <出力項目名>: <データ型> = Field(description = <項目概要>)
    <出力項目名>: <データ型> = Field(description = <項目概要>)
    <出力項目名>: <データ型> = Field(description = <項目概要>)
  ・・・

Prompt Templateの作成

LLMに渡すプロンプトテンプレートを作成します。

この時、引数にpartial_variablesを指定するようにします。

# ====================================================================================
# プロンプトテンプレート作成
# ====================================================================================

# テンプレート
template = "{query}\n\n{format_instructions}\n"


# プロンプトテンプレート
prompt_template = PromptTemplate(
                    input_variables   = ["query"],                      # 入力変数 
                    template          = template,                       # テンプレート
                    validate_template = True,                           # 入力変数とテンプレートの検証有無
                    partial_variables = {"format_instructions": parser.get_format_instructions()} # 出力形式
                       )

モデル作成(LLM)

OpenAIのAPIを用いてLLMを作成します。

# ====================================================================================
# LLMオブジェクト作成
# ===================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

LLM実行とOutputParsersによる出力結果の構造化

LLMを実行し、出力結果responseを取得します。さらに、その出力結果に対してparserを適用し、出力結果を構造化します。

コード

# ====================================================================================
# Prompt Templateを適用しLLM実行
# ====================================================================================

# プロンプトテンプレートにフォーマット適用
prompt_format = prompt_template.format_prompt(query="日本のおすすめ料理を教えて")

# 出力形式
response = LLM(prompt_format.to_string())
perser   = parser.parse(response)

出力イメージ

出力結果を見ると、output_formatクラスで指定した形式で出力結果が得られました。

# 出力
print("Output Perser:")
print(perser)

# 出力イメージ
# Output Perser:
# name='Japan' food_list=['Sushi', 'Tempura', 'Ramen', 'Sukiyaki', 'Yakitori', 'Udon', 'Sashimi']

OutputParsersを用いた言語モデル実装コードまとめ

ここまで紹介したPythonコードをまとめて記述します。

import openai
import os
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List

# ====================================================================================
# API認証情報
# ====================================================================================

# APIシークレットキーを記述
SECRET_KEY  = "............."

# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY

# ====================================================================================
# 出力形式の定義
# ====================================================================================

# 出力形式を指定したクラス
class output_format(BaseModel):
    name:            str = Field(description = "国名")
    food_list: List[str] = Field(description = "国の美味しい料理名リスト")

# プロンプトテンプレートに挿入するためのPerser作成
parser = PydanticOutputParser(pydantic_object = output_format)


# ====================================================================================
# プロンプトテンプレート作成
# ====================================================================================

# テンプレート
template = "{query}\n\n{format_instructions}\n"


# プロンプトテンプレート
prompt_template = PromptTemplate(
                    input_variables   = ["query"],                      # 入力変数 
                    template          = template,                       # テンプレート
                    validate_template = True,                           # 入力変数とテンプレートの検証有無
                    partial_variables = {"format_instructions": parser.get_format_instructions()} # 出力形式
                       )


# ====================================================================================
# OpenAIのGPT3.5モデル作成
# ====================================================================================

LLM = OpenAI(
            model_name        = "text-davinci-003", # OpenAIモデル名
            temperature       = 0,                  # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
            n                 = 1,                  # いくつの返答を生成するか           
            )

# ====================================================================================
# Prompt Templateを適用しLLM実行
# ====================================================================================

# プロンプトテンプレートにフォーマット適用
prompt_format = prompt_template.format_prompt(query="日本のおすすめ料理を教えて")

# 出力形式
response = LLM(prompt_format.to_string())
perser   = parser.parse(response)

print("Output Perser:")
print(perser)

【参考】PythonによるLLM実装|ChatGPT・LangChain

本記事では、PythonでLLMを構築し、様々なタスクをこなす機能の実装方法を多数解説しています。

Python × ChatGPT関連記事

【あわせて読みたい】

Python × LangChain関連記事

【あわせて読みたい】

自然言語処理の学習におすすめの書籍

あわせて読みたい
自然言語処理(NLP)学習におすすめ入門本・動画教材8選|Pythonによる機械学習・ディープラーニング向け... 「自然言語処理の概要とそれを実装するPythonプログラミング手法を学びたい」「機械学習・AIを組み合わせたモデル開発手法を知りたい」このような要望にお答えします。

自然言語処理の概要について詳しく学びたい方向けに、厳選したおすすめの学習教材を紹介しています。

最後に

この記事が気に入ったら
フォローしてね!

目次