LangChain (0.0.340) 公式ドキュメント 3: プロンプト - プロンプト テンプレートをカスタマイズし、リアルタイム機能または少数の例を使用してプロンプト テンプレートを作成します

記事ディレクトリ

LangChain は、ヒントの構築と使用を支援するいくつかのクラスと関数を提供します。

以下に一つずつ紹介していきます。

一、迅速なエンジニアリング

1.1 プロンプトエンジニアリングの概要

参考「Langchain を使用したプロンプト エンジニアリングと LLM」「大規模モデル開発の全体的なプロセス」 「

  転移学習以前の従来の機械学習では、さまざまなタスクを実行するためにさまざまなモデルに依存していました。たとえば、分類、固有表現認識 (NER)、質問応答 (QA)、およびその他の多くのタスクに個別のモデルが必要でした。
ここに画像の説明を挿入します

転移学習の前に、さまざまなタスクやユースケースでさまざまなモデルをトレーニングする必要があります。

  トランスフォーマーと転移学習の導入により、言語モデルをさまざまなタスクに適応させるために、ネットワークの末端 (ヘッド) で言語モデルを微調整するだけで済みます。
ここに画像の説明を挿入します
Transformer と転移学習の考え方により、モデルの「ヘッド」を切り替え、微調整を実行してさまざまなタスクを実行することで、事前トレーニングされた Transformer モデルの同じコア コンポーネントを再利用できます。

  今日では、このアプローチさえ時代遅れです。複数のアプリケーションをサポートするベース モデルとしての大規模言語モデル (LLM) の機能により、さまざまなタスクに対してさまざまなプロンプトを構築したり、プロンプト リンクの組み合わせを通じてビジネス ロジックを実装したり、微調整のために最後のいくつかのモデル レイヤーを変更したりすることさえ可能になります。必要な場合は、プロンプトエンジニアリングです。
ここに画像の説明を挿入します

同じラージ言語モデル (LLM) を使用して、プロンプト内の指示を変更するだけで多くのタスクを実行できます。

  従来の AI 開発では、まず非常に複雑なビジネス ロジックを順番に解体し、各サブビジネスのトレーニング データと検証データを構築し、各サブビジネスの最適化モデルをトレーニングし、最後に問題を解決するための完全なモデル リンクを形成する必要があります。ビジネスロジック全体。ただし、大規模なモデル開発では、一般的な大規模なモデルといくつかのビジネス プロンプトを使用することでタスクを解決できるため、従来のモデルのトレーニングとチューニングが、よりシンプルで簡単、低コストのプロンプトの設計とチューニングに変換されます。

  同時に、大規模モデル開発と従来のAI開発との間には、評価の考え方という点で質的な違いもあります。従来の AI 開発では、最初にトレーニング セット、テスト セット、検証セットを構築する必要があります。パフォーマンス評価は、トレーニング セットでモデルをトレーニングし、テスト セットでモデルを調整し、最後に検証セットでのモデルの効果を検証することによって達成されます。 。ただし、大規模なモデル開発はより機敏で柔軟です。通常、初期段階ではトレーニング セットと検証セットを明示的に決定しません。サブモデルをトレーニングする必要がなくなったため、トレーニング セットを構築するのではなく、直接構築します。実際のビジネスニーズに基づいた、小規模なバッチ検証セット、検証セットの効果を満たす合理的な迅速な設計。次に、ビジネス ロジックから現在のプロンプトの悪いケースを収集し続け、悪いケースを検証セットに追加し、的を絞った方法でプロンプトを最適化し、最終的により良い汎化効果を達成します。

1.2 プロンプトコンポーネント

  Langchain の PromptTemplate について詳しく説明する前に、プロンプトについてより深く理解する必要があります。通常、プロンプトはいくつかの部分で構成されます。
ここに画像の説明を挿入します

典型的なプロンプト構造

  すべてのプロンプトにこれらのコンポーネントが含まれているわけではありませんが、優れたプロンプトは通常、複数の部分で構成されています。

  • Instructions: 何をすべきか、外部情報 (提供されている場合) を使用する方法、クエリを処理する方法、出力を構造化する方法などをモデルに指示する命令。
  • External information or context(s): 外部情報またはコンテキスト。通常はモデルの追加知識のソースとして機能します。この部分は、ベクトル データベースの検索 (RAG、検索拡張の生成) やその他の手段 (API、計算など) などを通じて、手動でヒントに挿入できます。
  • User input:ユーザー入力
  • Output indicator: 出力インジケーターは、生成されるテキストの始まりを示します。

各コンポーネントは通常、次のような順序でプロンプトに配置されます。

prompt = """Answer the question based on the context below. If the
question cannot be answered using the information provided answer
with "I don't know".

Context: Large Language Models (LLMs) are the latest models used in NLP.
Their superior performance over smaller models has made them incredibly
useful for developers building NLP enabled applications. These models
can be accessed via Hugging Face's `transformers` library, via OpenAI
using the `openai` library, and via Cohere using the `cohere` library.

Question: Which libraries and model providers offer LLMs?

Answer: """

  以下では主に、langchain ライブラリのプロンプト テンプレートを使用してプロンプトを構築する方法について説明します。プロンプト プロジェクトでプロンプトを記述する原則やより複雑な例については、「」を参照してください。 LangChain: LLM アプリケーション開発 (パート 1) - モデル、プロンプト、パーサー、メモリ、チェーン》《ChatGLM 大規模モデル アプリケーションの構築& プロンプト プロジェクト》 「Andrew Ng と OpenAI の最新コース: 開発者向けプロンプト エンジニアリングの読書ノート」

二、プロンプトテンプレート

リファレンス ドキュメント《プロンプト テンプレート》

  プロンプトの再利用性を高めるため、通常はコンテキストやユーザー入力をハードコーディングせず、テンプレートを通じて入力します。 LangChain は、言語モデルのヒントを生成するための事前定義されたテンプレートを提供します。これらのテンプレートには、手順、いくつかの例、特定のタスクに関する特定のコンテキストと質問が含まれています。

  基本的に 2 つの異なるプロンプト テンプレートが使用可能です。文字列プロンプト テンプレートPromptTemplate とチャット プロンプト テンプレート< a i=3>ChatPromptTemplate 。前者は単純なプロンプトを文字列形式で提供し、後者はチャット API で使用するためのより構造化されたプロンプトを生成します。

2.1 langchain_core.prompts

langchain_core.prompts ドキュメントで導入されており、そのクラス階層は次のとおりです:

BasePromptTemplate --> PipelinePromptTemplate
                       StringPromptTemplate --> PromptTemplate
                                                FewShotPromptTemplate
                                                FewShotPromptWithTemplates
                       BaseChatPromptTemplate --> AutoGPTPrompt
                                                  ChatPromptTemplate --> AgentScratchPadChatPromptTemplate



BaseMessagePromptTemplate --> MessagesPlaceholder
                              BaseStringMessagePromptTemplate --> ChatMessagePromptTemplate
                                                                  HumanMessagePromptTemplate
                                                                  AIMessagePromptTemplate
                                                                  SystemMessagePromptTemplate

  まず見てみましょうBasePromptTemplate。これはすべてのプロンプト テンプレートの基本クラスであり、特定の形式でプロンプトを生成するために使用されます。このクラスはRunnableSerializable クラス (ジェネリック クラス、ジェネリック パラメータは Dict および PromptValue) および ABC クラス (抽象基本クラス、抽象基本クラス) には、次のパラメータが含まれます。

パラメータ タイプ 必須 説明する
input_types 辞書[str、任意] オプション 予期されるヒント テンプレート変数タイプの辞書。指定しない場合、すべての変数は文字列とみなされます。
input_variables リスト[文字列] 必須 予期されるプロンプト テンプレート変数の名前のリスト。
output_parser オプション[lBaseOutputParser] = なし オプション この書式設定ヒントを呼び出して LLM 出力を解析するために使用されるメソッド。
partial_variables マッピング[str, Union[str, Callable[[], str]]] オプション 値を生成するいくつかの変数またはコールバック関数の名前と型を含むディクショナリ マップ。

このクラスには次のメソッドも含まれています。

  1. 非同期メソッド:
    abatchainvokeastream などは、タスクを非同期に実行するために使用されます。これらのメソッドにはデフォルトの実装が提供されていますが、より効率的なバッチまたは非同期実行のためにサブクラスでオーバーライドできます。

  2. 設定関連のメソッド:

    • config_schemaこのメソッドは、構成の検証に使用される Pydantic モデルを返します。
    • configurable_fieldsこのメソッドは、構成可能なフィールドを持つシリアル化されたオブジェクトを返します。
  3. 入力および出力関連のメソッド:

    • get_input_schema メソッドと get_output_schema メソッドは、入力と出力を検証するための Pydantic モデルを返します。
    • invokeメソッドは、単一の入力を出力に変換するために使用されます。
  4. ストリーミング関連のメソッド:

    • astream_logこのメソッドは、内部実行ログやその他の情報を含む実行出力をストリーミングするために使用されます。
    • astream メソッドはastream_log メソッドのデフォルト実装です。
  5. その他の方法:

    • には、lc_idjsondict 待ってください。
  6. 属性:

    • には、入力タイプ、出力タイプを取得するために使用される InputTypeOutputTypeconfig_specs などの属性が含まれます。 、および構成仕様。
  7. クラスメソッド:

    • オブジェクトの解析、JSON 表現の生成、参照の更新などのためのクラス メソッドが含まれます。

  全体として、このクラスは、構成、入出力、非同期実行、その他の機能を処理するための一連のメソッドを提供する一般的なプロンプト テンプレート クラスです。このテンプレートを使用する必要がある場合は、このクラスを継承し、必要なメソッドを実装することで、特定のプロンプトの動作をカスタマイズできます。

  BaseMessagePromptTemplate は、メッセージ プロンプトの基本クラスである Serializable および ABC (抽象基本クラス) を継承します。 template 、新しいモデルを作成し、入力データを検証するために使用されます。

  1. クラス メソッド construct: キーワード引数の入力データを解析して検証することにより、新しいモデルを作成します。入力データを有効なモデルに解析できない場合にValidationError発生します。パラメータは _fields_set (オプションのフィールド セット) と **values (その他の値) で、新しいモデル インスタンスが返されます。

  2. クラス メソッド copy: モデルをコピーし、含めるフィールド、除外するフィールド、変更するフィールドを選択し、新しいモデル インスタンスを返します。

  3. クラス メソッド dict: モデルの辞書表現を生成します。オプションで特定のフィールドを含めたり除外したりできます。

  4. 抽象メソッド format_messages: キーワード引数からメッセージをフォーマットし、BaseMessage のリストを返す必要があります。

    • パラメータ:kwargs、書式設定に使用されるキーワード パラメータ。
    • 戻り値: BaseMessage のリスト。
  5. その他のクラスのメソッドと属性: 省略

2.2 プロンプトテンプレート

2.2.1 はじめに

  PromptTemplate を使用して、文字列プロンプトのテンプレートを作成します。デフォルトでは、PromptTemplate はテンプレート化に Python の str.format 構文を使用します。

  • Python f-string template:
from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template(
    "Tell me a {adjective} joke about {content}."
)
prompt_template.format(adjective="funny", content="chickens")
'Tell me a funny joke about chickens.'

テンプレートは、変数をサポートしない場合も含め、任意の数の変数をサポートします。

from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template("Tell me a joke")
prompt_template.format()
'Tell me a joke'

  PromptTemplate は、デフォルトで Python f-string をテンプレート形式として使用しますが、現在は jinja2 形式もサポートしています。 jinja2 は、template_format パラメータを通じて指定できます (「テンプレート形式」 を参照)。

  • jinja2 template:
from langchain.prompts import PromptTemplate

jinja2_template = "Tell me a {
    
    { adjective }} joke about {
    
    { content }}"
prompt = PromptTemplate.from_template(jinja2_template, template_format="jinja2")

prompt.format(adjective="funny", content="chickens")
# Output: Tell me a funny joke about chickens.
2.2.2 アイセル

  PromptTemplateChatPromptTemplate は、LangChain Expression Language (LCEL) の基本構成要素である Runnable インターフェイスを実装します。これは、invokeainvokestreamastream、< a i をサポートすることを意味します。 =6>、 など。 batchabatchastream_log

  PromptTemplate は辞書 (プロンプト変数) を受け入れ、StringPromptValue を返します。 ChatPromptTemplate 辞書を受け入れ、ChatPromptValue を返します。これらの値オブジェクトは、後で使用したり処理したりするためにさまざまな形式に変換できます。利便性が提供されます。

  StringPromptValue ドキュメントによると、StringPromptValue クラスは基本クラスPromptValue は文字列プロンプトの値を表し、次のメソッドがあります:

  • __init__メソッド: キーワード パラメーターに基づいて StringPromptValue インスタンスを構築するために使用されます。プロンプトのテキストを表すテキスト パラメーターが必要です。オプションの type パラメータもあります。デフォルトは「StringPromptValue」で、値のタイプを示します。入力データが不正な場合は、ValidationError がスローされます。
  • copyメソッド: モデルをコピーするためのメソッド。オプションで特定のフィールドを含めたり、除外したり、更新したりできます。 deep=True の場合、ディープコピーです。
  • dictメソッド: モデルを辞書に変換するメソッド。オプションで特定のフィールドを含めたり除外したりできます。
  • to_messagesメソッド: プロンプトの値をメッセージ リストに変換して返します。
  • to_stringメソッド: プロンプトの値を文字列に変換して返します。
