LangChain4j从入门到实战
内 容来自黑马程序员
LangChain4j
目前市面上有关java调用大模型的工具库,主流的有两种, 一种是LangChain4j, 一种是SpringAI。
有关使用SpringAI如何调用大模型,可参考《SpringAI+DeepSeek大模型应用开发实战》
LangChain4j的官网 。里面提供了langchain4j的详细使用教程
1.1 快速入门
1.1.1 创建一个普通的maven工程

3.1.2 引入依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.0.1</version>
</dependency>
3.1.3 构建聊天对象OpenAiChatModel
构建OpenAiChatModel对象的时候,需要指定大模型的url地址,百炼平台的API-KEY,以及调用的模型名称。这里的API-KEY给大家说明一下,API-KEY可以直接写死到代码中,也可以配置到操作系统的环境变量中,然后通过代码获取再使用。这里推荐大家把API-KEY配置到系统的环境变量中再使用,因为如果直接写死在代码里面,会存在API-KEY泄露的风险。所以在写代码前,请先在系统的用户变量中创建一个名字叫API-KEY的环境变量,值就是你在百炼平台申请的api-key。最后一定记得重启IDEA!

下面是构建OpenAiChatModel对象的代码:
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")//url参考百炼平台API文档
.apiKey(System.getenv("API-KEY"))//获取环境变量API-KEY使用
.modelName("qwen-plus")//设置模型名称
.build();
3.1.4 调用方法与大模型交互
public class App {
public static void main(String[] args) {
//2.构建OpenAiChatModel对象
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.apiKey(System.getenv("API-KEY"))
.modelName("qwen-plus")
.build();
//3.调用chat方法,交互
String result = model.chat("东哥帅不帅?");
System.out.println(result);
}
}
3.1.5 查看日志信息
为了查看与大模型交互过程中具体发送的请求消息和大模型响应的数据,可以打开日志开关,我们只需要在构建OpenAiChatModel对象的时候调用logRequests和logResponses方法设置一下即可。
public class App {
public static void main(String[] args) {
//2.构建OpenAiChatModel对象
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.apiKey(System.getenv("API-KEY"))
.modelName("qwen-plus")
.logRequests(true)//设置打印请求日志
.logResponses(true)//设置打印响应日志
.build();
//3.调用chat方 法,交互
String result = model.chat("东哥帅不帅?");
System.out.println(result);
}
}

3.2 Spring整合LangChain4j
因为将来我们的java项目,必然是离不开Spring的,既然我们做的是大模型与传统软件的结合,那么毫无疑问,langchain4j的使用必然要和spring结合起来才可以。
3.2.1 创建SpringBoot项目

3.2.2 引入LangChain4j起步依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
3.2.3 在application.yml中配置调用大模型的信息
langchain4j:
open-ai:
chat-model:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: ${API-KEY}
model-name: qwen-plus
起步依赖会检测到配置信息,自动的往IOC容器中注入一个OpenAiChatModel对象。
3.2.4 开发接口,调用大模型
@RestController
public class ChatController {
@Autowired
private OpenAiChatModel model;
@RequestMapping("/chat")
public String chat(String message){
String result = model.chat(message);
return result;
}
}
3.2.5 查看日志信息
为了查看与大模型交互过程中具体发送的请求消息和大模型响应的数据,我们需要在application.yml配置文件中开启配置即可。
langchain4j:
open-ai:
chat-model:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: ${API-KEY}
model-name: qwen-plus
log-requests: true #请求消息日志
log-responses: true #响应消息日志
logging:
level:
dev.langchain4j: debug #日志级别
3.3 AiServices工具类
接下来我们学习LangChain4j提供的工具类AiServices,一个非常宝藏的工具。在之前的案例中,我们访问大模型是借助于OpenAiChatModel的chat方法完成的。其实这种方式在实际开发中并不是很常用,因为如果使用这种方式调用大模型,将来我们完成一些高阶的功能,比如会话记忆/RAG知识库/Tools工具的时候,在调用chat方法访问大模型前,我们需要自己做很多很多的工作,完成起来是比较复杂的。

为了简化我们程序员的使用,LangChain4j提供了AiServices工具类,封装了有关model对象和其它一些功能的操作,用起来会非常简单。接下类我们先来聊一聊AiServices工具类的基本使用。
3.3.1 AiServices工具类基本使用
3.3.1.1 引入AiServices相关依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
3.3.1.2 声明用于封装聊天方法的接口
public interface ConsultantService {
//用于聊天的方法,message为用户输入的内容
public String chat(String message);
}
3.3.1.3 使用AiServices工具类创建接口的动态代理对象
由于创建好的代理对象,将来在ChatController中需要使用,所以这些代码将会放到统一的配置类CommonConfig中完成。
@Configuration
public class CommonConfig {
@Autowired
private OpenAiChatModel model;
@Bean
public ConsultantService consultantService() {
ConsultantService cs = AiServices.builder(ConsultantService.class)
.chatModel(model)//设置对话时使用的模型对象
.build();
return cs;
}
}
3.3.1.4 ChatController中注入ConsultantService并使用
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
@RequestMapping("/chat")
public String chat(String message){
String result = consultantService.chat(message);
return result;
}
}
3.3.2 AiServices工具类声明式使用
为了简化AIServices工具类的使用,LangChain4j提供了声明式使用方法,想为哪个接口创建代理对象,只需要在该接口上添加@AiService注解并指定要使用的模型,将来LangChain4j扫描到该注解后会自动的创建该接口的代理对象并注入到IOC容器中。接下来修改ConsultantService中的代码,并重新测试。
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "openAiChatModel"
)
public interface ConsultantService {
//用于聊天的方法,message为用户输入的内容
public String chat(String message);
}
上述代码中,AiService注解的wiringMode用于指定装配模式,默认的取值为AiServiceWiringMode.AUTOMATIC,表示自动装配的意思,这里咱们设置为手动装配:AiServiceWiringMode.EXPLICIT。chatModel注解用于指定对话时需要使用的模型对象在IOC容器中的名字, 由于IOC容器中Bean对象的名字默认是类名首字母小写,所以这里的取值为 openAiChatModel。
实际上,在使用AiService注解时,我们不手动的指定这两个属性的值,也就是说采用AiService的自动装配模式也是可以的。
@AiService
public interface ConsultantService {
//用于聊天的方法,message为用户输入的内容
public String chat(String message);
}
只是如果我们手动设置的话,大家更容易理解这里究竟在做什么,所以将来咱们在使用AiService注解的 时候,都采用手动装配的方式。
3.4 流式调用
在第二章大模型的使用中我们有讲到,调用大模型有两种方式:流式调用和阻塞式调用。在我们前面演示的过程中,其实都是用的是阻塞式调用, 结果是一次性响应的, 接下来我们学习如何使用LangChain4j发起流式调用。
3.4.1 流式调用步骤
3.4.1.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.0.1-beta6</version>
</dependency>
3.4.1.2 配置流式模型对象
之前咱们配置的是阻塞式对话模型对象,在流式调用中,我们需要使用LangChain4j的流式模型对象。和之前一样,也需要在配置文件中完成配置。
langchain4j:
open-ai:
streaming-chat-model: #流式模型配置
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: ${API-KEY}
model-name: qwen-plus
log-requests: true
log-responses: true
3.4.1.3 调整ConsultantService中的代码
ConsultantService中的chat方法的返回值类型,需要修改为支持流式处理的类型Flux,同时还需要在AiService注解中,通过streamingChatModel属性, 配置一下流式调用的模型对象,值为openAistreamingChatModel
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "openAiChatModel",
streamingChatModel = "openAistreamingChatModel"
)
public interface ConsultantService {
public Flux<String> chat(String message);
}
3.4.1.4 调整ChatController中 的代码
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
@RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
public Flux<String> chat(String memoryId,String message){
Flux<String> result = consultantService.chat(memoryId,message);
return result;
}
}
其中@RequestMapping注解的produces属性,用于解决乱码问题。
3.4.2 对接前端页面
我们将来成熟的项目肯定不能让用户通过地址栏输入,所以我们需要提供前端页面供用户更方便的使用,有关前端的知识不是本次课程的核心内容,所以这里就不带着大家一点一点儿写了,我已经提前给大家准备好了,大家只需要把资料中提供的前端页面直接拷贝到当前项目的static目录下,浏览器就能直接访问了。
项目结构:

浏览器访问:
