Docs 菜单
Docs 主页
/ /

开始使用 LangChain4j 集成

您可以将MongoDB Vector Search 与 LangChain4j 集成,以构建LLM 应用程序。本教程演示如何开始将MongoDB Vector Search 与 LangChain4j 结合使用,对数据执行语义搜索并构建简单的 RAG实施。具体来说,您执行以下操作:

  1. 设置环境。

  2. 实例化嵌入模型。

  3. 使用MongoDB作为嵌入式存储。

  4. 将自定义数据存储在MongoDB 集群中。

  5. 运行以下向量搜索查询:

    • 语义搜索。

    • 带元数据预过滤的语义搜索。

  6. 使用 MongoDB Vector Search 来回答有关数据的问题,从而实施RAG

LangChain4j 是一个框架,简化了在 Java 中创建 LLM 应用程序的过程。LangChain4j 结合了 LangChain、Haystack、LlamaIndex 和其他来源的概念和功能。您可以将此框架用于各种用例,包括语义搜索和 RAG

通过将MongoDB Vector Search 与 LangChain4j 集成,您可以将MongoDB用作向量数据库,并使用MongoDB Vector Search 通过使用语义相似的文档来实现RAG来回答查询。要学习;了解有关 RAG 的更多信息,请参阅 使用MongoDB检索增强生成 (RAG)

如要完成本教程,您必须具备以下条件:

  • 以下MongoDB 集群类型之一:

  • Voyage AI API 密钥。您必须拥有一个帐户,该帐户具有可用于 API 请求的令牌。如要了解有关注册 Voyage AI 帐户的更多信息,请参阅 Voyage AI 网站。

  • OpenAI API密钥。您必须拥有一个具有可用于API请求的积分的 OpenAI 帐户。要学习;了解有关注册 OpenAI 帐户的更多信息,请参阅 OpenAI API网站。

您必须首先为本教程设置环境,包括添加必要的依赖项和设置环境变量。

1
  1. 打开您的 IDE 并创建一个新的 Java 项目,设置以下配置:

    • 名称:LangChain4jSampleApp

    • 语言: Java

    • 构建系统: Maven

    • JDK:任何版本大于 8

    您可能会看到一个选项来包含示例代码。选择此选项可能有助于您测试环境是否正常运行,并定位您在以下步骤中编辑的应用程序文件。

2
  1. 将以下依赖项添加到项目的 pom.xml 文件中的 dependencies 数组中。这些依赖项将 LangChain4j、Voyage AI API for LangChain4j 和 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>
  2. 下一步,在您的依赖项列表下方为 LangChain4j 物料清单(BOM)添加一个 dependencyManagement 条目:

    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 文件后,请重新加载项目以确保依赖项已安装。

3

在您的项目中找到主应用程序文件 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.*;

在本教程的后面,您将使用这些类和方法来创建向量嵌入和查询数据。

4

根据您的 IDE,可能有多种方法来设置应用程序可以检索的环境变量。如要在 IntelliJ 中设置环境变量,您必须为应用程序创建一个运行配置。如要了解更多信息,请参阅 IntelliJ 文档中运行/调试配置:应用程序页面的操作系统部分。

设置以下环境变量:

  • MONGODB_URI:设置为MongoDB连接字符串。

  • VOYAGE_AI_KEY:设置为您的 Voyage AI API 密钥。

注意

连接字符串应使用以下格式:

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net/?<settings>

要了解有关检索连接字符串的更多信息,请参阅 Atlas入门教程。

5

通过在应用程序的 Main.java 文件的 main 方法中添加以下代码来检索环境变量:

String embeddingApiKey = System.getenv("VOYAGE_AI_KEY");
String uri = System.getenv("MONGODB_URI");

在此步骤中,您将实例化一个嵌入模型,该模型使用 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实例化为向量数据库,也称为向量或嵌入存储。当您实例化嵌入存储时,LangChain4j 会自动为您的数据创建MongoDB Vector Search索引。

注意

必需的访问权限

要创建MongoDB Vector Search索引,您必须对MongoDB项目具有Project Data Access Admin或更高访问权限。

此代码执行以下操作:

  • 创建一个与您的 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。

此代码执行以下操作:

  • 创建一个包含 textmetadata 字段的示例文档列表。

  • 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);
}

本节演示如何在矢量化数据上运行查询。

1

此代码对短语 "Where do penguins live?" 执行语义搜索查询,并返回三个最相关的结果。它还会打印一个分数,以显示每个结果与查询的匹配程度。

将以下代码添加到您的 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
2

如要执行带有元数据过滤的搜索,您可以使用 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 Vector Search 预过滤。

提示

有关更多信息,请参阅API参考文档。

本部分演示使用 LangChain4j框架和MongoDB Vector Search 的 RAG实施。现在,您已使用MongoDB Vector Search检索语义相似的文档,请使用以下代码示例提示 LLM 通过使用MongoDB中存储的文档中的信息来回答问题。

1
  1. 将以下依赖项添加到项目的 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 文件后,请重新加载项目以确保依赖项已安装。

  2. 将以下导入添加到 Main.java 文件中的导入列表中:

    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;
  3. OPENAI_KEY 环境变量设置为您的 OpenAI API 密钥。您使用此密钥创建一个聊天模型,以生成对您的查询的响应。

2

在此步骤中,您会将外部来源的数据摄取到 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);
3

在此步骤中,您将从示例文档创建向量嵌入,并将其持久化到 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);
}
4

在此步骤中,您将从 OpenAI 实例化一个聊天模型,以便能够根据您的数据回答问题。您还可以指定一个内容检索器,以便显示相关文档,从而为聊天模型生成的响应提供信息。

此代码执行以下操作:

  • 通过使用您的 OpenAI API 密钥实例化聊天模型

  • 创建具有以下规格的内容检索器:

    • 最多检索 3 个相关文档

    • 检索文档,相关性分数至少为 0.75

将以下代码添加到主方法正文的 Main.java 文件中:

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();

提示

元数据过滤器

您可以使用 filter() 构建者方法并传递 Filter 的实例,在 ContentRetriever 中实现元数据过滤。请参阅上一步中的元数据过滤示例,以了解如何构建 Filter

5

创建一个简单的 Assistant 接口,以在您的应用程序中实现 AI 服务 API。在与 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();
6

最后,执行对示例数据的查询。将以下代码添加到 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 还提供以下开发者资源:

后退

LangChainGo

在此页面上