プロンプトエンジニアリング

Langchainを使用したPythonでのゼロからアドバンスドプロンプトエンジニアリング

mm
Unite.AI を Google の優先ソースに追加

大規模言語モデル(LLM)には、学習に使用するパラメーターの数が重要な側面です。モデルが持つパラメーターの数が多いほど、単語やフレーズの関係をよりよく理解できるため、創造的なテキスト形式を生成し、オープンエンドの質問や難しい質問に情報を提供する回答を生成できます。

チャットGPTなどのTransformerモデルを使用するLLMは、人間の言語を理解して生成する能力が高く、自然言語理解を必要とするアプリケーションに役立ちます。ただし、限界もあります。例えば、古い知識、外部システムとのやり取りができないこと、コンテキストを理解できないこと、時には妥当な回答を生成するが誤った回答になることがあります。

これらの限界を克服するには、LLMを外部データソースや機能と統合する必要がありますが、これには複雑さや広範なコーディングとデータ処理スキルの必要性があります。これは、AIの概念や複雑なアルゴリズムを理解することの難しさと組み合わせて、LLMを使用したアプリケーションの開発の学習曲線に寄与しています。

それでも、LLMを他のツールと組み合わせてLLM駆動アプリケーションを形成することで、デジタル景観を再定義する可能性があります。効率と生産性の向上、タスクの簡素化、意思決定の強化、パーソナライズされた体験の提供など、潜在的な用途は広範囲にわたります。

この記事では、Langchainを使用したプロンプトエンジニアリングの高度なテクニックを探り、明確な説明、実践的な例、ステップバイステップの指示を提供して、Langchainを使用してこれらのテクニックを実装する方法について説明します。

Langchainは、プロンプトを設計、実装、調整するための最先端のライブラリであり、最先端のジェネレーティブAIモデル(GPT-4など)の強みを活用するための強力な機能を提供します。プロンプトエンジニアリングの原理と実践を解説するにつれて、Langchainの機能を使用してLLMの強みを最大限に引き出す方法を学びます。

プロンプトの理解

プロンプトエンジニアリングの技術的側面に突入する前に、プロンプトとその重要性の概念を理解することが不可欠です。

プロンプト」とは、言語モデルに特定のタイプのレスポンスを生成させるために使用されるトークンのシーケンスです。プロンプトは、モデルの動作に大きな影響を与える可能性があり、正しく設計されたプロンプトは、モデルの出力をより正確で関連性の高いものにすることができます。

プロンプトエンジニアリングとは、効果的なプロンプトを設計する芸術と科学です。目標は、言語モデルから望ましい出力を引き出すことです。プロンプトを慎重に選択して構造化することで、モデルがより正確で関連性の高いレスポンスを生成するように導くことができます。実践では、これにはモデルのトレーニングと構造的偏見に合わせて入力フレーズを微調整することが含まれます。

プロンプトエンジニアリングの複雑さは、単純なテクニック(例:モデルに関連キーワードを与える)から、モデル内部のメカニズムを活用する複雑な構造化プロンプトの設計まで、幅広いものです。

Langchain:最速で成長するプロンプトツール

LangChainは、2022年10月にHarrison Chaseによって立ち上げられ、2023年にGitHubで最も高く評価されているオープンソースフレームワークの1つになりました。LangChainは、大規模言語モデル(LLM)をアプリケーションに組み込むための簡素化された標準化インターフェイスを提供します。また、プロンプトエンジニアリングのための機能豊富なインターフェイスも提供し、開発者がさまざまな戦略を実験して結果を評価できるようにします。LangChainを使用することで、プロンプトエンジニアリングタスクをより効果的に、また直感的に実行できます。

LangFlowは、LangChainコンポーネントを実行可能なフローチャートにまとめるためのユーザーインターフェイスとして機能し、迅速なプロトタイピングと実験を可能にします。

LangChainは、AI開発における重要なギャップを埋めます。LangChainは、仮想アシスタント、コンテンツジェネレーター、質問回答システムなど、幅広いNLPアプリケーションを可能にし、さまざまな実世界の問題を解決することができます。

LangChainは、単独のモデルやプロバイダーではなく、さまざまなモデルとのやり取りを簡素化します。これにより、LLMアプリケーションの機能が、単純なAPIコールの制限を超えて拡大します。

LangChainのアーキテクチャ

 

LangChainの主なコンポーネントには、モデルI/O、プロンプトテンプレート、メモリ、エージェント、チェーンが含まれます。

モデルI/O

LangChainは、モデル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アプリケーションのパフォーマンスが向上し、以前のレスポンス、ユーザーのやり取り、環境の状態、およびエージェントの目標が保存されます。会話バッファーメモリと会話バッファーウィンドウメモリ戦略により、会話の全体または最近の部分を追跡できます。より洗練されたアプローチとして、会話KGメモリ戦略により、会話を知識グラフとしてエンコードし、プロンプトにフィードバックするか、LLMを呼び出すことなくレスポンスを予測することができます。

エージェント

エージェントは、タスクを実行するためにアクションを実行します。LangChainでは、エージェントはツールとチェーンをタスクの実行のために組み合わせます。エージェントは、LLMの知識の限界を克服するために外部の情報源への接続を確立できます。状況に応じて、計算を計算機またはPythonインタープリターにパスできます。

エージェントには、以下のサブコンポーネントがあります。

  • ツール:これらは機能コンポーネントです。
  • ツールキット:ツールのコレクションです。
  • エージェントエクスキューター:これは、ツールの間で選択するための実行メカニズムです。