prompt_val = prompt_template.invoke({
    
    "adjective": "funny", "content": "chickens"})

prompt_val     			  # 输出: StringPromptValue(text='Tell me a joke')
prompt_val.to_string()    # 输出:'Tell me a joke'
prompt_val.to_messages()  # 输出:[HumanMessage(content='Tell me a joke')]
prompt_val.copy(update={
    
    "text": "Hello! How are you?"})  	# 输出:StringPromptValue(text='Hello! How are you?')
prompt.dict()  			  # 输出:{'text': 'Tell me a funny joke about chickens.'}
prompt.json()   		  # 输出:'{"text": "Tell me a funny joke about chickens."}'
prompt.json().to_json()
{
    
    'lc': 1,
 'type': 'constructor',
 'id': ['langchain', 'prompts', 'base', 'StringPromptValue'],
 'kwargs': {
    
    'text': 'Tell me a funny joke about chickens.'}}
2.2.3 入力検証を無効にする

参考《テンプレートの検証》

  PromptTemplate は、入力変数がテンプレートで定義されている変数と一致するかどうかをチェックして、テンプレート文字列を検証します。一致しない変数がある場合、ValueError例外がデフォルトで発生します。 validate_template=False を設定することでこの検証動作を無効にできるため、エラーはスローされなくなります。

template = "I am learning langchain because {reason}."

prompt_template = PromptTemplate(template=template,
                                 input_variables=["reason", "foo"]) 	# ValueError due to extra variables
prompt_template = PromptTemplate(template=template,
                                 input_variables=["reason", "foo"],
                                 validate_template=False) 				# No error

2.3 チャットプロンプトテンプレート

  以下は、Baidu Wenxin Yiyan を例として使用したデモンストレーションです。 Wenxinyiyan API を呼び出すには、まず Wenxinyiyan 呼び出しキーを取得する必要があります。まず、Wenxin Qianfan サービス プラットフォームに入り、登録してログインし、[アプリケーション アクセス] - [アプリケーションの作成] を選択する必要があります。次に、基本情報を入力し、デフォルト構成を選択して、アプリケーションを作成するだけです。

ここに画像の説明を挿入します

  作成後、アプリケーションの [詳細] をクリックして、このアプリケーションの AppID,API Key,Secret Key を表示します。次に、Baidu Intelligent Cloud Online Debugging Platform-Sample Code Center Quick Debugging Interface に移動して、AccessToken を取得します (混乱がある場合は、 < を参照してください)。 a i =4>API ドキュメント)。最後に、 (Linux) または (Windows cmd) を使用して、プロジェクト フォルダーに ファイルを作成し、その中に書き込みます。 :vim .envtype nul > .env.env

QIANFAN_AK="xxx"
QIANFAN_SK="xxx"
access_token="xxx"

これらの変数を以下の環境に設定すると、後で自動的に使用できるようになります。

# 使用openai、智谱ChatGLM、百度文心需要分别安装openai,zhipuai,qianfan
import os
import openai,zhipuai,qianfan
from langchain.llms import ChatGLM
from langchain.chat_models import ChatOpenAI,QianfanChatEndpoint

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key =os.environ['OPENAI_API_KEY']
zhipuai.api_key =os.environ['ZHIPUAI_API_KEY']
qianfan.qianfan_ak=os.environ['QIANFAN_AK']
qianfan.qianfan_sk=os.environ['QIANFAN_SK']
2.3.1 (ロール、コンテンツ) を使用して作成する

  ChatPromptTemplate は、チャット モデルのチャット メッセージ リストです。各チャット メッセージはコンテンツに関連付けられており、role(role) と呼ばれる追加パラメータがあります。たとえば、OpenAI Chat Completion API では、チャット メッセージを AI アシスタント、人間、またはシステムの役割に関連付けることができます。次のようなチャット プロンプト テンプレートを作成します:

from langchain.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful AI bot. Your name is {name}."),
        ("human", "Hello, how are you doing?"),
        ("ai", "I'm doing well, thanks!"),
        ("human", "{user_input}"),
    ]
)

messages = chat_template.format_messages(name="Bob", user_input="What is your name?")
messages
[SystemMessage(content='You are a helpful AI bot. Your name is Bob.'),
 HumanMessage(content='Hello, how are you doing?'),
 AIMessage(content="I'm doing well, thanks!"),
 HumanMessage(content='What is your name?')]
2.3.2 MessagePromptTemplate を使用して作成する

  ChatPromptTemplate.from_messages は、複数のメッセージ表現方法を受け入れます。たとえば、上記の (type, content) の 2 タプル表現を使用することに加えて、MessagePromptTemplate または BaseMessage のインスタンスを渡すこともできます。 , これにより、Baidu Qianfan を使用して以下に示すように、チャット プロンプトを作成する際に大きな柔軟性が得られます。

import os
import openai,qianfan

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key =os.environ['OPENAI_API_KEY']
qianfan.qianfan_ak=os.environ['QIANFAN_AK']
qianfan.qianfan_sk=os.environ['QIANFAN_SK']
  1. MessagePromptTemplate の使用
from langchain.chat_models import QianfanChatEndpoint
from langchain.prompts import HumanMessagePromptTemplate,SystemMessagePromptTemplate

template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

chat = QianfanChatEndpoint()
chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
AIMessage(content='编程是一项非常有趣和有挑战性的工作,我很羡慕你能够享受其中的乐趣。', additional_kwargs={'id': 'as-cxezsmtfga', 'object': 'chat.completion', 'created': 1701520678, 'result': '编程是一项非常有趣和有挑战性的工作,我很羡慕你能够享受其中的乐趣。', 'is_truncated': False, 'need_clear_history': False, 'usage': {'prompt_tokens': 4, 'completion_tokens': 18, 'total_tokens': 22}})
  1. BaseMessageの使用例
from langchain.schema.messages import SystemMessage

chat_template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(
            content=(
                "You are a helpful assistant that re-writes the user's text to "
                "sound more upbeat."
            )
        ),
        HumanMessagePromptTemplate.from_template("{text}"),
    ]
)


