見出し画像

[LangChain]これが欲しかったPartial prompt templatesを分かりやすく解説

今回はLangchainのPartial prompt templatesについて解説します。



1. はじめに

ChatGPTなどの大規模言語モデルを使用すると、様々なタイプのプロンプトを使用するため、適切な管理が求められると思います。
特に、一部の情報が固定されている一方で、他の部分が動的に変わる場面では、そのテキストの構造を効率的に管理する方法が求められます。「Partial prompt templates(直訳で"部分的なプロンプトテンプレート")」は、このようなニーズに応えるための強力なツールです。

「Partial prompt templates」は、テンプレートの一部に固定の値や関数による動的な値をあらかじめ設定し、残りの部分を後から入力するという方法を提供します。このアプローチにより、コードの再利用性が向上し、テキストの生成や編集が非常に柔軟に行えるようになります。

それでは、「Partial prompt templates」をマスターしていましょう。

2. 基本的な概念の理解

・通常のプロンプトテンプレートとは?

プロンプトの中には、既にほぼ文章が決まっており、一部だけ柔軟に入力したい場合があります。
例えば

〇〇君、元気かい?

のような定型文です。
その場合に名前の箇所を佐藤君やら鈴木君などに動的に変えられるのがプロンプトテンプレートです。
スクリプトだとこのように書きます。

from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template(
    "{name}君、元気かい?"
)
text = prompt_template.format(name="佐藤")
print(text)

佐藤君、元気かい?

もちろん、複数の文章を動的に変えることもできます。

from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template(
    "{name}君、{message}"
)
text = prompt_template.format(name="佐藤", message="調子はどうだい?")
print(text)

佐藤君、調子はどうだい?

・Partial prompt templatesの重要性

さて、上記のプロンプトテンプレートは、場合によって不便です。
動的な2つの文章のうち1つは決まったが、もう1つはこれからも毎回変わる文章の場合に、コードの可読性や再利用性が落ちてしまいます。
ユースケースを見ていきましょう。

3. 文字列による部分的なフォーマット

上記の例を利用しましょう。このようなスクリプトでしたね。

from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template(
    "{name}君、{message}"
)
text = prompt_template.format(name="佐藤", message="元気かい?")
print(text)

例えばチャットボットで、冒頭にユーザー名が設定されたとしましょう。
その場合、通常のプロンプトテンプレートではスクリプトはこのようになるかもしれません。

from langchain.prompts import PromptTemplate

def talk_user(username, message):
    prompt_template = PromptTemplate.from_template(
        "{name}君、{message}"
    )
    text = prompt_template.format(name=username, message=message)
    return text

name = "佐藤"
text = talk_user(name, "元気かい?")
print(text)

もし会話がこの先もずっと続いていったら、そのたびに

text = talk_user(name, 何らかのメッセージ")

のように、name変数を毎回渡し続けなければならないのでしょうか?
もし、このように片方の文章が固定された場合に、もう片方だけを今後入力すれば済むような形にしたい場合に、Partial prompt templatesは役立ちます。

from langchain.prompts import PromptTemplate

def create_user_template(username):
    prompt_template = PromptTemplate.from_template("{username}君、{message}")
    user_template = prompt_template.partial(username=username)
    return user_template

name = "佐藤"
user_template = create_user_template(name)
text = user_template.format(message="元気かい?")
print(text)

このように、
1, プロンプトテンプレートを用意する
2, その変数のpartial関数を呼び、固定された箇所を渡す
3, 戻り値として新しいテンプレートが取得できる
ので、
4, 新しいテンプレートに、まだ渡していない文章を渡す
というスクリプトを組むことで、再利用していくことが出来るようになります。
なので、

text1 = user_template.format(message="元気かい?")
text2 = user_template.format(message="そうか、残念だね")
text3 = user_template.format(message="飴いるかい?")
text4 = user_template.format(message="また明日頑張ろう!")

と、もうnameを渡す必要がなくなります。

4. 関数による部分的なフォーマット

おそらく、このセクションの方がより使い勝手の良さを分かって頂けるでしょう。
固定できる部分は、変数ではなく関数でも可能です。
例えば今回はある人に日時を教えるとしましょう。
その対象の人物は毎回変わるとします。
その場合、時間は常に変動するわけですが、コード上は同じようにすっきり書くことが出来るのです。

from datetime import datetime
from langchain.prompts import PromptTemplate

def _get_datetime():
    now = datetime.now()
    return now.strftime("%m/%d/%Y, %H:%M:%S")

def create_user_template():
    prompt_template = PromptTemplate.from_template("{username}君、今は{date}だよ")
    user_template = prompt_template.partial(date=_get_datetime)
    return user_template

user_template = create_user_template()
text1 = user_template.format(username="佐藤")
text2 = user_template.format(username="鈴木")
print(text1)
print(text2)

佐藤君、今は10/02/2023, 20:07:53だよ
鈴木君、今は10/02/2023, 20:07:53だよ

5. おわりに

「Partial prompt templates」は、残念ながら劇的な変化をもたらすわけではありません。
ただし、実際スクリプトを書いていくと、「この機能があったらもうちょっとコードがスッキリするのになぁ」という場面が必ずあります。
そういった際に間違いなく効果を発揮するでしょう。

この記事が気に入ったらサポートをしてみませんか?