大規模言語モデル (LLM) は、非常に強力ですが、その知識はトレーニング データセットに限定されています。特に特定の、変化する、独自の情報に関する質問に答える際、LLMはハルシネーションを見せたり、一般的で無関係な回答を提供したりすることがあります。検索拡張生成(RAG) は、外部データソースから取得した関連する情報を LLM に提供することで役立ちます。
ただし、すべての RAG が同じように作成されるわけではありません。修正検索拡張生成(cRAG)は、単に従来のRAGの上に構築されているだけでなく、大幅な改善を表しています。取得した成果の品質と関連性を評価することで、より堅牢になるように考案されています。コンテキストが脆弱、無関係、または信頼できない情報源からの場合、cRAGは回答をでっち上げているのではなく、修正措置を通じてより適切な情報を見つけようとするか、明示的に回答を拒否します。この技術により、ポリシー関連の質問に答えるなどのクリティカルなアプリケーションにおいて、cRAGシステムの信頼性と信用性が高まります。
このチュートリアルでは、IBM GraniteモデルをWatsonxとLangChainで使用して、堅牢な修正RAG(cRAG)システムを構築する方法について説明します。LlamaIndexやLangGraphなどの同様のフレームワークも、個別のノードを持つ複雑な RAG フローの構築に使用できます。微調整などの手法により、ドメイン固有の RAG の特定の LLM の性能をさらに向上させることができます。OpenAIのようなLLM(たとえば、ChatGPTのようなGPTモデル)もこのようなエージェントの一般的な選択肢ですが、このチュートリアルではIBM Graniteに焦点を当てています。
ここでは、特定の保険契約書(PDF)に関する質問に答えるというユースケースに焦点を当てます。このチュートリアルでは、次のような高度なRAGアルゴリズムの実装について説明します。
独自の PDF ドキュメントから情報を取得します。
内部の文書が回答を生成するのに不十分な場合、エージェントはフォールバックとして外部Web検索(Tavily)を使用できます。
エージェントは無関係な外部の成果をインテリジェントに除外し、回答がプライベートポリシーに合わせて調整されるようにします。
エージェントは、利用可能な場合は部分的な情報を使用して明確かつ限定的な応答を行い、コンテキストが欠落している場合は明確に拒否します。
このチュートリアルでは、保険契約文書(PDFのパンフレット)を分析し、ユーザーの質問に正確に答えるように設計された保険契約クエリー・エージェントの作成について説明します。IBM GraniteモデルとLangChainを使用して、高品質でソースに制約のある回答を保証する堅固な検索および検証ステップを備えたエージェントを構築します。
信頼できるRAGの基本原則がユースケースにどのように適用されるかを理解しましょう。
内部知識ベース(PDF):エージェントの主要な情報源は、お客様の保険証書PDFです。このドキュメントを検索可能なベクトル・ストアに変換します。
外部検索フォールバック (Tavily):内部ナレッジベースに十分な情報がない場合、エージェントはTavilyを通して外部のウェブソースを参照することができます。Tavilyは、AIエージェントとLLM専用に構築された検索エンジンで、RAGベースのアプリケーションーション向けのアプリケーション・プログラミング・インターフェース(API)を通じて、より高速なリアルタイムの検索を実現します。
コンテキストスコア:LLMベースの検索評価者(採点者の役割)は、高品質の検索項目のみが含まれるようにしながら、内部PDFから検索された項目の関連性にスコアを提供します。
クエリの書き換え:ウェブ検索の場合、エージェントはユーザーのクエリを言い換えて、関連する外部情報を見つける可能性を高めることができます。
ソースの検証:LLMを利用したチェックでは、外部のウェブ検索成果が民間保険契約に関連しているかどうかを評価し、ヘルスプログラム(Medi-Calなど)に関する一般情報や詳細を除外します。この機能により、誤解を招く回答の生成を防ぎ、自己修正を可能にするため、知識の洗練を支援します。
制約された生成:LLMへの最終プロンプトでは、提供されたコンテキストのみを使用するか、正確な回答を提供する、情報が利用できない場合の状態、または明示的な制限を用いて部分的な回答を提供するように厳密に指示します。この機能により、生成された応答の適応性と信頼性が向上します。
watsonx.aiプロジェクトを作成するにはIBM Cloudのアカウントが必要です。watsonx APIキーとプロジェクトIDの両方にアクセスできることを確認してください。Web検索機能を使用するには、Tavily AIのAPIキーも必要になります。
いくつかあるツールの中から選択することもできますが、このチュートリアルでは、Jupyter Notebookを使用してIBMアカウントを設定する方法について説明します。
このステップでは、このチュートリアルのコードをコピーできるノートブック環境を開きます。あるいは、このノートブックをローカル・システムにダウンロードし、watsonx.aiプロジェクトにアセットとしてアップロードすることもできます。さらにGraniteのチュートリアルを表示するには、IBM® Graniteコミュニティをご覧ください。このチュートリアルはGithubでも公開されています。
LangChainのフレームワークを使用し、IBM® WatsonxLLMを統合するには、いくつかの必須ライブラリーをインストールする必要があります。必要なパッケージをインストールすることから始めましょう。このセットには、RAGフレームワーク用のlangchain、watsonx統合用のlangchain-ibm 、効率的なベクターストレージ用のfaiss-cpu 、PDFを処理するためのPyPDF2 、埋め込みとWeb API呼び出しの要求を取得するためのsentence-transformersが含まれています。これらのライブラリは、機械学習およびNLPソリューションを適用する上でクリティカルです。
注:GPUは不要ですが、CPUベースのシステムでは実行速度が低下する可能性があります。このステップでは、このチュートリアルのコードをコピーできるノートブック環境を開きます。このチュートリアルは、GitHubでも公開されています。
次に、必要なすべてのモジュールをインポートし、watsonxとTavilyのAPIキーとwatsonxのプロジェクトIDを安全に指定します。
osは、オペレーティングシステムとの連携に役立ちます。
ioは、データのストリームを扱うことができます。
getpassは、APIキーなどの機密情報を安全な方法でキャプチャし、画面にインプットを表示しません。
PyPDF2.PdfReaderは、PDFからのコンテンツ抽出を可能にします。
langchain_ibm.WatsonxLLMを使用すると、LangChainフレームワーク内でIBM Watsonx Granite LLMを簡単に使用できるようになります。
langchain.embeddings.HuggingFaceEmbeddings は、HuggingFaceモデルを使用し、セマンティック検索にとって重要な埋め込みを生成します。
langchain.vectorstores.FAISS は、効率的なベクトルストレージと類似性検索のためのライブラリで、ベクトルインデックスを構築してクエリを実行できます。
langchain.text_splitter.RecursiveCharacterTextSplitterは、大きなテキストを、メモリに収まらないようなドキュメントを処理するために必要な小さな塊に分割するのに役立ちます。
langchain.schema.Document、は任意のテキスト単位と関連するメタデータを表し、langchainの構成要素となります。
requestsは、APIに対して外部からHTTPリクエストを行う際に使用されます。
boxocore.client.Configは、AWS/IBM Cloud Object Storageクライアントの構成設定を定義するために使用される構成クラスです。
ibm_boto3は、Cloud Object Storageとの対話に役立つIBM Cloud Object Storage SDK for Pythonです。
langchain.prompts.PromptTemplate は、言語モデル用の再利用可能な構造化プロンプトを作成する方法を提供します。
langchain.tools.BaseToolは、LangChainエージェントに使用させるカスタムツールを構築するための基本クラスです。
このステップでは、テキストの処理、埋め込みの作成、ベクトル・データベースへの保管、IBMのWatsonxLLMとの対話に必要なすべてのツールとモジュールをセットアップします。さまざまなデータ型のソーシング、クエリ、検索が可能な実際のRAGシステムの作成に必要なすべての部分を確立します。
このステップでは、IBM Cloud Object Storageから保険契約のPDFをロードします。コードはPDFを読み取り、テキスト内容を読み取り、テキストをより小さく管理しやすいチャンクに分割します。これらのチャンクは数値埋め込みに変換され、FAISSベクトル・ストアに保存され、後でローカル・コンテキストで意味論的類似性検索を行い、成果を最適化できます。
ibm_boto3.clientでは、クライアントがIBM Cloud Object Storageと対話できるようになります。
バケットは、PDFを含むCloud Object Storageの名前です。
object_keyは、Cloud Object Storageバケット内のPDFの名前です。
cos_client.get_object(...).read()は、Cloud Object StorageにあるPDFファイルの内容をバイトとして取得します。
io.BytesIOは、PDFの生バイトを、PdfReaderで使用できる形式のメモリ内バイナリストリームに変換します。
PdfReaderは、PDFからテキストを解析し抽出することができるオブジェクトを作成します。
page.extract_text()は、PDF内の1ページのテキストを抽出します。
RecursiveCharacterTextSplitterは、抽出されたテキストを50文字の重なりを持つ500文字のチャンクに分割するように設定されています。
splitter.split_text(text)は、PDF テキストのすべてのページを小さなチャンクに分割します
HuggingFaceEmbeddingsは、テキストチャンクを密なベクトル表現に変換するために事前に学習された文変換モデルをロードします。
FAISS.from_texts(チャンク、埋め込み)は、テキストのチャンクを意味上の類似性によって検索できるようにするメモリ内FAISSインデックスを構築します。
このステップでは、クラウドからLLM対応テキストへのPDFドキュメントの完全な取り込みと、リアルタイム検索のための快適なインデックス作成が処理されます。
このステップでは、エージェントの推論を促進し、Tavily Web検索機能と統合するようにIBM Granite LLMを構成します。LLMのパラメーターは、事実に基づいた安定した応答を実現するために設定されています。
WatsonxLLMは、IBM watsonxのLLMラッパーをインスタンス化し、Graniteモデルとのやりとりを可能にします。
model_id="ibm/granite-3-2b-instruct"は、命令ベースの生成AIタスク用に設計されたIBM Graniteモデル(27億パラメーターの命令モデル)です。
class TavilySearch(BaseTool)は、Tavily APIを使ってウェブ検索を実行するためのカスタム LangChainツールを定義します。
tavily_tool = TavilySearch()は、カスタムTavily検索ツールの実行可能インスタンスを作成します。
watsonxLLMを初期化すると、以前に設定した認証情報のURL、APIkey、Project_idの値が認証され、サービスに渡されます。「max_new_tokens」:300などのパラメータは、応答の長さを制限し、「温度」:0.2は出力の創造性を制御し、より決定的な結果を優先します。
TavilySearchクラスの定義には、その機能の説明が含まれています。そのロジックはdef _run(self, query: str)メソッドに含まれています。このメソッドでは、TAVILY_API_KEYとJSONペイロードの検索クエリを含むTavily APIエンドポイントに、HTTP POSTリクエストを実行します。次に、Response. Raise_for_status()を使用してHTTPエラーがあるかどうかを確認します。JSON応答を解析し、最初の検索結果のコンテンツ・スニペットにアクセスすることもできます。
このステップでは、テキスト生成用の言語モデルをセットアップし、言語モデルの知識を強化する方法として外部のWeb検索ツールを含めます。
このステップでは、RAGプロセスのさまざまな段階でLLMの動作をガイドするさまざまなプロンプト・テンプレートを定義します。このアプローチには、内部文書のチャンクの関連性をスコアリングするプロンプト、Web検索を改善するユーザー・クエリーの書き換え、Web検索結果の出所をVerifyするためのクリティカルな新しいプロンプトが含まれます。チャンクをスコアリングし、ベクトル・ストアから取得するためのヘルパー関数も定義されています。
このステップでは、RAGプロセスのさまざまな段階でLLMの動作をガイドするさまざまなプロンプト・テンプレートを定義します。内部文書のチャンクの関連性をスコアリングするためのプロンプト、より適切なWeb検索のためにユーザー・クエリを書き換える、およびWeb検索結果のVerifyが含まれていることを確認するためのクリティカルな新しいプロンプト。チャンクをスコアリングし、ベクトル・ストアから取得するためのヘルパー関数も定義されています。
PromptTemplate.from_templateは、プロンプトを作成するための再利用可能なテンプレートを作成するためのLangChainのユーティリティ関数です。
logging_prompt_templateは、LLMが評価者として機能し、質問に基づいて特定のコンテキストチャンクに関連性スコア(0~5)を割り当てるように指示するプロンプトを定義します。
rewrite_prompt_templateは、LLMがユーザーの元の質問を改善したり、検索しやすくするためにガイドするプロンプトを定義します。
CONTEXT_SOURCE_VERIFICATION_PROMPTは、LLMに指示するプロンプトを定義し、テキスト(例えば、Web検索から)がプライベート・ポリシー・コンテキスト、または一般または公開ソースからのものであるかを確認します。
def score_chunks(chunks, query)は、テキストチャンクのリストとクエリを受け取り、LLMを使って各チャンクの関連性をスコア化する関数を定義すします。
defget_from_vectorstore(query)は、FAISS ベクトル・ストアから最も類似したドキュメントを取得する関数を定義します。
score_chunks関数内では、空のスコア付きリストが初期化されます。各チャンクに対して、scoring_prompt_templateは、特定のクエリーとチャンクでフォーマットされます。このフォーマットされたプロンプトがLLMに送信され、応答が除去されます。この関数は、モデルの応答内の「Score:」行を識別することにより、整数スコア(関連性または関連性のないものに単純化される場合は2進数スコア)を抽出しようとします。チャンクは、解析またはデフォルトのスコアとともにスコア付けリストに追加されます。システムのこの部分は、検索評価者または採点者として機能します。
関数retrieve_from_vectorstoreは、vectorstore.similarity_searchで、クエリに基づいて最も関連性の高い8つのドキュメントチャンクを検索し、検索されたLangChain Documentオブジェクトからpage_contentを取得します。
このステップでは、LLMがコンテキストと内部および外部の知識ソースから知識を取得する方法を評価できるように、修正RAGシステムの概念足場が構築されます。
最初の取得は、PDFのベクトルストアをスキャンする機能です。
コンテキストスコアリングは、関連性に応じてコンテキストスコアを付けるために、取得されたPDFチャンクを取ります。
PDFから十分な関連コンテキストがない場合、Tavilyにフォールバックし、Tavily(ウェブ検索)に問い合わせます。
ソース検証は、Tavilyの成果がプライベート・ポリシーに関連しているかどうかを使用する前に確認するLLMを利用したステップです。この機能は、公衆ヘルスプログラムからの誤解を招く回答を防ぎます。
クエリの書き換えと2回目のタビリーサーチは、まだ良いコンテキストがなければ、クエリを書き換えて再度タビリーサーチを試みます。
最終決定は、関連するコンテキストがある場合、回答を作成するための(厳密な)プロンプトを備えてLLMに送信されます。すべての実行可能な試行の後に関連するコンテキストがない場合は、丁寧な拒否を送信します。
policy_context_keywordsのパラメータの最初のパスでは、Tavilyの検索を絞り込むために、保険契約から特定の用語(例えば、その名前、保険会社)を追加することができます。
MIN_CONTEXT_LENGTHは、検索されるコンテキストの最小許容長を定義します。
SIMILARITY_THRESHOLDは、チャンクが「良い」とみなされるための最小関連性スコアを定義します。
def corrective_rag(...)は、修正RAGワークフロー全体を調整するメイン関数を定義します。
corrective_rag関数は、関連するコンテキストを収集するためのretrieved_context_piecesを作成することから始まります。まず、クエリに基づいてPDFベクトル・ストアからchunks_from_vectorstoreを取得してスコア付けし、次にstorage_chunks_vectorが言語モデルを使用してその関連性を評価します。SIMILARITY_THRESHOLDを満たすgood_chunks_vectorのみが保持されます。current_contextは、これらの断片からコンパイルされます。
current_contextがMIN_CONTEXT_LENGTHを下回っている場合、システムはWeb検索を試みます。tavily_search_queryを構築し、policy_context_keywordsを組み込む可能性があります。直接検索(tavily_context_direct)が実行されます。重要なのは、Verify_promptが作成され、LLMに送信され、Web検索結果(is_relevant_source)がパブリック・プログラムではなくプライベート・ポリシーからのものであるかどうかを判断することです。そうである場合、コンテキストが追加されます。
コンテキストが不十分な場合、システムはクエリを書き直す準備をします。rewrite_promptを使用してLLMからimproved_queryを取得し、2回目のWeb検索(tavily_context_rewritten)を実行します。この新しいコンテキストも、同じソース検証を受けます。
len(current_context.strip()) == 0が最後のチェックです。すべての試行後に関連するコンテキストが見つからない場合は、事前定義された拒否メッセージが返されます。それ以外の場合は、検証済みのすべてのコンテキストを使用してfinal_promptを作成し、言語モデルに送信して最終的な回答を生成します。
全体のCollective_rag関数は、修正RAGの段階的な取得、スコアリング、検証機能を詳細に処理します。これにより、知識ベースと知識ストリームを常に更新できるようになり、堅牢で状況に応じた回答が得られるというメリットがもたらされます。
最後に、サンプルのクエリーでcorrective_rag関数を実行します。PDF文書に固有のpolicy_context_keywordsを提供することが重要です。これらのキーワードは、TavilyのWeb検索が実際のヘルス政策により関連するものになり、一般的なヘルスプログラムや公衆ヘルスプログラムの情報がコンテキストを汚染するのを防ぐのに役立ちます。
印刷ステートメントを観察してコンテキストの長さと成果を観察し、情報の流れを理解します。
policy_specific_keywords = ["Super Star ヘルス", "Care ヘルス Insurance"]は、アップロードされた保険契約に関連するキーワードのリストを定義し、Web検索結果を絞り込むのに役立ちます。
query ="..."は、ユーザーが質問する可能性のある特定の質問を定義します。
result = corrective_rag(query, policy_context_keywords=policy_specific_keywords)は、メインのcorrective_rag関数を呼び出し、ユーザーのクエリとポリシー固有のキーワードを渡して、RAGプロセス全体を開始します。
print("\nFINAL ANSWER (...)")は、生成された答えを印刷する前に、クリアヘッダを表示します。
print(result)は、corrective_ragシステムから返された成果をアウトプットします。
このステップでは、サンプルのクエリとキーワードを使用して完全な修正RAGシステムを呼び出す方法を示し、実際のシナリオでのエンドツーエンドの機能を実証します。
RAGによる修正版では、社内のPDFナレッジ・ベースと外部サービス(Tavily)を完全に連携させて、複雑なリクエストに対する包括的な情報を取得できるようにしました。
LLMベースのスコアリングとクリティカルなソース検証を使用して、取得されたコンテキストを通じて正確に評価およびフィルタリングを行い、有効で信頼性の高い情報が使用されていることを確認します。
このシステムは、ユーザーのクエリーをインテリジェントに書き換えて、よりターゲットを絞った高品質の情報を要求することで外部検索を改善できることを実証しました。
制約生成を使用することで、信頼性が高く文脈に沿った正確な回答が通常生成され、検証済みの既知の情報が十分にない場合、システムは丁寧に回答を拒否しました。
この事例では、watsonx上のLangChainとIBM Granite LLMを使用して、保険保険に関する質問など機密性の高い領域で強力で信頼できるAIベースのアプリケーションを開発する方法を示しました。
生成AIを使用してワークフローとプロセスを自動化する強力なAIアシスタントとエージェントを構築、デプロイ、管理しましょう。
信頼できるAIソリューションでビジネスの未来を構築します。
IBMコンサルティングAIサービスは、企業がAIをトランスフォーメーションに活用する方法を再考するのに役立ちます。