🦜️🔗LangChain : モジュール : モデル I/O – プロンプト : プロンプトテンプレート : Few-shot プロンプトテンプレート / チャットモデル用 Few-shot サンプル (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 08/23/2023
* 本ページは、LangChain の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
- Modules : Model I/O – Prompts : Prompt templates : Few-shot prompt templates
- Modules : Model I/O – Prompts : Prompt templates : Few shot examples for chat models
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
🦜️🔗 LangChain : モジュール : モデル I/O – プロンプト : プロンプトテンプレート : Few-shot プロンプトテンプレート
このチュートリアルでは、few ショットサンプルを使用するプロンプトテンプレートを作成する方法を学習します。few ショット・プロンプトテンプレートはサンプルのセットか、Example Selector オブジェクトのいずれかから構築できます。
ユースケース
このチュートリアルでは、self-ask with search のために few ショットサンプルを configure します。
サンプルセットの使用
サンプルセットの作成
始めるには、few ショットサンプルのリストを作成します。各サンプルは、キーが入力変数で値はそれらの入力変数用の値を持つ辞書である必要があります。
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
examples = [
{
"question": "Who lived longer, Muhammad Ali or Alan Turing?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
"""
},
{
"question": "When was the founder of craigslist born?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
"""
},
{
"question": "Who was the maternal grandfather of George Washington?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
"""
},
{
"question": "Are both the directors of Jaws and Casino Royale from the same country?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
"""
}
]
few ショットサンプル用の formatter の作成
few ショットサンプルを文字列に整形する formatter を構成します。この formatter は PromptTemplate オブジェクトである必要があります。
example_prompt = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
print(example_prompt.format(**examples[0]))
Question: Who lived longer, Muhammad Ali or Alan Turing? Are follow up questions needed here: Yes. Follow up: How old was Muhammad Ali when he died? Intermediate answer: Muhammad Ali was 74 years old when he died. Follow up: How old was Alan Turing when he died? Intermediate answer: Alan Turing was 41 years old when he died. So the final answer is: Muhammad Ali
サンプルと formatter を FewShotPromptTemplate に供給する
最後に、FewShotPromptTemplate オブジェクトを作成します。このオブジェクトは few ショットサンプルと few ショットサンプル用の formatter を受け取ります。
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"]
)
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
Question: Who lived longer, Muhammad Ali or Alan Turing? Are follow up questions needed here: Yes. Follow up: How old was Muhammad Ali when he died? Intermediate answer: Muhammad Ali was 74 years old when he died. Follow up: How old was Alan Turing when he died? Intermediate answer: Alan Turing was 41 years old when he died. So the final answer is: Muhammad Ali Question: When was the founder of craigslist born? Are follow up questions needed here: Yes. Follow up: Who was the founder of craigslist? Intermediate answer: Craigslist was founded by Craig Newmark. Follow up: When was Craig Newmark born? Intermediate answer: Craig Newmark was born on December 6, 1952. So the final answer is: December 6, 1952 Question: Who was the maternal grandfather of George Washington? Are follow up questions needed here: Yes. Follow up: Who was the mother of George Washington? Intermediate answer: The mother of George Washington was Mary Ball Washington. Follow up: Who was the father of Mary Ball Washington? Intermediate answer: The father of Mary Ball Washington was Joseph Ball. So the final answer is: Joseph Ball Question: Are both the directors of Jaws and Casino Royale from the same country? Are follow up questions needed here: Yes. Follow up: Who is the director of Jaws? Intermediate Answer: The director of Jaws is Steven Spielberg. Follow up: Where is Steven Spielberg from? Intermediate Answer: The United States. Follow up: Who is the director of Casino Royale? Intermediate Answer: The director of Casino Royale is Martin Campbell. Follow up: Where is Martin Campbell from? Intermediate Answer: New Zealand. So the final answer is: No Question: Who was the father of Mary Ball Washington?
example selector の使用
サンプルを ExampleSelector に供給する
前のセクションのサンプルセットと formatter を再利用します。ただし、サンプルを FewShotPromptTemplate オブジェクトに直接供給する代わりに、それらを ExampleSelector オブジェクトに供給します。
このチュートリアルでは、SemanticSimilarityExampleSelector クラスを使用します。このクラスは入力への類似度に基づいて few ショットサンプルを選択します。それは入力と few ショットサンプル間の類似度を計算するために埋め込みモデルを使用し、最近傍検索を実行するためにベクトルストアを使用します。
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples(
# This is the list of examples available to select from.
examples,
# This is the embedding class used to produce embeddings which are used to measure semantic similarity.
OpenAIEmbeddings(),
# This is the VectorStore class that is used to store the embeddings and do a similarity search over.
Chroma,
# This is the number of examples to produce.
k=1
)
# Select the most similar example to the input.
question = "Who was the father of Mary Ball Washington?"
selected_examples = example_selector.select_examples({"question": question})
print(f"Examples most similar to the input: {question}")
for example in selected_examples:
print("\n")
for k, v in example.items():
print(f"{k}: {v}")
Running Chroma using direct local API. Using DuckDB in-memory for database. Data will be transient. Examples most similar to the input: Who was the father of Mary Ball Washington? question: Who was the maternal grandfather of George Washington? answer: Are follow up questions needed here: Yes. Follow up: Who was the mother of George Washington? Intermediate answer: The mother of George Washington was Mary Ball Washington. Follow up: Who was the father of Mary Ball Washington? Intermediate answer: The father of Mary Ball Washington was Joseph Ball. So the final answer is: Joseph Ball
example selector を FewShotPromptTemplate に供給する
最後に、FewShotPromptTemplate オブジェクトを作成します。このオブジェクトは example selector と few ショットサンプル用の formatter を受け取ります。
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"]
)
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
Question: Who was the maternal grandfather of George Washington? Are follow up questions needed here: Yes. Follow up: Who was the mother of George Washington? Intermediate answer: The mother of George Washington was Mary Ball Washington. Follow up: Who was the father of Mary Ball Washington? Intermediate answer: The father of Mary Ball Washington was Joseph Ball. So the final answer is: Joseph Ball Question: Who was the father of Mary Ball Washington?
🦜️🔗 LangChain : モジュール : モデル I/O – プロンプト : プロンプトテンプレート : チャットモデル用 Few-shot サンプル
このノートブックはチャットモデルで few shot サンプルを使用する方法をカバーします。few shot プロンプティングを行なうベストな方法の確かな意見の一致はないようで、最適なプロンプトの編集 (compilation) はモデルにより様々である傾向があります。このため、柔軟な開始点として FewShotChatMessagePromptTemplate のような few-shot プロンプト・テンプレートを提供し、そしてそれらを貴方が良いと思うように修正や置換することができます。
few-shot プロンプトテンプレートの目標は入力に基づいて動的にサンプルを選択し、そしてサンプルをモデルに提供する最終的なプロンプトに整形することです。
Note : 以下のコードサンプルはチャットモデル用です。補完モデル (LLM) 用の同様の few-shot プロンプトサンプルについては、few-shot プロンプトテンプレート ガイドをご覧ください。
固定 (fixed) サンプル
最も基本的な (そして一般的な) few-shot プロンプティング・テクニックは固定プロンプト・サンプルを使用することです。この方法でチェインを選択し、それを評価し、そしてプロダクションにおいて追加の可動部分について心配する必要がなくなります。
テンプレートの基本的なコンポーネントは :
- examples: 最終的なプロンプトに含める辞書サンプルのリスト。
- example_prompt: 各サンプルを format_messages メソッドを使用して 1 つまたはそれ以上のメッセージに変換します。一般的な例は各サンプルを一つのヒューマンメッセージと一つの AI メッセージレスポンス、または関数呼び出しメッセージが続くヒューマンメッセージに変換することです。
以下は単純なデモです。最初に、このサンプルのためにモジュールをインポートします :
from langchain.prompts import (
FewShotChatMessagePromptTemplate,
ChatPromptTemplate,
)
API リファレンス
- FewShotChatMessagePromptTemplate from langchain.prompts
- ChatPromptTemplate from langchain.prompts
それから、含めたいサンプルを定義します。
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
]
次に、それらを few-shot プロンプトテンプレートに集めます。
# This is a prompt template used to format each individual example.
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}"),
("ai", "{output}"),
]
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
print(few_shot_prompt.format())
Human: 2+2 AI: 4 Human: 2+3 AI: 5
最後に、最終的なプロンプトを組み立ててそれをモデルで使用します。
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are wonderous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
from langchain.chat_models import ChatAnthropic
chain = final_prompt | ChatAnthropic(temperature=0.0)
chain.invoke({"input": "What's the square of a triangle?"})
API リファレンス :
- ChatAnthropic from langchain.chat_models
AIMessage(content=' Triangles do not have a "square". A square refers to a shape with 4 equal sides and 4 right angles. Triangles have 3 sides and 3 angles.\n\nThe area of a triangle can be calculated using the formula:\n\nA = 1/2 * b * h\n\nWhere:\n\nA is the area \nb is the base (the length of one of the sides)\nh is the height (the length from the base to the opposite vertex)\n\nSo the area depends on the specific dimensions of the triangle. There is no single "square of a triangle". The area can vary greatly depending on the base and height measurements.', additional_kwargs={}, example=False)
動的 Few-shot プロンプティング
入力に基づいてどのサンプルが示されるかを条件付けすることを望む場合があるかもしれません。このためには、サンプルを example_selector で置き換えることができます。他のコンポーネントは上記と同じままです!おさらいすると、動的 few-shot プロンプトテンプレートは以下のようなものです :
- example_selector: 与えられた入力に対して few-shot サンプル (そしてそれらが返される順序) の選択を担います。これらは BaseExampleSelector インターフェイスを実装します。一般的な例はベクトルストアに支援された SemanticSimilarityExampleSelector です。
- example_prompt: 各サンプルを format_messages により 1 つまたはそれ以上のメッセージに変換します。一般的な例は各サンプルを一つのヒューマンメッセージと一つの AI メッセージレスポンス、または関数呼び出しメッセージが続くヒューマンメッセージに変換することです。
これらは再度、最終的なプロンプトを集めるために他のメッセージとチャットテンプレートで構成することができます。
from langchain.prompts import SemanticSimilarityExampleSelector
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
API リファレンス :
- SemanticSimilarityExampleSelector from langchain.prompts
- OpenAIEmbeddings from langchain.embeddings
- Chroma from langchain.vectorstores
セマンティック類似度に基づいてサンプルを選択するためにベクトルストアを使用していますので、最初にストアにデータを投入 (populate) したいです。
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
{"input": "2+4", "output": "6"},
{"input": "What did the cow say to the moon?", "output": "nothing at all"},
{
"input": "Write me a poem about the moon",
"output": "One for the moon, and one for me, who are we to talk about the moon?",
},
]
to_vectorize = [" ".join(example.values()) for example in examples]
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_texts(to_vectorize, embeddings, metadatas=examples)
example_selector の作成
作成されたベクトルストアによって、example_selector を作成することができます。ここでは top 2 サンプルだけを取得するようにそれに指示します。
example_selector = SemanticSimilarityExampleSelector(
vectorstore=vectorstore,
k=2,
)
# The prompt template will load examples by passing the input do the `select_examples` method
example_selector.select_examples({"input": "horse"})
[{'input': 'What did the cow say to the moon?', 'output': 'nothing at all'}, {'input': '2+4', 'output': '6'}]
プロンプトテンプレートの作成
上記で作成された example_selector を使用して、プロンプトテンプレートを組み立てます。
from langchain.prompts import (
FewShotChatMessagePromptTemplate,
ChatPromptTemplate,
)
# Define the few-shot prompt.
few_shot_prompt = FewShotChatMessagePromptTemplate(
# The input variables select the values to pass to the example_selector
input_variables=["input"],
example_selector=example_selector,
# Define how each example will be formatted.
# In this case, each example will become 2 messages:
# 1 human, and 1 AI
example_prompt=ChatPromptTemplate.from_messages(
[("human", "{input}"), ("ai", "{output}")]
),
)
API Reference :
- FewShotChatMessagePromptTemplate from langchain.prompts
- ChatPromptTemplate from langchain.prompts
以下はこれがどのように組み立てられるかのサンプルです。
print(few_shot_prompt.format(input="What's 3+3?"))
Human: 2+3 AI: 5 Human: 2+2 AI: 4
Assemble the final prompt template:
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are wonderous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
print(few_shot_prompt.format(input="What's 3+3?"))
Human: 2+3 AI: 5 Human: 2+2 AI: 4
LLM で使用する
これで、モデルを few-shot プロンプトに接続できます。
from langchain.chat_models import ChatAnthropic
chain = final_prompt | ChatAnthropic(temperature=0.0)
chain.invoke({"input": "What's 3+3?"})
API Reference :
- ChatAnthropic from langchain.chat_models
AIMessage(content=' 3 + 3 = 6', additional_kwargs={}, example=False)
以上