当前位置: 首页 > news >正文

【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解

目录

一、前言

二、Langchain4j概述

2.1 Langchain4j 介绍

2.1.1 Langchain4j 是什么

2.1.2 主要特点

2.2 Langchain4j 核心组件介绍

2.3 Langchain4j 核心优势

2.4 Langchain4j 核心应用场景

三、SpringBoot 整合 LangChain4j 组件使用

3.1 前置准备

3.1.1 获取apikey

3.1.2 导入基础依赖

3.1.3 添加配置文件

3.2 对话能力使用

3.2.1 Low Level API使用

3.2.3 High Level API使用

3.2.4 设置角色

3.3 会话记忆

3.3.1 Low Level API的实现

3.3.2 High Level API的实现

3.4 Function Calling

3.4.1 核心概念

3.4.2 应用场景

3.4.3 案例代码

3.5 联网搜索能力

3.5.1 注册并获取apikey

3.5.2 添加依赖

3.5.3 添加配置信息

3.5.4 添加配置类

3.5.5 接口效果测试

四、写在文末


一、前言

当下随着各种AI大模型的纷纷登场,AI赋能为业务的拓展和商业价值的延伸带来了无限的可能,于是各大厂商陆续推出对主流AI大模型的接入和支持,方便普通用户或开发者快速体验最新的大模型能力,以DeepSeek为例,像阿里云,硅基流动,腾讯云等多家互联网云厂商,强势接入DeepSeek,让使用者快速尝鲜。与此同时,为了应用开发者能够基于自身的业务快速对接各类AI大模型API能力,更灵活的拓展自身的业务能力。本篇以Langchain4j为例进行说明,详细介绍下如何基于Springboot ,利用Langchain4j的通用能力,完成对主流大模型的使用能力。从而实现微服务自身价值的提升。

二、Langchain4j概述

2.1 Langchain4j 介绍

LangChain4j作为一款专注于AI大模型集成的开源库,近年来受到了广泛关注。它旨在为开发者提供一种简单且高效的方式来接入和利用各种AI大模型,从而提升应用程序的智能化水平。LangChain4j的核心优势在于其高度的灵活性和易用性,使得开发者可以在不改变现有架构的前提下,快速实现AI功能的集成。

入口:LangChain4j

github地址: GitCode - 全球开发者的开源社区,开源代码托管平台

2.1.1 Langchain4j 是什么

LangChain4j 是一个基于 Java 的框架,旨在简化与大型语言模型(LLMs)的集成和应用开发。它提供了丰富的工具和组件,帮助开发者快速构建基于 LLM 的应用程序,如聊天机器人、问答系统、文本生成等。

2.1.2 主要特点

LangChain4j 主要具备如下特点:

  • 模块化设计

    • LangChain4j 采用模块化架构,允许开发者根据需要选择和使用特定功能,如模型集成、数据加载、链式调用等。

  • 多模型支持

    • 支持多种 LLM 提供商,如 OpenAI、Hugging Face 等,方便切换和集成不同模型。

  • 链式调用

    • 提供链式调用功能,允许将多个任务串联,如文本生成后自动进行情感分析。

  • 数据加载与处理

    • 内置多种数据加载器和处理器,支持从不同来源加载数据并进行预处理。

  • 扩展性好

    • 提供丰富的 API 和扩展点,开发者可以自定义组件以满足特定需求。

  • 社区活跃

    • 拥有活跃的社区和详细的文档,便于开发者获取支持和学习。

2.2 Langchain4j 核心组件介绍

Langchain4j 的强大之处正是在于其内置了丰富的可以做到开箱即用的组件能力,相比Spring AI,Langchain4j 的组件更加丰富,在使用的时候也更灵活,下面是一张关于Langchain4j 的组件全景图。

下面对其中核心组件做简单的说明。

Models

  • Models是LangChain中用于生成文本或执行其他任务的AI模型。

  • Models 通常是预训练语言模型(如GPT-3、GPT-4等), 用于生成文本、回答问题、翻译、总结等任务。

  • LangChain允许你通过API调用这些模型,并将它们集成到更复杂的应用中。

Prompts

  • Prompts 是用户提供给模型的输入文本,用于引导模型生成特定的输出。

  • Prompts可以是简单的文本,也可以是结构化的模板。

  • Prompts用于控制模型的输出,使其生成符合预期的结果。

  • 通过设计好的Prompts,可以引导模型执行特定的任务,如问答、翻译、生成代码等。

Vector Store

  • Vector Store 是用于存储和检索文本向量的数据库。

  • 文本向量是通过将文本嵌入到高维空间中生成的数值表示。

  • Vector Store 用于快速检索与查询文本相似的文本片段,类似于搜索引擎ES的功能,在文档检索、推荐系统、语义搜索等任务中非常有用。

Document Loaders

  • Document Loaders 是用于从不同来源,如文件、数据库、API等加载文档的工具。

  • Document Loaders 用于将外部数据加载到LangChain中,以便进一步处理。例如,可以从PDF、Word文档、网页等加载文本数据。

Text Splitters

  • Text Splitters 用于将长文本分割成较小的片段或块。

  • Text Splitters用于处理长文本,使其适合模型的输入长度限制。这在处理大型文档或长篇文章时非常有用,可以确保模型能够处理整个文本。

Output Parsers

  • Output Parsers用于将模型的输出解析为结构化数据或特定格式。

  • Output Parsers用于处理模型的原始输出,将其转换为更易用的格式,如JSON、字典、列表等。这对于后续的数据处理和分析非常有用。

Tools

  • Tools是LangChain中用于执行特定任务的函数或接口。它们可以是内置的工具,也可以是自定义的工具。

  • Tools用于扩展模型的能力,例如调用外部API、执行计算、查询数据库等。通过Tools,模型可以与环境进行交互,执行更复杂的任务。

2.3 Langchain4j 核心优势

LangChain4j 是一个专为 Java 开发者设计的框架,旨在简化与大型语言模型(LLMs)的集成和应用开发。它的核心优势主要体现在以下几个方面:

Java 原生支持

  • LangChain4j 是专为 Java 生态系统设计的,与 Java 开发工具和框架无缝集成。

  • 对于 Java 开发者来说,无需学习其他语言(如 Python)即可使用 LLM 的强大功能。

  • 支持 Spring Boot 等主流 Java 框架,便于快速集成到现有项目中。

模块化与灵活性

  • 采用模块化设计,开发者可以根据需求选择特定功能,如模型集成、数据加载、链式调用等。

  • 提供丰富的扩展点,支持自定义组件和插件,满足个性化需求。

多模型支持

  • 支持多种主流 LLM 提供商,如 OpenAI、Hugging Face、Cohere 等。

  • 提供统一的 API 接口,方便切换不同模型,降低对单一供应商的依赖。

链式调用(Chains)

  • 支持将多个任务串联成链,实现复杂的任务流程。

  • 例如,可以将文本生成、情感分析、翻译等任务组合成一个链式调用,简化开发流程。

数据加载与处理

  • 内置多种数据加载器,支持从文件、数据库、API 等来源加载数据。

  • 提供数据预处理工具,如文本清洗、分词、格式化等,便于后续分析和处理。

高性能与可扩展性

  • 针对 Java 的高性能特性进行优化,适合处理大规模数据和复杂任务。

  • 支持分布式计算和异步调用,适合高并发场景。

丰富的工具和实用功能

  • 提供多种实用工具,如日志记录、配置管理、缓存机制等。

  • 内置对 Prompt 工程的支持,帮助开发者更好地设计和优化提示词(Prompts)。

活跃的社区与文档支持

  • 拥有活跃的开发者社区,提供及时的技术支持和问题解答。

  • 提供详细的文档和示例代码,帮助开发者快速上手。

企业级支持

  • 提供对安全性和合规性的支持,适合企业级应用开发。

  • 支持模型微调和自定义训练,满足特定业务需求。

跨平台与云原生支持

  • 支持在本地、云端或混合环境中部署。

  • 与 Kubernetes、Docker 等云原生技术兼容,适合现代微服务架构。

LangChain4j 的核心优势在于其 Java 原生支持模块化设计多模型兼容性强大的链式调用功能。这些特性使其成为 Java 开发者构建基于 LLM 的智能应用的理想选择。无论是开发聊天机器人、问答系统,还是进行文本生成和数据分析,LangChain4j 都能提供高效、灵活的解决方案。

2.4 Langchain4j 核心应用场景

LangChain4j 是一个功能强大的 Java 框架,专为集成和应用大型语言模型(LLMs)而设计。它的灵活性和模块化特性使其适用于多种应用场景。如下列举了LangChain4j 的几个核心应用场景

智能聊天机器人

  • 场景描述:开发基于 LLM 的聊天机器人,用于客户服务、娱乐、教育等领域。

  • LangChain4j 优势

    • 支持多轮对话管理。

    • 可集成多种 LLM 提供商(如 OpenAI、Hugging Face)。

    • 提供上下文管理功能,确保对话连贯性。

问答系统

  • 场景描述:构建智能问答系统,用于知识库查询、技术支持、法律咨询等。

  • LangChain4j 优势

    • 支持从结构化或非结构化数据中提取答案。

    • 提供语义搜索和上下文理解能力。

    • 可与其他数据源(如数据库、API)集成。

文本生成

  • 场景描述:自动生成文章、故事、代码、营销文案等。

  • LangChain4j 优势

    • 支持多种生成模型(如 GPT、BERT)。

    • 提供 Prompt 工程工具,优化生成效果。

    • 支持批量生成和自定义模板。

数据分析与挖掘

  • 场景描述:利用 LLM 进行文本数据分析,如情感分析、主题提取、趋势预测等。

  • LangChain4j 的优势

    • 提供数据加载和预处理工具。

    • 支持与数据分析工具(如 Apache Spark、Pandas)集成。

    • 可处理大规模文本数据。

自动化文档处理

  • 场景描述:自动处理文档,如合同分析、报告生成、文档摘要等。

  • LangChain4j 的优势

    • 支持从 PDF、Word 等格式中提取文本。

    • 提供文本摘要和关键信息提取功能。

    • 可与其他文档处理工具(如 OCR)集成。

代码生成与辅助开发

  • 场景描述:利用 LLM 生成代码、修复 Bug、优化代码结构等。

  • LangChain4j 的优势

    • 支持多种编程语言的代码生成。

    • 提供代码补全和错误检测功能。

    • 可集成到 IDE 中,提升开发效率。

个性化推荐系统

  • 场景描述:基于用户行为和偏好,生成个性化推荐(如商品、内容、服务)。

  • LangChain4j 的优势

    • 支持自然语言理解,精准捕捉用户需求。

    • 可与其他推荐算法(如协同过滤)结合。

    • 提供实时推荐功能。

