LangChain4j
原本用的是 OpenAiChatModel,如果要实现一些高级功能(如会话记忆、提示词模板、流式输出)的话会非常复杂,AiServices 是 LangChain4j 封装的高阶工具,自动整合 OpenAiChatModel 并提供更易用的接口,简化高级功能开发。系统提示词(System Message)是大模型的「底层规则」,优先级高于用户输入,决定了 AI 的角色定位、回答风格、约束条件等。通
·
LangChain4j
远程大模型调用
maven-会话功能
引入依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.4.0</version>
</dependency>
构建OpenAiChatModel对象
关键配置说明:
- baseUrl:阿里云通义千问兼容 OpenAI 的接口地址,固定为https://dashscope.aliyuncs.com/compatible-mode/v1;
- apiKey:阿里云百炼平台申请的 API 密钥(需替换为自己的有效密钥);
- modelName:指定调用的模型版本,qwen-flash 为通义千问轻量版,也可替换为 qwen-turbo/qwen-plus 等。
OpenAiChatModel model = OpenAiChatModel.builder()
// 在大模型的api中查找
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.apiKey(apiKey)
.modelName("qwen-flash") // 所使用的大模型的name
.build();
调用chat方法与大模型交互
String result = model.chat("西北大学是211吗");
System.out.println(result);
打印日志信息
引入 logback 依赖可输出详细的请求 / 响应日志,便于调试接口调用过程中的参数、返回值等问题。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.apiKey(apiKey)
.modelName("qwen-flash")
.logRequests(true) // 请求的日志信息
.logResponses(true) // 响应的日志信息
.build();
springboot整合
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.2.0-beta8</version>
</dependency>
langchain4j:
open-ai:
chat-model:
api-key: ${API-KEY:sk-576746ec85384deea25770688e439042}
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
model-name: qwen-flash
log-requests: true # 日志
log-responses: true # 日志
logging:
level:
dev.langchain4j: debug
@Resource
private OpenAiChatModel model;
@RequestMapping("chat")
public String chat(String message){
return model.chat(message);
}
AiServices工具类
原本用的是 OpenAiChatModel,如果要实现一些高级功能(如会话记忆、提示词模板、流式输出)的话会非常复杂,AiServices 是 LangChain4j 封装的高阶工具,自动整合 OpenAiChatModel 并提供更易用的接口,简化高级功能开发
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.2.0-beta8</version>
</dependency>
@AiService
public interface ConsultantService {
public String chat(String message);
}
@Resource
private ConsultantService consultantService;
@RequestMapping("chat")
public String chat(String message){
return consultantService.chat(message);
}
流式输出
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.2.0-beta8</version>
</dependency>
@RequestMapping(value = "chat", produces = "text/html;charset=utf-8")
public Flux<String> chat(String message){
return consultantService.chat(message);
}
消息注解
系统提示词(System Message)是大模型的「底层规则」,优先级高于用户输入,决定了 AI 的角色定位、回答风格、约束条件等。@SystemMessage 就是将这些规则以注解形式绑定到 AI 服务接口 / 方法上,替代手动拼接系统消息的样板代码。
补充说明:
- @SystemMessage:可直接写死提示词,也可通过 fromResource 从外部文件读取(便于维护);
- @UserMessage:支持占位符 {{xxx}},通过 @V (“xxx”) 绑定方法入参,实现动态拼接用户消息;
- 未指定 @V 时,默认占位符为 {{it}},绑定第一个方法入参。
@AiService
public interface ConsultantService {
// @SystemMessage("你是搞笑的ai助手,你叫邓超")
@SystemMessage(fromResource = "system.txt")// 指定外部文件作为提示词
//@UserMessage("你是搞笑的ai助手,你叫邓超.{{it}}") 不使用@V注解的话默认是it
@UserMessage("你是搞笑的ai助手,你叫邓超.{{msg}}")//相当于拼接了message
public Flux<String> chat(@V("msg") String message);
}
会话记忆
会话记忆用于保存上下文消息,让模型能关联历史对话生成响应;以下提供两种实现方式:
- ChatMemory:全局共享的记忆对象,无用户隔离,所有请求共用同一份上下文(适用于单用户场景);
- ChatMemoryProvider:按 memoryId 生成独立的记忆对象,实现会话隔离(适用于多用户场景),两者二选一即可。
@Configuration
public class CommonConfig {
// 不能会话隔离
@Bean
public ChatMemory chatMemory(){
return MessageWindowChatMemory.builder()
.maxMessages(20) // 单次会话最大会话数
.build();
}
// 实现会话隔离,两者留其一即可
@Bean
public ChatMemoryProvider chatMemoryProvider(){
ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
@Override
public ChatMemory get(Object memoryId) {
return MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20)
.build();
}
};
return chatMemoryProvider;
}
}
@AiService
public interface ConsultantService {
public Flux<String> chat(@UserMessage String message, @MemoryId String memoryId);
}
@RequestMapping(value = "chat", produces = "text/html;charset=utf-8")
public Flux<String> chat(String memoryId, String message){
return consultantService.chat(message, memoryId);
}
会话记忆持久化
上述会话记忆为内存级,服务重启后丢失;通过实现 ChatMemoryStore 接口并结合 Redis,可将会话记忆持久化,重启后仍能恢复上下文。
@Repository
public class RedisChatMemoryStore implements ChatMemoryStore {
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public List<ChatMessage> getMessages(Object memoryId) {
//反序列化
String json = redisTemplate.opsForValue().get(memoryId.toString());
return ChatMessageDeserializer.messagesFromJson(json);
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> list) {
//序列化存入redis
String json = ChatMessageSerializer.messagesToJson(list);
redisTemplate.opsForValue().set(memoryId.toString(), json, Duration.ofDays(1));
}
@Override
public void deleteMessages(Object memoryId) {
redisTemplate.delete(memoryId.toString());
}
}
spring:
data:
redis:
host: localhost
port: 6379
password: 123456
lettuce:
pool:
max-active: 8 # 最大连接
max-idle: 8 # 最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: 100 # 连接等待时间
@Autowired
private ChatMemoryStore redisChatMemoryStore;
@Bean
public ChatMemoryProvider chatMemoryProvider(){
ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
@Override
public ChatMemory get(Object memoryId) {
return MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20)
.chatMemoryStore(redisChatMemoryStore)//写入存储机制
.build();
}
};
return chatMemoryProvider;
}
更多推荐


所有评论(0)