news 2026/9/15 16:46:08

LangChain4j 集成 Voyage AI 嵌入模型:从文本嵌入到多模态向量化的完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain4j 集成 Voyage AI 嵌入模型:从文本嵌入到多模态向量化的完整实战指南

LangChain4j 集成 Voyage AI 嵌入模型:从文本嵌入到多模态向量化的完整实战指南

【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4j

导读

本指南基于 LangChain4j 官方集成文档 docs/docs/integrations/embedding-models/voyage-ai.md,系统讲解如何在 JVM 项目中通过 LangChain4j 使用 Voyage AI 嵌入(Embedding)模型:从 Maven 依赖引入、VoyageAiEmbeddingModel的完整 Builder 配置,到文本嵌入、批量嵌入、多模态(文本 + 图片)融合嵌入的实际用法。读完本文,你将能够把 Voyage AI 的向量化能力无缝接入 LangChain4j 的 RAG 检索链路与向量存储体系,并理解其底层请求/响应处理与路由机制。

一、Voyage AI 集成概览

Voyage AI 是提供文本与多模态嵌入(Embedding)服务的模型提供商。LangChain4j 通过独立模块langchain4j-voyage-ai将其封装为标准的 EmbeddingModel 实现,使上层 RAG、向量检索代码完全复用 LangChain4j 统一的模型抽象,无需关心 Voyage 的 HTTP API 细节。

本模块的核心能力由官方文档与源码共同确认:

  • 核心 APIVoyageAiEmbeddingModel(实现类位于 VoyageAiEmbeddingModel.java);
  • 多模态支持voyage-multimodal-3voyage-multimodal-3.5可将交错排列的文本与图片融合为单一向量(从模型名自动检测);
  • 按调用参数:支持input_typequery/document),用于优化检索场景的向量质量;
  • 可观测性:支持通过listeners(...)配置EmbeddingModelListener,接入 LangChain4j 的观测体系。

该模块依赖langchain4j-corelangchain4j-http-client,运行时默认使用 JDK 自带 HTTP 客户端(langchain4j-http-client-jdk),可参考 langchain4j-voyage-ai/pom.xml。

二、添加 Maven 依赖

在你的pom.xml中引入如下依赖:

<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-voyage-ai</artifactId> <version>1.20.0-beta30</version> </dependency>

说明:上述版本来自官方集成文档。当前仓库主分支的模块版本为1.21.0-beta31-SNAPSHOT(见 langchain4j-voyage-ai/pom.xml),实际使用时请根据你的发布渠道选择正式发布的版本号。

三、API 与构建方式:VoyageAiEmbeddingModel

VoyageAiEmbeddingModelDimensionAwareEmbeddingModel的实现(后者在 langchain4j-core 中提供维度感知能力),它封装了 Voyage AI 的 Embedding API,并通过链式 Builder 提供全部配置项。

最简创建方式(与集成测试 VoyageAiEmbeddingModelIT.java 中的用法一致):

import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.voyageai.VoyageAiEmbeddingModel; import dev.langchain4j.model.voyageai.VoyageAiEmbeddingModelName; EmbeddingModel model = VoyageAiEmbeddingModel.builder() .apiKey(System.getenv("VOYAGE_API_KEY")) // 必填:Voyage AI API Key .modelName(VoyageAiEmbeddingModelName.VOYAGE_3_LITE) .build();

modelName既支持枚举VoyageAiEmbeddingModelName,也支持任意字符串(便于使用仓库枚举未收录的新模型名),见 VoyageAiEmbeddingModel.java。

Builder 配置项全解(默认值来自源码)

配置项类型默认值说明
apiKeyString无(必填)Voyage AI 的 API Key,用于Authorization: Bearer <apiKey>请求头
modelNameVoyageAiEmbeddingModelName/String无(必填)模型名,见下文模型清单
baseUrlStringhttps://api.voyageai.com/v1/API 基地址,见 VoyageAiClient.java
timeoutDuration60 秒HTTP 连接/读取超时;源码中同时将连接超时兜底为 15 秒
maxRetriesInteger2对瞬时错误的最大重试次数,通过withRetryMappingExceptions实现
inputTypeStringnullquery/document/ null,见下文专门说明
truncationBooleantrue超长文本是否截断以适配上下文长度;false 时超长会直接报错
encodingFormatStringnull向量编码格式:null(浮点数列表)或base64(压缩为 Base64)
maxSegmentsPerBatchInteger128单次批量请求最多包含的文本段数量,超出自动分批
multimodalBoolean从模型名自动推断强制开启多模态路由(命名含multimodal时自动为 true)
logRequests/logResponsesBooleanfalse调试日志:打印请求/响应体
loggerorg.slf4j.Logger默认 Logger自定义请求/响应日志所用 Logger
httpClientBuilderHttpClientBuilderSPI 加载自定义 HTTP 客户端(超时、代理等)
customHeadersMap/Supplier<Map>每次请求附加的自定义 Header;Supplier 形式每次请求前调用,适合动态令牌(如 OAuth2 刷新)
listenersList<EmbeddingModelListener>空列表嵌入模型监听器,用于观测与追踪