多语言支持与翻译

  • 场景描述:开发多语言翻译工具,支持实时翻译、文档翻译等。

  • LangChain4j 的优势

    • 支持多种语言的翻译模型。

    • 提供上下文感知翻译功能。

    • 可集成到多语言应用中。

教育与培训

  • 场景描述:开发智能教育工具,如自动批改作业、生成试题、提供学习建议等。

  • LangChain4j 的优势

    • 支持自然语言交互,提供个性化学习体验。

    • 可生成高质量的教育内容。

    • 支持多语言教学。

医疗与健康

  • 场景描述:构建智能医疗助手,用于疾病诊断、药物推荐、健康咨询等。

  • LangChain4j 的优势

    • 支持医学文本分析和理解。

    • 可集成医疗知识库。

    • 提供高精度的自然语言处理能力。

总的来说,LangChain4j 核心应用场景涵盖了从 聊天机器人问答系统文本生成数据分析 等多个领域。其模块化设计、多模型支持和强大的链式调用功能,使其成为构建智能应用的理想选择。无论是企业级应用还是个人项目,LangChain4j 都能提供高效、灵活的解决方案。

三、SpringBoot 整合 LangChain4j 组件使用

3.1 前置准备

3.1.1 获取apikey

LangChain4j 可以理解为一个类似JDBC的底层SDK,支持与多种大模型进行对接使用,本文将使用阿里云百炼平台集成的大模型进行对接,所以,首先你需要在阿里云百炼平台注册一个账户并获取到apikey,百炼平台入口:https://bailian.console.aliyun.com/ ,在模型广场中,该平台对接了很多种主流大模型,只需要在程序中配置对应的模型名称,以及apikey即可;

比如下文以deepseek为例进行说明,首先从模型广场找到第一个DeepSeek R1 ,进入之后,找到下面的位置,拷贝模型名称

然后,在个人账户那里,查看API-KEY,进去之后创建一个API-KEY即可,每个账户免费可以创建10个API-KEY

3.1.2 导入基础依赖

