LangChain4j-202509120155
LangChain4j
一、前言
LangChain4j 可以理解是Java版本的LangChain,是一个旨在简化将大型语言模型(LLM)
集成到 Java 应用程序中的框架。它帮我们封装了不同LLM 提供商(如 OpenAI、Google Vertex
AI)的专有API方便在不同 LLM 或嵌入式存储之间切换,而无需重写代码。
该项目于 2023 年初启动,旨在填补 Java 生态系统中缺乏 LLM 库和框架的空白。LangChai
n4j 融合了 LangChain、Haystack、LlamaIndex 等项目的理念,并加入了自身的创新。项目处于
积极开发中,核心功能已就绪,开发者可以开始构建 LLM 驱动的应用程序。此外,LangChain4j
还与 Quarkus 和 Spring Boot 集成,方便开发者在不同的 Java 框架中使用。
总的来说,LangChain4j 为 Java 开发者提供了一个强大且灵活的工具,简化了 LLM 的集成
过程,促进了 AI 驱动应用程序的开发。
官网参考:https://docs.langchain4j.dev
二、大模型理论
1.AI实践的方向
LLMops:例如,GPT4、GPT5、以及国内的文心一言、讯飞大模型等;
AIGC:利用AI生成各种内容,AI特效、数字人等;
工具类方向:提供职场提升效率的工具,企业AI知识库,智能客服,法律顾问等;
Prompt提示工程方向:是一门新兴学科,用好提示词才能用好AI。
2.LLM能为我们做什么
LLM模型为核心的开发框架的出现为自然语言处理NLP打开了一个新世界,我们可以用其创
建各种应用程序,包括聊天机器人的智能问答工具等。LLM理论框架如下:
3.LLM模型的发展历程
2017年,Google推出Transformer,“Attention is all you need”展现野心;
2018年6月,OpenAI推出基于自回归模型GPT-1(Generative Pre-Training),有效证明了在NL
P领域上使用预训练+微调方式的有效性。
2018年10月Google推出自编码模型BERT,在同样参数大小的前提下,其效果优于 GPT-1,
在之后数年,BERT一统江湖。
2019年2月,OpenAI推出更大的模型GPT-2(GPT1:110M,Bert: 340M,,GPT2:
1.5B),引入zero-shot概念并验证其有效性。
2020年6月,OpenAl推出巨无霸GPT-3(175B),各项评测达到SOTA水平,单次训练成本上千
万美元,OpenAI在LLM的道路上坚定不移的进行探索。
2022年11月,OpenAl推出ChatGPT,2023年3月,推出GPT-4,开启AIGC的新纪元。
4.语言模型的发展阶段
第一阶段:Pre-training+Fine-tuning阶段,基于Transformer,通过自监督任务进行预训练,任
务数据进行微调。典型代表是BERT、GPT、XLNet等;
第二阶段:逐步扩大模型参数和训练语料规模,探索不同类型的架构。典型代表是 BART、T
5、GPT-3等;
第三阶段:AIGC(ArtificialIntelligent Generated Content)初期,模型参数规模步入千万亿级
别,大模型走向对话式、生成式、多模态时代,更加注重与人类交互进行对齐,实现可靠、
安全、无毒的模型。典型代表是InstructionGPT、ChatGPT、 Bard、GPT-4等。
总结:所谓模型,就是一个包含了大量未知参数的函数,所谓训练,就是通过大量的数据去迭代
逼近这些未知参数的最优解。
5.LLM、ChatGPT、和AIGC三者的关系:
LLM(大语言模型,Large Language Model)
基于海量文本数据训练的自然语言处理模型,能够理解、生成和推理文本。代表技术如 GP
T、PaLM、LLaMA 等,核心能力是语言理解和生成。
ChatGPT
由 OpenAI 开发的对话式 LLM 应用,基于 GPT 架构(如 GPT-3.5、GPT-4)优化,专门用于
人机对话交互,具有上下文感知和连贯回复的能力。
AIGC(人工智能生成内容,AI Generated Content)
指由 AI 生成的所有形式的内容,包括文本、图像、音频、视频等。AIGC 是应用层概念,覆
盖广泛的生成场景。
总结:
LLM 是技术基础,支持自然语言任务的通用处理。
ChatGPT 是 LLM 的垂直应用,专注于对话场景。
AIGC 是更广泛的概念,包含所有由 AI 生成的内容,LLM 和 ChatGPT 是其文本生成领域的
代表。
6.SpringAI框架-Java开发者的AI集成利器
官网: https://spring.io/projects/spring-ai#overview
Spring AI 是一个面向人工智能工程的应用框架。其目标在于将 Spring 生态系统的设计原则
(如可移植性和模块化设计)应用于人工智能领域,并推动将 POJO(普通 Java 对象)作为人
工智能领域的应用程序构建模块加以使用。
Spring AI支持所有主要的 AI 模型提供商,例如 Anthropic、OpenAI、微软、亚马逊、谷歌
和 Ollama。支持的模型类型包括:
聊天生成
嵌入
文本到图像
音频转录
文本转语音
审核
在所有 AI 提供商之间支持跨平台的同步和流式 API 选项的 API 支持。还可以访问特定于模
型的功能。
结构化输出 - 将 AI 模型输出映射到 POJO(Plain Old Java Object)。
支持所有主要的向量数据库提供商,例如 Apache Cassandra、Azure Vector Search、Chro
ma、Milvus、MongoDB Atlas、Neo4j、Oracle、PostgreSQL/PGVector、PineCone、Qdra
nt、Redis 和 Weaviate。
在向量存储提供商之间支持跨平台的 API,包括一种新颖的类似 SQL 的元数据过滤 API。
工具/函数调用 - 允许模型请求执行客户端工具和函数,从而根据需要获取必要的实时信息。
可观测性 - 提供有关 AI 相关操作的洞察。
数据工程的文档注入 ETL 框架。
AI 模型评估 - 提供实用工具来评估生成的内容并防止幻觉响应。ChatClient API - 用于与 AI
聊天模型进行通信的流畅 API,其用法与 WebClient 和 RestClient API 类似。
Advisors API - 封装了常见的生成式 AI 模式,对发送至语言模型(LLMs)的数据进行转换,
并在各种模型和用例之间提供可移植性。
支持聊天对话记忆和检索增强生成(RAG)。
适用于所有 AI 模型和向量存储的 Spring Boot 自动配置和启动器 - 使用 start.spring.io 选择
您偏好的模型或向量存储。
三、LangChain之永远的HelloWorld
1.大模型的分类
大模型分类的核心逻辑是从通用能力到垂直场景,再到个性化应用的逐层细化。
基础通用大模型:基于海量多领域数据训练的大模型,具备广泛的语言理解、生成和推理能
力,不针对特定任务或行业优化。能处理开放领域的文本生成、问答、翻译等任务、依赖千
亿级参数和超大规模算力训练、在专业领域(如医疗、法律)中可能缺乏深度知识或准确
性。作为技术基础设施,为上层垂直模型提供底层能力支持。
行业垂直大模型:在通用大模型基础上,通过领域数据微调(Fine-tuning)或知识增强(R
AG),针对特定行业需求优化。深度融合行业知识库、术语和业务流程、牺牲部分泛化能
力,换取专业场景的高准确性、依赖高质量行业数据集。
超级个体+智能体:基于大模型构建的个性化AI代理,能够自主完成复杂任务或服务于特定
用户需求。根据用户行为和偏好动态调整、结合文本、语音、图像等多模态输入输出、通过
ReAct、Agent框架实现任务规划与执行
2.大模型产品的定位
3.大模型的Token和Web开发中的Token
在Web开发中,“token”通常指的是用于认证和授权的一种加密字符串。它被用来确保用户身
份的安全验证,比如JWT(JSON Web Token) 这类token一般由服务器生成,并发给客户端保存
(例如存储在浏览器的本地存储或cookie中),之后每次请求都需要携带这个token来证明用户的身
份。
4.永远的HelloWorld
阿里云百炼平台官网:https://bailian.console.aliyun.com/
DeepSeek API文档:https://api-docs.deepseek.com/zh-cn/
LangChain4j开发文档参考:https://docs.langchain4j.dev/tutorials/spring-boot-integration/
#spring-boot-starters
Spring Boot starter 有助于通过属性创建和配置语言模型、嵌入模型、嵌入存储以及其他核
心 LangChain4j 组件。要使用Spring Boot starter之一,请导入相应的依赖项。Spring Boot start
er依赖的命名约定为:langchain4j-{integration-name}-spring-boot-starter。
例如,对于OpenAI(langchain4j-open-ai),依赖项的名称将是langchain4j-open-AI-spring-b
oot-starter:
application.properties:
项目的父模块pom.xml:
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o
langchain4j.open-ai.chat-model.log-requests=true
langchain4j.open-ai.chat-model.log-responses=true
...
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
application.properties:
8
langchain4j.open-ai.chat-model.api-key=sk-
dd4b632a987b49328d2ee14d53b0126b
langchain4j.open-ai.chat-model.model-name=qwen-plus
Controller:
Result:
关于ApiKey和模型名:
进入阿里云百炼平台模型广场:
langchain4j.open-ai.chat-model.base-
url=https://dashscope.aliyuncs.com/compatible-mode/v1
@RestController
@Slf4j
public class HelloLangChain4JController
{
@Resource
private ChatLanguageModel chatLanguageModel;
@GetMapping(value = "/langchain4j/hello")
public String hello(@RequestParam(value = "prompt", defaultValue =
"你是谁") String prompt)
{
String result = chatLanguageModel.generate(prompt);
System.out.println("通过langchain4j调用qwen-plus模型返回结果:
\n"+result);
return result;
}
}
参考:https://bailian.console.aliyun.com/?tab=api#/api/?type=model&url=https%3A%2F%2Fhel
p.aliyun.com%2Fdocument_detail%2F2712576.html
项目中获取的base_url:https://dashscope.aliyuncs.com/compatible-mode/v1
获取模型名:qwen-plus
四、视觉理解
参考开发文档:https://docs.langchain4j.dev/tutorials/chat-and-language-models#multimo
dality
切换支持视觉理解的模型:
子模块的pom.xml:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
8
配置类:
@Configuration(proxyBeanMethods = false)
Controller:
public class ChatLanguageModelConfig
{
@Bean
public ChatLanguageModel chatLanguageModel() {
return OpenAiChatModel.builder()
.apiKey("sk-dd4b632a987b49328d2ee14d53b0126b")
.modelName("qwen-vl-max")
.baseUrl("https://dashscope.aliyuncs.com/compatible-
mode/v1")
.build();
}
}
@RestController
@Slf4j
public class ChatLanguageModelController
{
@Autowired
private ChatLanguageModel chatLanguageModel;
@Value("classpath:static/images/1.png")
private Resource resource;
// http://localhost:9004/image/call
@GetMapping(value = "/image/call")
public String readImageContent() throws IOException
{
byte[] byteArray = resource.getContentAsByteArray();
String base64Data =
Base64.getEncoder().encodeToString(byteArray);
System.out.println("**base64Data: "+base64Data);
UserMessage userMessage = UserMessage.from(
TextContent.from("从以下图片中获取来源网站名称和9.27号上证指
数"),
ImageContent.from(base64Data,"image/png")
);
Response
chatLanguageModel.generate(userMessage);
Input:
Result:
五、 FunctionCalling/动态函数调用
官网参考:https://docs.langchain4j.dev/tutorials/tools
一些LLM除了生成文本外,还可以触发的操作。
不开启会怎么样:
大语言模型(LLMs)不仅仅是文本生成的能手,它们还能触发并调用第3方函数,比如查询微信/
调用支付宝/查看顺丰快递单据号等等......
提示:LLM 本身并不执行函数,它只是指示应该调用哪个函数以及如何调用。
System.out.println(response.content().text());
return response.content().text();
}
}
pom.xml:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
8
功能接口:
配置类:
public interface FunctionAssistant {
//
String chat(String message);
}
@Configuration(proxyBeanMethods = false)
public class ChatLanguageModelConfig
{
@Bean
public ChatLanguageModel chatLanguageModel()
{
return OpenAiChatModel.builder()
.apiKey("sk-dd4b632a987b49328d2ee14d53b0126b")
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-
mode/v1")
.build();
}
/* @Bean
public FunctionAssistant functionAssistant(ChatLanguageModel
chatLanguageModel) {
// 工具说明 ToolSpecification
ToolSpecification toolSpecification =
ToolSpecification.builder()
.name("invoice_assistant")
.description("根据用户提交的开票信息,开具发票")
.addParameter("companyName", type("string"),
description("公司名称"))
.addParameter("dutyNumber", type("string"),
description("税号"))
.addParameter("amount", type("string"), description("金
额,保留两位有效数字"))
.build();
// 业务逻辑 ToolExecutor
ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -
> {
System.out.println(toolExecutionRequest.id());
System.out.println(toolExecutionRequest.name());
String arguments1 = toolExecutionRequest.arguments();
System.out.println("arguments1 =>>>> " + arguments1);
return "开具成功";
};
return AiServices.builder(FunctionAssistant.class)
.chatLanguageModel(chatLanguageModel)
.tools(Map.of(toolSpecification, toolExecutor))
.build();
}*/
@Bean
public FunctionAssistant functionAssistant(ChatLanguageModel
chatLanguageModel) {
Handler:
调用和风天气的接口:
return AiServices.builder(FunctionAssistant.class)
.chatLanguageModel(chatLanguageModel)
.tools(new InvoiceHandler())
.build();
}
@Slf4j
public class InvoiceHandler
{
@Tool("根据用户提交的开票信息进行开票")
public String handle(@P("公司名称") String companyName,
@P("税号") String dutyNumber,
@P("金额保留两位有效数字") String amount) throws
Exception
{
log.info("companyName =>>>> {} dutyNumber =>>>> {} amount
=>>>> {}", companyName, dutyNumber, amount);
//----------------------------------
// 这块写自己的业务逻辑,调用redis/rabbitmq/kafka/mybatis/顺丰单据/医
疗化验报告/支付接口等第3方
//----------------------------------
//咱们这里是调用和风天气的接口,查询今日的天气
System.out.println(new
WeatherService().getWeatherV2("101010100"));
return "开票成功";
}
}
@Service
public class WeatherService
{
//和风天气开发服务 https://dev.qweather.com/
private static final String API_KEY =
"a37a94a3f3b24ccfac10045eb7da7959";
private static final String BASE_URL =
"https://devapi.qweather.com/v7/weather/now?location=%s&key=%s";
public JsonNode getWeatherV2(String city) throws Exception {
String url = String.format(BASE_URL, city, API_KEY);
// 使用默认配置创建HttpClient实例
Result:
六、RAG-向量数据库
var httpClient = HttpClients.createDefault();
// 创建请求工厂并将其设置给RestTemplate
HttpComponentsClientHttpRequestFactory factory = new
HttpComponentsClientHttpRequestFactory(httpClient);
String response = new RestTemplate(factory).getForObject(url,
String.class);
// 解析JSON响应
JsonNode jsonNode = new ObjectMapper().readTree(response);
return jsonNode;
}
}
"code": "200",
"updateTime": "2025-04-21T00:04+08:00",
"fxLink": "https://www.qweather.com/en/weather/beijing-
101010100.html",
"now": {
"obsTime": "2025-04-21T00:00+08:00",
"temp": "17",
"feelsLike": "16",
"icon": "104",
"text": "阴",
"wind360": "90",
"windDir": "东风",
"windScale": "2",
"windSpeed": "6",
"humidity": "56",
"precip": "0.0",
"pressure": "1006",
"vis": "9",
"cloud": "91",
"dew": "4"
},
"refer": {
"sources": ["QWeather"],
"license": ["QWeather Developers License"]
}
}
发票已成功开具给公司: 北京字节跳动科技有限公司, 税号为sgg533, 金额为668 .12。
1.RAG(Retrieval-Augmented Generation)检索增强生成
官网参考:https://docs.langchain4j.dev/tutorials/rag/
RAG(Retrieval-Augmented Generation,检索增强生成)是一种在将数据发送到LLM大型语
言模型之前,从数据中查找并注入相关信息的方法。这样,LLM将获得(希望获得的)相关信
息,并能够利用这些信息进行回复,从而降低产生幻觉(即生成不准确或无关信息)的可能性。
可以使用各种信息检索方法来查找相关信息:
全文(关键字)搜索。此方法利用TF-IDF和BM25等技术,通过匹配查询中的关键字来搜索
文档数据库(例如,用户正在询问的内容)。它根据每个文档中这些关键字的频率和相关性对结
果进行排名。
向量搜索,也称为“语义搜索”。文本文档使用嵌入模型转换为数字向量。然后,根据余弦相
似性或其他相似性/距离度量(如查询向量和文档向量之间的度量)来查找并排序文档,从而捕
捉到更深层次的语义含义。
混合搜索。组合多种搜索方法(例如,全文搜索 + 向量搜索)通常会提高搜索效率。
目前,全文搜索和混合搜索仅受Azure AI搜索集成支持,因此本文主要关注向量搜索。
RAG阶段
RAG 过程分两个阶段:索引和检索,LangChain4j 为这两个阶段提供了工具。
在索引阶段,对文档进行预处理的方式能够在检索阶段实现高效的搜索。
这一过程可能会因所采用的信息检索方法而有所不同,以向量搜索为例,通常包括清理文
档、利用额外数据和元数据对文档进行丰富处理、将文档拆分成更小的段落(即分块)、对这些
段落进行嵌入处理,最后将其存储到嵌入存储(即向量数据库)中。
索引阶段通常是在离线状态下进行的,无需最终用户等待其完成。这可以通过定时任务(如
cron作业)来实现,例如,该任务可以在周末每周对公司内部文档进行一次重新索引。负责索引
的代码也可以作为一个独立的应用程序,仅用于处理索引任务。
然而,在某些情况下,最终用户可能希望上传其自定义文档,以便让LLM能够访问这些文
档。在这种情况下,索引操作应该在线执行,并成为主应用程序的一部分。
索引阶段的简化图:
检索阶段通常是在线进行的,会利用已索引的文档来回答用户提交的问题。
这一过程可能会因所采用的信息检索方法而有所不同。以向量搜索为例,这通常涉及将用户
的查询(即问 题)进行嵌入处理,然后在嵌入存储中执行相似性搜索。之后将相关句段(即原
始文档的片段)注入到提示信息中,并发送给LLM进行处理。
检索阶段的简化图:
pom.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
8
配置类
public class ChatLanguageModelConfig
{
@Bean
public ChatLanguageModel chatLanguageModel()
{
return OpenAiChatModel.builder()
.apiKey(System.getenv("LANGCHAIN4J_KEY"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-
mode/v1")
.build();
}
@Bean
public InMemoryEmbeddingStore
return new InMemoryEmbeddingStore<>();
}
@Bean
public ChatAssistant assistant(ChatLanguageModel
chatLanguageModel, EmbeddingStore
return AiServices.builder(ChatAssistant.class)
.chatLanguageModel(chatLanguageModel)
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
.contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore))
.build();
}
}
Controller
Result:
通过读取文件,将文件内容进行向量化存储,之后通过检索获取内容,并且在此基础上,能
够获取到相似的内容。
2.向量数据库
向量化及存储:
Embedding Model模型简介:官网参考:https://docs.langchain4j.dev/tutorials/rag#em
bedding-model
@Slf4j
public class RAGController
{
@Resource
InMemoryEmbeddingStore
@Resource
ChatAssistant chatAssistant;
@GetMapping(value = "/rag/add")
public String testAdd()
{
Document document =
FileSystemDocumentLoader.loadDocument("D:\\44\\alibaba-java.docx");
EmbeddingStoreIngestor.ingest(document, embeddingStore);
String result = chatAssistant.chat("错误码00000和A0001分别是什
么");
System.out.println(result);
return result;
}
}
EmbeddingModel接口代表一种将文本向量化的特殊类型。
嵌入给定的文本
嵌入给定的TextSegment
嵌入所有给定的TextSegment
返回由此模型生成的嵌入的维度
嵌入模型(Embedding Model)核心概念:嵌入(Embedding )的工作原理是将文本、图像和视
频转换为称为向量(Vectors)的浮点数数组。这些向量旨在捕捉文本、图像和视频的含义。嵌入数
组的长度称为向量的维度(Dimensionality)。
嵌入模型(EmbeddingModel)是嵌入过程中采用的模型。当前EmbeddingModel的接口主要用
于将文本转换为数值向量,接口的设计主要围绕这两个目标展开:
可移植性:该接口确保在各种嵌入模型之间的轻松适配。它允许开发者在不同的嵌入技术或模
型之间切换,所需的代码更改最小化。这一设计与Spring模块化和互换性的理念一致。
简单性:嵌入模型简化了文本转换为嵌入的过程。通过提供如embed(String text)和embed(Docu
ment document) 这样简单的方法,它去除了处理原始文本数据和嵌入算法的复杂性。这个设计
选择使开发者,尤其是那些初次接触AI的开发者,更容易在他们的应用程序中使用嵌入,而无需
深入了解其底层机制。
Embedding Store存储简介:官网参考:https://docs.langchain4j.dev/tutorials/rag#embed
ding-store
EmbeddingStore接口代表的是一种用于向量的存储,也称为向量数据库。它允许存储和高效
搜索相似的(在嵌入空间中接近的) Embedding。
EmbeddingStore可以将Embedding单独存储或与相应的TextSegment一起存储:它只能通过I
D 存储Embedding。原始嵌入数据可以存储在其他地方,并使用ID进行关联。·它可以存储Embedd
ing和已嵌入的原始数据(通常是TextSegment)。
EmbeddingStore.add(Embedding)将给定项添加Embedding到存储并返回随机 ID
EmbeddingStore.addAll(List
机ID 列表
EmbeddingSearchRequest:官网参考:https://docs.langchain4j.dev/tutorials/rag#embed
dingsearchrequest
总结:
嵌入模型是一种机器学习模型,旨在在连续的低维向量空间中表示数据(例如文本、图像或其
他形式的信息)。这些嵌入可以捕获数据之间的语义或上下文相似性,使机器能够更有效地执行比
较、聚类或分类等任务。假设你想描述不同的水果。你不用长篇大论,而是用数字来描述甜度、
大小和颜色等特征。例如,苹果可能是[8,5,7],而香蕉是[9,7,4]。这些数字使比较或对相似的水果
进行分组变得更容易。
将文本、图像和视频转换为称为向量(Vectors)的浮点数数组在 VectorStore中,查询与传
统关系数据库不同。它们执行相似性搜索,而不是精确匹配。当给定一个向量作为查询时,Vect
orStore 返回与查询向量“相似”的向量
优点:捕捉复杂的词汇关系(如语义相似性、同义词、多义词)、超越传统词袋模型的简单
计数方式、动态嵌入模型(如BERT)可根据上下文生成不同的词向量、向量嵌入为现代搜索和检
索增强生成 (RAG) 应用程序提供支持。
例如,“肯德基”和”麦当劳”的向量可能会比”肯德基”和”新疆大盘鸡”的向量更接近
LangChain4J支持的向量数据库List清单:https://docs.langchain4j.dev/integrations/embed
ding-stores/
可以用来做什么:
文本搜索:想象一下在搜索引擎中输入“最好的四川美食”。嵌入模型会将您的查询转换为数
字并检索具有类似嵌入的文档。然后,该模型将显示与您的查询接近的结果。
推荐电影:如果您喜欢一部电影《哪吒2》,系统会使用嵌入模型将其(例如类型、演员阵
容、情绪)表示为数字。它会将这些数字与其他电影嵌入进行比较,并推荐类似的电影。
匹配 图片和标题:通过将图像和潜在标题转换为数字表示(嵌入),嵌入模型可以将海上日
落图像与标题“平静海浪上的宁静日落”相匹配。该模型使用最接近图像嵌入的嵌入来识别标
题,从而确保准确匹配。该技术为图像搜索和照片标记等工具提供支持。
将相似项目归类:购物网站使用嵌入将相似的产品归为一组。例如,“红色运动鞋”在嵌入空
间中可能靠近“蓝色运动鞋”,因此它们显示为相关。
Pom.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
8
Qdrant向量库存储:
Qdrant是一个高性能的向量数据库,用于存储嵌入并进行快速的向量搜索。
使用Docker安装:docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
端口6333:用于HTTP API,浏览器web界面
端口6334:用于gRPC API
阿里云百炼平台向量大模型:text-embedding-v3
配置类
@Configuration(proxyBeanMethods = false)
public class EmbeddingModelConfig
{
//可以将Api-Key配置为系统环境变量
@Bean
public EmbeddingModel embeddingModel() {
return OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("LANGCHAIN4J_KEY"))
.modelName("text-embedding-v3")
.baseUrl("https://dashscope.aliyuncs.com/compatible-
mode/v1")
.build();
/**
*/
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient.Builder grpcClientBuilder =
QdrantGrpcClient.newBuilder("127.0.0.1", 6334, false);
return new QdrantClient(grpcClientBuilder.build());
}
@Bean
public EmbeddingStore
Controller
return QdrantEmbeddingStore.builder()
.host("127.0.0.1")
.port(6334)
.collectionName("test-qdrant")
.build();
}
}
@Slf4j
public class EmbeddinglController
{
@Resource
private EmbeddingModel embeddingModel;
@Resource
private QdrantClient qdrantClient;
@Resource
private EmbeddingStore
/**
*/
@GetMapping(value = "/embedding/embed")
public String embed()
{
String prompt = """
咏鸡
鸡鸣破晓光,
红冠映朝阳。
金羽披霞彩,
昂首步高岗。
""";
//文本向量化
Response
embeddingModel.embed(prompt);
System.out.println(embeddingResponse);
return embeddingResponse.content().toString();
}
@GetMapping(value = "/embedding/createCollection")