以上默认值均可从 VoyageAiEmbeddingModel.java 的构造逻辑核实。

内置模型清单与向量维度

VoyageAiEmbeddingModelName.java 定义了仓库已知的模型与维度,供knownDimension()做维度校验:

枚举值模型名输出维度
VOYAGE_3voyage-31024
VOYAGE_3_LITEvoyage-3-lite512
VOYAGE_3_LARGEvoyage-3-large1024
VOYAGE_FINANCE_2voyage-finance-21024
VOYAGE_MULTILINGUAL_2voyage-multilingual-21024
VOYAGE_LAW_2voyage-law-21024
VOYAGE_CODE_2voyage-code-21536
VOYAGE_CODE_3voyage-code-31024

四、文本嵌入:单条与批量

单条文本嵌入

import dev.langchain4j.model.output.Response; import dev.langchain4j.data.embedding.Embedding; Response<Embedding> response = model.embed("Hello World"); int dimension = response.content().dimension(); // 与模型维度一致

批量文本段嵌入

embedAll接收TextSegment列表,返回值与输入顺序一一对应:

import dev.langchain4j.data.segment.TextSegment; import java.util.List; import static java.util.Arrays.asList; TextSegment segment1 = TextSegment.from("hello"); TextSegment segment2 = TextSegment.from("hi"); Response<List<Embedding>> response = model.embedAll(asList(segment1, segment2));

从源码 doEmbed 可以看到内部处理逻辑:

  1. 分批:按maxSegmentsPerBatch(默认 128)将输入切分为多个批次,避免单请求过大;
  2. 并发串行请求:逐批调用 Voyage API,最后合并全部向量结果;
  3. 响应排序:按响应的index字段排序,保证输出与输入顺序一致(见 EmbeddingResponse.java);
  4. Token 统计:汇总每批的total_tokens,以TokenUsage形式随响应返回。

集成测试 VoyageAiEmbeddingModelIT.java 验证了 97 个文本段(超过默认批大小 128 的一半场景用maxSegmentsPerBatch(96)强制分批)依然能全部正确返回;测试还断言了"hello""hi"两个段的余弦相似度大于 0.8(使用CosineSimilarity),可用于验证语义相关性的基本合理性。

提示:集成测试需要环境变量VOYAGE_API_KEY,且测试类标注了@EnabledIfEnvironmentVariable(named = "VOYAGE_API_KEY", matches = ".+"),未配置时自动跳过。

五、input_type:检索场景的优化参数

Voyage AI 支持通过input_type参数对嵌入做检索场景优化,LangChain4j 将其映射为EmbeddingInputType枚举(QUERY/DOCUMENT),映射逻辑见 VoyageAiEmbeddingModel.java:

取值语义(来自源码 Javadoc)
query用于搜索或检索的查询文本。Voyage AI 会在嵌入前为查询场景前置优化提示(prepend a prompt)
document用于希望被检索到的文档/内容。Voyage AI 会为文档场景前置优化提示
null(默认)直接编码原始文本,不附加任何额外提示

两种设置方式

方式一:全局配置(构建时固定)

VoyageAiEmbeddingModel model = VoyageAiEmbeddingModel.builder() .apiKey(System.getenv("VOYAGE_API_KEY")) .modelName(VoyageAiEmbeddingModelName.VOYAGE_3_LITE) .inputType("query") // 所有请求统一使用 query 模式 .build();

方式二:按请求配置(per-call)

LangChain4j 的嵌入请求支持按调用传入参数。VoyageAiEmbeddingModel.supportedParameters()声明支持EmbeddingRequestParameters.INPUT_TYPE(见 VoyageAiEmbeddingModel.java),这也是官方文档强调的“Per-call parameters”能力:

import dev.langchain4j.model.embedding.request.EmbeddingInputType; import dev.langchain4j.model.embedding.request.EmbeddingRequest; model.embed(EmbeddingRequest.builder() .input("LangChain4j 是什么?") .inputType(EmbeddingInputType.QUERY) // 本次请求按查询处理 .build());

请求级参数优先于模型级配置——源码中getOrDefault(toVoyageInputType(request.inputType()), inputType)正是“先取请求参数、缺省时回退到 Builder 配置”的实现。

典型用法:RAG 系统中,入库文档用DOCUMENT,检索查询用QUERY,两者在各自优化空间内编码,可显著提升召回质量。

六、多模态嵌入:文本 + 图片融合为单一向量

官方文档明确指出:voyage-multimodal-3voyage-multimodal-3.5可将文本和图片嵌入到共享向量空间,且交错排列的文本 + 图片会被融合为一个嵌入向量。图片输入通过EmbeddingRequest中的ImageContent(URL 或 Base64)提供。

自动检测与路由机制

从源码 isMultimodalModel 可见:模型名包含子串multimodal即自动判定为多模态,例如voyage-multimodal-3.5。此时:

  • supportedContentTypes()返回TEXT+IMAGE(纯文本模型仅返回TEXT);
  • 内部请求路由到/multimodalembeddings端点;否则走/embeddings端点(见 VoyageAiClient.java)。

路由测试 VoyageAiMultimodalRoutingTest.java 验证了以下关键行为:

  • voyage-multimodal-3/voyage-multimodal-3.5自动启用图文支持;
  • voyage-3纯文本模型请求图片会快速失败(抛出UnsupportedFeatureException,消息含IMAGE);
  • voyage-multilingual-2不会被误判为多模态(避免multilingualmultimodal混淆);
  • 显式设置.multimodal(true)可覆盖自动检测(例如使用自定义代理模型名时);
  • VideoContent输入同样会快速失败(消息含VIDEO)。

图文混合嵌入示例

import dev.langchain4j.data.message.TextContent; import dev.langchain4j.data.message.ImageContent; Response<Embedding> response = model.embed(EmbeddingRequest.builder() .input( TextContent.from("a photo of a cat"), // 文本块 ImageContent.from("https://example.com/cat.png")) // 图片 URL .inputType(EmbeddingInputType.QUERY) .build());

图片输入的两种形式

图片使用ImageContent.from(...)创建,常用重载(见 ImageContent.java):

1. URL 形式

ImageContent image = ImageContent.from("https://example.com/cat.png");

底层序列化为image_url内容块,请求体会包含"image_url"与 URL。

2. Base64 形式

ImageContent image = ImageContent.from("aGVsbG8=", "image/png"); // Base64 数据 + MIME 类型

源码 toContentBlock 会将其拼装为data:<mimeType>;base64,<data>的 Data URL 发送,MIME 缺省时默认为image/png。路由测试确认请求体形如data:image/png;base64,aGVsbG8=

注意:图片内容必须提供 URL 或 Base64 数据二者之一,否则抛出UnsupportedFeatureException(消息为 "ImageContent must have either a URL or base64 data")。

多模态请求的底层结构

多模态请求体由 MultimodalEmbeddingRequest.java 定义:每个输入包含一个有序的内容块列表text/image_url/image_base64三种类型),这些内容块被融合为单个嵌入向量。响应侧仍复用标准EmbeddingResponse,可从中取回向量、模型名与 Token 用量。

七、响应结构:向量、Token 用量与 Base64 解码

Response<Embedding>/Response<List<Embedding>>中除向量本身外,还包含:

  • tokenUsage():Voyage 返回的total_tokens(注意集成测试中的备注:Voyage 有时会返回totalTokens=0,属正常现象);outputTokenCount为 null(嵌入无输出 token);
  • finishReason():嵌入请求为 null;
  • metadata().modelName():实际响应模型名。

encodingFormat("base64") 的底层解码

当设置encodingFormat("base64")时,Voyage 会以小端(little-endian)浮点字节的 Base64 字符串返回向量。响应解析器 EmbeddingResponse.java 负责透明解码:

VoyageAiEmbeddingModel model = VoyageAiEmbeddingModel.builder() .apiKey(System.getenv("VOYAGE_API_KEY")) .modelName(VoyageAiEmbeddingModelName.VOYAGE_3_LITE) .encodingFormat("base64") // 服务端压缩返回,减少传输体积 .build();

对使用者而言,response.content().vector()拿到的始终是float[]形式,无需关心底层是否 Base64 编码——解码细节已被封装。

八、监听器与观测(Listeners)

官方文档强调可通过VoyageAiEmbeddingModel.builder().listeners(...)配置监听器。EmbeddingModelListener是 LangChain4j 观测体系的一部分,可在嵌入请求发起前后、成功/失败时获得回调,用于日志、指标与链路追踪。

import dev.langchain4j.model.embedding.listener.EmbeddingModelListener; EmbeddingModelListener listener = new EmbeddingModelListener() { @Override public void onRequest(EmbeddingModelRequestContext context) { System.out.println("请求模型: " + context.request().modelName()); } // 其余回调按需覆写 }; VoyageAiEmbeddingModel model = VoyageAiEmbeddingModel.builder() .apiKey(System.getenv("VOYAGE_API_KEY")) .modelName("voyage-multimodal-3.5") .listeners(List.of(listener)) .build();

公共集成测试 common/VoyageAiEmbeddingModelIT.java 继承AbstractEmbeddingModelIT,对监听器场景做了完整覆盖(包括使用错误 API Key"banana"maxRetries(0)构造失败模型的监听器回调验证)。

九、错误处理与调试

  • 瞬时错误重试:默认maxRetries = 2,由withRetryMappingExceptions统一处理(源码 VoyageAiEmbeddingModel.java);
  • 快速失败:对不支持的内容类型(如图片喂给纯文本模型、视频内容)在本地立即抛出UnsupportedFeatureException,避免无效的网络请求;
  • 请求/响应日志logRequests(true)打印请求体;logResponses(true)打印响应体——注意向量体积巨大,集成测试中特别注释"embeddings are huge in logs",生产环境建议关闭响应日志或谨慎使用;
  • 自定义 HTTP 客户端:通过httpClientBuilder(...)注入自定义实现(如代理、连接池配置),模块默认通过 SPI 加载HttpClientBuilder,并在 pom 中提供langchain4j-http-client-jdk作为运行时实现。

十、与 LangChain4j RAG / 向量存储的衔接

VoyageAiEmbeddingModel实现了统一的 EmbeddingModel 接口,因此可以无缝替换 LangChain4j RAG 流程中的任意嵌入模型位置。典型接入方式:

  1. 使用TextSegment将文档切分为文本段;
  2. 调用embedAll(...)批量向量化;
  3. 将向量写入 LangChain4j 支持的向量存储(如 langchain4j-pgvector、langchain4j-milvus 等模块);
  4. 检索时用embed(EmbeddingRequest.builder().input(query).inputType(EmbeddingInputType.QUERY).build())生成查询向量,配合DOCUMENT入库向量做相似度检索。

关于请求/响应 API 与多模态用法的更多通用说明,可参考官方教程 Embedding Model 中的 embedding-model 章节。

十一、参考资源(仓库内)

  • 官方集成文档:voyage-ai.md
  • 核心实现:VoyageAiEmbeddingModel.java
  • 模型与维度定义:VoyageAiEmbeddingModelName.java
  • HTTP 客户端封装:VoyageAiClient.java
  • 多模态请求模型:MultimodalEmbeddingRequest.java
  • 实时集成测试(需VOYAGE_API_KEY):VoyageAiEmbeddingModelIT.java
  • 多模态路由单元测试:VoyageAiMultimodalRoutingTest.java
  • 模块依赖定义:langchain4j-voyage-ai/pom.xml

【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4j

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 16:42:36

如何5步用Buf CLI治好Proto目录的“脏乱差“:完整上手指南

如何5步用Buf CLI治好Proto目录的"脏乱差"&#xff1a;完整上手指南 【免费下载链接】buf The best way of working with Protocol Buffers. 项目地址: https://gitcode.com/GitHub_Trending/bu/buf 仓库里的 .proto 文件还在靠人肉对齐缩进、生成代码靠一长串…

作者头像 李华
网站建设 2026/9/15 16:39:30

Nextra 图片放大功能怎么全局关闭或按单张图片控制?

Nextra 图片放大功能怎么全局关闭或按单张图片控制&#xff1f; 【免费下载链接】nextra Simple, powerful and flexible site generation framework with everything you love from Next.js. 项目地址: https://gitcode.com/GitHub_Trending/ne/nextra 在 Nextra 构建的…

作者头像 李华
网站建设 2026/9/15 16:38:07

突发E层:短波通信的隐形杀手与VHF远距离惊喜

我到现在还记得第一次被Es层“扇耳光”的那个傍晚——本来坐在电台前想安静听一会6米波段的微弱信号&#xff0c;耳机里却突然蹦出一个响彻云霄的呼号&#xff0c;声线清晰得像对方就坐在隔壁房间。我确认了一下频率&#xff1a;144MHz&#xff0c;2米波段&#xff0c;一个理论…

作者头像 李华
网站建设 2026/9/15 16:36:53

服务有没有掉线?星空组网+Uptime Kuma 内网监控实战

项目部署成功后&#xff0c;事情往往还没结束。今天能打开的页面&#xff0c;明天会不会因为进程退出而失联&#xff1f;人在外面时&#xff0c;又该怎样确认服务状态&#xff1f;这次我用星空组网连接 Ubuntu 和访问设备&#xff0c;再部署 Uptime Kuma&#xff0c;给一个 Pyt…

作者头像 李华