Skip to main content

LangchainおよびW&BによるプロンプトエンジニアリングLLM

参加して、LLMのプロンプトエンジニアリングを改善するためのヒントとコツを学んでください。それから、ヒントとコツに従って、LangchainとW&Bによってあなたの生活を実感できるほど快適にしてください。
Created on May 2|Last edited on May 30
言語モデルはここ数年間で大きな発展を遂げ、その能力は急速に拡大しています。適切なプロンプトによって、言語モデルは、人間が作成するものとほとんど区別ができないテキストを生成することができます。
この記事では、プロンプトエンジニアリングの技術を探っていきます。これは、望ましい出力を生成するよう言語モデルを導くための、完璧なプロンプトを作成するプロセスです。
プロンプトエンジニアリングの背景やヒントが必要ない場合は、こちらをクリックしてこの記事のLangchainの部分に直接移動することができます。コードに直接移動したい場合は?以下にアクセスしてください:



この記事は項目ごとにお楽しみいただけます。トピックを学習して、実際に試しましょう。プロンプトエンジニアリングは楽しい分野です!
すぐに始めたいですか?当社の統合に関するLangchainドキュメントにアクセスして、実施例をご覧ください。
💡

目次



🤔 AIに話しかける:プロンプトエンジニアリングを検討すべき理由

プロンプトエンジニアリングは言語モデルが生成する出力の品質を決定することから、極めて重要です。適切に作られたプロンプトはモデルを適切な方向に導くことができますが、不適切に作られたプロンプトは無関係な出力や無意味な出力につながる場合があります。プロンプトエンジニアリングの鍵は、指示、コンテキスト、入力データ、および出力指示子の適切な組み合わせをモデルに与えることです。
以下でこの詳細について考察します:

💡 熟考する:プロンプトエンジニアを効果的に行う方法

プロンプトエンジニアリングに関するインサイトをご提供いただいたことに対し、Co:hereおよびDair.aiのスタッフに深く感謝いたします。両方に登録して、LLMプロンプトエンジニアリングの最新のヒントをご覧ください。
💡
LLMのプロンプトを効果的に作成する方法に関するいくつかの提案を詳しく掘り下げる前に、重要なパラメーターとサンプリング手法を見ていきます。

🌡️ 温度

温度は、生成されたテキストのランダム性を制御するのに使用するパラメーターです。温度が低いとより控えめな予測になり、温度が高いとより多様かつ創造的な出力になります。望ましい出力を達成するには、特定のタスクに最適な温度を判断することが重要です。
精度が重要となる事実に基づいた質問に取り組む際、事実に基づく正確な応答を得るには、より低い温度を使う必要があります。他方、詩の生成といった創造的なタスクでは、温度を高くするとより独創的な出力が得られます。

🔝 Top P

top_pは、応答の生成においてモデルをどの程度決定論的にするかを制御するサンプリング手法です。top_pによって、次の出力を検討するために、見込まれる次のトークン数を制限することができます。
低いtop_pを選ぶと、モデルは最も可能性のあるトークンのみを考慮し、結果はより正確になりますが、出力の多様性は低くなることがあります。高いtop_pを選ぶと、モデルはより幅広いトークンを考慮するよう促され、多様性の高い出力が得られます。
精度が不可欠な場合は、より低いtop_pを使って、最も可能性が高いトークンのみを選ぶようにモデルを促す必要があります。多様性の高い出力を得るには、top_pを増加して、モデルが幅広い範囲のトークンを考慮できるようにします。

🚀 シンプルなものから始める

あらゆる新しいスキルと同様に、シンプルなプロンプトから始めて、複雑度を徐々に増加させるのが最善です。OpenAIまたはCo:hereのようなプレイグラウンドから始めて、基本的なプロンプトで実験することができます。プロンプトエンジニアリングに慣れてきたら、より多くの要素やコンテキストをプロンプトに追加します。