chat(chat_template.format_messages(text="i dont like eating tasty things."))
AIMessage(content='很抱歉听到您不喜欢吃美味的食物。您有其他喜欢的食物类型吗?或许我们可以找到一些其他您喜欢吃的食物,您试试看是否能够喜欢呢?', additional_kwargs={
    
    'id': 'as-sdcbpxad11', 'object': 'chat.completion', 'created': 1701520841, 'result': '很抱歉听到您不喜欢吃美味的食物。您有其他喜欢的食物类型吗?或许我们可以找到一些其他您喜欢吃的食物,您试试看是否能够喜欢呢?', 'is_truncated': False, 'need_clear_history': False, 'usage': {
    
    'prompt_tokens': 8, 'completion_tokens': 34, 'total_tokens': 42}})
2.3.3 MessagePromptTemplate のカスタマイズ

参考《MessagePromptTemplate の種類》

  チャット モデルの基礎となる実装は LLM ですが、「テキスト入力、テキスト出力」API は使用せず、入出力インターフェイスとして「チャット メッセージ」を使用します。つまり、チャット モデルは元のテキストの代わりにメッセージ (< a i=1> ) に表示されます。 langchain では、メッセージ インターフェイスは BaseMessage によって定義されます。BaseMessage には次の 2 つの必須属性があります。List[BaseMessage]

  • content: メッセージの内容。通常は文字列です。
  • role: メッセージ ソース (BaseMessage) のエンティティ カテゴリ。次のようなものです。
    • HumanMessage: 人間/ユーザーからの BaseMessage。
    • AIMessage: AI/アシスタントからのBaseMessage。
    • SystemMessage: システムからの BaseMessage。
    • FunctionMessage/ToolMessage: 関数またはツール呼び出しの出力を含む BaseMessage。
    • ChatMessage: 上記のロールがどれも適切でない場合は、ロールをカスタマイズできます。
    • メッセージは、 str ( HumanMessage に自動的に変換されます) および PromptValue (PromptTemplate の値) にすることもできます。

  同様に、LangChain はさまざまなタイプの MessagePromptTemplate を提供します。最も一般的に使用されるのは、AIMessagePromptTemplateSystemMessagePromptTemplate および です。 HumanMessagePromptTemplate: AI メッセージ、システム メッセージ、ユーザー メッセージをそれぞれ作成します。

2.3.3.1 カスタムメッセージロール名

  チャット メッセージを取得するロールを作成する場合は、ChatMessagePromptTemplate を使用できます。これにより、ユーザーはロール名を指定できます。

from langchain.prompts import ChatMessagePromptTemplate

prompt = "May the {subject} be with you"

chat_message_prompt = ChatMessagePromptTemplate.from_template(role="Jedi", template=prompt)
chat_message_prompt.format(subject="force")
ChatMessage(content='May the force be with you', additional_kwargs={}, role='Jedi')
2.3.3.2 カスタムメッセージ

  LangChain は、フォーマット中に表示されるメッセージを完全に制御できる MessagesPlaceholder も提供します。これは、メッセージ プロンプト テンプレートでどのような役割を使用する必要があるかわからない場合、または書式設定中にメッセージ リストを挿入したい場合に便利です。

from langchain.prompts import MessagesPlaceholder

human_prompt = "Summarize our conversation so far in {word_count} words."
human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)

chat_prompt = ChatPromptTemplate.from_messages([MessagesPlaceholder(variable_name="conversation"), human_message_template])
human_message = HumanMessage(content="What is the best way to learn programming?")
ai_message = AIMessage(content="""\
1. Choose a programming language: Decide on a programming language that you want to learn.

2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures.

3. Practice, practice, practice: The best way to learn programming is through hands-on experience\
""")

chat_prompt.format_prompt(conversation=[human_message, ai_message], word_count="10").to_messages()
[HumanMessage(content='What is the best way to learn programming?', additional_kwargs={}),
 AIMessage(content='1. Choose a programming language: Decide on a programming language that you want to learn. \n\n2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures.\n\n3. Practice, practice, practice: The best way to learn programming is through hands-on experience', additional_kwargs={}),
 HumanMessage(content='Summarize our conversation so far in 10 words.', additional_kwargs={})]
2.3.4 LCEL

  ChatPromptTemplateLCEL もサポートされており、ChatPromptValue と StringPromptValue のメソッドは基本的に同じです。

chat_val = chat_template.invoke({
    
    "text": "i dont like eating tasty things."})
chat_val.to_messages()
[SystemMessage(content="You are a helpful assistant that re-writes the user's text to sound more upbeat."),
HumanMessage(content='i dont like eating tasty things.')]
chat_val.to_string()
 "System: You are a helpful assistant that re-writes the user's text to sound more upbeat.\nHuman: i dont like eating tasty things."
2.3.5 chat_prompt 出力の 3 つのフォーマット方法

参考《出力テンプレートのフォーマット》

chat_prompt.format メソッドの出力は、次の 3 つの形式で取得できます。

  • 文字列形式: chat_prompt.format() または chat_prompt.format_prompt().to_string() を呼び出して、書式設定された文字列を出力として直接取得します。
output = chat_prompt.format(input_language="English", output_language="French", text="I love programming.")
output
'System: You are a helpful assistant that translates English to French.\nHuman: I love programming.'
# or alternatively
output_2 = chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_string()

assert output == output_2
  • メッセージ リストの形式: chat_prompt.format_prompt().to_messages() を呼び出して、フォーマットされた出力に対応する一連のメッセージ オブジェクト リストを取得します。
chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages()
[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}),
 HumanMessage(content='I love programming.', additional_kwargs={})]
  • ChatPromptValue オブジェクト フォーム: chat_prompt.format_prompt() を直接呼び出して、フォーマットされた出力情報をカプセル化する ChatPromptValue オブジェクトを取得します。
chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.")
ChatPromptValue(messages=[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}), HumanMessage(content='I love programming.', additional_kwargs={})])

3. プロンプトテンプレートをカスタマイズする

リファレンス ドキュメント《カスタム プロンプト テンプレート》

  LangChain は、さまざまなタスクのプロンプトを生成するためのデフォルトのプロンプト テンプレートのセットを提供します。ただし、言語モデルの特定の動的ディレクティブを含むカスタム テンプレートを作成する場合など、デフォルトのテンプレートが特定のニーズを満たさない場合があります。このセクションでは、PromptTemplate を使用してカスタム プロンプトを作成する方法を紹介します。

  カスタム文字列プロンプト テンプレートを作成するには、次の 2 つの要件を満たす必要があります。

  • には、テンプレートに必要な入力変数を示す input_variables 属性が必要です。
  • は、予期される に対応するキーワード引数を受け取り、書式設定されたプロンプトを返す format メソッドを定義する必要があります。 input_variables

  例: 関数名を入力として受け取るカスタム プロンプト テンプレートを作成します。これにより、関数のソース コードを提供するようにプロンプ​​トがフォーマットされます。まず、名前に基づいて関数のソース コードを返す関数を作成する必要があります。

