目次
■人工知能(AI)と機械学習
2024.01.16 2024.01.23 約4分
LangChainを基にしたLLMアプリ開発の入門から、ChatGPTの使い方、プロンプトエンジニアリングの基本、LangChainのモジュール解説までを網羅したガイド。
この記事は、2023年11月21日開催 『ChatGPT/LangChainによるチャットシステム構築[実践]入門』共同著者 大嶋 勇樹 氏による講演を再編集し記事化したものです。 |
共同著者 吉田 真吾 氏の講演はこちら
エンジニアの間で注目を集める ChatGPT 。「このエラーはどういう意味?」や「こんなプログラムを書いて」といった指示にも適切に対応します。有料プランでは、GPT-4 や GPT-3.5 などのモデルを選択可能です。これらは大規模言語モデル(Large Language Model: LLM)と呼ばれ、多くの組織が ChatGPT の API を活用したアプリケーション開発に着手しています。その応用例には、社内文書に基づいて回答するチャットボット、自然言語から SQL を自動生成・実行するツール、特定の口調や性格を持つ AI キャラクターなどが含まれます。
LLM アプリ開発の盛り上がりは、これまでの AI との一線を画す点に起因します。従来のチャット AI や要約翻訳 AI、小説生成 AI は、用途ごとに個別の開発が必要で、ファインチューニングや機械学習の知識、専用の GPU 環境が求められていました。一方で、LLM は「以下の文章を要約してください」のような自然言語の入力で多様な用途に応えられます。例えば、「要約して」と言えば要約し、「翻訳して」と言えば翻訳するなど、柔軟な対応が可能です。
GPT-3.5 や GPT-4 といったモデルは、API を介して手軽に利用できるようになりました。ChatGPT の API が登場したことで、AI をアプリケーションに組み込む際の障壁が大幅に低減し、新たな可能性の扉が開かれました。
LLMは、入力されたテキスト(プロンプト)を基に応答テキストを生成します。そのため、プロンプトの記述方法が非常に重要です。この入力プロンプトの工夫を「プロンプトエンジニアリング」と称します。プロンプトエンジニアリングに関するナレッジは、以下のリソースが参考になります。
https://platform.openai.com/docs/guides/prompt-engineering
|
Prompt Engineering Guideでは、プロンプトに以下の要素が含まれると整理されています。
|
これらの要素をプロンプトに効果的に整理し、組み込むことがプロンプトエンジニアリングの定番の手法です。次のセクションで、これらについて詳しく解説していきます。
「命令と入力データの分離」は、 ChatGPT を使う際の基本です。命令と入力データを「 ### 」や「 “”” 」などの記号で区切る方法が一般的です。
例えば、ChatGPT に「プロンプトエンジニアリングとは?」と質問すると、長い回答が返ってくることがあります。ここで、「以下の質問に 3 行で答えてください。」と出力方式を指定することで、より簡潔な回答を得られます。
Description:▲上記のように「形式はJSONにしてください」という要望などにも応える
プロンプトに外部の情報を文脈として組み込む方法もあります。例えば、LangChain のドキュメントの特定のページを文脈にすることで、ChatGPT が本来知らないはずの「LangSmith」機能についても回答できます。ChatGPT は 2023 年 4 月までの知識で学習しているため、それ以降の情報には通常精通していません。しかし、適切な文脈をプロンプトに組み込むことで、知らない内容についても回答することが可能です。
*ただし、文脈がない場合は「わからない」と返答するか、不正確な回答をすることがあります
LLMを活用したアプリケーション開発は、プロンプトをテンプレート化することが一般的です。この方法では、ユーザーは必要な部分のみを入力し、残りはテンプレートで補完します。例えば、レシピ生成AIアプリを考えてみましょう。ここでは、ユーザーが「カレー」などの料理名を入力するだけで、この入力はバックエンドでLLMに送られます。そこで、既に用意されているプロンプトのテンプレートに沿ってAPIが呼び出され、必要な情報が生成されるのです。このように、プロンプトのテンプレート化により、アプリケーションの使用がより簡便かつ効率的になります。
プロンプトには多くの要素が含まれるため、すべてをユーザーに入力させるのではなく、テンプレート化して必要な部分だけを入力させましょう。
LangChain は、LLM を用いたアプリケーション開発に特化したフレームワークです。詳細はこちらのGitHubリポジトリで確認できます。主に Python と JavaScript / TypeScript での公式実装が提供されていますが、近年では Java や Go など、さまざまなプログラミング言語での LangChain 実装も登場しています。LangChain は、要約、チャットボット、ドキュメントへの Q&A など、LLM を活用した多種多様なアプリケーションに適用可能です。
LangChainには様々なモジュールがあり、多くの機能が提供されています。ここでは下記の6つを簡単にご紹介します。
|
LangChainでは、Language models モジュールで様々なLLMを簡単に扱えます。(最新版のドキュメントには「LLMs」や「Chat Models」といった新しい名称が採用されています。)
例えば、OpenAI の API を利用する際、LangChain が提供する ‘ChatOpenAI’ というクラスを使ってモデル名を指定し、’predict’ という統一された方法でAPIを呼び出すことができます。これにより、「自己紹介してください」というような指示に対して、「こんにちは、私は OpenAI の AI アシスタントです」といった自己紹介のテキストが生成される仕組みです。
Prompt Templates は、LLM の入力用プロンプトをテンプレート化するためのモジュールです。このモジュールは、プロンプトに動的に情報を挿入して(穴埋めして)、API 呼び出しを行う際に特に便利です。使い方は非常に簡単で、「プロンプトテンプレートクラス」を利用します。
例えば、テンプレート「{料理名} のレシピを教えてください」に対して、プログラム上で「カレー」という具体的な料理名を挿入します。
実際には、Prompt Templates には文字列の穴埋め機能以外にも多くの機能が備わっていますが、基本的には文字列を柔軟にカスタマイズするための機能を提供しています。
LLM を活用したアプリケーション開発では、処理を連鎖させるニーズがしばしばあります。例えば、ユーザーが「カレー」と入力した場合、その入力に基づいてプロンプトテンプレートを穴埋めし、その後さらに LLM を呼び出してレシピを生成させるという処理の連鎖が考えられます。その際、「Chains」というモジュールを使用すると、このようなさまざまな処理をスムーズに連鎖させることが可能になります。
LLMを活用したアプリケーション開発では、より複雑な処理の連鎖が求められることが多々あります。
LLMに回答をステップバイステップで考えさせることで精度の向上が見込まれます。生成された出力を改めて LLM に要約させることで、より精緻な回答が得られます。
LLM にチャットボットとしての応答を生成させた後、その内容がサービスのポリシー(例えば差別表現など)に違反していないかをチェックします。
ユーザーの自然言語入力(例:「今月の売上は?」)に基づいて LLM に SQL を生成させ、データベースにその SQL を実行させます。その実行結果をもとに、LLM が自然言語で応答を生成します(例:「売上は ◯◯ 円でした」)。 |
ここまで、最も基礎的なモジュールについて見てきました。
|
次は「Memory」と「Retrieval」をご紹介します。
LLMを使用したチャットボットの実装では、会話履歴の管理が重要な要素となります。例えば、ユーザーが「昨日何を食べたか」と質問し、後に「昨日何を食べたと言ったか覚えている?」と再度尋ねるような場合、チャットボットが過去の会話を正確に覚えていることが求められます。
このような要求を満たすためには、ユーザーからの入力に対して、会話履歴のデータベースから過去の会話を検索し、それを新たなリクエストに含める必要があります。OpenAI が提供する GPT-3.5 や GPT-4 などのモデルは、API がステートレス(つまり、会話履歴を毎回プロンプトに含める必要がある)であるため、開発者は自ら会話履歴を管理する必要があります。最近では、ベータ版の API で会話履歴を管理する機能が提供されていますが、それでも一定の制約があるため、特定のユースケースでは自らの会話履歴管理が求められます。
そこで「Memory」というモジュールが役立ちます。Memoryモジュールを使用すると、開発者は会話履歴を効率的に管理し、LLMを用いたチャットボットにより自然で継続的な会話体験を提供できます。
GPT-3.5 や GPT-4 は 2023 年 4 月までの公開情報を基にしていますが、より新しい情報やプライベートなデータの活用が必要な場合があります。その際、プロンプトに文脈(context)を追加することが考えられます。しかし、GPT の API はトークン数に最大値の制限があるため、多くの情報を含めることには制約があります。
この課題を解決するために、RAG(Retrieval Augmented Generation)という手法を用います。この手法では、文書をベクトル化して Vector Stores に保存し、入力に関連する文章を検索します。検索された文書はプロンプトに組み込まれ、その内容を踏まえた上で LLM が回答を生成します。
Retrievalの使用例
「AIエージェント」は、LLMの応用例の中でも特に注目されています。AIエージェントは、与えられた目的に基づいて自律的に判断し、行動します。これらのエージェントは、必要に応じてWeb上の情報を検索して回答したり、試行錯誤を繰り返しながらプログラムを実装したりする能力を持ちます。LangChainの ‘Agents’ モジュールを使用すると、このようなシンプルなAIエージェントを容易に実装できます。例えば、「東京の天気を教えて」というユーザーの入力に対して、エージェントは検索が必要であると判断し、実際にWeb検索を行い、その結果をもとに回答を生成します。
今日はLangChainの基本的な機能に焦点を当てましたが、さらに応用的な機能や工夫も多数存在し、ドキュメントを読むだけでも楽しむことができます。
また、LangChainのエコシステムは絶えず拡大しています。例えば、「LangSmith」というデバッグ・テスト・評価・監視ツールや、「LangServe」というデプロイのためのパッケージ、さらには「LangChain Template」というリファレンスアプリケーションなどが新たに登場しています。
LangChain を学ぶことはLLMを使ったアプリケーション開発を学ぶことになります。ぜひ、私の書籍を参考にしてLangChainを実際に使ってみてください。