LangChainのエージェントは、ツールの説明のみに基づいて決定を下すゼロショットReActパターンも従います。このメカニズムは、会話の完全な履歴を考慮するためにメモリを使用して拡張できます。ReActを使用すると、テキストを自動補完するのではなく、モデルの思考/アクション/観察のループに応答するよう促すことができます。

チェーン

チェーンとは、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を使用して、LangChainとその他の必要なモジュールをインストールおよび管理します。Pythonの配布に含まれていない場合は、https://pip.pypa.io/の指示に従ってPipをインストールできます。

ライブラリをPipでインストールするには、pip install library_nameコマンドを使用します。

ただし、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は、テキスト埋め込みモデル用の埋め込みクラスも提供しています。主なLLMモデルは、GPT-3.5とGPT-4で、主な違いはトークン長です。各モデルの価格は、OpenAIのWebサイトで見つけることができます。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

Hugging Faceは、PyTorch、TensorFlow、JAXと互換性のある、無料のTransformers Pythonライブラリです。BERT、T5などのモデルを実装しています。

Hugging Faceは、コードリポジトリ、機械学習モデル、データセット、WebアプリケーションをホストするためのHugging Face Hubプラットフォームも提供しています。

モデルを使用するには、Hugging FaceのWebサイトからアカウントとAPIキーを取得する必要があります。トークンは、HUGGINGFACEHUB_API_TOKENとして環境に公開できます。

Googleが開発したFlan-T5-XXLモデルを使用する次のPythonスニペットを考えてみましょう。

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システムの構築

ここでは、最近の学術論文について質問に答えることができる学術文献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の最近の論文の要約を収集し、それらをLangChainのドキュメントオブジェクトにカプセル化します。要約をコンテンツとして、ユニークなエントリIDをソースとして使用します。

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},
))

この関数は、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("最近のNLPの進歩は何ですか?")

出力は、質問に対する答えとなり、情報源として使用されたソースが示されます。たとえば:

最近のNLPの進歩には、リトライバーアグメンテーションインストラクションフォローモデルや、グラフィックスプロセッシングユニット(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)の進歩には、情報を求めるタスクなどのさまざまなドメインやタスクに適応できるリトライバーアグメンテーションインストラクションフォローモデルが含まれます。これらのモデルは、追加のファインチューニングなしでさまざまな情報ドメインやタスクに適応できますが、提供された知識に固執し、回答で妄想することがあります。別の進歩には、グラフィックスプロセッシングユニット(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は、1回の実行で最大32,000トークンを処理できますが、GPT-4-8KやGPT-3.5-turboは、それぞれ8,000トークンと4,000トークンをサポートします。ただし、重要なのは、これらのモデルの各インタラクションには、入力または出力に関係なく、トークン数に比例したコストがかかるということです。

学術Q&Aシステムのコンテキストでは、学術論文が最大トークン数を超える場合、システムは論文全体を処理できず、回答の品質と完全性が影響を受ける可能性があります。この問題を回避するために、テキストをトークン数制限に従って小さな部分に分割できます。

FAISS(Facebook AI Similarity Search) (META ) は、質問に関連する最も関連性の高いテキストのチャンクを迅速に検索するのに役立ちます。各テキストのチャンクのベクトル表現を作成し、これらのベクトルを使用して、与えられた質問のベクトル表現に最も似ているチャンクを特定および取得します。

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)の使用が含まれます。
ソース:http://arxiv.org/abs/2307.10652v1、http://arxiv.org/abs/2307.07002v1、http://arxiv.org/abs/2307.12114v1、http://arxiv.org/abs/2307.16217v1

結論

大規模言語モデル(LLM)のアプリケーションへの統合は、言語翻訳、感情分析、情報検索を含むさまざまな分野の採用を促進しました。プロンプトエンジニアリングは、これらのモデルの潜在能力を最大限に引き出すための強力なツールであり、LangChainはこの複雑なタスクを簡素化する先頭に立っています。標準化されたインターフェイス、柔軟なプロンプトテンプレート、ロバストなモデル統合、革新的なエージェントとチェーンの使用により、LLMのパフォーマンスを最適化します。

ただし、注意すべき点がいくつかあります。LangChainを使用するにつれて、出力の品質はプロンプトの表現に大きく依存することがわかります。さまざまなプロンプトスタイルや構造を試すと、結果が改善されることがあります。また、LangChainはさまざまな言語モデルをサポートしていますが、各モデルには長所と短所があり、特定のタスクに最適なモデルを選択することが重要です。最後に、これらのモデルの使用にはコストの考慮が伴うことがあり、トークンの処理は直接コストに影響します。

ステップバイステップガイドで示されているように、LangChainは、学術文献Q&Aシステムなどの強力なアプリケーションを実行できます。ユーザーコミュニティの成長とオープンソース風景での存在感の増大により、LangChainは、GPT-4のようなLLMの全潜在力を解き放つための重要なツールになることを約束しています。

LangChainを使用すると、LLMを活用した強力なアプリケーションを構築できます。プロンプトエンジニアリングの力とLangChainの柔軟性を組み合わせることで、LLMの可能性を最大限に引き出し、革新的なソリューションを実現することができます。

私は過去5年間、機械学習とディープラーニングの魅力的世界に没頭してきました。私の情熱と専門知識は、AI/MLに特に焦点を当てた50以上の多様なソフトウェアエンジニアリングプロジェクトに貢献することになりました。私の継続的な好奇心は、自然言語処理という分野にも私を引き付け、さらに探求したいと思っています。