import inspect

def get_source_code(function_name):
    # Get the source code of the function
    return inspect.getsource(function_name)

inspectこれはPythonの組み込みモジュールであり、ソースコードやその他の情報を取得するために使用されます。

  次に、関数名を入力として受け入れ、関数のソース コードを提供するようにプロンプ​​トをフォーマットするカスタム プロンプト テンプレートを作成します。さらに、データ モデルの作成と入力の検証のために、BaseModel クラスとバリデーター デコレーターを pydantic モジュールからインポートします。

from langchain.prompts import StringPromptTemplate
from pydantic import BaseModel,validator

# 根据给定的函数名称和源代码,生成一个关于函数的英语解释
PROMPT = """\
Given the function name and source code, generate an English language explanation of the function.
Function Name: {function_name}
Source Code:
{source_code}
Explanation:
"""

class FunctionExplainerPromptTemplate(StringPromptTemplate, BaseModel):
    """一个自定义的提示模板,接受函数名称作为输入,并格式化提示模板以提供函数的源代码。"""

    @validator("input_variables")		# 使用 validator 装饰器定义了一个用于验证输入变量的方法。
    def validate_input_variables(cls, v):
        """定义了验证输入变量的方法,确保只有一个名为 function_name 的输入变量。"""
        if len(v) != 1 or "function_name" not in v:
            raise ValueError("function_name 必须是唯一的输入变量。")
        return v

    def format(self, **kwargs) -> str:
        # 获取函数的源代码
        source_code = get_source_code(kwargs["function_name"])

        # 生成要发送到语言模型的提示
        prompt = PROMPT.format(
            function_name=kwargs["function_name"].__name__, source_code=source_code
        )
        return prompt

    def _prompt_type(self):
        return "function-explainer"
  • プロンプト テンプレート FunctionExplainerPromptTemplate をカスタマイズします。これは、関数名を入力変数として受け入れ、検査モジュールを通じて関数のソース コードを取得し、そのソース コードをプロンプト テキストに埋め込みます。

  • プロンプト テンプレートはStringPromptTemplate と pydantic のBaseModelを継承し、後者は入力検証機能を提供します

  • @validator("input_variables"): これは pydantic バリデータ デコレータです。この機能は、input_variables 属性の値を確認することです。コードが input_variables に値を割り当てると、検証が自動的にトリガーされます。

  • validate_input_variablesメソッド: input_variables の検証ロジックを定義します。

    • cls パラメーターは、現在のプロンプト テンプレート クラス自体を表し、クラス レベルのメソッドでクラス自体にアクセスするために使用されます。このメソッドはクラス メソッドとして定義されているため (@classmethod デコレーターを使用)、その最初のパラメーターはインスタンス自体 (self) ではなくクラス自体です。
    • v パラメータは、検証する input_variables 属性の値を表します。
  • format メソッドは、関数名とソース コードを含む最終的なプロンプト テキストを生成します (関数 func の場合、func.__name__ は関数の名前を文字列として取得できます。つまり、< /a >func.__name__=“func” )

  • _prompt_typeメソッドはプロンプト タイプの文字列識別子を返します

これで、このプロンプト テンプレートを使用できるようになります。

fn_explainer = FunctionExplainerPromptTemplate(input_variables=["function_name"])

# 根据"get_source_code"函数生成提示
prompt = fn_explainer.format(function_name=get_source_code)
prompt
Given the function name and source code, generate an English language explanation of the function.
Function Name: get_source_code
Source Code:
def get_source_code(function_name):
    # Get the source code of the function
    return inspect.getsource(function_name)

Explanation:
  • インスタンス fn_explainer を作成するとき、input_variables の値はコンストラクター パラメーター ["function_name"] を通じて渡されます。これは、FunctionExplainerPromptTemplate クラス メソッド validate_input_variables の v パラメーターに対応します。
  • format メソッド シグネチャは def format(self, **kwargs) -> str: です。**kwargs は、任意の数のキーワード パラメータを受け入れることができることを意味します。これを行うことの利点は次のとおりです。
    • 柔軟性: 呼び出し元は、数や名前に制限がなく、必要な数のパラメーターを渡すことができます。
    • デカップリング: コード内部フォーマットは特定の外部パラメーターに依存しません。外部パラメータが変更された場合でも、内部実装は kwargs を通じて必要なパラメータにアクセスするだけでよいため、内部実装には影響しません。

たとえば、プロンプトの関数の説明を生成するために、後で新しいパラメーターの説明を追加する必要がある場合があります。 **kwargs を使用する場合、呼び出し側で必要なのは次のことだけです。

prompt = fn_explainer.format(
  function_name=get_source_code,
  description="utility function"
)

フォーマットの内部コードを変更する必要はありません。厳密なパラメーター署名の場合、新しいパラメーターは形式を変更する必要があり、これが大きな問題となります。

4. フィーチャー ストアのリアルタイム機能を使用してテンプレートを作成する

参考《Feature Store への接続》

4.1 フィーチャー ストアとは何ですか?

参考《Feature Storeとは何ですか?》

4.1.1 フィーチャー ストアの概要

  実際に機械学習システムを運用環境に導入する際、チームは、正しい生データの取得、機能の構築、機能のトレーニング データへの結合、運用環境での機能の計算と提供、環境での運用特性の監視に関連する複数のデータの課題に直面します。 Feature Store は、データ エンジニアリング作業の重複を減らし、機械学習のライフサイクルを加速し、チーム間のコラボレーションを促進することにより、組織に複数のメリットをもたらします。
ここに画像の説明を挿入します

  フィーチャ ストレージの中核機能は、フィーチャ データを一元的に保存および管理するための、フィーチャ データの効率的で信頼性の高い集中管理プラットフォームを提供することです。フィーチャー ストアには次の特徴があります。

  • フィーチャ データの一元管理: フィーチャ ストアにフィーチャが登録されると、さまざまなチームやモデルがこれらのフィーチャを共有して再利用できるため、データ エンジニアリング作業の重複が削減され、データの安全性も確保されます。一貫性と信頼性。

  • データのバージョン管理と追跡: フィーチャ データのバージョン管理、データの変更と更新履歴の記録が可能になります。これは、データの進化の追跡、実験の複製、モデルのパフォーマンスの変化の監視に役立ちます。

  • トレーニング データとサービス データの間の一貫性を実現する: モデルのトレーニングに使用される特徴定義は、オンライン サービスで提供される特徴と正確に一致する必要があります。そうでない場合、トレーニング サービスのバイアスが導入されます。 , これにより、モデルのパフォーマンスに致命的なデバッグが困難な問題が発生する可能性があります。

  • フィーチャのリアルタイム: 運用環境では、モデルで使用されるフィーチャ データが最新で関連性のあるものであることを確認することが重要です。フィーチャー ストアは、モデルが推論中に正確なデータを使用できるように、データのリアルタイム性と一貫性を保証するメカニズムを提供します。

  • 特徴エンジニアリング: 特徴ストアは通常、データの前処理と特徴エンジニアリング機能を統合して、特徴の計算、バックフィル、ロギングを自動化します。新しい機械学習プロジェクトで、フィルタリングされた実稼働対応の機能ライブラリを使用できるようにします。
    ここに画像の説明を挿入します

4.1.2 フィーチャーストアの構成

  最新の機能ストレージには、変換、ストレージ、提供、監視、機能レジストリという 5 つの主要コンポーネントがあります。
ここに画像の説明を挿入します

  1. 変換: データの処理と特徴値の生成を担当します。バッチ処理、ストリーミング処理、オンデマンド処理をサポートします。コードを再利用し、トレーニング サービス データの偏りを回避します。

  2. ストレージ: モデルのトレーニングを容易にするために履歴データ用のオフライン ストレージを提供し、低遅延の機能サービス用にオンライン ストレージを提供します。通常はデータ レイクまたはデータベースと統合されます。エンティティ中心のデータ モデルを使用します。

  3. 提供: 高性能 API を通じてフィーチャ データをリアルタイムで提供します。バイアスを避けるために、トレーニングとサービスでは一貫した機能ビューが使用されていることを確認します。モデルトレーニングのための SDK を介したアクセスをサポートします。

  4. モニタリング: データの品質や一貫性などの問題を検出して、システムの正常な動作を保証します。複数の指標を集約して相関付けることで、根本原因の特定を容易にすることができます。

  5. レジストリ: 機能定義とメタデータを一元管理します。機能変換、ストレージ、サービスなどを構成およびスケジュールします。他のシステムと統合するためのインターフェイスを提供します。追跡可能なソースと依存関係、監査のサポート。

4.2 祝宴

参考《Feature Store への接続》feast Github祝祭文档

  LLM アプリケーションを作成する場合、パーソナライズされたユーザー エクスペリエンスが非常に重要です。フィーチャー ストレージの中心的な概念は、データを最新かつ関連性の高いものに保つことです。これは、実際の運用環境で大規模言語モデル (LLM) を適用するのに特に適しています。 LangChain は、LLM でこのデータを使用する簡単な方法を提供します。

  Feast は、人気のあるオープンソースの機能ストレージ フレームワークです。詳しい手順については、Feast のドキュメントをご覧ください。 Feast の README の指示に従ってすでにセットアップと準備が完了していることを前提としています。次に、カスタマイズされたプロンプト テンプレート クラスを使用して、Feast によって提供される機能データをプロンプト テキスト生成ロジックに挿入し、最後にリアルタイム機能を統合するプロンプト コンテンツを出力する方法を示します。

from feast import FeatureStore

# You may need to update the path depending on where you stored it
feast_repo_path = "../../../../../my_feature_repo/feature_repo/"
# 初始化连接到 Feast 特征存储(Feature Store)。
store = FeatureStore(repo_path=feast_repo_path)

  FeatureStoreこれは、フィーチャ ストレージにアクセスするために Feast によって提供されるクライアント クラスです。初期化時に、事前に構築された Feast フィーチャ ライブラリ ストレージ パスをローカルに指す repo_path パラメータを指定する必要があります。これにより、リモート ストレージ内のフィーチャ データにアクセスできるようになります。ストアインスタンス。

  次に、カスタム FeastPromptTemplate を作成します。このプロンプト テンプレートは driver id を取得し、統計を検索し、それらの統計をプロンプト メッセージにフォーマットします。

  このプロンプト テンプレートへの入力は driver id のみであることに注意してください。これは、これがユーザー定義される唯一の部分であるためです (他のすべての変数はプロンプト テンプレート内で検索されます)。

from langchain.prompts import PromptTemplate, StringPromptTemplate

template = """Given the driver's up to date stats, write them note relaying those stats to them.
If they have a conversation rate above .5, give them a compliment. Otherwise, make a silly joke about chickens at the end to make them feel better

Here are the drivers stats:
Conversation rate: {conv_rate}
Acceptance rate: {acc_rate}
Average Daily Trips: {avg_daily_trips}

Your response:"""
prompt = PromptTemplate.from_template(template)

  このプロンプトは、最新のドライバー統計 (セッション率、受信率、1 日の平均乗車回数) を生成し、ドライバーに提供することを意味します。コンバージョン率が 0.5 を超えている場合は、褒めてください。そうでない場合は、メッセージの最後につまらないジョークを入れて相手の気分を良くしてください。

class FeastPromptTemplate(StringPromptTemplate):
	# **kwargs表示它可以接收任意多个关键字参数。
    def format(self, **kwargs) -> str:
        driver_id = kwargs.pop("driver_id")
        feature_vector = store.get_online_features(
            features=[
                "driver_hourly_stats:conv_rate",
                "driver_hourly_stats:acc_rate",
                "driver_hourly_stats:avg_daily_trips",
            ],
            entity_rows=[{
    
    "driver_id": driver_id}],
        ).to_dict()
        kwargs["conv_rate"] = feature_vector["conv_rate"][0]
        kwargs["acc_rate"] = feature_vector["acc_rate"][0]
        kwargs["avg_daily_trips"] = feature_vector["avg_daily_trips"][0]
        return prompt.format(**kwargs)
  • driver_id = kwargs.pop("driver_id"): kwargs ディクショナリから「driver_id」に対応する値を取得し、それを driver_id 変数に割り当てます。ポップ メソッドは、このキーと値のペアをディクショナリから削除します。この時点では、kwargs は空のディクショナリです。 。 driver_id は、このパラメータを単独で使用する必要があるため削除されますが、conv_rate などの他のパラメータは後続の prompt.format(**kwargs) メソッドに渡されます。
  • feature_vector = store.get_online_features(...):get_online_features メソッドはリアルタイム特徴を取得します。で:
    • feature: 取得する必要がある機能のリストです (「プロジェクト: 機能名」)
    • entity_rows:: エンティティ行リストをクエリします。
    • この段落は、ドライバー ID の機能リスト機能 (driver_id) 内の対応する機能データをクエリすることを意味します。
prompt_template = FeastPromptTemplate(input_variables=["driver_id"])
print(prompt_template.format(driver_id=1001))
Given the driver's up to date stats, write them note relaying those stats to them.
If they have a conversation rate above .5, give them a compliment. Otherwise, make a silly joke about chickens at the end to make them feel better

Here are the drivers stats:
Conversation rate: 0.4745151400566101
Acceptance rate: 0.055561766028404236
Average Daily Trips: 936

Your response:

パーソナライゼーションのために機能ストレージを活用するチェーンを作成できるようになりました。

from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI

chain = LLMChain(llm=ChatOpenAI(), prompt=prompt_template)
chain.run(1001)
 "Hi there! I wanted to update you on your current stats. Your acceptance rate is 0.055561766028404236 and your average daily trips are 936. While your conversation rate is currently 0.4745151400566101, I have no doubt that with a little extra effort, you'll be able to exceed that .5 mark! Keep up the great work! And remember, even chickens can't always cross the road, but they still give it their best shot."

5. いくつかの例を使用してプロンプト テンプレートを作成する

参考《数ショット プロンプト テンプレート》

  この章では、いくつかの例を用いてプロンプトテンプレートの作成方法を学びます。サンプルのないプロンプト テンプレートは、サンプルのセットまたはサンプル セレクター オブジェクトから構築できます。後者は、例セットから例セレクターを作成し、類似性検索を実行して例をフィルターする追加のステップにすぎません。

5.1 サンプルセットの使用

5.1.1 サンプルセットの作成

