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

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.lryc.cn/news/2399278.html

相关文章:

  • 慢SQL调优(二):大表查询
  • 【C++】—— 从零开始封装 Map 与 Set:实现与优化
  • 内网穿透之Linux版客户端安装(神卓互联)
  • 开疆智能Profinet转Profibus网关连接CMDF5-8ADe分布式IO配置案例
  • 华为云Flexus+DeepSeek征文|Flexus云服务器单机部署+CCE容器高可用部署快速搭建生产级的生成式AI应用
  • 扫地机产品--材质传感器算法开发与虚拟示波器
  • [蓝桥杯]上三角方阵
  • 60天python训练计划----day44
  • 【JAVA版】意象CRM客户关系管理系统+uniapp全开源
  • API异常信息如何实时发送到钉钉
  • Python爬虫(48)基于Scrapy-Redis与深度强化学习的智能分布式爬虫架构设计与实践
  • AtCoder Beginner Contest 407 E - Most Valuable Parentheses
  • (1-6-3)Java 多线程
  • java31
  • 多模态之智能数字人
  • 界面组件DevExpress WPF中文教程:Grid - 如何识别行和卡片?
  • 【HarmonyOS Next之旅】DevEco Studio使用指南(三十)
  • AI基础知识(LLM、prompt、rag、embedding、rerank、mcp、agent、多模态)
  • [蓝桥杯]高僧斗法
  • pycharm F2 修改文件名 修改快捷键
  • Python Flask中启用AWS Secrets Manager+AWS Parameter Store配置中心
  • 机器学习与深度学习10-支持向量机02
  • 《深入解析UART协议及其硬件实现》-- 第二篇:UART硬件架构设计与FPGA实现
  • java swing 晃动鼠标改变背景颜色
  • HikariCP 可观测性最佳实践
  • 简简单单探讨下starter
  • PyTest框架学习
  • SIP、SAP、SDP、mDNS、SSH、PTP
  • 【AI学习笔记】Coze工作流写入飞书多维表格(即:多维表格飞书官方插件使用教程)
  • System.Threading.Timer 和 System.Timers.Timer