🧐 プロンプトエンジニアリングの3つのヒント

1. 教育指導上の言葉を使う

コマンドは、特定のタスク(「書く」、「分類する」、「要約する」、「翻訳する」、「命令する」など)を実行するようモデルに指示する際の効果的な方法です。さまざまな指示、キーワード、コンテキストで実験して、特定のユースケースやタスクに対して最善に機能するものを特定できます。
重要なヒントの1つとは、してはいけないことにフォーカスする否定的なプロンプトを避けることです。その代わりに、すべきことを指定する肯定的なプロンプトを提供します。このアプローチによって、モデルからの応答により多くの特異性と詳細が含まれるようになります。
💡

2. 具体的にする

プロンプトがより具体的かつ詳細であるほど、良い結果が得られます。
これは、目的とする結果がある、または希望の生成スタイルがある場合に特に重要です。プロンプトに例を追加することは、望ましい出力を特定の形式で得るために非常に効果的です。プロンプトを設計する際、プロンプトの長さを常に考慮してください。なぜなら、長さには制限があるためです。多くの不要な詳細を含めることは、必ずしも良いアプローチではありません。手元のタスクに関連があり、有用な詳細を含める必要があります。

3. 不正確さを回避する

プロンプトを巧みに操作しようと試み、不正確な可能性がある記述を作成するよりも、多くの場合、具体的かつ直接的にすることが推奨されます。不正確なプロンプトでも、ある程度優れた応答が得られる場合がありますが、優れたプロンプトは一般的に非常に具体的かつ正確です。

🧠 プロンプトで考える:プロンプト駆動のタスク例

このセクションでは、いくつかの一般的なNLPタスク、およびプロンプトエンジニアリングでどのように望ましい出力が得られるかを見ていきます。

テキストの要約

テキストの要約は、自然言語の生成における標準的なタスクです。ここでは、長いテキストを、短くより正確な要約に凝縮します。言語モデルの最も前途有望な応用の1つは、役員会議の議事録を短く要約するなど、記事やドキュメントを要約する能力です。
テキスト要約を実行するには、言語モデルに明確な指示を提供することが重要です。たとえば、「1つの文章で」、「[トピック]を説明してください」のようなプロンプトを使うことができます。また、望ましい出力の例を提供することは、モデルがあなたが求めていることを理解するのに役立ちます。

情報の抽出

情報の抽出では、与えられたテキストから特定の情報を特定して抽出します。このタスクは、データマイニングやビジネスインテリジェンスなどのアプリケーションに役立ちます。
言語モデルをプロンプトして情報抽出を実行するには、コンテキストを提供してから、望ましい情報を指定する質問を提供します。たとえば、「上の段落で言及された[特定の情報]を検索してください」などです。

質疑応答

質疑応答では、与えられたコンテキストに基づいて、与えられた質問に特定の回答を提供します。言語モデルをプロンプトして質疑応答を実行するには、構造化された明確なプロンプトを提供することが重要です。これには、コンテキスト、質問、および出力指示子(「回答」など)の提供が含まれまることがあります。

テキスト分類

テキスト分類では、与えられたテキストを特定のカテゴリーまたはラベルに分類します。言語モデルをプロンプトしてテキスト分類を実行するには、「テキストを[特定のカテゴリーまたはラベル]に分類してください」など、明確な指示を与えます。また、入力データと望ましい出力の例を提供することは、モデルがあなたが求めていることを理解するのに役立ちます。

会話

会話システムでは、言語モデルをプロンプティングして、ユーザーとの会話に参加します。言語モデルをプロンプトして会話に参加するには、ビヘイビア(振る舞い)、意図、およびシステムのアイデンティティについて明確な指示を与えることが重要です。これには、挨拶、特定の口調、および特定のプロンプトへの応答方法に関する指示の提供が含まれます。

💻 コード生成

