langchain4j基本使用方法(一)

langchain4j入门基本使用

1. 初始准备工作

1.1 创建springboot 项目

正常引入springboot所需要的一些依赖以后,添加langchain4j的依赖

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
    <version>1.0.0-beta2</version>
</dependency>

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    <version>1.0.0-beta2</version>
</dependency>

1.2 获取API-Key

由于我们需要获取一个API-Key来调用大模型的接口,所以我们可以在一些提供免费接口试用的厂商申请一个额apikey,比如DeepSeek、BaiChuan、阿里云百炼、智谱清言等。我们以阿里云百炼为例
链接:阿里云百炼
点击免费体验
在这里插入图片描述
然后登陆账号,进入页面点击左上角的账户中的API-key
在这里插入图片描述
然后创建一个API-KEY
在这里插入图片描述
然后得到的API-KEY好好保存,然后开始进行配置文件

1.3 配置文件

langchain4j:
  open-ai:
    chat-model:
      api-key: sk-8d83 # 换成自己的
      model-name: qwen-plus # 模型可以换成自己想要的模型
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1 # 阿里云的接口链接,如果访问失败,去官网找最新的链接
      # 流式返回的配置
    streaming-chat-model:
      api-key: sk-8d83
      model-name: qwen-plus
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1

2 功能实现

我们首先编写一个最简单的接口进行测试,先看看我们的接口是否能够访问到阿里的接口并得到相应的信息

package com.jolly.chatmat.chat;


import dev.langchain4j.model.chat.ChatLanguageModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class chat2QW_plus {
	
	// 创建一个实例对象用于调用接口
    private ChatLanguageModel chatLanguageModel;
    
    // 创建一个构造函数,这样会自动创建一个OpenAiChatModel的对象,不需要我们手动创建
    public chat2QW_plus(ChatLanguageModel chatLanguageModel) {
        this.chatLanguageModel = chatLanguageModel;
    }

    @GetMapping("/chat")
    public String model(@RequestParam(value = "message", defaultValue = "Hello") String message) {
        return chatLanguageModel.chat(message);
    }

}

调用chat接口,可以得到返回的结果
在这里插入图片描述

但是这种方式是偏向于底层的方式,我们不能有效的对其进行扩展使用,比如日志打印等等。
所以我们使用更高级的方式进行使用,首先创建一个对应模型的接口

2.1 编写接口

package com.jolly.chatmat.models;

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;

@AiService
public interface QWen {

    @SystemMessage("你是一个计算机专家")
    String chat(String userMessage);
}

可以使用注入的方式获取到对应的模型实体

	@Resource
    private QWen qWen;

    @GetMapping("/chat")
    public String model(@RequestParam(value = "message", defaultValue = "算法的特性是什么") String message) {
        return qWen.chat(message);
    }

模型也是进行了有效的输出
在这里插入图片描述

2.2 实现流式返回

LLM 每次生成一个标记,因此许多 LLM 提供商都提供逐个标记流式传输响应的方法,而不是等待生成整个文本。这显著改善了用户体验,因为用户无需等待未知的时间,几乎可以立即开始阅读响应。
我们常见大模型的对话都是流式传输。然后前端有打印机的效果,这样可以更快的响应和更好的体验,所以流式返回都是最基本的操作。

为了实现流式传输,需要导入一个依赖

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-reactor</artifactId>
    <version>1.0.0-beta2</version>
</dependency>

然后在刚才的**QWen **接口种,添加一个方法

 @SystemMessage("You are a polite assistant")
 Flux<String> chatWithStream(String userMessage);

然后添加一个流式返回的接口

@GetMapping(value = "/chatWithStream",produces = TEXT_EVENT_STREAM_VALUE)
public Flux<String> chatWithStream(@RequestParam(value = "message", defaultValue = "算法的特性是什么") String message) {
        return qWen.chatWithStream(message);
}

得到的结果为
在这里插入图片描述
这里想要吐槽一下,为什么流式传输的需要进行配置文件的方式进行配置,同样的模型直接在接口上添加一个注解的方式进行实现不好吗?

2.3 实现日志打印

首先创建一个监听类,对调用接口前和调用接口后的返回值进行打印,实现**ChatModelListener **接口的方法

import dev.langchain4j.model.chat.listener.ChatModelErrorContext;
import dev.langchain4j.model.chat.listener.ChatModelListener;
import dev.langchain4j.model.chat.listener.ChatModelRequestContext;
import dev.langchain4j.model.chat.listener.ChatModelResponseContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyChatModelListener implements ChatModelListener {

    private static final Logger log = LoggerFactory.getLogger(MyChatModelListener.class);

    @Override
    public void onRequest(ChatModelRequestContext requestContext) {
        log.info("onRequest(): {}", requestContext.chatRequest());
    }

    @Override
    public void onResponse(ChatModelResponseContext responseContext) {
        log.info("onResponse(): {}", responseContext.chatResponse());
    }

    @Override
    public void onError(ChatModelErrorContext errorContext) {
        log.info("onError(): {}", errorContext.error().getMessage());
    }
}

