LangChain

【Python】LangChain: PromptTemplateで柔軟にプロンプトを定義する

【Python】LangChain PromptTemplateで柔軟にプロンプトを定義する

Pythonで大規模言語モデル(LLM: Large Language Model)を活用する際に使用できるLangChainでPromptTemplateを使用する方法を解説します。

LangChainのPromptTemplate機能

LangChainは、大規模言語モデル(LLM: Large Language Model)を活用するためのオープンソースPythonライブラリです。LangChain自体の概要については「LangChainで大規模言語モデル(LLM)を活用する」で説明していますので参考にしてください。

LangChainは、LLMの複雑なタスクを実行するためのライブラリですが、構成要素としてPrompt(プロンプト)というものがあります。プロンプトは、モデルに対する入力であり、どのようなタスクを実行するべきかを指示するために使用されます。

PromptTemplateという機能を使用することで、変数を埋め込んだようなPrompt(プロンプト)を生成することができ、効率的なモデルへの指示が可能となります。この記事では、PromptTemplateの使用方法について紹介します。

この記事で紹介しているプログラムは以下のバージョンで動作確認しています。生成AIの分野は進歩が速いため、API等の変更により最新バージョンではプログラムがそのままでは動作しない可能性もありますので注意してください。

  • Python: 3.11.5
  • langchain: 0.2.11
  • langchain-core: 0.2.26
  • langchain-community: 0.2.10
  • langchain-openai: 0.1.16

PromptTemplate機能

PromptTemplateは、特定のプロンプトを生成するモジュールで、変数を中に埋め込むことができます。以下の簡単なプログラムで確認してみましょう。

基本的な使い方

PromptTemplateは、以下のように使用します。

from langchain_core.prompts import PromptTemplate

# テンプレート文字列を定義
template = "プログラミング言語{language}の{content}について教えてください。"

# from_templateメソッドを使用してPromptTemplateインスタンスを作成
prompt = PromptTemplate.from_template(template)

# PromptTemplateに具体的な値を埋め込む
formatted_prompt1 = prompt.format(language="Python", content="特徴")
formatted_prompt2 = prompt.format(language="Java", content="歴史")

# 表示
print(formatted_prompt1)
print(formatted_prompt2)
【実行結果】
プログラミング言語Pythonの特徴について教えてください。
プログラミング言語Javaの歴史について教えてください。

テンプレートを使用する際には、langchain_core.promptsからPromptTemplateをインポートして使用します。

テンプレート文字列を定義する際には、文字列の中に波括弧{}で変数を指定すると、この変数部分に値を埋め込むことができるようになります。文字列からテンプレートを作成する際には、from_templateメソッドを使用します。これによりテンプレートが作成されます。

実際に値を埋め込む際には、formatメソッドを通じて値を割り当てることができます。具体的にはprompt.format(language="Python", content="特徴")のように指定すると、生成されるプロンプトは「プログラミング言語Pythonの特徴について教えてください。」になります。

上記の例では、formatの呼び出し方を変えるだけで、対象プログラミング言語や、聞きたい内容を切り替えることができていることが分かるかと思います。

ChatPromptTemplate機能を使用する

PromptTemplateの種類として「ChatPromptTemplate」という対話用のテンプレートがあります。

通常のPromptTemplateは、単一のプロンプトを扱うものに対して、ChatPromptTemplateは、複数メッセージ(ユーザー、AI、システム等)の組み合わせを扱うことが可能となります。これにより対話形式のプロンプトをより簡単に構築できます。

ここでは、LangChainでOpenAIのモデルに対してChatPromptTemplateによる問い合わせを行う例を見てみましょう。OpenAIを使用するためには、キーを取得しておく必要があります。キーの取得は、OpenAI APIの使い方の基本の中でも紹介しているので参考にしてください。

キーは、環境変数を使用する場合とプログラム中に記載する方法がありますが、今回はコンフィグファイルに記載しておいて読み込み使用することにします。コンフィグファイルとして、以下のようなconfig.iniをPythonプログラムと同フォルダに格納して実行してください。xxxxの部分には、OpenAIから取得したキーを設定してください。

[OPENAI]
key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

以下がChatPromptTemplateを使用する例です。

import configparser

from langchain_core.prompts import (
    AIMessagePromptTemplate,
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
    SystemMessagePromptTemplate,
)
from langchain_openai import ChatOpenAI

# コンフィグファイルからキーを取得する
config = configparser.ConfigParser()
config.read("config.ini")

# モデルを初期化する
model = ChatOpenAI(
    openai_api_key=config["OPENAI"]["key"],
    model="gpt-3.5-turbo",
)

# ChatPromtTemplateを生成する
prompt_template = ChatPromptTemplate.from_messages(
    [
        SystemMessagePromptTemplate.from_template(
            "あなたは優秀な{language}プログラマです。ユーザーをサポートしてください。"
        ),
        AIMessagePromptTemplate.from_template(
            "こんにちは{name}さん。何か質問があればお気軽にどうぞ。"
        ),
        HumanMessagePromptTemplate.from_template(
            "プログラミング言語:{language}の{user_input}について教えてください。"
        ),
    ]
)