创建一个springboot工程,然后导入下面基本依赖,主要是springboot核心依赖,以及LangChain4j 相关的组件依赖

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><langchain.version>1.0.0-beta1</langchain.version>
</properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePath/>
</parent><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-tika-document-reader</artifactId><version>1.0.0-M3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.35</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><version>2.16.9</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>${langchain.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.32</version> <!-- 使用最新版本 --></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-bom</artifactId><version>${langchain.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories><build><finalName>boot-docker</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

3.1.3 添加配置文件

在springboot工程配置文件中添加下面的信息

  • 这里直接通过第三方云平台对接大模型,只需要配置两个参数,即apikey和模型名称即可;

  • 如果是本地搭建的大模型,也同样调整下该参数即可;

server:port: 8081langchain4j:community:dashscope:chat-model:api-key: 你的apikeymodel-name: deepseek-r1

3.2 对话能力使用

即聊天对话组件,对话组件是langchain4j最基本也是非常重要的基础组件,利用这个组件,应用可以完成与大模型的常规对话能力,在langchain4j的对话模型API中,提供了Low Level API与High Level API;

  • Low Level API,提供的API能力更偏向底层,使用起来更为灵活,开发者可控制性更强;

  • High Level API,封装性更高,调用更简单,但缺点是不够灵活,可控性差点;

3.2.1 Low Level API使用

在工程中添加一个接口,参考下面的代码:

import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/langchain/api")
@RequiredArgsConstructor
public class ChatController {final ChatLanguageModel chatLanguageModel;//localhost:8081/langchain/api/chat?message=你好,你是谁@GetMapping("/chat")public Object lowChat(@RequestParam(value = "message") String message) {String text = chatLanguageModel.chat(UserMessage.from(message)).aiMessage().text();return text;//return chatLanguageModel.chat(message);}
}

chatLanguageModel.chat()这个方法中,支持传入的是一组ChatMessage类型的参数,通过源码可以看到,ChatMessage是一个接口,当前的SDK内置了5种实现,每一种都有特定的使用场景:

  • UserMessage:

    • 这是来自用户的消息。包含文本,但某些LLM也支持文本和图像的混合

  • AiMessage:

    • 这是由 AI 生成的消息,响应 UserMessage。generate 方法返回包装在 Response 中的 AiMessage。AiMessage 可以包含文本响应 (String) 或执行工具的请求 (ToolExecutionRequest)。

  • ToolExecutionResultMessage:

    • ToolExecutionRequest 的结果。

  • SystemMessage:

    • 定义AI的系统角色信息。

工程启动后,调用一下接口可以看到下面的效果

3.2.3 High Level API使用

首先提供一个Assistant接口,并添加一个chat()方法

public interface Assistant {String chat(String message);
}

将上述Assistant作为一个bean初始化到spring容器中,添加如下的配置类

package com.congge.config;import com.congge.service.Assistant;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.service.AiServices;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@RequiredArgsConstructor
public class AssistantConfig {final ChatLanguageModel chatLanguageModel;@Beanpublic Assistant assistant(){return AiServices.builder(Assistant.class).chatLanguageModel(chatLanguageModel).build();}}

下面再提供另一个接口,使用一下High Level API的方式进行对话

final Assistant assistant;//localhost:8081/langchain/api/high/chat?message=你好,你是谁
@GetMapping("/high/chat")
public Object highChat(@RequestParam(value = "message") String message) {String text = assistant.chat(message);return text;
}

调用一下上面的接口,看到下面的响应内容

3.2.4 设置角色

设置角色也叫角色扮演,利用这个特性,在将问题投递给大模型之前,先为大模型设置一个特定的角色,比如“你是一个资深导演”,或者“请模仿XXX风格”,这样可以让大模型在给出回答的时候缩小范围,从而给出给符合角色身份的回答,看下面的代码示例。

/*** 设定身份* localhost:8081/langchain/api/role/chat?message=你是如何评价秦始皇这个皇帝的* @param message* @return*/
@GetMapping("/role/chat")
public Object roleChat(@RequestParam(value = "message") String message) {String text = chatLanguageModel.chat(List.of(SystemMessage.systemMessage("假如你是一位中文历史专家,请以该身份回答问题"),UserMessage.userMessage(message))).aiMessage().text();return text;
}

调用一下接口,看到下面的效果,从回答的结果来看,明显具有一定的专业性,这就是设置身份带来的效果

如果是在High Level API中,首先在上述自定义接口的方法上面添加 @SystemMessage 注解,补充角色设定的文案

接口逻辑不用动,然后再次调用上述的那个接口测试一下,给出下面的回答

3.3 会话记忆

即memory,还记得在刚开始使用AI大模型的时候,很多初次接触的同学对于AI大模型能够进行对话觉得不可思议,简单来说,就是利用了会话记忆,即将对话的上下文进行了存储,这样在回答用户的提问时就能进行参考。

Langchain4j内置了两个chatMemory的实现

  1. MessageWindowChatMemory ,基于内存的会话记忆实现,如果服务被重启,会话记忆将会丢失;

  2. TokenWindowChatMemory,基于token的实现;

3.3.1 Low Level API的实现

参考下面的代码

//基于消息数量的窗口内存,这里设置最大保存数量为15个,表示会话记忆最多能存储15条消息
private final ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(15);final ChatLanguageModel chatLanguageModel;/*** localhost:8081/api/memory/low/chat?message=jdk8之后创建线程有哪些方式* localhost:8081/api/memory/low/chat?message=在以上的方式中,你更推荐使用哪种方式* @param message* @return*/
@GetMapping("/low/chat")
public Object lowChat(@RequestParam(value = "message") String message) {chatMemory.add(UserMessage.from(message));ChatResponse chat = chatLanguageModel.chat(chatMemory.messages());chatMemory.add(chat.aiMessage());return chat.aiMessage().text();
}

在这里准备两个具有上下文连贯性的问题

  • jdk8之后创建线程有哪些方式

  • 在以上的方式中,你更推荐使用哪种方式

启动工程后,调用第一个接口,给出下面的回答

基于上面的回答,我们再用第二个问题请求接口,从回答的结果不难看出,第二个问题的回答是参考了第一次的回答内容

3.3.2 High Level API的实现

基于High Level API的实现,需要对自定义的接口做一下改造,首先在Assistant接口增加一个方法,并使用@MemoryId进行参数标准

  • MemoryId,可以理解为一个会话的唯一标识,在与大模型对话时候可以实现不同会话的隔离,这里就是利用了这个思想进行实现

再在AssistantConfig类中初始化Assistant的bean的时候添加会话记忆的配置信息

@Bean
public Assistant assistant(){return AiServices.builder(Assistant.class).chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(15)).chatLanguageModel(chatLanguageModel).build();
}

增加一个接口

final Assistant assistant;/*** localhost:8081/api/memory/high/chat?memoryId=1&message=jdk8之后创建线程有哪些方式* localhost:8081/api/memory/high/chat?memoryId=1&message=在以上的方式中,你更推荐使用哪种方式* @param message* @return*/
@GetMapping("/high/chat")
public Object highChat(@RequestParam(value = "memoryId") String memoryId,@RequestParam(value = "message") String message) {return assistant.chat(memoryId, message);
}

按照上述同样的方式分别再调用下两个接口,第一次调用效果如下:

第二次调用时候,从回答效果来看,是参考了第一次的内容的

3.4 Function Calling

Function Calling 也叫结构化输入,在 LangChain4j 中,Function Calling 是一种强大的功能,允许开发者将语言模型(如 OpenAI 的 GPT)与外部工具或 API 集成。通过 Function Calling,语言模型可以决定何时调用外部函数,并将函数的返回结果整合到生成的响应中。这种机制非常适合构建需要动态获取数据或执行特定任务的应用程序。

3.4.1 核心概念

模型决定调用函数

  • 语言模型根据用户输入的内容,决定是否需要调用外部函数。

  • 如果需要调用函数,模型会生成一个包含函数名称和参数的 JSON 对象。

执行外部函数

  • 应用程序接收到模型生成的 JSON 对象后,调用相应的外部函数或 API。

  • 外部函数执行完成后,将结果返回给应用程序。

整合函数结果

  • 应用程序将函数的结果传递给语言模型。

  • 语言模型根据函数结果生成最终的响应。

3.4.2 应用场景

Function Calling 主要有如下应用场景:

  1. 动态数据获取

    1. 例如,用户询问天气时,模型可以调用天气 API 获取实时数据。

  2. 执行特定任务

    1. 例如,用户要求发送邮件时,模型可以调用邮件发送 API。

  3. 复杂逻辑处理

    1. 例如,用户需要计算复杂的数学公式时,模型可以调用计算引擎。

3.4.3 案例代码

参考下面的代码,核心思路如下:

  • 自定义工具方法,添加@Tool注解;

  • 将上述方法所在类配置到全局bean;

  • 执行调用的位置使用即可;

自定义工具方法

public class DataCalculator {@Tooldouble add(int a, int b) {return a + b;}@Tooldouble squareRoot(double x) {return Math.sqrt(x);}
}

自定义对话接口,里面有一个提问的方法

public interface MathGenius {String ask(String question);
}

添加一个配置类,将上述的DataCalculator 配置进去

package com.congge.config;import com.congge.util.DataCalculator;
import com.congge.util.MathGenius;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.service.AiServices;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@RequiredArgsConstructor
public class MathGeniusConfig {final ChatLanguageModel chatLanguageModel;@Beanpublic MathGenius mathGenius(){return AiServices.builder(MathGenius.class).tools(new DataCalculator()).chatLanguageModel(chatLanguageModel).build();}}

自定义接口

    final MathGenius mathGenius;//http://localhost:8081/api/func/high/chat@GetMapping("/high/chat")public String highChat() {String answer = mathGenius.ask("What is the square root of 475695037565?");return answer;}

调用一下接口,效果如下

或者换一个问题,可以看到,在实际进行计算的时候底层会根据工具类中提供的方法,结合问题自动进行选择和识别

3.5 联网搜索能力

大模型的联网搜索能力是大模型实现多模态基础,同时也是后续实现各种Agent应用的基础,下面看一个具体的案例,用于联网搜索天气。

3.5.1 注册并获取apikey

首先需要注册: Google Search API for real-time SERP scraping ,并申请到API key

  • 登录进去之后,进入主页,会默认给你分配一个apikey

  • 网站提供了多个厂商的信息,你可以选择其中一个使用,本例使用baidu提供的服务;

3.5.2 添加依赖

要结合LangChain4j 的联网搜索能力,需要在pom中添加如下依赖

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-web-search-engine-searchapi</artifactId><version>${langchain.version}</version>
</dependency>

3.5.3 添加配置信息

将第一步申请到的apikey配置到工程的配置文件中

search:apiKey: 你的apikeyengine: baidu

3.5.4 添加配置类

为了在对话API中能够用上联网搜索能力,还需要将web-search-engine-searchapi的能力配置到全局的bean中,添加如下的自定义配置类

@Configuration
@RequiredArgsConstructor
public class WebSearchInit {final SearchConfig searchConfig;@Beanpublic SearchApiWebSearchEngine initWebSearchEngine() {return SearchApiWebSearchEngine.builder().engine(searchConfig.getEngine()).apiKey(searchConfig.getApiKey()).build();}
}

然后再在AssistantConfig配置类中把WebSearchTool加进去

@Bean
public Assistant assistant(SearchApiWebSearchEngine engine){return AiServices.builder(Assistant.class).chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(15)).tools(new WebSearchTool(engine)).chatLanguageModel(chatLanguageModel).build();
}

3.5.5 接口效果测试

上面的准备工作都做完之后,使用之前的一个对话接口,调用一下,咨询一下今天某个城市的天气如何,可以看到,能够进行联网搜索查到今天的南京的天气信息

四、写在文末

本文通过较大的篇幅详细介绍了langchain4J的使用,并通过案例代码演示了其核心组件的使用,希望对看到的同学有用哦,本篇到此结束,感谢观看。

相关文章:

【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…...

rust学习笔记16-206.反转链表(递归)

rust函数递归在14中已经提到&#xff0c;接下来我们把206.反转链表&#xff0c;用递归法实现 递归函数通常包含两个主要部分&#xff1a; 基准条件&#xff08;Base Case&#xff09;&#xff1a;递归终止的条件&#xff0c;避免无限递归。 递归步骤&#xff08;Recursive Ste…...

Unity 中实例化预制体的完整过程

1.资源加载&#xff08;Load Asset to Memory&#xff09; Unity 的资源加载是指将各种资源&#xff08;如模型、纹理、音频、预制体 等&#xff09;从存储介质&#xff08;如磁盘、AssetBundle、远程服务器&#xff09;到运行时内存的过程&#xff0c;使其成为可用的资源&…...

Unity动画片段丢失(AnimationClip),如何进行重新绑定

从外部导入的AnimationClip存在黄色丢失的missing提示&#xff0c;这时候不需要重新制作动画&#xff0c;只需要重新绑定动画即可。 我们以第一条Intro1:Anchored Position(缺失!)为例 第一步&#xff1a;双击动画中的Intro1条目&#xff0c;可以查看片段存储该动画的对应路径…...

mysql5.7主从部署(docker-compose版本)

mysql5.7主从部署&#xff08;docker-compose版本&#xff09; 1:docker-compose-test.yml 文件信息 version: 3services:# MySQL 数据库mysql-master:image: mysql:5.7container_name: mysql-masterenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: nacosports:- 23…...

模型部署实战:PyTorch生产化指南

‌一、为什么要做模型部署&#xff1f;‌ 模型部署是将训练好的模型‌投入实际应用‌的关键步骤&#xff0c;涉及&#xff1a; 模型格式转换&#xff08;TorchScript/ONNX&#xff09;性能优化&#xff08;量化/剪枝&#xff09;构建API服务移动端集成 本章使用ResNet18实现图…...

SQLMesh 系列教程:Airbnb数据分析项目实战

在本文中&#xff0c;我们将探讨如何利用dbt项目的代码库来实现一个简单的SQLMesh项目。本文的基础是基于Udemy讲师为dbt课程创建的示例项目&#xff0c;可以在这个GitHub repo中获得。这个dbt项目是相对完整的示例&#xff0c;我们将使用它作为模板来演示SQLMesh&#xff08;下…...

LeetCode hot 100 每日一题(11)——189. 轮转数组

这是一道难度为中等的题目&#xff0c;让我们来看看题目描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3…...

VLAN综合实验

一、实验拓扑 二、实验要求 1、PC1/3处于同一个网段&#xff0c;所在接口为access&#xff0c;属于VLAN 2。 2、PC2/4/5/6处于同一网段。 3、PC2可以访问PC4/5/6。 4、PC4可以访问PC5&#xff0c;但不能访问PC6。 5、PC5不能访问PC6。 6、所有PC通过DHCP获取IP地址&#…...

杨辉三角(js实现,LeetCode118)

看到这道题我的第一反应是找规律&#xff0c;核心突破点是numRows这个参数&#xff0c;杨辉三角的第numRows行拥有的元素数量为numRows个&#xff0c;并且头尾都是1&#xff0c;由此我们可以通过双层for循环&#xff0c;先生成每一行的数组&#xff0c;然后将每一行的数组push进…...

C语言复习笔记--数组

今天继续来浅浅推进一下C语言的复习,这次是数组的复习,话不多说,正文开始. 数组的概念 数组是⼀组相同类型元素的集合,一种自定义类型.数组中元素个数不能为0.数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般⽐较多⻅的是⼆维数组. 下面从一维数组说起. 一维数组的创建和…...

Linux操作系统实验报告单(3)文本编辑器vi/vim

一、实验目的 掌握vi/vim编辑器的进入和退出方式了解vi/vim的三种模式熟练vi/vim的操作命令 二、实验内容 1.在家目录下新建一个名为“vitest_name”&#xff08;“name”为学生姓名拼音&#xff09;的目录。 ●创建用户目录命令&#xff1a;sudo mkdir /home/vitest_lw3613 …...

docker linux 常用操作命令

以下是 Docker 的常见操作命令及其简单介绍&#xff0c;帮助你快速上手 Docker 的基本使用&#xff1a; 1. 镜像操作 拉取镜像 docker pull 镜像名称:标签示例&#xff1a; docker pull ubuntu:20.04从 Docker Hub 拉取 Ubuntu 20.04 镜像。 拉取镜像 docker build -t"…...

除自身以外数组的乘积——面试经典150题(力扣)

题目 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时…...

打破煤矿通信屏障,无线系统赋能生产安全与智能进阶

项目背景 在煤矿行业智能化转型的浪潮中&#xff0c;七台河矿业局积极回应国家煤矿智能化建设的号召&#xff0c;采取了具有前瞻性的战略举措——在七台河地区的煤矿部署了“井上井下”无线覆盖与广播一体化系统。此举旨在消除井上与井下之间的通信障碍&#xff0c;加强矿业局与…...

DeepSeek + Kimi 自动生成 PPT

可以先用deepseek生成ppt大纲&#xff0c;再把这个大纲复制到Kimi的ppt助手里&#xff1a; https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 选择ppt模板&#xff1a; 点击生成ppt就制作好了。...

Blender标注工具

按住键盘D键 鼠标左键绘制 / 右键擦除 也可以在上方选择删除...

鸿蒙开发:远场通信服务rcp拦截器问题

前言 本文基于Api13。 上篇文章&#xff0c;简单的对rcp中的会话问题做了概述&#xff0c;本篇文章&#xff0c;我们聊一聊rcp中的拦截器问题&#xff0c;按照正常开发&#xff0c;其实拦截器中也不存在问题的&#xff0c;毕竟都是很官方的开发方式&#xff0c;但是在结合了创建…...

调研报告:Hadoop 3.x Ozone 全景解析

Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…...

Thinkphp 多文件压缩

控制器 <?phpnamespace app\api\controller; use think\Controller; use think\facade\Db; use think\facade\Request;use ZipArchive;class DrugTestResult {public function download(){if(Request::isPost()){$data Request::post();$idnumber Request::param(idnumb…...

NGINX中的反向代理实践

以下是一个全面和优化的配置示例&#xff0c;包括了错误处理、超时设置、头部信息调整等&#xff1a; server {listen 80;server_name your.domain.name; # 替换为你的实际域名或IP地址# 前端应用的静态资源处理location / {root /path/to/vue/dist; # Vue 应用的dist目录try_…...

redis分布式锁实现Redisson+redlock中watch dog是如何判断当前线程是否持有锁进行续租的呢?

在 Redis 中&#xff0c;Watch Dog&#xff08;看门狗&#xff09;机制主要用于实现分布式锁的自动续期&#xff08;如 Redisson 的 RedLock 实现&#xff09;。其核心目的是确保当业务逻辑执行时间超过锁的初始过期时间&#xff08;leaseTime&#xff09;时&#xff0c;锁不会…...

[spring] Spring JPA - Hibernate 多表联查 1

[spring] Spring JPA - Hibernate 多表联查 1 之前在 [spring] spring jpa - hibernate 名词解释&配置 和 [spring] spring jpa - hibernate CRUD 简单的学习了一下怎么使用 Hibernate 实现 CRUD 操作&#xff0c;不过涉及到的部分都是逻辑上比较简单的实现——只在一张表…...

在 Elasticsearch 中探索基于 NVIDIA 的 GPU 加速向量搜索

作者&#xff1a;来自 Elastic Chris Hegarty 及 Hemant Malik 由 NVIDIA cuVS 提供支持&#xff0c;此次合作旨在为开发者在 Elasticsearch 中的向量搜索提供 GPU 加速。 在 Elastic Engineering 组织内&#xff0c;我们一直致力于优化向量数据库的性能。我们的使命是让 Lucen…...

2025年图生视频模型技术全景解析

一、开源图生视频模型 阿里通义万象Wan2.1系列 I2V-14B-480P&#xff1a; 14B参数基础模型支持480P分辨率图生视频显存需求16GB以上 I2V-14B-720P&#xff1a; 高清增强版模型采用分帧渲染技术&#xff0c;输出分辨率达1280720 技术特性&#xff1a; 支持中文提示词自动解析内置…...

Docker build 会在本地产生巨大的文件

Docker build 会在本地产生巨大的文件&#xff0c; 比如 用 这个命令列出本地镜像 docker images 可见size都是很大的&#xff0c; 到docker目录下&#xff0c;看到ext4.vhdx的大小 80多G 那只能用这个命令把不用的镜像删掉了&#xff1a; &#xff08;rmi后面是镜像id&a…...

使用LLaMA Factory微调导出模型,并用ollama运行,用open webui使用该模型

本篇记录学习使用llama factory微调模型的过程&#xff0c;使用ollama运行微调好的模型&#xff0c;使用open webui前端调用ollama的模型&#xff1b; 测试机信息&#xff1a; 系统&#xff1a;Ubuntu 24.04.2 LTS&#xff08;桌面版&#xff09; cpu&#xff1a;i9-14900KF …...

Git远程拉取和推送配置

Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景&#xff1a;换新电脑后使用Git进行代码拉取和推送过程中&#xff0c;提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次&#xf…...

正则魔法:解码 return /^\d+$/.test(text) ? text : ‘0‘ 的秘密

&#x1f680; 正则魔法&#xff1a;解码 return /^\d$/.test(text) ? text : 0 的秘密 &#x1f31f; 嘿&#xff0c;技术探险家们&#xff01;&#x1f44b; 今天我们要破解一段看似简单的代码&#xff1a;return /^\d$/.test(text) ? text : 0。它藏在一个 Vue 前端组件中…...

[023-01-47].第47节:组件应用 - GetWay与 Sentinel 集成实现服务限流

SpringCloud学习大纲 一、需求说明&#xff1a; 实现网关cloudalibaba-sentinel-gateway9528模块保护cloudalibaba-provider-payment9001 二、编码实现&#xff1a; 2.1.建module: 新建模块&#xff0c;名称是&#xff1a;cloudalibaba-sentinel-gateway9528 2.2.改pom &l…...

【自用】NLP算法面经(5)

一、L1、L2正则化 正则化是机器学习中用于防止过拟合并提高模型泛化能力的技术。当模型过拟合时&#xff0c;它已经很好地学习了训练数据&#xff0c;甚至是训练数据中的噪声&#xff0c;所以可能无法在新的、未见过的数据上表现良好。 比如&#xff1a; 其中&#xff0c;x1和…...

AI视频生成产品体验分享(第2趴):Vidu、Hailuo、Runway、Pika谁更胜一筹?

hi&#xff0c;大家&#xff0c;继上次体验完可灵、即梦和pixverse&#xff0c;今天打算从产品经理的角度再研究下Vidu、Hailuo、Runway、Pika这几款产品&#xff01;欢迎加入讨论&#xff01; 一、产品简介 1. Vidu&#xff1a;国产自研的「一致性标杆」 &#x1f4cc;官网…...

火绒终端安全管理系统V2.0——行为管理(软件禁用+违规外联)

火绒终端安全管理系统V2.0&#xff1a;行为管理策略分为软件禁用和违规外联两部分&#xff0c;能够管理终端用户软件的使用&#xff0c;以及终端用户违规连接外部网络的问题。 l 软件禁用 软件禁用策略可以选择软件名单的属性、添加软件名单以及设置发现终端使用禁用软件时的…...

台式机电脑组装---电脑机箱与主板接线

台式机电脑组装—电脑机箱与主板接线 1、机箱连接主板的跳线一般主要有USB 2.0、USB 3.0、前置音频接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四个主板跳线&#xff0c;这些跳线分别的含义如下。 RESET SW&#xff1a;机箱重启按键&#xff1b;注&#xff1a…...

【总结】常用API架构类型

引言 在现代软件开发中&#xff0c;API(应用程序编程接口)已经成为各类系统之间交互的核心。不同的 API 架构类型适用于不同的业务需求和技术场景&#xff0c;选择合适的架构可以提高系统的性能、可维护性和扩展性。本文将介绍几种常见的 API 架构类型&#xff0c;并分析它们的…...

ffmpeg库视频硬解码使用流程

FFmpeg 的硬解码&#xff08;Hardware Decoding&#xff09;通过调用 GPU 或专用硬件的编解码能力实现&#xff0c;能显著降低 CPU 占用率。 ‌一、FFmpeg 支持的硬件解码类型‌ FFmpeg 原生支持多种硬件加速类型&#xff0c;具体由 AVHWDeviceType 定义&#xff0c;包括&…...

两个常用的用于读写和操作DXF文件C#库:netDxf 和 DXF.NET

netDxf 和 DXF.NET 是两个常用的C#库&#xff0c;用于读取、写入和操作DXF文件。以下是它们的详细介绍和用法示例。 1. netDxf 简介 netDxf 是一个开源的DXF文件读写库&#xff0c;支持AutoCAD DXF格式的读取和写入。它支持大多数DXF实体和对象&#xff0c;并且易于使用。 Gi…...

jmeter吞吐量控制器-Throughput Controller

jmeter吞吐量控制器-Throughput Controller 新增吞吐量控制器名词解释测试场景场景1&#xff1a;场景2&#xff1a;场景3场景4场景5场景6场景7场景8 测试结论 根据百分比执行不同的接口测试场景测试结果 新增吞吐量控制器 名词解释 Based on: Total Executions(总执行数)/Perc…...

windows 平台编译openssl

文章目录 准备环境安装perl安装NASM获取源码 源码编译配置编译 准备环境 安装perl 下载Perl 5.40.0.1 Portable zip strawberryperl 解压后设置系统环境变量 测试安装是否成功 perl --versionThis is perl 5, version 40, subversion 0 (v5.40.0) built for MSWin32-x64-m…...

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…...

Python散点图(Scatter Plot):数据探索的“第一张图表”

在数据可视化领域,散点图是一种强大而灵活的工具,它能够帮助我们直观地理解和探索数据集中变量之间的关系。本文将深入探讨散点图的核心原理、应用场景以及如何使用Python进行高效绘制。 后续几篇将介绍高级技巧、复杂应用场景。 Python散点图(Scatter Plot):高阶分析、散点…...

Spring AI Alibaba快速使用

AI 时代&#xff0c;Java 程序员也需要与时俱进&#xff0c;这两个框架必须掌握。 一个是 Spring AI一个是 Spring Alibaba AI。 Spring AI 是一个AI工程领域的应用程序框架&#xff0c;它的目标是将 Spring生态系统的设计原则应用于人工智能领域。 但是&#xff0c; Spring…...

Redis 跳表原理详解

一、引言 在 Redis 中&#xff0c;有序集合&#xff08;Sorted Set&#xff09;是一种非常重要的数据结构&#xff0c;它可以实现元素的有序存储和高效查找。而实现有序集合的底层数据结构之一就是跳表&#xff08;Skip List&#xff09;。跳表是一种随机化的数据结构&#xff…...

安全地自动重新启动 Windows 资源管理器Bat脚本

安全地自动重新启动 Windows 资源管理器脚本 可以直接运行的 Windows 批处理脚本&#xff0c;用于安全地自动重新启动 Windows 资源管理器。该脚本会在杀死资源管理器之前检查是否有其他进程正在使用资源管理器相关的文件。 Bat脚本 echo off title 资源管理器安全重启工具 co…...

【C++模板】

模板初阶 前言1.定义模板2.函数模板2.1定义2.2实例化函数模板2.3模板参数的匹配原则 3.类模板3.1类模板实例化 前言 模板是C中泛型编程的基础&#xff0c;一个模板就是一个创建类和函数的蓝图或公式。 1.定义模板 假定我们希望编写一个函数来比较两个值&#xff0c;并指出第…...

基于Debian搭建FTP服务器

操作系统 Debian-9.6.0-amd64&#xff0c;图形化安装 基础操作 1.软件安装管理 命令方式&#xff1a; 在线安装 sudo apt-get install vim/ifconfig 查看安装软件 dpkg -l 图形化桌面方式 &#xff1a; 通过“软件管理”工具管理 2.网络管理 /etc/network/interfaces 3.文本…...

如果我的项目是用ts写的,那么如何使用webpack的动态导入功能呢?

在 TypeScript 项目中使用 Webpack 的动态导入&#xff08;Dynamic Imports&#xff09;功能&#xff0c;需要结合 TypeScript 的语法和 Webpack 的配置。以下是具体实现方法和注意事项&#xff1a; 一、基础配置 1. 修改 tsconfig.json 确保 TypeScript 支持动态导入语法&am…...

构建高效的LinkedIn图像爬取工具

一. 项目背景与目标 LinkedIn上的用户头像数据可以用于多种场景&#xff0c;例如&#xff1a; 人才招聘&#xff1a;通过分析目标职位候选人的头像&#xff0c;了解其职业形象。市场调研&#xff1a;收集特定行业从业者的头像&#xff0c;用于分析职业群体的特征。学术研究&a…...

在windows下安装windows+Ubuntu16.04双系统(下)

这篇文章的内容主要来源于这篇文章&#xff0c;为正式安装windowsUbuntu16.04双系统部分。在正式安装前&#xff0c;若还没有进行前期准备工作&#xff08;1.分区2.制作启动u盘&#xff09;&#xff0c;见《在windows下安装windowsUbuntu16.04双系统(上)》 二、正式安装Ubuntu …...

浅分析 PE3R 感知高效的三维重建

"近期&#xff0c;二维到三维感知技术的进步显著提升了对二维图像中三维场景的理解能力。然而&#xff0c;现有方法面临诸多关键挑战&#xff0c;包括跨场景泛化能力有限、感知精度欠佳以及重建速度缓慢。为克服这些局限&#xff0c;我们提出了感知高效三维重建框架&#…...