然后将监听类创建为一个Bean对象给SpringBoot管理,创建一个config类

import dev.langchain4j.model.chat.listener.ChatModelListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class QwenConfig {
    @Bean
    ChatModelListener chatModelListener() {
        return new MyChatModelListener();
    }
}

这样在使用过程中就可以实现日志打印功能
在这里插入图片描述

2.4 对话记忆

请注意,“记忆”和“历史”是相似但又不同的概念。

历史记录保存了用户和 AI 之间的所有消息。历史记录是用户在 UI 中看到的内容。它代表了实际说过的内容。
记忆会保留一些信息,这些信息会呈现给 LLM,使其表现得好像“记住”了对话一样。

实现记忆的方式很简单,在刚才的Config文件中加入一下内容,我们可以实现对话的记忆

@Bean
ChatModelListener chatModelListener() {
   return new MyChatModelListener();
}

我们可以在日志打印中查看到效果
在这里插入图片描述

但是注意,这个对话历史是没有和任何用户信息绑定的,所以不管换一个链接请求,还是什么的都会有对话历史,所以是不安全的,对话历史需要和用户进行绑定

如果需要实现此功能,需要使用声明式的创建方式进行创建,我们首先创建一个新的接口

public interface QWen {
    @SystemMessage("你是一个高效的人工智能助手")
    String chatWithMemory(@MemoryId int memoryId, @UserMessage String userMessage);
}

然后使用@Bean将创建的模型对象交给springboot管理,这里可以将参数解析换成对配置文件的解析,就可以实现解耦,withMaxMessages就是设置的最大历史对话长度,如果太长了会导致我们的对话非常消耗token,这是很不好的。

@Bean(name = "Qwen01")
    public QWen Qwen_Assistant() {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey("sk-8d83")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .modelName("qwen-plus")
                .build();
        return AiServices.builder(QWen.class).chatLanguageModel(model).
                chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
                .build();
    }

然后创建一个接口用于接受请求,这里我使用的是userid,但是在真正的开发环境中,是不可以这样进行使用的,需要将userid和当前会话的id进行结合,得到一个当前用户会话独一无二的id


@RestController
public class chat2QW_plus {

    @Resource(name = "Qwen01")
    private QWen qWen01;

    @GetMapping(value = "/chatWithMemory",produces = TEXT_EVENT_STREAM_VALUE)
    public String chatWithMemory(@RequestParam(value = "message", defaultValue = "算法的特性是什么") String message,@RequestParam("userid") Integer userid) {
        return qWen01.chatWithMemory(userid,message);
    }

结果如下:
在这里插入图片描述

在这里插入图片描述
我们可以明显的看到,已经实现了对话记忆的功能,当然如果需要实现持久化的记忆需要进行另外的实现,当我们修改userid后,就可以实现每个用户都有临时的对话记忆能力
在这里插入图片描述
如果需要进行持久化的对话记忆存储,可以参考以下代码

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.mapdb.DB;
import org.mapdb.DBMaker;

import java.util.List;
import java.util.Map;

import static dev.langchain4j.data.message.ChatMessageDeserializer.messagesFromJson;
import static dev.langchain4j.data.message.ChatMessageSerializer.messagesToJson;
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
import static org.mapdb.Serializer.INTEGER;
import static org.mapdb.Serializer.STRING;

public class ServiceWithPersistentMemoryForEachUserExample {

    interface Assistant {

        String chat(@MemoryId int memoryId, @UserMessage String userMessage);
    }

    public static void main(String[] args) {

        PersistentChatMemoryStore store = new PersistentChatMemoryStore();

        ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory.builder()
                .id(memoryId)
                .maxMessages(10)
                .chatMemoryStore(store)
                .build();

        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(ApiKeys.OPENAI_API_KEY)
                .modelName(GPT_4_O_MINI)
                .build();

        Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(model)
                .chatMemoryProvider(chatMemoryProvider)
                .build();

        System.out.println(assistant.chat(1, "Hello, my name is Klaus"));
        System.out.println(assistant.chat(2, "Hi, my name is Francine"));

        // Now, comment out the two lines above, uncomment the two lines below, and run again.

        // System.out.println(assistant.chat(1, "What is my name?"));
        // System.out.println(assistant.chat(2, "What is my name?"));
    }

    // You can create your own implementation of ChatMemoryStore and store chat memory whenever you'd like
    static class PersistentChatMemoryStore implements ChatMemoryStore {

