こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!
- LangChain Promptsの機能である「Example Selector」について詳しく知りたい。
 - 大量のExamplesから適した例文のみを動的に選択し、プロンプトに埋め込む方法が知りたい。
 - 上記、Pythonでの実装方法が知りたい。
 
LangChainとは?

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

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

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

Example Selectorsとは、特定の文脈において、特定の種類の例文を適切に選択できるようにするための機能です。
Example Selectorは、言語モデルの出力に多数の例が想定される際に有効な機能です。
例えば、OpenAIが提供するGPTモデルの場合、GPTモデルで入出力できる最大トークン数が制限されています。プロンプトテンプレートに多数の例文を含めてしまうと、最大トークン数を超過してしまったり、出力できるトークン数の上限を小さくしなければならなくなります。
そこで検討されたのが、ユーザーが入力した文脈に対して適当な例文のみをプロンプトテンプレートに含めるという考えです。これをExample Selectorsを用いて実現し、特定の種類の例を優先したり、無関係な例を除外したり制御するのです。
LangChain Prompts
Example SelectorはLangChain Promptsの機能の1つとして実装されます。LangChain Promptsの仕組みについて詳しく知りたい方はこちらの記事をご覧ください。

【事前準備】Python環境構築・OpenAIのChatGPT API取得
PythonとLangChainを用いて、LangChain Promptsの利用方法を後述します。そのためにいくつか実施すべき事前準備があります。
Pythonライブラリのインストール
プログラム実装に際して、以下に示すライブラリが必要となります。ターミナル(MacOS)またはコマンドプロンプト(Windows)を通じて事前にインストールしておきましょう。
OpenAI
ChatGPTを代表とするOpenAI社のAPI利用に際して必要となるライブラリです。
pip install openaiLangChain
LangChainの利用に際して必要となるライブラリです。
pip install langchainfaiss-cpu
ベクトル変換されたテキストデータから目的の情報を抽出する際に役立つライブラリです。
pip install faiss-cpuChromaDB
ベクトル変換したデータを格納するためのライブラリです。
pip install chromadb【ChatGPT】OpenAI社のAPI発行

LangChain機能構築に際して、OpenAI社が提供するGPTモデルをAPI経由で呼び出す必要があります。
OpenAI社の公式サイトから「API シークレットキー」を事前に発行しておきましょう。なお、シークレットキーの発行方法はこちらの記事で詳しく解説しています。

【Python】LangChain Example Selectorを用いた例文プロンプト作成
LangChain Promptsの機能である Example Selectorを用いて、ユーザーの質問に類似した例文を選択し、プロンプトに埋め込む方法を解説します。
OpenAI API認証情報の設定
後述するプログラムは全てOpenAI社のAPI情報を利用します。
以下のPythonプログラムを先頭に配置し、OpenAI社のサイトから取得したシークレットキーを自身のものに書き換えましょう。
import openai
import os
# APIシークレットキーを記述
SECRET_KEY  = "............."
# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEYExampleリストの作成
後述するExample Selectorが参照するExampleリストを作成します。今回の例では、「国の首都」と「感情表現」という2つの異なる辞書型Exampleが含まれたリストを用意することとします。
# ========================================================================
# Example Selectorに渡す Exampleリスト作成
# ========================================================================
examples = [
    {"Question": "日本の首都は?",  "Answer": "東京"},      # ①首都に関するExample
    {"Question": "韓国の首都は?",  "Answer": "ソウル"},    # ①首都に関するExample
    {"Question": "好きの反対は?",  "Answer": "嫌い"},     # ②感情に関するExample
    {"Question": "嬉しいの反対は?","Answer": "悲しい"},    # ②感情に関するExample
]Example Prompt作成
後述するExample Selectorに渡すExample Promptを作成します。これはExampleリストをどのような形式で後述するFewShot PromptTemplateに埋め込むかを指示したテンプレートです。
前述のExampleリストで指定したキー(Question, Answer)を入力変数としたPromptTemplateとして次のように記述します。
from langchain.prompts import PromptTemplate
# ========================================================================
# Example Selectorに渡す Prompt Template作成
# ========================================================================
# テンプレート
template  = \
      """
        Q: {Question}
        A: {Answer}              
      """
# Example Selectorに渡すPrompt Template
example_prompt = PromptTemplate(
                    # ExamplesのKeyを入力変数として指定
                    input_variables = ["Question", "Answer"],      
                    # テンプレート
                    template        = template
                )Example Selector実装
