MongoDB ベクトル検索 をLgachein4j と統合して、LM アプリケーションを構築できます。このチュートリアルでは、Lgachein4j とMongoDB ベクトル検索 の使用を開始し、データに対してセマンティック検索を実行し、シンプルな RAG実装を構築する方法を説明します。具体的には、次のアクションを実行します。
環境を設定します。
埋め込みモデルをインスタンス化します。
MongoDB を埋め込みストアとして使用します。
カスタム データをMongoDBクラスターに保存します。
次のベクトル検索クエリを実行します。
セマンティック検索。
メタデータの事前フィルタリングによるセマンティック検索。
MongoDB ベクトル検索を使用してデータの質問に答え、RAG を実装します。
バックグラウンド
LangChain4j は、Java でのLLMアプリケーションの作成を簡素化するフレームワークです。LangChain4j は、LangChain、Haystack、LlamaIndex、その他のソースからの概念と機能を組み合わせています。このフレームワークは、セマンティック検索やRAGなど、さまざまなユースケースにご利用いただけます。
MongoDB ベクトル検索 をLgachein4j と統合することで、 MongoDB をベクトルデータベースとして使用し、セマンティックで類似したドキュメントを使用してクエリに答えることで、 MongoDB ベクトル検索を使用して RAG を実装できます。RG の詳細については、MongoDBを使用した 検索拡張生成(RAG) を参照してください。
前提条件
Atlas の サンプル データ セット からの映画データを含むコレクションを使用します。
次のいずれかのMongoDBクラスター タイプ
MongoDB バージョン 6.0.11、7.0.2、またはそれ以降を実行している Atlas クラスター。IP アドレスが Atlas プロジェクトのアクセスリストに含まれていることを確認する。
Atlas CLI を使用して作成されたローカル Atlas 配置。詳細については、「Atlas 配置のローカル配置の作成」を参照してください。
Search とベクトル検索がインストールされたMongoDB Community または Enterprise クラスター。
投票AI APIキー。APIリクエストにはトークンが使用可能なアカウントが必要です。 Vyage AIアカウントの登録の詳細については、Vyage AI のウェブサイト を参照してください。
OpenAI APIキー。APIリクエストに使用できるクレジットを持つ OpenAI アカウントが必要です。OpenAI アカウントの登録の詳細については、OpenAI APIウェブサイト を参照してください。
Java 開発キット(JDK) バージョン8 以降。
Javaアプリケーションを設定して実行する環境。Maven または Gradle を構成してプロジェクトを構築および実行するようにするには、IntelliJ IDEA や Eclipse IDE などの統合開発環境(IDE)を使用することをお勧めします。
環境を設定する
まず、このチュートリアルのための環境をセットアップする必要があります。これには、必要な依存関係の追加と環境変数の設定が含まれます。
依存関係を追加します。
プロジェクトの
pom.xmlファイルのdependencies配列に次の依存関係を追加します。これらの依存関係は、LangChain4j、LangChain4j 用の Voyage AI API、および MongoDB Java Sync Driver ライブラリをアプリケーションに追加します。pom.xml<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-mongodb-atlas</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-voyage-ai</artifactId> <version>1.1.0-beta7</version> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>5.4.0</version> </dependency> 次に、LangChain の依存関係リストの下に
dependencyManagementエントリを j 部品表 (BOM)4追加します。pom.xml<dependencyManagement> <dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-bom</artifactId> <version>1.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> LangChain4j BOM の詳細については、LangChain4j ドキュメントの「導入ガイド」ページを参照してください。
pom.xmlファイルの編集が終了したら、プロジェクトを再読み込みして、依存関係がインストールされていることを確認します。
クラスとメソッドをインポートします。
プロジェクト内でメインのアプリケーションファイルMain.javaを見つけてください。既存のインポートを次のインポートリストに差し替えてください:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import dev.langchain4j.data.document.Metadata; import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.voyageai.VoyageAiEmbeddingModel; import dev.langchain4j.store.embedding.EmbeddingMatch; import dev.langchain4j.store.embedding.EmbeddingSearchRequest; import dev.langchain4j.store.embedding.EmbeddingSearchResult; import dev.langchain4j.store.embedding.filter.comparison.*; import dev.langchain4j.store.embedding.mongodb.IndexMapping; import dev.langchain4j.store.embedding.mongodb.MongoDbEmbeddingStore; import org.bson.Document; import java.io.*; import java.util.*;
このチュートリアルの後半では、これらのクラスとメソッドを使用してベクトル埋め込みを作成し、データをクエリします。
環境変数を設定してください。
IDEによっては、アプリケーションが検索できる環境変数を設定する方法が複数あるかもしれません。IntelliJで環境変数を設定するには、アプリケーションの実行構成を作成する必要があります。詳細については、IntelliJ ドキュメントの「実行/デバッグ構成: アプリケーション」ページのオペレーティングシステムセクションを参照してください。
次の環境変数を設定します。
MONGODB_URI: MongoDB接続文字列に設定します。VOYAGE_AI_KEY: Voyage AI API キーを設定します。
注意
接続stringには、次の形式を使用する必要があります。
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net/?<settings>
接続文字列の取得の詳細については、「 Atlasを使い始める」チュートリアルを参照してください。
埋め込みモデルをインスタンス化する
このステップでは、Voyage AI を使用してサンプルデータ内のテキストをベクトル埋め込みに変換する埋め込みモデルをインスタンス化します。
次のコードを Main.java ファイルに追加し、Voyage AI API キーを使用して埋め込みモデルをインスタンス化し、モデルとして voyage-3-large を選択します。
EmbeddingModel embeddingModel = VoyageAiEmbeddingModel.builder() .apiKey(embeddingApiKey) .modelName("voyage-3-large") .build();
voyage-3-large モデルの詳細については、Voyage AI ウェブサイトのvoyage-3 & voyage-3-liteに関するブログ記事を参照してください。
埋め込みストアとしてMongoDBを使用
このセクションでは、 MongoDB をベクトルデータベースとしてインスタンス化します。これはベクトルまたは埋め込みストアとも呼ばれます。埋め込みストアをインスタンス化すると、Lgachein4j はデータ上にMongoDB ベクトル検索インデックスを自動的に作成します。
このコードは、次のアクションを実行します。
Atlas デプロイメントに接続される
MongoClientインスタンスを作成します。ベクトル検索インデックス定義の次元数をAIモデルの埋め込み次元に設定します。結果として得られるベクトル検索インデックスは、次のように定義されます。
{ "fields": [ { "type": "vector", "path": "embedding", "numDimensions": 1024, "similarity": "cosine" } ] } 次のパラメータを指定してMongoDBコレクションを構成します。
langchain4j_test.vector_storeドキュメントを保存するMongoDBコレクションとして 。vector_index埋め込みストアをクエリする際に使用するインデックスとして指定します。
createIndex ブール値が true に設定されているため、埋め込みストアをインスタンス化すると、自動的にベクトル検索インデックスが作成されます。このコードには、インデックスが正常に作成されるように遅延が含まれています。
次のコードをMain.javaファイルに追加します。
MongoClient mongoClient = MongoClients.create(uri); System.out.println("Instantiating the embedding store..."); // Set to false if the vector index already exists Boolean createIndex = true; IndexMapping indexMapping = IndexMapping.builder() .dimension(embeddingModel.dimension()) .metadataFieldNames(new HashSet<>()) .build(); MongoDbEmbeddingStore embeddingStore = MongoDbEmbeddingStore.builder() .databaseName("search") .collectionName("langchaintest") .createIndex(createIndex) .indexName("vector_index") .indexMapping(indexMapping) .fromClient(mongoClient) .build(); if (createIndex) { // Creating a vector search index can take up to a minute, // so this delay allows the index to become queryable try { Thread.sleep(15000); } catch (InterruptedException e) { throw new RuntimeException(e); } }
前述のコードで使用されているクラスとメソッドの詳細については、dev.langchain4j.store.embedding.mongodb パッケージ の API ドキュメントを参照してください。
カスタムデータの保存
このセクションでは、サンプルドキュメントを作成し、埋め込みモデルを使用してテキストを埋め込みに変換し、データをMongoDBに永続化します。
このコードは、次のアクションを実行します。
textとmetadataフィールドを含むサンプルドキュメントのリストを作成します。textフィールドの内容を埋め込みに変換し、データをMongoDBに永続化します。コードにはベクトル変換に必要な時間に対応するための遅延が含まれています。
次のコードをMain.javaファイルに追加します。
ArrayList<Document> docs = new ArrayList<>(); docs.add(new Document() .append("text", "In Zadie Smith's new novel, the true story of a heated nineteenth-century criminal trial connects to the unrest of current times.") .append("metadata", new Metadata(Map.of("author", "A")))); docs.add(new Document() .append("text", "Emperor penguins are the tallest and heaviest of all penguin species, standing up to 4 feet.") .append("metadata", new Metadata(Map.of("author", "D")))); docs.add(new Document() .append("text", "Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates.") .append("metadata", new Metadata(Map.of("author", "C")))); docs.add(new Document() .append("text", "Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King.") .append("metadata", new Metadata(Map.of("author", "B")))); System.out.println("Persisting document embeddings..."); for (Document doc : docs) { TextSegment segment = TextSegment.from( doc.getString("text"), doc.get("metadata", Metadata.class) ); Embedding embedding = embeddingModel.embed(segment).content(); embeddingStore.add(embedding, segment); } // Delay for persisting data try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); }
ベクトル検索クエリの実行
このセクションでは、ベクトル化されたデータに対してクエリを実行する方法を説明します。
セマンティック検索を実行してください。
このコードは、フレーズ"Where do penguins live?"のセマンティック検索クエリを実行し、関連性の高い3件の結果を返します。また、各結果がクエリにどの程度一致しているかを示すスコアも出力されます。
次のコードをMain.javaファイルに追加します。
String query = "Where do penguins live?"; Embedding queryEmbedding = embeddingModel.embed(query).content(); EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .maxResults(3) .build(); System.out.println("Performing the query..."); EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest); List<EmbeddingMatch<TextSegment>> matches = searchResult.matches(); for (EmbeddingMatch<TextSegment> embeddingMatch : matches) { System.out.println("Response: " + embeddingMatch.embedded().text()); System.out.println("Author: " + embeddingMatch.embedded().metadata().getString("author")); System.out.println("Score: " + embeddingMatch.score()); }
Response: Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates. Author: C Score: 0.829620897769928 Response: Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King. Author: B Score: 0.7459062337875366 Response: Emperor penguins are the tallest and heaviest of all penguin species, standing up to 4 feet. Author: D Score: 0.6908764839172363
(任意)メタデータ フィルタリングを使用してセマンティック検索を実行します。
メタデータフィルターを使用して検索するには、dev.langchain4j.store.embedding.filter.comparison パッケージのクラスを使用できます。これらのクラスを使用すると、メタデータの値を指定された値と比較するフィルターを作成し、検索結果を絞り込むことができます。
この例では、author フィールドの値が "B" または "C" のいずれかであるドキュメントをフィルタリングします。その後、"Where do penguins live?" というフレーズに対してセマンティック検索クエリを実行します。
前の手順で EmbeddingSearchRequest インスタンスを生成するコードを次のコードに置き換えてください。
EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .filter(new IsIn("author", List.of("B", "C"))) .maxResults(3) .build();
Response: Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates. Author: C Score: 0.8520907163619995 Response: Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King. Author: B Score: 0.7666836977005005
メタデータの事前フィルタリングの詳細については、 MongoDB ベクトル検索 のプレフィルター を参照してください。
Tip
詳しくは、API参照を参照してください。
データを使用して質問に答えてください
このセクションでは、 LgChuin4 jフレームワークとMongoDB ベクトル検索 の実装を使用する RG を示します。MongoDB ベクトル検索を使用してセマンティックに類似したドキュメントを検索したので、次のコード例を使用して、 MongoDBに保存されているドキュメントの情報を使用して LM に質問に回答するように要求します。
RAG 用のプロジェクトを設定します。
プロジェクトの
pom.xmlファイル内のdependencies配列に、以下の依存関係を追加してください。ただし、すでに追加済みの依存関係は削除しないでください。これらの依存関係により、LangChain4j AI サービスと LangChain4j ライブラリ用の OpenAI API がアプリケーションに追加されます。pom.xml<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> <version>1.1.0</version> </dependency> pom.xmlファイルの編集が終了したら、プロジェクトを再読み込みして、依存関係がインストールされていることを確認します。Main.javaファイルに次の import 文を追加します。import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import dev.langchain4j.service.AiServices; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; OPENAI_KEY環境変数をOpenAI API キーに設定してください。このキーを使用して、クエリに対する応答を生成するチャットモデルを作成します。
サンプル データをロードします。
このステップでは、外部ソースから Atlas にデータを取り込みます。docs-code-examples GitHub リポジトリからrainforest-docs.json サンプルデータファイルをダウンロードします。このファイル内のドキュメントには、熱帯雨林の植物、動物、天候に関する情報が含まれています。
このファイルを、プロジェクト内のresourcesディレクトリにアップロードしてください(このディレクトリは、アプリケーションを含む javaディレクトリと同じ階層にあります)。
データを、埋め込みを作成し、Atlasに永続化できる形式に処理する必要があります。このコードは、次のアクションを実行する loadJsonDocuments() メソッドを定義します。
ClassLoaderクラスを使用して、resourcesディレクトリからサンプルデータを取得します。ObjectMapperクラスを使用して、JSON ドキュメントを MongoDB のDocumentインスタンスのListに変換します。
次のコードを、メインメソッドの外側にある Main.java ファイルに追加します。
private static List<Document> loadJsonDocuments(String resourcePath) throws IOException { // Loads file from resources directory using the ClassLoader InputStream inputStream = Main.class.getClassLoader().getResourceAsStream(resourcePath); if (inputStream == null) { throw new FileNotFoundException("Resource not found: " + resourcePath); } // Parses JSON file to List of MongoDB Documents ObjectMapper objectMapper = new ObjectMapper(); List<Document> documents = objectMapper.readValue(inputStream, new TypeReference<>() {}); return documents; }
次に、メインメソッドの本体に次のコードを追加し、ドキュメントをロードするために loadJsonDocuments() メソッドを呼び出します。
System.out.println("Loading documents from file..."); String resourcePath = "rainforest-docs.json"; List<Document> documents = loadJsonDocuments(resourcePath);
Atlas にベクター埋め込みを保存します。
このステップでは、サンプルドキュメントからベクター埋め込みを作成し、それをAtlasに永続化します。
このコードは、サンプルドキュメント内の text フィールドの内容を埋め込みに変換し、データを Atlas に永続化します。このコードには、ベクトル変換に必要な時間に対応するための遅延が含まれています。
次のコードをMain.javaファイルに追加します。
System.out.println("Persisting document embeddings..."); for (Document doc : documents) { TextSegment segment = TextSegment.from( doc.getString("text"), new Metadata(doc.get("metadata", Map.class))); Embedding embedding = embeddingModel.embed(segment).content(); embeddingStore.add(embedding, segment); } try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); }
チャット モデルをインスタンス化し、コンテンツ リトリーバーを指定します。
このステップでは、OpenAI のチャットモデルをインスタンス化し、データに基づいて質問に答えられるようにします。また、チャットモデルが作成した回答を補完するために関連ドキュメントを表示するコンテンツレトリーバーを指定します。
このコードは、次のアクションを実行します。
OpenAI APIキーを使用して、チャットモデルをインスタンス化します。
以下の仕様でコンテンツ検索機能を作成します。
最大
3件の関連ドキュメントを取得します関連性スコアが少なくとも指定された値以上のドキュメントを検索します
0.75
Main.java ファイルの main メソッド内に、以下のコードを追加します。
String chatApiKey = System.getenv("OPENAI_KEY"); ChatLanguageModel chatModel = OpenAiChatModel.builder() .apiKey(chatApiKey) .modelName("gpt-4") .build(); ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .maxResults(3) .minScore(0.75) .build();
Tip
メタデータ フィルター
filter() ビルダー メソッドを使用し、Filter のインスタンスを渡すことで、ContentRetriever にメタデータ フィルタリングを実装できます。Filter の構築方法については、前のステップの「メタデータ フィルタリングの例」をご覧ください。
チャットアシスタントを作成してください。
アプリケーションに AI サービス API を実装するシンプルなAssistantインターフェースを作成してください。Main.javaファイルと同じレベルにAssistant.javaというインターフェースファイルを作成してください。
Assistant インターフェースを定義してください。
package org.example; public interface Assistant { String answer(String question); }
Main.java ファイル内で、Assistant をインスタンス化します。
Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatModel) .contentRetriever(contentRetriever) .build();
データに対してクエリを実行します。
最後に、サンプル データに対してクエリを実行します。クエリを実行して出力を印刷するには、以下のコードをMain.java ファイルに追加します。
String ragQuery = "What types of insects live in the rainforest?"; String output = assistant.answer(ragQuery); System.out.println("Response:\n" + output);
Response: In the rainforest, there are numerous species of insects such as beetles, butterflies, moths, wasps, bees, flies, and ants. Of the many insects that live in the rainforest, ants are particularly important as they play a crucial role in nutrient recycling and aeration of the soil. Moreover, many of these insects are involved in the processes of pollination and decomposition. The adaptations these insects have developed enable their survival in the rainforest's specific conditions, characterized by heavy rainfall.
次のステップ
MongoDBは、次の開発者リソースも提供しています。
LangChain4j を使用した RAG アプリケーションの作成方法に関する DEV コミュニティのチュートリアル