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

LangChain4J 使用实践

这里写目录标题

  • 大模型应用场景:
  • 创建一个测试示例
  • AIService
  • 聊天记忆实现
    • 简单实现聊天记录记忆
    • MessageWindowChatMemory实现聊天记忆
  • 隔离聊天记忆
    • 聊天记忆持久化
  • 添加AI提示词

大模型应用场景:

在这里插入图片描述

创建一个测试示例

导入依赖

        <dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-spring-boot-starter</artifactId><version>1.0.1-beta6</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai-spring-boot-starter</artifactId><version>1.0.1-beta6</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>1.0.1</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>1.0.1</version></dependency></dependencies>

在配置文件中配置好对应的api

langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o
langchain4j.open-ai.chat-model.log-requests=true
langchain4j.open-ai.chat-model.log-responses=true
...

测试效果

package com.aidemo.demo;import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class DemoApplicationTests {@Autowiredprivate OpenAiChatModel openAiChatModel;@Testvoid contextLoads() {String test = openAiChatModel.chat("你好");System.out.println(test);}}

在这里插入图片描述

AIService

在这里插入图片描述

package com.aidemo.demo.assistant;import dev.langchain4j.service.spring.AiService;@AiService
public interface Assistant {String chat(String message);
}

用于自动配置 AI 服务 , RAG, 工具 等
测试调用

    @Autowiredprivate Assistant assistant;@Testvoid contextLoads() {String test = assistant.chat("我是谁");System.out.println(test);}

聊天记忆实现

测试是否有记忆功能

    @Autowiredprivate Assistant assistant;@Testvoid contextLoads() {String test = assistant.chat("我是彭于晏");System.out.println(test);String testa = assistant.chat("我是谁");System.out.println(testa);}

AI没有记住名字
在这里插入图片描述

简单实现聊天记录记忆

每次问答都把把上一次的问答内容输出给ai
在这里插入图片描述

MessageWindowChatMemory实现聊天记忆

目前,LangChain4j 提供了 2 个开箱即用的实现:

更简单的一个,MessageWindowChatMemory,作为一个滑动窗口工作,保留最近的 N 条消息,并移除不再符合条件的老消息。 然而,因为每条消息可以包含不同数量的 token, MessageWindowChatMemory 主要适用于快速原型开发。
一个更复杂的选项是 TokenWindowChatMemory,它同样以滑动窗口方式运行,但专注于保留最近的 N 个 token, 根据需要移除旧消息。 消息是不可分割的。如果消息不适用,它将被完全移除。 TokenWindowChatMemory 需要一个 TokenCountEstimator 来计算每个 ChatMessage 中的 token 数量。

@Configuration
public class LangChainMemoryConfig {@Beanpublic ChatMemory chatMemory() {return MessageWindowChatMemory.withMaxMessages(10); // 保留最近 10 条消息}
}

在这里插入图片描述

隔离聊天记忆

在这里插入图片描述
创建记忆提供器,通过id区分用户 在这个场景中,ChatMemory 将由 ChatMemoryProvider 提供,每个内存 ID 对应一个实例。

package com.aidemo.demo.assistant;import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;@Configuration
public class LangChainMemoryConfig {private static final Logger logger = LoggerFactory.getLogger(LangChainMemoryConfig.class);// 可以通过配置文件或构造函数注入private final int maxMessagesPerUser = 10;@Beanpublic ChatMemoryProvider chatMemoryProvider() {ConcurrentMap<String, ChatMemory> memoryMap = new ConcurrentHashMap<>();return new ChatMemoryProvider() {@Overridepublic ChatMemory get(Object memoryId) {if (memoryId == null) {logger.error("Memory ID cannot be null");throw new IllegalArgumentException("Memory ID cannot be null");}if (!(memoryId instanceof String)) {logger.error("Memory ID must be a String, but was: {}", memoryId.getClass());throw new IllegalArgumentException("Memory ID must be a String");}String userId = (String) memoryId;return memoryMap.computeIfAbsent(userId, id -> {logger.info("Creating new chat memory for user: {}", id);return MessageWindowChatMemory.withMaxMessages(maxMessagesPerUser);});}};}
}

实现多用户接口

@AiService(wiringMode =EXPLICIT, // 表示必须手动指定依赖 BeanchatModel = "openAiChatModel",      // 绑定具体的模型 Bean 名称chatMemoryProvider = "chatMemoryProvider" // 指定记忆提供器 Bean 名称
)
public interface SeparateChatAssistant {String chat(@MemoryId String userId, @UserMessage String message);
}

调用测试