まず、例のセットを作成します。各例は、入力変数のキーと対応する値を含む辞書です。

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
"""
  }
]
5.1.2 サンプルフォーマッタの作成

  例を文字列にフォーマットするためのフォーマッタ(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
5.1.3 FewShotPromptTemplate の作成

サンプル セットとサンプル フォーマッタを受け取る FewShotPromptTemplate オブジェクトを作成します。

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?"))
  • suffixパラメータ: 入力質問の形式を指定します。具体的には、suffix="Question: {input}" は、いくつかの学習例の後に、「Question: 」という接頭辞と入力変数 {input} が存在することを意味します。

      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?
    

5.2 サンプルセレクターの使用

  サンプル セレクターの機能の 1 つは、クエリの長​​さに基づいて含めるサンプルの数を変更できることです。入力の最大長は制限されており、サンプルを動的に選択できるため、サンプルを動的に選択することが重要です。サンプルの数とヒントのサイズ、トークンの数などのバランスをとることを含む、少数ショット学習を実行するための適切な数のサンプル。サンプル セレクターを使用すると、これらの変数に基づいて、含まれるサンプルの数を変更できます。
con t e x t w i n d o w = in p u t t o k en s + o u t p u t t o k e n s context window=入力トークン + 出力トークン contex 2dow=putt<​​/span>sneko+outputt okens

  セレクターの例には多くの種類がありますが、一般的に使用されるものは次のとおりです。

  • SemanticSimilarityExampleSelector : 入力と例の間の類似性に基づいて k 個の例を選択します。具体的には、埋め込みモデルを使用して入力と少数の例の間の類似性を計算し、ベクトルストアを使用して最近傍検索を実行します。
  • LengthBasedExampleSelector: 入力長に基づいて使用するサンプルを選択します。入力が長い場合は選択される例が少なくなり、入力が短い場合はより多くの例が選択されます。
5.2.1 SemanticSimilarityExampleSelector

   SemanticSimilarityExampleSelector クラスは BaseExampleSelectorBaseModel を継承します。詳細は次のとおりです。

パラメータ タイプ 説明する
例のキー オプション[リスト[str]] 例としてキーのリストをフィルタリングするためのオプションのパラメータ。
入力キー オプション[リスト[str]] 入力キーリストをフィルタリングするためのオプションのパラメータ。指定した場合、検索はすべての変数ではなく入力変数に基づいて行われます。
k 整数 選択する例の数、デフォルトは 4 です。
ベクトルストア langchain_core.vectorstores.VectorStore [必須] サンプルに関する情報を含む VectorStore (必須)。
方法 説明する
init(example_keys、input_keys、k、vectorstore) キーワード引数の入力データを解析および検証して、新しいモデルを作成します。入力データを解析して有効なモデルにできない場合は、ValidationError が発生します。
add_example(例) 新しいサンプルを Vectorstore に追加します。
from_examples(例、埋め込み、vectorstore_cls、k、input_keys、**vectorstore_cls_kwargs) サンプル リストと埋め込みを使用して、k-shot サンプル セレクターを作成します。クエリの類似性に基づいて例を動的に並べ替えます。
select_examples(入力変数) 意味上の類似性に基づいて、使用する例を選択します。選択した例を含むリストを返します。
  1. サンプル セットに基づいて ExampleSelector を作成する

  まず、前のセクションのサンプル セットとフォーマッタを再利用しますが、今回はサンプルを FewShotPromptTemplate オブジェクトに直接供給するのではなく、まず ExampleSelector オブジェクトに供給して選択します。

  サンプル セレクターで定義する必要がある唯一のメソッドは select_examples です。これは、入力サンプルに基づいて選択されたサンプルのリストを返します。 長さで選択MMR で選択、できます。 N グラムの重複によって選択類似性によって選択

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 创建语义相似性示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    # 可供选择的示例列表。
    examples,
    # 用于生成嵌入的嵌入类,用于测量语义相似性。
    OpenAIEmbeddings(),
    # 用于存储嵌入并进行相似性搜索的VectorStore类。
    Chroma,
    # 要生成的示例数量。
    k=1
)

# 选择与输入最相似的示例。
question = "Who was the father of Mary Ball Washington?"
selected_examples = example_selector.select_examples({
    
    "question": question})
print(f"与输入最相似的示例:{
      
      question}")
for example in selected_examples:
    print("\n")
    for k, v in example.items():
        print(f"{
      
      k}: {
      
      v}") 				# 打印example键值对,即question,answer及其对应的值
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

Chroma はベクター ストアです。詳細については、「ベクター ストア」をご覧ください。

  1. FewShotPromptTemplate にサンプル セレクターを入力します

  最後に、4.1.3 と同様に、サンプル セレクタといくつかのサンプルのフォーマッタを受け入れる FewShotPromptTemplate オブジェクトを作成します。

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?
5.2.2 長さベースのExampleSelector
examples = [
    {
    
    
        "query": "How are you?",
        "answer": "I can't complain but sometimes I still do."
    }, {
    
    
        "query": "What time is it?",
        "answer": "It's time to get a watch."
    }, {
    
    
        "query": "What is the meaning of life?",
        "answer": "42"
    }, {
    
    
        "query": "What is the weather like today?",
        "answer": "Cloudy with a chance of memes."
    }, {
    
    
        "query": "What is your favorite movie?",
        "answer": "Terminator"
    }, {
    
    
        "query": "Who is your best friend?",
        "answer": "Siri. We have spirited debates about the meaning of life."
    }, {
    
    
        "query": "What should I do today?",
        "answer": "Stop talking to chatbots on the internet and go outside."
    }
]

LengthBasedExampleSelector を有効にします。

from langchain.prompts.example_selector import LengthBasedExampleSelector

example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=50  # this sets the max length that examples should be
)

max_length は、文字列をスペースと改行に分割することによって決定される単語の数として測定されます。正確なロジックは次のとおりです。

import re

some_text = "There are a total of 8 words here.\nPlus 6 here, totaling 14 words."
words = re.split('[\n ]', some_text)
print(words, len(words))
['There', 'are', 'a', 'total', 'of', '8', 'words', 'here.', 'Plus', '6', 'here,', 'totaling', '14', 'words.'] 14

example_selector を FewShotPromptTemplate に渡して、新しい動的プロンプト テンプレートを作成します。

# now create the few shot prompt template
dynamic_prompt_template = FewShotPromptTemplate(
    example_selector=example_selector,  # use example_selector instead of examples
    example_prompt=example_prompt,
    prefix=prefix,
    suffix=suffix,
    input_variables=["query"],
    example_separator="\n"
)

ここで、より短いクエリを渡すか、より長いクエリを渡すと、含まれる例の数に違いが見られるはずです。

print(dynamic_prompt_template.format(query="How do birds fly?"))
The following are exerpts from conversations with an AI
assistant. The assistant is typically sarcastic and witty, producing
creative  and funny responses to the users questions. Here are some
examples: 


User: How are you?
AI: I can't complain but sometimes I still do.


User: What time is it?
AI: It's time to get a watch.


User: What is the meaning of life?
AI: 42


User: What is the weather like today?
AI: Cloudy with a chance of memes.


User: How do birds fly?
AI: 
query = """If I am in America, and I want to call someone in another country, I'm
thinking maybe Europe, possibly western Europe like France, Germany, or the UK,
what is the best way to do that?"""

print(dynamic_prompt_template.format(query=query))
The following are exerpts from conversations with an AI
assistant. The assistant is typically sarcastic and witty, producing
creative  and funny responses to the users questions. Here are some
examples: 


User: How are you?
AI: I can't complain but sometimes I still do.


User: If I am in America, and I want to call someone in another country, I'm
thinking maybe Europe, possibly western Europe like France, Germany, or the UK,
what is the best way to do that?
AI: 

これにより、トークンの過剰使用や LLM の最大コンテキスト長の超過を制限することができます。

6. いくつかの例を使用して ChatPromptTemplate を作成します

  少数ショット プロンプトの目的は、FewShotChatMessagePromptTemplate を使用して、入力に基づいて関連サンプルを動的に選択し、これらのサンプルをモデルのプロンプトにフォーマットすることです。 これを達成できます。

6.1 サンプルセットの使用方法

最も基本的な少数のプロンプトは、固定プロンプトの例を使用することです。この方法は、運用環境では最も簡単で信頼性が高くなります。その基本コンポーネントは次のとおりです。

  • examples: 最終プロンプトに含める例 (辞書タイプ) のリスト
  • example_prompt: サンプルの format_messages メソッドを使用して、各サンプルを 1 つ以上のメッセージに変換します。たとえば、1 つのヒューマン メッセージと 1 つの AI メッセージ応答、またはヒューマン メッセージの後に関数呼び出しメッセージが続く (関数呼び出しメッセージが続く)。

以下のデモンストレーション。まずサンプルをインポートします。

from langchain.prompts import ChatPromptTemplate,FewShotChatMessagePromptTemplate

examples = [
    {
    
    "input": "2+2", "output": "4"},
    {
    
    "input": "2+3", "output": "5"},
]

FewShotChatMessagePromptTemplate を作成します。

# 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

作成した FewShotChatMessagePromptTemplate を呼び出します。

from langchain.chat_models import ChatAnthropic

final_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a wondrous wizard of math."),
        few_shot_prompt,
        ("human", "{input}"),
    ]
)

chain = final_prompt | ChatAnthropic(temperature=0.0)
chain.invoke({
    
    "input": "What's the square of a triangle?"})
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)

  最終的な推論プロンプトを構築するときは、最初にシステムの役割を設定し、次にいくつかのサンプル例を提供し、最後にユーザーの入力を渡してモデルに推論を実行させます。また、final_prompt はモデルにコンテキスト、例、入力を提供し、モデルが対象を絞った方法で応答を生成できるようにします。

6.2 サンプルセレクターの使用

  動的な少数ショット プロンプトの効果を得るために、入力に基づいて表示される例を制限したい場合があります。これを行うには、例を example_selector に置き換えます。他のコンポーネントは上記と同じです (つまり、example_selectorexample_prompt が含まれます)。

  まず、入力および出力のエンベディングを保存するベクトル ストア (vectorstore) を構築し、次にベクトルの類似性に基づいた動的なサンプル選択を実装します。

from langchain.embeddings import OpenAIEmbeddings
from langchain.prompts import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma

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を作成します。ここでは、最初の 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'}]

FewShotChatMessagePromptTemplate を作成します。

from langchain.prompts import ChatPromptTemplate,FewShotChatMessagePromptTemplate,


# 定义few-shot prompt.
few_shot_prompt = FewShotChatMessagePromptTemplate(
    # input variables选择要传递给示例选择器的值
    input_variables=["input"],
    example_selector=example_selector,
    # 定义每个示例的格式。在这种情况下,每个示例将变成 2 条消息:
    # 1 条来自人类,1 条来自 AI
    example_prompt=ChatPromptTemplate.from_messages(
        [("human", "{input}"), ("ai", "{output}")]
    ),
)

print(few_shot_prompt.format(input="What's 3+3?"))
Human: 2+3
AI: 5
Human: 2+2
AI: 4

最終的なプロンプト テンプレートを作成します。

final_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a wondrous 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
from langchain.chat_models import ChatAnthropic

chain = final_prompt | ChatAnthropic(temperature=0.0)
chain.invoke({
    
    "input": "What's 3+3?"})
AIMessage(content=' 3 + 3 = 6', additional_kwargs={}, example=False)

おすすめ

転載: blog.csdn.net/qq_56591814/article/details/134619031