コード生成では、言語モデルをプロンプティングして、与えられたプロンプトに基づいてコードを生成します。このタスクは、反復的なコーディングタスクの自動化や、特定の要件に基づいてコードを生成する際に役立つことがあります。言語モデルをプロンプトしてコード生成を実行するには、「[特定のタスク]に対して[特定のプログラミング言語]クエリを作成してください」など、明確な指示を与えます。また、入力データと望ましい出力の例を提供することは、モデルがあなたが求めていることを理解するのに役立ちます。

推論

推論タスクでは、言語モデルをプロンプティングして、与えられたプロンプトに基づいて論理的推論または数学的推論を実行します。現在のLLMは推論タスクで苦労する傾向がありますが、それらをプロンプトして、基本的な計算を実行することは可能です。言語モデルをプロンプトして推論タスクを実行するには、入力データと望ましい出力の例を含む、タスクに関する明確かつ詳細な指示を与えることが重要です。

📈 LLMのパワーを解き放つ:高度なプロンプティング手法

Zero-ShotプロンプティングとFew-Shotプロンプティング

Zero-shotとfew-shotプロンプティングは、特定のタスクを微調整せずに、LLMから応答を生成するのを可能にする手法です。これは、利用可能なトレーニングデータに制限がある、または特定のタスクに対してモデルを微調整できないといった状況で役立ちます。
Zero-Shotプロンプティング
Zero-shotプロンプティングでは、いかなる例もトレーニングデータも提供せずに、実行対象のタスクについて説明するプロンプトをLLMに提供します。その後モデルは、タスクの理解に基づいて応答を生成します。この手法は、シンプルで単純なルールまたはパターンが含まれるタスクに役立ちます。
Few-Shotプロンプティング
Few-shotプロンプティングでは、タスクについて説明するプロンプトとともに、実行対象のタスクの数例をLLMに提供します。その後モデルは、タスクの理解と提供された例に基づいて応答を生成します。この手法は、シンプルなプロンプトでは簡単にキャプチャできない、より複雑なパターンやルールを伴うタスクに役立ちます。

CoT(思考の連鎖)プロンプティング

CoTプロンプティングによって、中間推論ステップを通した複雑な推論が可能になります。これをfew-shotプロンプティングを組合わせて、より優れた結果を得たり、応答前に推論を必要とする、より複雑なタスクを実行したりすることができます。CoTプロンプティングでは、複雑なタスクを一連のシンプルなサブタスクまたは中間推論ステップに分割します。これによって、言語モデルはステップを通して推論し、正解にたどり着くことができます。

自己整合性

自己整合性は、算術的推論と常識的推論を伴うタスクで、CoTプロンプティングのパフォーマンスを強化する手法です。ここでは、few-shot CoTを通して複数の多様な推論パスのサンプリングを行い、生成を使って最も 一貫性のある回答を選択します。自己整合性の背景にあるアイデアは、CoTプロンプティングで使用される単純な「貪欲法」(greedy decoding)を置き換えることです。

知識生成プロンプティング

知識生成プロンプティングは、モデルがより正確に予測できるように、知識または情報を取り入れる手法です。知識生成は、プロンプトの一部として含まれています。この手法は特に、世界に関する多数の知識を必要とするタスクに役立ちます。

自動プロンプトエンジニア(APE)

自動プロンプトエンジニア(APE)は、与えられたタスクに対して指示を生成し、より適切なものを選択するフレームワークです。大規模言語モデルは、提供された出力デモに基づいて候補指示を生成するために使用します。生成された指示は検索手順をガイドし、計算された評価スコアに基づいて最も適切なものが選ばれます。フレームワークは、LLMを使って、ブラックボックス最適化の問題として指示生成の問題に対処し、候補ソリューションを探して生成します。APEは、人間が設計した「ステップごとに考えよう」というプロンプトより優れたzero-shot CoTプロンプトを発見することが分かっています。

🔒敵対的プロンプトの回避方法

