【Springboot+LangChain4j】实现多轮对话,即记忆对话功能
前置条件:已完成Springboot项目集成LangChain4j 可以参考上篇内容:【Springboot+LangChain4j】Springboot项目集成LangChain4j(下)-CSDN博客
1.问题描述
在实现了调用Ollama接口实现对话功能后,发现每次对话都是一个新的对话环境,不能针对一个问题多轮的询问下去。
在langchain4j中,其实有提供ChatMemory的类,来实现多轮对话功能。
2.新建配置类
建一个配置类ChatConfig
@Configuration
public class ChatConfig {public interface Assistant {String chat(String message);TokenStream stream(String message);}@Beanpublic Assistant assistant(ChatModel chatModel,StreamingChatModel streamingChatModel) {ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(20);return AiServices.builder(Assistant.class).chatModel(chatModel).streamingChatModel(streamingChatModel).chatMemory(chatMemory).build();}
代码解释:
public interface Assistant {String chat(String message);TokenStream stream(String message);
}
定义了一个AI助手接口,LangChain4j 会基于这个接口生成实现类,一个非流式,一个流式。
@Bean
public Assistant assistant(ChatModel chatModel,StreamingChatModel streamingChatModel) {ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(20);return AiServices.builder(Assistant.class).chatModel(chatModel).streamingChatModel(streamingChatModel).chatMemory(chatMemory).build();
}
ChatMemory:聊天上下文记忆,创建一个聊天记忆对象,记住最近的 20 条消息,消息数是可以根据自己需求改的
return:构建Assistant实例
-
AiServices.builder(...)
:LangChain4j 提供的构造工具,用于生成Assistant
实现。 -
.chatModel(...)
:设置用于普通对话的模型。 -
.streamingChatModel(...)
:设置用于流式对话的模型。 -
.chatMemory(...)
:指定对话记忆方式。 -
.build()
:生成最终的实现类并返回。
3.接口修改
在接口实现类中,注入这个实例
@Autowired
ChatConfig.Assistant assistant;
非流式的实现方法直接这么改就可以用
@GetMapping("/ai/generate_memory")
public String generateMemory(@RequestParam String text) {return assistant.chat(text);
}
流式就这么写就可以
@GetMapping(value = "/ai/generateStream_memory", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStreamMemory(@RequestParam String text) {return Flux.create(sink -> {TokenStream tokenStream = assistant.stream(text);tokenStream.onPartialResponse(sink::next) // 每接收到一个 token,就推送到前端.onCompleteResponse(response -> sink.complete()) // 完成流.onError(sink::error) // 异常处理.start(); // 最后一定要调用 start() 启动流式响应});
}