# ChatPromptTemplateに文字列を埋め込んでみる
chat_sample = prompt_template.format_prompt(
    language="Python", name="Ichiro", user_input="概要"
)
print(chat_sample.to_messages())
print("==========")

# OpenAIのモデルにChatPromptTemplateを使って問い合わせする
response = model.generate(
    [
        prompt_template.format_prompt(
            language="Python", name="Taro", user_input="特徴"
        ).to_messages(),
        prompt_template.format_prompt(
            language="Java", name="Yoko", user_input="歴史"
        ).to_messages(),
    ]
)
# 結果を表示する
print(response.generations[0][0].text)
print("==========")
print(response.generations[1][0].text)
【実行結果】
[SystemMessage(content='あなたは優秀なPythonプログラマです。ユーザーをサポートしてください。'), AIMessage(content='こんにちはIchiroさん。何か質問があればお気軽にどうぞ。'), HumanMessage(content='プログラミング言語:Pythonの概要について教えてください。')]
==========
Pythonの特徴は以下の通りです:

1. **シンプルで読みやすい構文**:Pythonはシンプルで読みやすい構文を特徴としており、初心者にも親しまれています。

2. **豊富な標準ライブラリ**:Pythonには豊富な標準ライブラリが用意されており、さまざまな用途に使える便利な機能が揃っています。

3. **オブジェクト指向言語**:Pythonはオブジェクト指向言語であり、クラスやオブジェクト指向の機能をサポートしています。

4. **動的型付け**:Pythonは動的型付け言語であり、変数の型を宣言せずに使用できます。

5. **豊富なサードパーティライブラリ**:Pythonには豊富なサードパーティライブラリが存在し、さまざまな用途に使えるパッケージが提供されています。

6. **クロスプラットフォーム**:Pythonはクロスプラットフォームであり、Windows、Mac、Linuxなどさまざまな環境で実行することができます。

これらの特徴を活かして、Pythonを使って効率的にプログラミングを行うことができます。
==========
Javaの歴史についてご説明しますね。

Javaは1995年にサン・マイクロシステムズ(現在のオラクル)によって開発されました。当初、Javaはオーク言語(Oak)として知られていましたが、後にJavaと改名されました。

Javaは最初、組み込みシステム向けのプログラミング言語として開発されましたが、その後インターネットの普及と共にWebアプリケーション開発にも利用されるようになりました。Javaはプラットフォームに依存しない(Write Once, Run Anywhere)特性を持ち、異なるプラットフォーム上で同じJavaコードを実行できるため、広く普及しました。

Javaの主要な特徴として、オブジェクト指向言語であること、ガベージコレクションによるメモリ管理、豊富な標準ライブラリなどが挙げられます。現在でもJavaは広く利用されており、エンタープライズアプリケーションやモバイルアプリケーションの開発など、さまざまな分野で活躍しています。

今回はいくつかのテンプレートをインポートしています。ChatPromptTemplateが会話の流れを定義するために使いたいテンプレートです。

ChatPromptTamplateの中の会話の流れを作成する際に、HumanMessagePromptTemplateはユーザー、AIMessagePromptTemplateはAI、SystemMessagePromptTemplateはシステムのテンプレートとして会話を定義するために使用しています。

ChatPromptTemplateを作成するにはfrom_messagesメソッドにリストで会話の流れを指定します。今回の例では以下の流れを指定しています。

  1. Systemに「"あなたは優秀な{language}プログラマです。ユーザーをサポートしてください。"」というような役割を指示します。
  2. AIが「"こんにちは{name}さん。何か質問があればお気軽にどうぞ。"」というような問いかけをしてきています。
  3. ユーザーの質問として「"プログラミング言語:{language}の{user_input}について教えてください。"」を実行しています。

このような一連の会話の流れをChatPromptTemplateで定義できます。具体的な埋め込みをする際には、format_promtメソッドにキーワード引数の書き方で「chat_sample = prompt_template.format_prompt(language="Python", name="Ichiro", user_input="概要")」のように埋め込みを行います。to_messagesメソッドを使うことで埋め込んだ会話の流れをリストで確認することが可能です。

このような一連の流れの会話をOpenAIのモデルに渡して結果を確認してみましょう。ChatOpenAIgenerateメソッドにChatPromptTemplateで生成したメッセージを流し込んでいます。その際には、テンプレートに指定する値を変えて異なる2つの種類の問い合わせを行っています。

  • language="Python", name="Taro", user_input="特徴"
  • language="Java", name="Yoko", user_input="歴史"

レスポンスには、それぞれの質問の回答結果が返ってきています。回答としてちゃんと「Pythonの特徴」についての回答と「Javaの歴史」についての回答が返ってきていることが分かるかと思います。

このように決まった流れの会話を値を変えて実行させたい場合に、PromptTemplateは非常に便利な機能となります。

まとめ

Pythonで大規模言語モデル(LLM: Large Language Model)を活用する際に使用できるLangChainでPromptTemplateを使用する方法を解説しました。

PromptTemplateは、変数を埋め込んだようなPromptを定義することができるため、効率的にモデルへの指示が可能となります。この記事では単一のPromptTemplateと会話の流れを定義できるChatPromptTemplateを簡単な例を使って紹介しました。

LangChainには、他にも様々な機能があります。皆さんもLangChainの使い方をぜひ覚えていってもらえるといいと思います。