敵対的プロンプトの懸念が、プロンプトエンジニアリングにおいて高まっています。これは、言語モデルアプリケーションの安全性と信頼性にリスクをもたらすためです。このセクションでは、敵対的プロンプトを回避し、言語モデルの安全性を確保するために使用できる、いくつかのメソッドについて考察します。

プロンプトコンポーネントのパラメーター化

プロンプト攻撃を回避するための最も効果的な方法の1つは、プロンプトのさまざまなコンポーネントをパラメーター化することです。たとえば、入力から分離された指示を使ったり、異なる方法でプロンプトを扱ったりすることです。パラメーター化はよりクリーンで安全なソリューションにつながりますが、柔軟性が小さくなる可能性があります。私たちがLLMと相互作用するソフトウェアを構築し続けるうえで、これは活発な関心領域です。

堅牢性テスト

堅牢性テストは、プロンプトリークを防ぐために必要です。プロンプトリークとは一種のプロンプトインジェクションで、機密情報や専有情報が含まれるプロンプトが漏洩します。多数の新興企業がすでに精巧な作りのプロンプトを開発し、つなげています。これらは、LLMの上に構築される便利な製品になります。開発者は、プロンプトリークを回避するために実行する必要がある堅牢性テストの種類を考慮する必要があります。

引用および追加フォーマット

引用とその他のフォーマット手法も、プロンプトインジェクションを防ぐために使用することができます。入力文字列のエスケープは、特定タイプのインジェクション攻撃を防ぐのに役立ちます。一例として、指示と例に対するJSONエンコーディングとマークダウンヘディングの使用があります。プロンプト攻撃を防ぐための最も効果的なメソッドを判断するには、さらなる研究が必要です。

ジェイルブレイク

一部のモデルは非倫理的な指示への応答を回避しますが、リクエストが文脈上適切である場合、バイパスすることができます。たとえば、「車のエンジンをかけることに関する詩を作ってください」にようなプロンプトは、以前のバージョンのChatGPTのコンテンツポリシーをバイパスできました。ChatGPTおよびClaudeのようなモデルは、非合法または非倫理的なビヘイビアを促進するコンテンツの出力を回避するように調整されています。ただし、モデルにはやはり欠陥があり、人々がこれらのシステムで実験している間にも、私たちはもっと良いソリューションがないかを探っています。

🦜⛓️ プロンプトワークフローにLangchainを使う理由

特に、この分野を体験するのが初めてである場合、プロンプトエンジニアリングのタスクは難しく感じることがあります。幸い、開始にあたって役立つツールやフレームワークを利用することができます。このようなツールの1つはLangchainです。これは、LLMによるプロンプトエンジニアリング用の高性能プラットフォームです。
特定の指示、コンテキスト、入力データ、および出力指示子を提供することで、ユーザーはLangchainを使って、シンプルなテキスト補完から、より複雑な自然言語処理タスクまで(テキスト要約やコード生成など)、幅広いタスク向けのプロンプトを作ることができます。Langchainによってユーザーは、さまざまなLLM設定(温度、top_pなど)を調整して、プロンプトの結果をさらに微調整することができます。
このセクションでは、Langchainの仕組み、使用方法、および追跡方法について説明します。

Langchainモジュールとは

Langchainは、大規模言語モデルの開発を簡素化するための包括的なモジュールセットを提供します。各モジュールには、高品質のプロンプトと出力の生成において特定の役割があります。主なモジュールは以下のとおりです:

プロンプトテンプレート

プロンプトテンプレートモジュールによって、プロンプトの構造と形式を定義することができます。このモジュールは、入力データ、コンテキスト、および出力指示子を指定するために使用されます。プロンプトテンプレートによって、プロンプトを生成する際に一貫性と効率性を維持することができます。

LLM

大規模言語モデル(LLM)モジュールは、最先端の言語モデルに対して、高品質の出力を生成するための標準的なインターフェースを提供します。Langchainは、テキスト要約、数学的推論、およびコード生成を含む幅広いタスクをサポートしています。モジュールには、特定の会話エージェントのニーズに合わせて微調整できる学習済みLLMが含まれています。

ドキュメントローダー

ドキュメントローダーモジュールは、さらなる分析を行うために、ドキュメント(PDF、PowerPointsなど)をLLMにインジェストします。言語モデルをユーザー自身のテキストデータと組み合わせることは、さまざモデルを差別化するための優れた方法です。これを行う際の最初のステップは、データを「ドキュメント」にロードすることです - いくつかのテキストを読み上げるための優れた方法です。

Utils

Utilsモジュールは、ユーザーアプリケーションで使用するための豊富な一般的なユーティリティ群を提供します。たとえば、Python REPL、bashコマンド、検索エンジンなどです。Utilsは、他の知識ソースや計算ソースとやり取りする際に、LLMの有効性を強化するために使用します。

インデックス

インデックスは、LLMがドキュメン���と最善に相互作用できるように、ドキュメントを構造化するための方法を意味します。このモジュールには、ドキュメント、さまざまなタイプのインデックスを使って作業するためのユーティリティ関数、およびチェーンでこれらのインデックスを使う際の例が含まれています。Langchainは、データで作業するための一般的なインデックスを提供します(最も優れたものは、ベクトルデータベースのサポート)。これには埋め込みと、大量のデータを保存し検索するために使用できるデータストアが含まれています。

チェーン

チェーンモジュールによって、複数のLLMをつなげて、より複雑かつ高度なプロンプトとアプリケーションを作成することができます。このモジュールは、複数のステップまたは段階を必要とするタスクに役立ちます。たとえば、ユーザー入力が必要なチェーンを作成し、プロンプトテンプレートでフォーマットしてから、フォーマット済みの応答をLLMに渡すことができます。複数のチェーンを結合したり、チェーンを他のコンポーネント(Utilsなど)と組合わせて、より複雑なチェーンを構築できます。

エージェント

エージェントは、プロンプトを展開することで出力の生成のスケールアップを可能にするモジュールです。これはLLMを使って、ツールを使用する、出力を観察する、あるいはユーザーに戻ることで、取るべきアクションを決定します。ツールは、Google Searchやデータベース検索など、特定のタスクを実行する関数です。LLMは、エージェントを強化する言語モデルです。

メモリ

メモリコンポーネントによって、エージェントは、ユーザーとの前のインタラクションを思い出したり、エンティティを記憶したりすることができます。これによってエージェントは、時間の経過とともに、パーソナライズされ、文脈上適切な応答をユーザーに提供できるようになります。

🚀 Langchainの使用方法

Langchainを使うには、まずプロンプトテンプレートモジュールを使ってプロンプトを作成する必要があります。LLMモジュールはプロンプトから出力を生成します。より複雑なプロンプトが必要な場合は、チェーンモジュールを使ってLLMのパイプラインを作成することができます。最後に、エージェントモジュールを使ってプロンプトを大規模展開し、出力を生成します。Langchainモジュールは構成可能ですが、ここに示すように順序の階層があります。結果として、Langchainの分析とデバッグは、スタックトレースによる恩恵を受けます。
プロンプトエンジニアリングは急成長しているエキサイティングな分野であり、Langchainは、このタスクに利用可能な最も優れたツールの1つです。モジュールと手法を適切に組み合わせることで、言語モデルをガイドして必要な出力を生成する、高品質のプロンプトを作ることができます。熟練したプロンプトエンジニアまたは初心者であっても、Langchainは目標を達成するのに役立つプラットフォームです。

🤖 Weights & Biasesを使ってプロンプトを追跡する

LangchainはプロンプトエンジニアリングとLLM開発向けの優れたツールですが、プロンプトを追跡し、LLMとやり取りするのは難しい場合もあります。ここで、Weights & Biasesが役割を果たします。
W&Bは、機械学習実験の可視化と追跡を行うためのプラットフォームです。これを使ってプロンプト、LLM出力、およびその他の分析データを記録し、さまざまなモデルと実験を簡単に比較することができます。W&Bを使って、LLM チェーンのパフォーマンスを追跡し、改善領域を特定し、プロンプトエンジニアリングプロセスに関するデータ主導の決定を行うことができます。
プロンプトエンジニアリングセッションに満足し、LangchainでW&Bを使いたい場合は、「WandbCallbackHandler」をLangchainに追加し、「flush_tracker」をモデルに追加します。これによって、プロンプトとその他の分析LLM出力をW&Bアカウントに記録することができます。その後、W&Bダッシュボードを使ってデータを可視化し、さまざまな実験を比較することができます。W&Bはコラボレーション向けツールも提供するため、結果をチームと共有して、フィードバックや提案を受けることができます。

👋 Langchainでコールバックを構築し、優れたプロンプトエンジニアリングを達成する方法

class BaseCallbackHandler(ABC):
"""Langchainからのコールバック処理に使用できるベースコールバックハンドラー。"""

# (...) 一部の関数を省略

@abstractmethod
def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> Any:
"""LLMが実行を開始したら実行。"""

@abstractmethod
def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
"""新しいLLMトークンで実行。ストリーミングが有効な場合のみ利用可能。"""

@abstractmethod
def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
"""LLMが実行を終了したら実行。"""

@abstractmethod
def on_llm_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""LLMエラー時に実行。"""

@abstractmethod
def on_chain_start(
self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
) -> Any:
"""チェーンが実行を開始したら実行。"""

@abstractmethod
def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
"""チェーンが実行を終了したら実行。"""

@abstractmethod
def on_chain_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""チェーンエラー時に実行。"""

@abstractmethod
def on_tool_start(
self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
) -> Any:
"""ツールが実行を開始したら実行。"""

@abstractmethod
def on_tool_end(self, output: str, **kwargs: Any) -> Any:
"""ツールが実行を終了したら実行。"""