        private final DB db = DBMaker.fileDB("multi-user-chat-memory.db").transactionEnable().make();
        private final Map<Integer, String> map = db.hashMap("messages", INTEGER, STRING).createOrOpen();

        @Override
        public List<ChatMessage> getMessages(Object memoryId) {
            String json = map.get((int) memoryId);
            return messagesFromJson(json);
        }

        @Override
        public void updateMessages(Object memoryId, List<ChatMessage> messages) {
            String json = messagesToJson(messages);
            map.put((int) memoryId, json);
            db.commit();
        }

        @Override
        public void deleteMessages(Object memoryId) {
            map.remove((int) memoryId);
            db.commit();
        }
    }
}

后续将更新langchain4j使用RAG进行检索增强

<think>嗯,用户想在Spring Boot项目中整合LangChain4j和DeepSeek,需要示例教程。首先,我得确认这两个库的整合方式。根据提供的引用,LangChain4j有Spring Boot Starter,可以自动配置,而DeepSeek也有对应的starter依赖。 用户可能已经了解基本的Spring Boot配置,但需要具体的步骤。我需要先整理依赖项,确保两个库的版本兼容。然后,配置application.yml文件,添加API密钥和模型设置。接下来,可能需要创建服务类,注入AI服务实例,并编写示例代码来调用这两个库的功能。 需要注意的是,用户可能遇到依赖冲突或配置错误的问题,所以需要提醒检查依赖版本和API密钥的正确性。此外,示例代码应该简单明了,展示如何同时使用LangChain4j和DeepSeek的功能,比如生成文本和调用聊天模型。 可能还需要解释每个步骤的作用,比如@Configuration注解的配置类,以及如何在控制器中调用服务。最后,生成相关问题,帮助用户进步探索性能优化或高级集成方法。</think>### Spring Boot整合LangChain4j与DeepSeek示例教程 #### 、环境准备 1. 创建Spring Boot项目(建议使用Spring Boot 3.x) 2. 添加依赖: ```xml <!-- LangChain4j核心依赖 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-spring-boot-starter</artifactId> <version>0.24.0</version> </dependency> <!-- DeepSeek官方starter --> <dependency> <groupId>io.github.pig-mesh.ai</groupId> <artifactId>deepseek-spring-boot-starter</artifactId> <version>1.4.2</version> </dependency> ``` #### 二、基础配置 ```yaml # application.yml langchain4j: open-ai: api-key: ${OPENAI_API_KEY} model-name: gpt-3.5-turbo deepseek: api-key: ${DEEPSEEK_API_KEY} model: deepseek-chat timeout: 60000 ``` 注:环境变量需在系统或IDE中配置[^2] #### 三、服务配置类 ```java @Configuration public class AIConfig { @Bean @ConditionalOnProperty(name = "langchain4j.open-ai.enabled", havingValue = "true") OpenAiChatModel openAiChatModel(LangChain4jProperties properties) { return OpenAiChatModel.builder() .apiKey(properties.getOpenAi().getApiKey()) .modelName(properties.getOpenAi().getModelName()) .build(); } @Bean @ConditionalOnProperty(name = "deepseek.enabled", havingValue = "true") DeepSeekClient deepSeekClient(DeepSeekProperties properties) { return new DeepSeekClient(properties.getApiKey(), properties.getModel()); } } ``` #### 四、示例服务类 ```java @Service public class AIService { private final OpenAiChatModel openAi; private final DeepSeekClient deepSeek; public AIService(OpenAiChatModel openAi, DeepSeekClient deepSeek) { this.openAi = openAi; this.deepSeek = deepSeek; } public String generateContent(String prompt) { // 使用LangChain4j生成基础内容 String draft = openAi.generate(prompt); // 使用DeepSeek优化结果 return deepSeek.chatCompletion( new ChatRequest() .setMessages(List.of( new Message("system", "优化以下内容:"), new Message("user", draft) )) ); } } ``` #### 五、控制器示例 ```java @RestController @RequestMapping("/api/ai") public class AIController { private final AIService aiService; public AIController(AIService aiService) { this.aiService = aiService; } @PostMapping("/generate") public ResponseEntity<String> generate(@RequestBody String prompt) { return ResponseEntity.ok(aiService.generateContent(prompt)); } } ``` #### 六、验证测试 使用curl测试接口: ```bash curl -X POST -H "Content-Type: text/plain" \ -d "请生成关于机器学习的简介" \ http://localhost:8080/api/ai/generate ``` **注意事项:** 1. 确保API密钥正确配置 2. 检查依赖版本兼容性 3. 建议添加限流和异常处理 4. 生产环境应配置HTTPS加密通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值