Docs 菜单
Docs 主页
/
Atlas
/ /

开始使用 LangChain4j 集成

在此页面上

  • 背景
  • 先决条件
  • 设置环境
  • 实例化嵌入模型
  • 使用Atlas作为嵌入存储
  • 存储自定义数据
  • 运行向量搜索查询
  • 使用数据回答问题
  • 后续步骤

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

  1. 设置环境。

  2. 实例化嵌入模型。

  3. 使用Atlas作为嵌入存储。

  4. 在 Atlas 上存储自定义数据。

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

    • 语义搜索。

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

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

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

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

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

  • 一个 Atlas 帐户,而其集群运行着 MongoDB 版本 6.0.11、7.0.2 或更高版本(包括 RC)。确保您的 IP 地址包含在 Atlas 项目的访问列表中。如需了解详情,请参阅创建集群

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

  • 一个 OpenAI API 密钥。您必须拥有一个 OpenAI 账号,该账号具有可用于 API 请求的信用额度。要了解有关注册 OpenAI 账号的更多信息,请参阅 OpenAI API 网站

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

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

    • 名称:LangChain4jSampleApp

    • 语言: Java

    • 构建系统: Maven

    • JDK:任何大于 8

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

2
  1. 将以下依赖项添加到项目的 pom.xml文件的 dependencies大量中。这些依赖项将 LangChain4j、适用于 LangChain4j 的 Voyage AI API和MongoDB Java同步驱动程序库添加到您的应用程序:

    pom.xml
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-mongodb-atlas</artifactId>
    <version>1.0.0-beta1</version>
    </dependency>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-voyage-ai</artifactId>
    <version>1.0.0-beta1</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.0.0-beta1</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>

    要学习;了解有关 LangChain4 j BOM 的详情,请参阅 LangChain4 j 文档中的入门页面。

    完成编辑 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:设置为Atlas连接字符串。

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

注意

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

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

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

5

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

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

在此步骤中,您将实例化一个嵌入模型,该模型使用 Voyage AI将示例数据中的文本转换为向量嵌入。

将以下代码添加到您的 Main.java文件,以使用您的 Voyage AI API密钥并选择 voyage-3 作为模型来实例化嵌入模型:

EmbeddingModel embeddingModel = VoyageAiEmbeddingModel.builder()
.apiKey(embeddingApiKey)
.modelName("voyage-3")
.build();

要学习;了解有关 voyage-3 模型的更多信息,请参阅 Voyage AI网站上有关 voyage-3 和 voyage-3-lite 的博文

在本部分中,您将 Atlas 实例化为向量数据库,也称为向量或嵌入存储。当您实例化嵌入存储时,LangChain4j 会自动为您的数据创建 Atlas Vector Search 索引。

注意

必需的访问权限

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

此代码执行以下操作:

  • 创建一个连接到Atlas部署的MongoClient实例。

  • 将向量搜索索引定义中的维数设置为AI模型的嵌入维数。生成的向量搜索索引具有以下定义:

    {
    "fields": [
    {
    "type": "vector",
    "path": "embedding",
    "numDimensions": 1024,
    "similarity": "cosine"
    }
    ]
    }
  • 通过指定以下参数来配置 Atlas 集合:

    • langchain4j_test.vector_store 作为 Atlas 集合来存储文档。

    • 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。存储.embedding.mongodb包 API文档。

在本部分中,您将创建示例文档,使用嵌入模型将文本转换为嵌入,并将数据保存到Atlas。

此代码执行以下操作:

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

  • text字段的内容转换为嵌入并将数据保存到Atlas。该代码包含一个延迟,以适应向量转换所需的时间。

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

要了解有关元数据预过滤的更多信息,请参阅 Atlas Vector Search 预过滤

另请参阅:

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

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

1
  1. 将以下依赖项添加到项目dependencies pom.xml文件的 大量中,但不要删除已添加的任何依赖项。这些依赖项会将 LangChain4 j AI服务和 OpenAI API for LangChain4 j 库添加到您的应用程序中:

    pom.xml
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai</artifactId>
    <version>1.0.0-beta1</version>
    </dependency>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    <version>1.0.0-beta1</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-examplesGitHub存储库下载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();

提示

元数据过滤

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

5

创建一个简单的 Assistant 接口,用于在应用程序中实施AI Services API 。创建一个名为 Assistant.java 的接口文件,其级别与 Main.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