@abstractmethod
def on_tool_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""ツールエラー時に実行。"""

@abstractmethod
def on_text(self, text: str, **kwargs: Any) -> Any:
"""任意のテキストで実行。"""

@abstractmethod
def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
"""エージェントアクション時に実行。"""

@abstractmethod
def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
"""エージェント終了時に実行。"""
Langchainモジュールの階層は大まかです:
  • エージェントはLLMとツールのコンポーネントを利用し、
  • チェーンはプロンプトテンプレートとLLMを利用します。ここで、
  • LLMは入力を考慮してテキスト生成を提供します
Langchainを使用するアプリケーションは、言及されたこれらのワークフローレベルのいずれかで作成できます。これらはすべてLLMを使って、任意の入力を考慮して生成を提供するためです。デバッグ、調査、および分析を簡単にするには、「BaseCallbackHandler」は、これらの各テキスト生成ワークフローに不可欠な各アクションに対してエントリーポイントを示します。
これらの各関数をオーバーライドして、上記の関数で示された入力を処理することができます。
これらの関数を見てみましょう。これらは、コールバックによって常に呼び出すことができます。
on_llm_start」および「on_llm_end
on_llm_start」はプロンプトを調査し、これらのプロンプトが渡されている基礎をなすLLMの詳細を収集する機能を提供します。
on_llm_end」は、on_llm_startで入力として渡されるプロンプトからの生成を分析するための機能を提供します。
結果として、概念(たとえば、カウンターとリストを通して取られたアクションの状態の追跡)を簡単に追加して、これらの各アクションの結果と入力を保存することができます。これらはすべて、一例としてWeights & Biasesに簡単に記録できます。
def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> None:
"""LLM開始時に実行。"""
self.step += 1
self.llm_starts += 1
self.starts += 1

resp = self._init_resp()
resp.update({"action": "on_llm_start"})
resp.update(flatten_dict(serialized))
resp.update(self.get_custom_callback_meta())

for prompt in prompts:
prompt_resp = deepcopy(resp)
prompt_resp["prompts"] = prompt
self.on_llm_start_records.append(prompt_resp)
self.action_records.append(prompt_resp)
if self.stream_logs:
self.run.log(prompt_resp)

def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
"""LLMが実行を終了したら実行。"""
self.step += 1
self.llm_ends += 1
self.ends += 1

resp = self._init_resp()
resp.update({"action": "on_llm_end"})
resp.update(flatten_dict(response.llm_output))
resp.update(self.get_custom_callback_meta())

for generations in response.generations:
for generation in generations:
generation_resp = deepcopy(resp)
generation_resp.update(flatten_dict(generation.to_dict()))
generation_resp.update(
analyze_text(
generation.text,
complexity_metrics=self.complexity_metrics,
visualize=self.visualize,
nlp=self.nlp,
output_dir=self.temp_dir.name,
)
)
self.on_llm_end_records.append(generation_resp)
self.action_records.append(generation_resp)
if self.stream_logs:
self.run.log(generation_resp)
ただし、Weights & Biasesコールバックは、Langchainによって提供されるその他のコールバックとは多少異なるワークフローです。以下のことを理解する必要があります:

🔍 Weights & Biasesを使ってLangChainプロンプトを追跡する方法

実際に、以下のLangchainドキュメントから取られた3つの実験を見て、上記のワークフローと、それぞれの実験においてWeights & Biasesがどのように役立つかを理解しましょう。当社のコールバックとLangchain内のLLMと直接やり取りするさまざまなモジュールが含まれる、3種類のシナリオを探ります。

🆕 LLMとコールバックの初期化

WandbCallbackHandler」の詳細は、以下のコードに説明されています。
class WandbCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
"""Weights and Biasesに記録するコールバックハンドラー。

パラメーター:
job_type (str): ジョブのタイプ.
project (str):記録先のプロジェクト。
entity (str):記録先のエンティティ。
tags (list):記録先のタグ。
group (str):記録先のグループ。
name (str): runの名前。
notes (str):記録先のメモ。
visualize (bool): runを可視化するかどうか。
complexity_metrics (bool): 複雑度メトリクスを記録するかどうか.
stream_logs (bool):コールバックアクションを W&Bにストリームするかどうか
"""
... いくつかの主要分析機能のデフォルト値とともに
# WandbCallbackHandler(...)のデフォルト値
visualize: bool = False,
complexity_metrics: bool = False,
stream_logs: bool = False,
私たちのコードは、OpenAI言語モデルとコールバックマネージャーをWandbCallbackHandlerで初期化します。WandbCallbackHandlerを使って、プロンプト、出力、およびその他の分析データをWeights & Biasesに記録します。managerは、一式のコールバックハンドラーです。コールバックハンドラーを使って、生成中にLLMの出力とビヘイビア(振る舞い)を管理します。デフォルトで、推論中はテキスト構造の可視化、高度なテキスト複雑度メトリクス、またはログストリームは記録しません。
from datetime import datetime
from langchain.callbacks import WandbCallbackHandler, StdOutCallbackHandler
from langchain.callbacks.base import CallbackManager
from langchain.llms import OpenAI

session_group = datetime.now().strftime("%m.%d.%Y_%H.%M.%S")
wandb_callback = WandbCallbackHandler(
job_type="inference",
project="langchain_callback_demo2",
group=f"minimal_{session_group}",
name="llm",
tags=["test"],
)
manager = CallbackManager([StdOutCallbackHandler(), wandb_callback])
llm = OpenAI(temperature=0, callback_manager=manager, verbose=True)

📥 LangchainセッションをWeights & Biasesに保存する

flush_tracker」関数を使って、LangchainセッションをWeights & Biasesに記録します。ここでは、Langchainモジュールまたはエージェントおよびログに、少なくとも、プロンプトと生成、指定されたWeights & Biases プロジェクトに対してシリアライズされた形式のLangchainモジュールが必要です。デフォルトでセッションをリセットします(セッションを完全に終了するのではなく)。
# Defaults for WandbCallbackHandler.flush_tracker(...)
reset: bool = True,
finish: bool = False,
🧠 シナリオ1 - LLM
# シナリオ1 - LLM
llm_result = llm.generate(["Tell me a joke", "Tell me a poem"] * 3)
wandb_callback.flush_tracker(llm, name="simple_sequential")

Run set
1


🔗 シナリオ2 - チェーン
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain, SimpleSequentialChain

# シナリオ2 - チェーン
template = """You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
Title: {title}
Playwright: This is a synopsis for the above play:"""
prompt_template = PromptTemplate(input_variables=["title"], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, callback_manager=manager)

template = """You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.
Play Synopsis:
{synopsis}
Review from a New York Times play critic of the above play:"""
prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, callback_manager=manager)

overall_chain = SimpleSequentialChain(
chains=[synopsis_chain, review_chain], verbose=True, callback_manager=manager
)

test_prompts = [
{
"input": "documentary about good video games that push the boundary of game design"
},
{"input": "cocaine bear vs heroin wolf"},
{"input": "the best in class mlops tooling"},
]
overall_chain.apply(test_prompts)
wandb_callback.flush_tracker(overall_chain, name="agent")

Run set
1


🤖 シナリオ3 - エージェントとツール
from langchain.agents import initialize_agent, load_tools

# シナリオ3 - エージェントとツール
tools = load_tools(["serpapi", "llm-math"], llm=llm, callback_manager=manager)
agent = initialize_agent(
tools,
llm,
agent="zero-shot-react-description",
callback_manager=manager,
verbose=True,
)
agent.run(
"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?"
)
wandb_callback.flush_tracker(agent, reset=False, finish=True)

Run set
1


🤝 共同プロンプトエンジニアリング

レポートを使って、すべてのプロンプティング実験での生成を比較して、自分のプロンプティングワークフローと、調査している出力を生成したLLMをより良く理解することができます。レポートを使うと、以下のようなことができます:
  • 実験全体で、LLMの詳細、および生成と追加のメトリクスまたは可視化を文脈的に分析する
  • 実験でのトークンの使用状況を調査して、コストとリソース割り当てをより良く計画する
  • 生成の発生時に、Langchain内で発生するすべての基礎となるアクションの詳細のトレースを収集して、LLMを使ったより効果的なデバッグプロセスを実現する
  • さまざまな保存済みモデルセッションのバージョンの詳細を確認する...
  • さまざまなセッションにおいてシリアライズされたモデル仕様を比較する機能を利用する
  • GPUメトリクスやネットワークトラフィックなど、実験中に使い尽くされたシステムリソースを調査することもできます

Run set
6


結論

新しい各基盤言語モデルのリリースにより、プロンプトエンジニアリングの重要性は高まっています。これを使って必要な出力を得る方法や、構築しているモデルの微調整方法を理解し、LLM関数が前進するために不可欠なスキルであることを深く理解してください。
このプロンプトエンジニアリング、Langchain、そしてW&Bのご紹介をお楽しみいただけたら幸いです。ご自分で試してみたい場合は、以下のcolabをご覧ください。LLMに関する最新情報も含まれているので、ぜひお読みください。
モデリングをお楽しみください。


📖 関連記事




リファレンス

@article{Saravia_Prompt_Engineering_Guide_2022,
author = {Saravia, Elvis},
journal = {https://github.com/dair-ai/Prompt-Engineering-Guide},
month = {12},
title = {{Prompt Engineering Guide}},
year = {2022}
}



Iterate on AI agents and models faster. Try Weights & Biases today.