    @Autowiredprivate SeparateChatAssistant separateChatAssistant;@Testvoid contextLoads2() {// 发起对话,测试记忆能力separateChatAssistant.chat("1","我是彭于晏");String reply =  separateChatAssistant.chat("1","我是谁?");System.out.println("模型回答:" + reply);String reply2 =  separateChatAssistant.chat("12","我是谁?");System.out.println("模型回答:" + reply2);// 理想返回应为:“你是彭于晏” 或 类似记忆体现的内容}

在这里插入图片描述

聊天记忆持久化

在这里插入图片描述
使用MongoDB的形式

spring.data.mongodb.uri=mongodb://localhost:27017/chat_memory_db
package com.aidemo.demo.bean;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_messages")
public class ChatMessages {@Idprivate ObjectId id;private int messageId;//存储当前聊天记录列表的json字符串private String content;
}

创建持久化类

package com.aidemo.demo.store;import com.aidemo.demo.bean.ChatMessages;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;import java.util.LinkedList;
import java.util.List;
import java.util.Queue;@Component
public class MongoChatMemoryStore implements ChatMemoryStore {@Resourceprivate MongoTemplate mongoTemplate;/*** 根据 memoryId 获取消息* @param memoryId* @return*/@Overridepublic List<ChatMessage> getMessages(Object memoryId) {Criteria criteria = Criteria.where("memoryId").is(memoryId);Query query = new Query(criteria);ChatMessages storeChatMessage = mongoTemplate.findOne(query, ChatMessages.class);if (storeChatMessage == null) {return new LinkedList<>();}return ChatMessageDeserializer.messagesFromJson(storeChatMessage.getContent());}@Overridepublic void updateMessages(Object memoryId, List<ChatMessage> list) {Criteria criteria = Criteria.where("memoryId").is(memoryId);Query query = new Query(criteria);Update update = new Update();update.set("content", ChatMessageSerializer.messagesToJson(list));mongoTemplate.upsert(query, update, ChatMessages.class);}@Overridepublic void deleteMessages(Object memoryId) {Criteria criteria = Criteria.where("memoryId").is(memoryId);Query query = new Query(criteria);mongoTemplate.remove(query, ChatMessages.class);}}
package com.aidemo.demo.assistant;import com.aidemo.demo.store.MongoChatMemoryStore;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;@Configuration
public class SeparateChatAssistantConfig {@Resourceprivate MongoChatMemoryStore mongoChatMemoryStore;@Beanpublic ChatMemoryProvider chatMemoryProvider() {return memoryId -> MessageWindowChatMemory.builder().id(memoryId).maxMessages(10).chatMemoryStore(mongoChatMemoryStore) // 持久化到 mongoDB.build();}
}

在这里插入图片描述

添加AI提示词

作用是塑造ai的身份。

http://www.lqws.cn/news/133039.html

相关文章:

  • PPTAGENT:让PPT生成更智能
  • Java中的多态
  • Canal
  • A2A MCP 集成
  • 硬路由与软路由
  • GMS地下水数值模拟技术及地下水环评
  • NNLM和word2vec的区别
  • 软件工程专业的本科生应该具备哪些技能
  • 4种常见Python设计爱心创意实现方法
  • ROS中的里程计与IMU的消息类型解读
  • apt-get update提示gpg错误
  • 跨域请求解决方案全解析
  • JAVA-springboot JOSN解析库
  • 基于Web的安全漏洞分析与修复平台设计与实现
  • AT2401C中科微2.4g芯片PA
  • 软件工程专业本科毕业论文模板
  • Vue中的自定义事件
  • 手写 vue 源码 === runtime-dom 实现
  • 第十四章 Java基础-接口
  • CMake入门:3、变量操作 set 和 list
  • 使用TypeScript构建一个最简单的MCP服务器
  • 【docker】Windows安装docker
  • 智慧货运飞船多维度可视化管控系统
  • Kubernetes Pod DNS 配置
  • 2025年计算机科学与网络安全国际会议(CSNS 2025)
  • 关于Dify聊天对话名称无法自动生成的原因和解决方法
  • 区块链跨链通信:使用 Cosmos SDK 实现链间互操作
  • Modbus转EtherNET IP网关开启节能改造新范式
  • Mermaid 绘图--以企业权限视图为例
  • Cursor 工具项目构建指南: Web Vue-Element UI 环境下的 Prompt Rules 约束(new Vue 方式)