今回メインとなるExample Selectorを作成します。ユーザー入力に対して適切なExampleを選択する際、その選択方法に応じていろんな書き方ができます。
今回は以下3種類のExample Selectorについて紹介します。お好みの1つを記述してみましょう。
| Example Selectors | 概要 | 
|---|---|
| MMR | 入力に対してコサイン類似度が高い類似例文を見つけ出し、すでに選択されている例文に近いかどうかをペナルティも与えながら、最終的な類似例文を選択する方法。 | 
| Select by n-gram overlap | どの例文が入力に最も類似しているかをngram overlap score(0.0 ~ 1.0)をもとに計算。Example Selectorには閾値を設定でき、scoreが閾値以下の例は除外する。デフォルトは閾値が -1.0 に設定されており、サンプルは除外されず並べ替えられるだけとなる。 | 
| Select by similarity | 入力に対してコサイン類似度が最も高い類似例文を選択する方法。 | 
Select by maximal marginal relevance (MMR)
from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# ========================================================================
# Example Selector作成
# ========================================================================
example_selector = MaxMarginalRelevanceExampleSelector.from_examples(
                    examples,             # Examplesリスト
                    OpenAIEmbeddings(),   # 類似度を計算するためにテキストをベクトル変換するモデル
                    FAISS,                # 入力とExamplesリストの類似度検索を行うための VectorStoreクラス
                    k=2,                  # 指定するExamplesの数
)Select by n-gram overlap
from langchain.prompts.example_selector.ngram_overlap import NGramOverlapExampleSelector
from langchain.embeddings import OpenAIEmbeddings
# ========================================================================
# Example Selector作成
# ========================================================================
example_selector = NGramOverlapExampleSelector(
                examples       = examples,             # Example Selectorのインスタンス
                example_prompt = example_prompt,       # Example Selectorのプロンプトテンプレート
                threshold      = -1.0,                 # 閾値
            )Select by similarity
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# ========================================================================
# Example Selector作成
# ========================================================================
example_selector = SemanticSimilarityExampleSelector.from_examples(
                    examples,             # Examplesリスト           
                    OpenAIEmbeddings(),   # 類似度を計算するためにテキストをベクトル変換するモデル 
                    Chroma,               # 入力とExamplesリストの類似度検索を行うための VectorStoreクラス
                    k=2,                  # 指定するExamplesの数
)FewShot Prompt Templateの作成
大規模言語モデル(LLM)が参照するプロンプトテンプレートFewshot PromptTemplateを作成します。
引数に前述で作成したExample SelectorとExample Promptを与えましょう。さらに、プロンプトメッセージ(prefix、suffix)およびユーザーから受け取る入力変数input_variablesも指定します。
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
# ========================================================================
# Examplesを含むFewShotPromptTemplate作成
# ========================================================================
fewshot_prompt_template = FewShotPromptTemplate(
            example_selector = example_selector,          # Example Selectorのインスタンス
            example_prompt   = example_prompt,            # Example Selectorのプロンプトテンプレート
            prefix=\
                """
                あなたは質問に回答するチャットボットです。
                以下の例を参考にし、質問に回答してください。
                """,
            suffix="質問: {user_question}\n回答:",         # 末尾
            input_variables=["user_question"],            # 入力変数
        )【稼働確認】入力値を与えてプロンプト生成
前述で作成したプロンプトに入力値を与え、実際にどのようなプロンプトが生成されるか確認してみましょう。
コード
# 入力値
user_question = "中国の首都は?"
prompt_format = fewshot_prompt_template.format(user_question=user_question)
# 生成したプロンプト
print("===============生成したプロンプト====================")
print(prompt_format)
print("==================================================")出力イメージ
上記コードにてuser_questionに国の首都を聞く質問を与えてみたところ、類似するExampleが指定されていることが確認できますね。
# ===============生成したプロンプト====================
#
# あなたは質問に回答するチャットボットです。
# 以下の例を参考にし、質問に回答してください。
#              
# Q: 日本の首都は?
# A: 東京              
#
# Q: 韓国の首都は?
# A: ソウル              
#
# 質問: 中国の首都は?
# 回答:
# ==================================================【稼働確認】LLM実行
作成したFewShot PromtTemplateを用いて実際にLLMを実行してみましょう!
コード
from langchain.llms import OpenAI
# ====================================================================================
# Prompt Templateを適用しLLM実行
# ====================================================================================
# 入力値
user_question = "中国の首都は?"
# LLMにPrompt Templateを指定
LLM      = OpenAI()
response = LLM(fewshot_prompt_template.format(user_question=user_question))出力イメージ
# 出力
print(response)
# 出力イメージ
# 北京【参考】PythonによるLLM実装|ChatGPT・LangChain

本記事では、PythonでLLMを構築し、様々なタスクをこなす機能の実装方法を多数解説しています。
Python × ChatGPT関連記事
Python × LangChain関連記事
自然言語処理の学習におすすめの書籍

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

お問い合わせフォーム
上記課題に向けてご気軽にご相談下さい。
お問い合わせはこちら



