PythonでのZeroからAdvancedなPromptエンジニアリングをLangchainで
PythonでのPromptエンジニアリングをLangchainで
大規模言語モデル(LLM)の重要な側面の一つは、これらのモデルが学習に使用するパラメータの数です。モデルが持つパラメータが多ければ多いほど、単語やフレーズの関係を理解する能力が向上します。これは、数十億のパラメータを持つモデルは、さまざまなクリエイティブなテキスト形式を生成し、情報を提供する形でオープンエンドで難解な質問に答える能力を持つことを意味します。
Transformerモデルを利用するChatGPTなどのLLMは、人間の言語を理解し生成することに優れており、自然言語理解が必要なアプリケーションに役立ちます。しかし、それらには古い知識、外部システムとの対話の不可能性、文脈理解の欠如、時には正しいと思われるが不正確または非意味的な応答を生成するなどの制約もあります。
これらの制約に対処するには、LLMを外部データソースと機能と統合する必要がありますが、これには複雑さが伴い、コーディングとデータ処理のスキルが要求されます。これに加えて、AIの概念と複雑なアルゴリズムの理解の難しさが、LLMを使用したアプリケーションの開発に関連する学習曲線に寄与します。
- ChatGPTを忘れてください、この新しいAIアシスタントは圧倒的に進んでおり、あなたの働き方を永遠に変えるでしょう
- 「Synthesysレビュー:最高のAIビデオジェネレーター?(2023年8月)」
- 「ビーチでの読書:事前学習モデルの短い歴史」
それにもかかわらず、LLMを他のツールと統合してLLMを活用したアプリケーションを形成することは、私たちのデジタルランドスケープを再定義する可能性を秘めています。そのようなアプリケーションの可能性は広がり、効率と生産性の向上、タスクの簡素化、意思決定の強化、パーソナライズされた体験の提供などが含まれます。
この記事では、これらの課題について詳しく掘り下げ、Langchainを使ったprompt engineeringの高度なテクニックを探求し、明確な説明、実践的な例、ステップバイステップの手順を提供します。
Langchainは、設計、実装、調整の柔軟性と便利さをもたらす最先端のライブラリです。prompt engineeringの原則と実践を解説するにあたり、Langchainの強力な機能を活用してGPT-4などのSOTA Generative AIモデルの強みを引き出す方法を学びます。
プロンプトの理解
prompt engineeringの技術的な側面に入る前に、プロンプトの概念とその重要性を把握することが重要です。
「プロンプト」は、言語モデルに入力されるトークンのシーケンスであり、特定のタイプの応答を生成するように指示します。プロンプトはモデルの動作を制御する重要な役割を果たします。生成されるテキストの品質に影響を与え、適切に作成されると、モデルが洞察に富み、正確で文脈に即した結果を提供することができます。
プロンプトエンジニアリングは、効果的なプロンプトの設計の芸術と科学です。目標は、言語モデルから望ましい出力を引き出すことです。適切なプロンプトを慎重に選択し構築することで、モデルがより正確かつ関連性のある応答を生成するように誘導することができます。実際には、これにはモデルのトレーニングと構造的なバイアスに合わせて入力フレーズを微調整することが含まれます。
プロンプトエンジニアリングの洗練度は、関連キーワードをモデルにフィードするなどの単純な技術から、モデルの内部メカニズムを利用した複雑な構造化プロンプトの設計まで様々です。
Langchain:急成長するプロンプトツール
2022年10月にHarrison ChaseによってローンチされたLangChainは、2023年のGitHubで最も高評価を受けたオープンソースのフレームワークの一つになりました。これは、大規模言語モデル(LLM)をアプリケーションに組み込むための簡素化された標準化されたインターフェースを提供します。また、機能豊富なプロンプトエンジニアリングのインターフェースも提供し、開発者が異なる戦略を試し、結果を評価することができます。Langchainを利用することで、プロンプトエンジニアリングのタスクをより効果的かつ直感的に実行できます。
LangFlowは、LangChainコンポーネントを実行可能なフローチャートに組み合わせるためのユーザーインターフェースとして機能し、迅速なプロトタイピングと実験を可能にします。
LangChainは、大衆向けAI開発の重要なギャップを埋める役割を果たしています。これにより、仮想アシスタント、コンテンツ生成ツール、質問応答システムなどのNLPアプリケーションを使用して、さまざまな現実世界の問題を解決することができます。
LangChainは、単なるモデルやプロバイダーではなく、シンプルなAPIコールの制約を超えたLLMアプリケーションの機能を拡張するための相互作用を簡素化します。
LangChainのアーキテクチャ
LangChainの主なコンポーネントには、モデルI/O、プロンプトテンプレート、メモリ、エージェント、およびチェーンが含まれます。
Model I/O
LangChainは、さまざまな言語モデルとのシームレスな接続を可能にするために、それらを標準化されたインターフェースであるModel I/Oでラップします。これにより、最適化やパフォーマンスの向上のために、モデルの切り替えが容易になります。LangChainは、OpenAI、HuggingFace、Azure、Fireworksなど、さまざまな言語モデルプロバイダをサポートしています。
プロンプトテンプレート
プロンプトテンプレートは、LLMとのインタラクションを管理および最適化するために使用されます。プロンプトの最適化はモデルのパフォーマンスを向上させ、その柔軟性は入力プロセスに大きく貢献します。
プロンプトテンプレートの単純な例:
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(input_variables=["subject"],
template="最近の{subject}の進歩は何ですか?")
print(prompt.format(subject="自然言語処理"))
複雑さが増すと、LangChainではReason and Act(ReAct)パターンなど、より洗練されたパターンに遭遇します。ReActは、エージェントがタスクを適切なツールに割り当て、それに対して入力をカスタマイズし、出力を解析してタスクを達成するための重要なパターンです。以下のPythonの例は、ReActパターンを示しています。これは、LangChainでプロンプトがどのように構造化されるかを示し、問題を理解し、最終的な回答を生成するために一連の思考とアクションを使用します:
PREFIX = """以下のツールを使用して次の質問に答えてください:"""
FORMAT_INSTRUCTIONS = """以下の形式に従ってください:
質問:{input_question}
思考:質問に対するあなたの最初の考え
アクション:[{tool_names}]から選択したアクション
アクションの入力:アクション用の入力
観察:アクションの結果"""
SUFFIX = """開始!
質問:{input}
思考:{agent_scratchpad}"""
メモリ
メモリは、LangChainで重要な概念であり、LLMとツールが情報を時間にわたって保持できるようにします。この状態を持つ振る舞いは、以前の応答、ユーザーとのインタラクション、環境の状態、エージェントの目標を保存することにより、LangChainアプリケーションのパフォーマンスを向上させます。ConversationBufferMemoryとConversationBufferWindowMemoryの戦略は、会話の完全な部分または最近の部分を追跡するのに役立ちます。より洗練されたアプローチでは、ConversationKGMemory戦略を使用して会話を知識グラフとしてエンコードし、プロンプトにフィードバックしたり、LLMを呼び出さずに応答を予測することができます。
エージェント
エージェントは、アクションとタスクを実行することで世界と対話します。LangChainでは、エージェントはツールとチェーンを組み合わせてタスク実行を行います。LLMの知識を補完するために、情報の取得のために外部の世界への接続を確立することができ、それにより、LLMの固有の制約を克服することができます。状況に応じて、計算を計算機またはPythonインタプリタに渡すかどうかを決定することができます。
エージェントは、次のサブコンポーネントで構成されています:
- ツール:これらは機能的なコンポーネントです。
- ツールキット:ツールのコレクションです。
- エージェントエグゼキュータ:ツールの選択を可能にする実行メカニズムです。
LangChainのエージェントは、ツールの説明に基づいてのみ決定されるゼロショットReActパターンに従います。このメカニズムは、会話の完全な履歴を考慮に入れるためにメモリで拡張することもできます。ReActを使用すると、LLMにテキストの自動補完を依頼する代わりに、思考/アクト/観察のループで応答するようにプロンプトすることができます。
チェーン
チェーンは、LangChainライブラリが言語モデルの入力と出力をシームレスに処理するための操作のシーケンスです。LangChainのこの重要なコンポーネントは、リンク(他のチェーンまたはプロンプト、言語モデル、ユーティリティなどのプリミティブ)から構成されています。
チェーンを工場のコンベアベルトと考えてみてください。このベルトの各ステップは、言語モデルの呼び出し、テキストに対してPython関数の適用、あるいは特定の方法でモデルにプロンプトを与えるなど、ある操作を表します。
LangChainは、ユーティリティチェーン、ジェネリックチェーン、ドキュメントの結合チェーンの3つのタイプにチェーンを分類しています。この質問では、ユーティリティチェーンとジェネリックチェーンについて詳しく説明します。
- ユーティリティチェーンは、狭く定義されたタスクのために言語モデルから正確な回答を抽出するために特別に設計されています。例えば、LLMMathChainを見てみましょう。このユーティリティチェーンは、言語モデルが数学的な計算を実行することを可能にします。自然言語での質問を受け取り、言語モデルがPythonのコードスニペットを生成し、それを実行して回答を生成します。
- ジェネリックチェーンは、他のチェーンの構築ブロックとして機能しますが、直接単体で使用することはできません。LLMChainなどのこれらのチェーンは、基礎となるものであり、複雑なタスクを達成するために他のチェーンと組み合わせて使用されることがよくあります。たとえば、LLMChainは、プロンプトテンプレートに基づいて入力をフォーマットし、それを言語モデルに渡すことで、言語モデルオブジェクトにクエリを行うために頻繁に使用されます。
Langchainを使ったプロンプトエンジニアリングのステップバイステップの実装
Langchainを使ったプロンプトエンジニアリングの実装プロセスを説明します。進む前に、必要なソフトウェアとパッケージがインストールされていることを確認してください。
Docker、Conda、Pip、Poetryなどの人気のあるツールを利用して、LangChainをセットアップすることができます。これらの方法ごとに関連するインストールファイルは、LangChainのリポジトリ(https://github.com/benman1/generative_ai_with_langchain)内にあります。これには、Docker用のDockerfile、Pip用のrequirements.txt、Poetry用のpyproject.toml、Conda用のlangchain_ai.ymlファイルが含まれています。
この記事では、Pythonの標準的なパッケージマネージャであるPipを使用して、サードパーティのライブラリのインストールと管理を容易にします。Pythonディストリビューションに含まれていない場合、https://pip.pypa.io/の手順に従ってPipをインストールすることができます。
Pipを使用してライブラリをインストールするには、pip install ライブラリ名
というコマンドを使用します。
ただし、Pipは環境の管理を独自に行うことはありません。異なる環境を扱うために、virtualenvというツールを使用します。
次のセクションでは、モデルの統合について説明します。
ステップ1:Langchainのセットアップ
まず、Langchainパッケージをインストールする必要があります。Windows OSを使用しています。ターミナルで以下のコマンドを実行してインストールしてください:
pip install langchain
ステップ2:Langchainおよびその他の必要なモジュールのインポート
次に、Langchainと他の必要なモジュールをインポートします。ここでは、NLPのタスクで広く使用されているtransformersライブラリもインポートしています。
import langchain
from transformers import AutoModelWithLMHead, AutoTokenizer
ステップ3:事前学習済みモデルの読み込み
Open AI
OpenAIモデルは、LangChainライブラリまたはOpenAI Pythonクライアントライブラリと便利に連携することができます。特に、OpenAIはテキスト埋め込みモデルに対してEmbeddingクラスを提供しています。主要なLLMモデルにはGPT-3.5とGPT-4があり、トークンの長さが主な違いです。それぞれのモデルの価格はOpenAIのウェブサイトで確認することができます。トークンの受け入れ数が高いGPT-4-32Kなどのより洗練されたモデルもありますが、API経由での利用が常に保証されているわけではありません。
これらのモデルにアクセスするには、OpenAIのAPIキーが必要です。これは、OpenAIのプラットフォームでアカウントを作成し、課金情報を設定し、新しいシークレットキーを生成することで取得できます。
import os
os.environ["OPENAI_API_KEY"] = 'your-openai-token'
キーの作成に成功したら、環境変数(OPENAI_API_KEY)として設定するか、OpenAIの呼び出し時にパラメータとして渡すことができます。
OpenAIモデルとの対話を示すLangChainスクリプトを考えてみましょう:
from langchain.llms import OpenAI
llm = OpenAI(model_name="text-davinci-003")
# LLMはプロンプトを入力として受け取り、補完を出力します
prompt = "アメリカ合衆国の大統領は誰ですか?"
completion = llm(prompt)
現在のアメリカ合衆国の大統領はジョー・バイデンです。
この例では、計算を実行するエージェントが初期化されます。エージェントは、簡単な加算のタスクを入力として受け取り、提供されたOpenAIモデルを使用して結果を返します。
Hugging Face
Hugging Faceは、PyTorch、TensorFlow、JAXと互換性のある無料で使用できるTransformers Pythonライブラリであり、BERT、T5などのモデルの実装を含んでいます。
Hugging Faceはまた、コードリポジトリ、機械学習モデル、データセット、WebアプリケーションをホスティングするためのHugging Face Hubというプラットフォームも提供しています。
モデルのプロバイダとしてHugging Faceを使用するには、アカウントとAPIキーが必要です。これは、彼らのウェブサイトから入手することができます。トークンは環境変数としてHUGGINGFACEHUB_API_TOKENで利用できるようにすることができます。
以下のPythonスニペットを考えてみましょう。これはGoogleが開発したオープンソースのモデル、Flan-T5-XXLモデルを利用しています:
from langchain.llms import HuggingFaceHub
llm = HuggingFaceHub(model_kwargs={"temperature": 0.5, "max_length": 64},repo_id="google/flan-t5-xxl")
prompt = "東京はどの国にありますか?"
completion = llm(prompt)
print(completion)
このスクリプトは、質問を入力として受け取り、モデルの知識と予測能力を示す回答を返します。
ステップ4:基本的なプロンプトエンジニアリング
まず、簡単なプロンプトを生成して、モデルの応答を見てみましょう。
prompt = '以下の英文をフランス語に翻訳してください:"{0}"'
input_text = 'こんにちは、元気ですか?'
input_ids = tokenizer.encode(prompt.format(input_text), return_tensors='pt')
generated_ids = model.generate(input_ids, max_length=100, temperature=0.9)
print(tokenizer.decode(generated_ids[0], skip_special_tokens=True))
上記のコードスニペットでは、英文をフランス語に翻訳するためのプロンプトを提供しています。言語モデルは、プロンプトに基づいて与えられたテキストを翻訳しようとします。
ステップ5:高度なプロンプトエンジニアリング
上記の方法はうまく機能しますが、プロンプトエンジニアリングの力を十分に活用していません。より複雑なプロンプト構造を導入することで、それを改善しましょう。
prompt = '非常に優れたフランス語翻訳者として、以下の英文をフランス語に翻訳してください:"{0}"'
input_text = 'こんにちは、元気ですか?'
input_ids = tokenizer.encode(prompt.format(input_text), return_tensors='pt')
generated_ids = model.generate(input_ids, max_length=100, temperature=0.9)
print(tokenizer.decode(generated_ids[0], skip_special_tokens=True))
このコードスニペットでは、プロンプトを変更して、翻訳が「非常に優れたフランス語翻訳者」によって行われていることを示します。プロンプトの変更により、モデルは専門家の役割を想定するため、翻訳の向上が期待できます。
Langchainを使用した学術文献Q&Aシステムの構築
Langchainを使用して、最近発表された学術論文に関する質問に答えることができる学術文献の質問応答システムを構築します。
まず、環境をセットアップするために必要な依存関係をインストールします。
pip install langchain arxiv openai transformers faiss-cpu
インストール後、新しいPythonノートブックを作成し、必要なライブラリをインポートします:
from langchain.llms import OpenAI
from langchain.chains.qa_with_sources import load_qa_with_sources_chain
from langchain.docstore.document import Document
import arxiv
Q&Aシステムの中核は、特定の分野に関連する関連する学術論文を取得する能力です。ここでは自然言語処理(NLP)を考慮し、arXiv学術データベースを使用します。これを実行するために、get_arxiv_data(max_results=10)
という関数を定義します。この関数は、arXivから最新のNLP論文の要約を収集し、要約をコンテンツとして、一意のエントリIDをソースとしてLangChainのドキュメントオブジェクトにカプセル化します。
arXiv APIを使用して、NLPに関連する最新の論文を取得します:
def get_arxiv_data(max_results=10):
search = arxiv.Search(
query="NLP",
max_results=max_results,
sort_by=arxiv.SortCriterion.SubmittedDate,
)
documents = []
for result in search.results():
documents.append(Document(
page_content=result.summary,
metadata={"source": result.entry_id},
))
return documents
この関数は、arXivから最新のNLP論文の要約を取得し、LangChainのドキュメントオブジェクトに変換します。論文の要約とその一意のエントリID(論文へのURL)をそれぞれコンテンツとソースとして使用しています。
def print_answer(question):
print(
chain(
{
"input_documents": sources,
"question": question,
},
return_only_outputs=True,
)["output_text"]
)
コーパスを定義し、LangChainをセットアップしましょう:
sources = get_arxiv_data(2)
chain = load_qa_with_sources_chain(OpenAI(temperature=0))
学術的なQ&Aシステムが準備できたので、質問をしてテストすることができます:
print_answer("最近の自然言語処理の進展には何がありますか?")
出力は質問に対する回答であり、情報が抽出されたソースを引用しています。例えば:
自然言語処理の最近の進展には、Retriever-augmented instruction-followingモデルや、グラフィックス処理ユニット(GPU)を使用して交流最適電力フロー(ACOPF)問題を解決するための新しい計算フレームワークなどが含まれます。
ソース:http://arxiv.org/abs/2307.16877v1, http://arxiv.org/abs/2307.16830v1
必要に応じてモデルを切り替えたり、システムを変更することが簡単です。例えば、ここではGPT-4に変更して、より良く詳細な応答を得ることができます。
sources = get_arxiv_data(2)
chain = load_qa_with_sources_chain(OpenAI(model_name="gpt-4",temperature=0))
自然言語処理(NLP)の最近の進展には、情報検索タスク(例:質問応答)向けのRetriever-augmented instruction-followingモデルの開発が含まれます。これらのモデルは、追加の微調整なしでさまざまな情報ドメインとタスクに適応することができます。しかし、これらのモデルは提供された知識に固執するのに苦労することがあり、応答時に幻想を抱くことがあります。もう一つの進展は、グラフィックス処理ユニット(GPU)を使用して交流最適電力フロー(ACOPF)問題を解決するための計算フレームワークの導入です。このアプローチは、非線形プログラム(NLP)の単一命令、複数データ(SIMD)抽象化を利用し、不等式緩和戦略を用いたコンデンス空間内点法(IPM)を採用しています。この戦略により、数値的なピボット操作を伴わずにKKT行列を因数分解することが可能となり、IPMアルゴリズムの並列化を妨げていた問題が解決されました。
ソース:http://arxiv.org/abs/2307.16877v1, http://arxiv.org/abs/2307.16830v1
GPT-4のトークンは1文字から1単語までの範囲であります。例えば、GPT-4-32Kは単一の実行で最大32,000トークンを処理することができます。一方、GPT-4-8KやGPT-3.5-turboはそれぞれ8,000トークンと4,000トークンをサポートしています。ただし、重要な点として、これらのモデルとのやり取りは、入力または出力のトークンの数に比例してコストが発生することに留意する必要があります。
Q&Aシステムの文脈において、学術文献のトークン数が最大制限を超える場合、システムは完全に処理できず、回答の品質と完全性に影響を及ぼす可能性があります。この問題を回避するために、テキストをトークン制限に準拠するように小さなパーツに分割することができます。
FAISS(Facebook AI Similarity Search)は、ユーザーのクエリに関連する最も関連のあるテキストチャンクを素早く見つけるのに役立ちます。それぞれのテキストチャンクに対してベクトル表現を作成し、これらのベクトルを使用して与えられた質問のベクトル表現に最も類似したチャンクを特定して取得します。
ただし、FAISSのようなツールを使用していても、トークン制限によりテキストを小さなチャンクに分割する必要がある場合、文脈の喪失が発生することがあり、回答の品質に影響を及ぼす可能性があります。したがって、これらの大規模な言語モデルを使用する際には、トークンの使用を注意深く管理および最適化することが重要です。
pip install faiss-cpu langchain CharacterTextSplitter
上記のライブラリがインストールされていることを確認した後、次のコードを実行してください:
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores.faiss import FAISS
from langchain.text_splitter import CharacterTextSplitter
documents = get_arxiv_data(max_results=10) # より多くのデータをフィードできるようになりました
document_chunks = []
splitter = CharacterTextSplitter(separator=" ", chunk_size=1024, chunk_overlap=0)
for document in documents:
for chunk in splitter.split_text(document.page_content):
document_chunks.append(Document(page_content=chunk, metadata=document.metadata))
search_index = FAISS.from_documents(document_chunks, OpenAIEmbeddings())
chain = load_qa_with_sources_chain(OpenAI(temperature=0))
def print_answer(question):
print(
chain(
{
"input_documents": search_index.similarity_search(question, k=4),
"question": question,
},
return_only_outputs=True,
)["output_text"]
)
コードが完成したので、NLPの学術文献を問い合わせるための強力なツールが手に入りました。
NLPの最新の進歩には、ディープニューラルネットワーク(DNN)を使用した自動テキスト分析や自然言語処理(NLP)のタスク(スペルチェック、言語検出、エンティティ抽出、著者検出、質問応答など)が含まれます。
ソース:http://arxiv.org/abs/2307.10652v1、http://arxiv.org/abs/2307.07002v1、http://arxiv.org/abs/2307.12114v1、http://arxiv.org/abs/2307.16217v1
結論
Large Language Models(LLM)のアプリケーションへの統合により、言語翻訳、感情分析、情報検索など、いくつかの領域での採用が加速しました。プロンプトエンジニアリングは、これらのモデルの潜在能力を最大限に引き出すための強力なツールであり、Langchainはこの複雑なタスクを簡素化することで先導しています。標準化されたインターフェース、柔軟なプロンプトテンプレート、堅牢なモデル統合、エージェントとチェーンの革新的な使用により、LLMのパフォーマンスを最適化します。
しかし、これらの進歩にもかかわらず、いくつかの注意点があります。Langchainを使用する際には、出力の品質はプロンプトの表現方法に大きく依存することを理解することが重要です。異なるプロンプトスタイルと構造を試行することで、改善された結果が得られる場合があります。また、Langchainはさまざまな言語モデルをサポートしていますが、それぞれには強みと弱点があります。特定のタスクに適したモデルを選ぶことが重要です。最後に、これらのモデルの使用にはコストの考慮も重要です。トークン処理は相互作用のコストに直接影響を与えます。
ステップバイステップのガイドで示されているように、Langchainは学術文献のQ&Aシステムなど、堅牢なアプリケーションの強力なエンジンとなることができます。ユーザーコミュニティが拡大し、オープンソースの景色でもますます目立つようになることで、LangchainはGPT-4のようなLLMのフルポテンシャルを引き出すための重要なツールになることを約束しています。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles