Elasticsearch と LlamaIndex を使用して RAG の機密情報と PII 情報を保護する

Elasticsearch と LlamaIndex を使用して RAG アプリケーション内の機密データと PII データを保護する方法。

Elasticsearchは、業界をリードする生成AIツールやプロバイダーとネイティブに統合されています。RAG応用編やElasticベクトルデータベースで本番環境対応のアプリを構築する方法についてのウェビナーをご覧ください。

ユースケースに最適な検索ソリューションを構築するには、無料のクラウドトライアルを始めるか、ローカルマシンでElasticを試してみてください。

この記事では、RAG (Retrieval Augmented Generation) フローでパブリック LLM を使用する際に、個人識別情報 (PII) と機密データを保護する方法について説明します。オープンソース ライブラリと正規表現を使用して PII と機密データをマスキングする方法と、パブリック LLM を呼び出す前にローカル LLM を使用してデータをマスキングする方法を検討します。

始める前に、この投稿で使用するいくつかの用語を確認しましょう。

用語について

LlamaIndex は、LLM (大規模言語モデル) アプリケーションを構築するための主要なデータ フレームワークです。LlamaIndex は、RAG (Retrieval Augmented Generation) アプリケーションの構築のさまざまな段階に抽象化を提供します。LlamaIndex や LangChain などのフレームワークは、アプリケーションが特定の LLM の API に密結合されないように抽象化を提供します。

ElasticsearchElasticによって提供されています。Elastic は、精度の高い全文検索、意味理解のためのベクトル検索、両方の長所を生かしたハイブリッド検索をサポートするスケーラブルなデータ ストアおよびベクトル データベースである Elasticsearch を提供する業界リーダーです。Elasticsearch は、分散型の RESTful 検索および分析エンジン、スケーラブルなデータ ストア、およびベクター データベースです。このブログで使用している Elasticsearch 機能は、Elasticsearch の無料およびオープン バージョンで利用できます。

検索拡張生成 (RAG)は、LLM に外部知識を提供してユーザーのクエリに対する応答を生成する AI テクニック/パターンです。これにより、LLM 応答を特定のコンテキストに合わせてカスタマイズし、汎用性を抑えることができます。

埋め込みは、テキスト/メディアの意味を数値的に表現したものです。それらは高次元情報の低次元表現です。

RAGとデータ保護

一般的に、大規模言語モデル (LLM) は、インターネット データでトレーニングできるモデル内で利用可能な情報に基づいて応答を生成するのに適しています。ただし、モデル内で情報が得られないクエリの場合、LLM にはモデル内に含まれていない外部知識または特定の詳細が提供される必要がありま す。このような情報は、データベースまたは社内のナレッジ システム内にある可能性があります。検索拡張生成 (RAG) は、特定のユーザー クエリに対して、まず外部 (LLM に対して) システム (データベースなど) から関連するコンテキスト/情報を取得し、そのコンテキストをユーザー クエリとともに LLM に送信して、より具体的で関連性の高い応答を生成する手法です。

これにより、RAG テクニックは、質問への回答、コンテンツの作成、コンテキストと詳細の深い理解が役立つあらゆるアプリケーションに非常に効果的になります。

その結果、RAG パイプラインでは、PII (個人識別情報) などの内部情報や機密情報 (名前、生年月日、口座番号など) がパブリック LLM に公開されるリスクがあります。

Elasticsearch のようなベクター データベースを使用する場合、データは安全です (ロール ベースのアクセス制御ドキュメント レベルのセキュリティなどのさまざまな手段を通じて)。ただし、データを外部のパブリック LLM に送信する場合は注意が必要です。

大規模言語モデル (LLM) を使用する場合、個人を特定できる情報 (PII) と機密データを保護することは、いくつかの理由から重要です。

  • プライバシーコンプライアンス: 多くの地域では、ヨーロッパの一般データ保護規則 (GDPR) や米国のカリフォルニア州消費者プライバシー法 (CCPA) など、個人データの保護を義務付ける厳格な規制があります。法的責任や罰金を回避するには、これらの法律を遵守する必要があります。
  • ユーザーの信頼: 機密情報の機密性と整合性を確保することで、ユーザーの信頼が構築されます。ユーザーは、自分のプライバシーが保護されると信じるシステムを使用したり、やり取りしたりする可能性が高くなります。
  • データ セキュリティ: データ侵害に対する保護が不可欠です。適切な保護措置を講じずに LLM に公開された機密データは盗難や悪用される可能性があり、個人情報の盗難や金融詐欺などの潜在的な危害につながる可能性があります。
  • 倫理的な考慮事項: 倫理的には、ユーザーのプライバシーを尊重し、ユーザーのデータを責任を持って扱うことが重要です。個人情報を不適切に取り扱うと、差別、汚名、その他の社会的悪影響が生じる可能性があります。
  • 企業の評判: 機密データを保護できない企業は評判が損なわれる可能性があり、顧客や収益の喪失など、ビジネスに長期的な悪影響を及ぼす可能性があります。
  • 悪用リスクの軽減: 機密データを安全に扱うことで、偏ったデータでモデルをトレーニングしたり、データを使用して個人を操作したり害を与えたりするなど、データやモデルの悪意のある使用を防ぐことができます。

全体として、PII と機密データの堅牢な保護は、法令遵守の確保、ユーザーの信頼の維持、データ セキュリティの確保、倫理基準の遵守、ビジネスの評判の保護、不正使用のリスクの軽減に必要です。

簡単な要約

前回の投稿では、LlamaIndex とローカルで実行される Mistral LLM を使用しながら、Elasticsearch をベクター データベースとして RAG テクニックを使用して Q&A エクスペリエンスを実装する方法について説明しました。ここではそれを基に構築します。

前回の投稿を読むことはオプションです。今回は前回の投稿で行った内容を簡単に説明/要約します。

架空の住宅保険会社のエージェントと顧客間のコールセンターの会話のサンプル データセットがありました。私たちは、「顧客はどのような水関連の問題について請求をしているのか?」といった質問に答えるシンプルな RAG アプリケーションを構築しました。

大まかに言うと、フローは次のようになります。

インデックス作成フェーズでは、LlamaIndex パイプラインを使用してドキュメントを読み込み、インデックスを作成しました。ドキュメントはチャンク化され、埋め込みとともに Elasticsearch ベクター データベースに保存されました。

ユーザーが質問したクエリフェーズで、LlamaIndex はクエリに関連する上位 K 件の類似ドキュメントを取得しました。これらの上位 K 件の関連ドキュメントはクエリとともに、ローカルで実行されている Mistral LLM に送信され、ユーザーに返される応答が生成されました。ぜひ前回の投稿をご覧になったり、コードを調べたりしてください

前回の投稿では、LLM をローカルで実行しました。ただし、本番環境では、 OpenAIMistralAnthropicなどのさまざまな企業が提供する外部 LLM を使用する必要がある場合があります。ユースケースでより大きな基礎モデルが必要であるか、スケーラビリティ、可用性、パフォーマンスなどのエンタープライズ生産のニーズによりローカルでの実行がオプションではないことが原因である可能性があります。

RAG パイプラインに外部 LLM を導入すると、機密情報や PII が LLM に誤って漏洩するリスクが生じます。この投稿では、ドキュメントを外部 LLM に送信する前に、RAG パイプラインの一部として PII 情報をマスクする方法について説明します。

公立LLM取得のRAG

RAG パイプラインで PII と機密情報を保護する方法について説明する前に、まず LlamaIndex、Elasticsearch Vector データベース、OpenAI LLM を使用してシンプルな RAG アプリケーションを構築します。

要件

以下のものが必要となります。

  • 埋め込みを保存するためのベクター データベースとしてElasticsearch を起動して実行します。Elasticsearch のインストールに関する前回の投稿の手順に従ってください。
  • AI API キーを開きます。

シンプルなRAGアプリケーション

参考までに、コード全体はこのGithubリポジトリ(branch:protecting-pii)にあります。以下のコードを見ていくので、リポジトリのクローンは任意です。

お気に入りの IDE で、以下の 3 つのファイルを使用して新しい Python アプリケーションを作成します。

  • index.py データのインデックス作成に関連するコードが配置される場所。
  • query.py クエリと LLM の相互作用に関連するコードが配置される場所。
  • .env API キーなどの構成プロパティが配置される場所。

いくつかのパッケージをインストールする必要があります。まず、アプリケーションのルート フォルダーに新しい Python仮想環境を作成します。

仮想環境をアクティブ化し、以下の必要なパッケージをインストールします。

.envでOpenAIとElasticsearchの接続プロパティを設定するファイル。

データのインデックス作成

架空の住宅保険会社の顧客とコールセンターエージェント間の 会話 が含まれる conversations.json ファイルをダウンロードします。アプリケーションのルートディレクトリに、2つのPythonファイルと.envファイルと一緒にファイルを配置します。先ほど作成したファイル。以下はファイルの内容の例です。

データのインデックス作成を処理する以下のコードをindex.pyに貼り付けます。

上記のコードを実行すると、Elasticsearch にインデックスが作成され、 convo_indexという名前の Elasticsearch インデックスに埋め込みが保存されます。

LlamaIndex IngestionPipeline に関する説明が必要な場合は、 IngestionPipeline の作成セクションの前の投稿を参照してください。

クエリ

前回の投稿では、クエリにローカル LLM を使用しました。

この投稿では、以下に示すように、公開 LLM である OpenAI を使用します。

上記のコードは、OpenAI からの応答を以下のように出力します。

顧客は、地下室の水害、水道管の破裂、屋根への雹害、適時通知の欠如、メンテナンスの問題、徐々に進行する消耗、既存の損傷などの理由による請求の拒否など、さまざまな水関連の請求を提起しています。いずれの場合も、顧客は請求の却下に対する不満を表明し、請求に関する公正な評価と決定を求めました。

RAG での PII のマスキング

これまで説明してきたのは、ユーザークエリとともにドキュメントをそのまま OpenAI に送信することです。

RAG パイプラインでは、関連するコンテキストが Vector ストアから取得された後、クエリとコンテキストを LLM に送信する前に、PII と機密情報をマスクする機会があります。

外部 LLM に送信する前に PII 情報をマスクする方法はいくつかあり、それぞれにメリットがあります。以下のオプションをいくつか見てみましょう

  1. spacy.io やPresidio (Microsoft が管理するオープン ソース ライブラリ) などの NLP ライブラリを使用します。
  2. LlamaIndexをそのまま使用する NERPIINodePostprocessor.
  3. ローカルLLMの使用 PIINodePostprocessor

上記のいずれかの方法を使用してマスキング ロジックを実装したら、PostProcessor (独自のカスタム PostProcessor または LlamaIndex が提供するすぐに使用できる PostProcessor) を使用して LlamaIndex IngestionPipeline を構成できます。

NLPライブラリの使用

RAG パイプラインの一部として、NLP ライブラリを使用して機密データをマスクできます。このデモでは、spacy.io パッケージを使用します。

新しいファイルquery_masking_nlp.pyを作成し、以下のコードを追加します。

LLM による応答を以下に示します。

顧客からは、地下室の水害、水道管の破裂、屋根への雹害、大雨による浸水など、さまざまな水関連のクレームが出ています。これらの請求は、適時の通知の欠如、メンテナンスの問題、徐々に進行する消耗、既存の損傷などの理由に基づいて請求が拒否されたために、フラストレーションを招いています。顧客は、こうした請求拒否の結果、失望、ストレス、経済的負担を感じており、請求の公正な評価と徹底的な見直しを求めています。一部の顧客は保険金請求処理の遅延にも直面しており、保険会社が提供するサービスに対するさらなる不満が生じています。

上記のコードでは、Llama Index QueryEngine を作成するときに CustomPostProcessor を指定します。

QueryEngine によって呼び出されるロジックは、 CustomPostProcessor_postprocess_nodesメソッドで定義されています。私たちは SpaCy.io ライブラリを使用して名前付きエンティティを検出し、ドキュメントを LLM に送信する前に、いくつかの正規表現を使用してそれらの名前と機密情報を置き換えます。

以下に、元の会話の一部と、CustomPostProcessor によって作成されたマスクされた会話の例を示します。

原文:

顧客: こんにちは。私はマシュー ロペスです。生年月日は 1984 年 10 月 12 日、住所は 456 Cedar St, Smalltown, NY 34567 です。私の保険証券番号はTUV8901です。エージェント: こんにちは、マシュー。本日はどのようなご用件でしょうか?顧客: こんにちは。私の請求を却下するという貴社の決定に、大変失望しております。

CustomPostProcessor によってマスクされたテキスト。

顧客: こんにちは。私は [MASKED] です。[MASKED] は [DOB MASKED] で、456 Cedar St, [MASKED], [MASKED] 34567 に住んでいます。私の保険証券番号は[MASKED]です。エージェント: こんにちは、[MASKED]。本日はどのようなご用件でしょうか?顧客: こんにちは。私の請求を却下するという貴社の決定に、大変失望しております。

注記:

個人情報や機密情報を識別してマスキングすることは簡単な作業ではありません。機密情報のさまざまな形式とセマンティクスをカバーするには、ドメインとデータに関する十分な理解が必要です。上記のコードは一部のユースケースでは機能する可能性がありますが、ニーズとテストに基づいて変更する必要がある場合もあります。

LlamaIndexをそのまま使用する

LlamaIndexは、RAGパイプラインでPII情報を保護しやすくするために、 NERPIINodePostprocessor.

応答は以下のとおりです

顧客は、火災により所有物件に損害が生じたとして損害賠償請求を起こした。あるケースでは、放火が補償範囲外であったため、ガレージの火災による損害に対する請求が却下されました。別の顧客は、保険でカバーされていた自宅の火災による損害について請求をしました。さらに、顧客がキッチンの火災を報告し、火災による損害が補償されることが保証されました。

ローカルLLMの使用

また、データをパブリック LLM に送信する前に、ローカルまたはプライベート ネットワークで実行されている LLM を活用してマスキング作業を行うこともできます。

マスキングを行うには、ローカル マシン上の Ollama で実行されている Mistral を使用します。

Mistralをローカルで実行する

Ollamaをダウンロードしてインストールします。Ollamaをインストールした後、このコマンドを実行してmistralをダウンロードして実行します。

モデルを初めてローカルにダウンロードして実行するには数分かかる場合があります。以下のような「雲についての詩を書いてください」という質問をして、ミストラルが実行されているかどうかを確認し、その詩が気に入ったものかどうかを確認します。後でコードを通じてミストラル モデルとやり取りする必要があるため、ollama を実行したままにしておきます。

query_masking_local_LLM.pyという新しいファイルを作成し、以下のコードを追加します。

応答は以下のようなものです

顧客は、火災により所有物件に損害が生じたとして損害賠償請求を起こした。あるケースでは、放火が補償範囲外であったため、ガレージの火災による損害に対する請求が却下されました。別の顧客は、保険でカバーされていた自宅の火災による損害について請求をしました。さらに、顧客がキッチンの火災を報告し、火災による損害が補償されることが保証されました。

まとめ

この投稿では、RAG フロー内でパブリック LLM を使用する際に PII と機密データを保護する方法を説明しました。私たちはそれを実現する複数の方法を実証しました。採用する前に、ユースケースとニーズに基づいてこれらのアプローチをテストすることを強くお勧めします。

関連記事

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう