ジェネラティブエージェンツの大嶋です。
この記事では、LangChainのChatPromptTemplateでSystemMessage・HumanMessageのプレースホルダーが置換されない理由と対応方法を紹介します。
ChatPromptTemplateの基本的な使い方
LangChainのChatPromptTemplateを使用すると、プロンプトのテンプレートを扱うことができます。
以下のコードでは{lang}
と{message}
の箇所がプレースホルダーとして扱われ、prompt.invoke
とするとその箇所が置き換えられます。
from langchain_core.prompts import ChatPromptTemplate prompt = ChatPromptTemplate.from_messages( [ ("system", "Speak in {lang}."), ("human", "{message}"), ], ) prompt_value = prompt.invoke({"lang": "日本語", "message": "こんにちは"}) print(prompt_value.to_string())
上記のコードの実行結果は次のようになります。
System: Speak in 日本語. Human: こんにちは
想定通り動作しないコード
ここで、ChatPromptTemplate.from_messagesにSystemMessageやHumanMessageを使用してみます。
from langchain_core.messages import HumanMessage, SystemMessage from langchain_core.prompts import ChatPromptTemplate prompt = ChatPromptTemplate.from_messages( [ SystemMessage("Speak in {lang}."), HumanMessage("{message}"), ], ) prompt_value = prompt.invoke({"lang": "日本語", "message": "こんにちは"}) print(prompt_value.to_string())
上記のコードの実行結果は次のようになります。
System: Speak in {lang}. Human: {message}
この例では、{lang}
と{message}
の箇所が置換されていません。
この原因を一言で言うと、SystemMessageやHumanMessageのようなBaseMessageを継承したクラスは、テンプレートではなくメッセージを表すためです。
SystemMessagePromptTemplate・HumanMessagePromptTemplate
実はLangChainには、SystemMessageやHumanMessageのテンプレート版であるSystemMessagePromptTemplate・HumanMessagePromptTemplateといったクラスがあります。
ChatPromptTemplateにSystemMessagePromptTemplateやHumanMessagePromptTemplateを与えると、想定通り動作します。
from langchain_core.prompts import ChatPromptTemplate from langchain_core.prompts.chat import ( HumanMessagePromptTemplate, SystemMessagePromptTemplate, ) prompt = ChatPromptTemplate.from_messages( [ SystemMessagePromptTemplate.from_template("Speak in {lang}."), HumanMessagePromptTemplate.from_template("{message}"), ], ) prompt_value = prompt.invoke({"lang": "日本語", "message": "こんにちは"}) print(prompt_value.to_string())
上記のコードの実行結果は次のようになります。
System: Speak in 日本語. Human: こんにちは
実は("system", "Speak in {lang}.")
はSystemMessagePromptTemplate.from_template("Speak in {lang}.")
と同じ意味なのです。
SystemMessageやHumanMessageを使ってプレースホルダーが置換されずに困っているときは、最初の例のように("system", "Speak in {lang}.")
や("human", "{message}")
のような書き方をすれば解決ということです。
まとめ
以上、LangChainのChatPromptTemplateでSystemMessage・HumanMessageのプレースホルダーが置換されない理由と対応方法を紹介しました。
この動作で困っている方の参考になれば幸いです。
なお、この記事のコードはGoogle Colab上のlangchain-core==0.3.45で動作確認しました。
参考)ソースコードの該当箇所
LangChainのソースコードの該当箇所が気になる方は、以下のあたりを参照してみてください。