Java基于大模型实现客服系统

2024-08-31 15:12
文章标签 java 实现 系统 模型 客服

本文主要是介绍Java基于大模型实现客服系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果你问大模型企业私有化的问题,大模型很可能就答非所问了,倘若让大模型结合企业内部数据回答, 用户满意度大幅提升 。以下基于RAG技术实现客服系统

1、引入相关包

    <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><langchain4j.version>0.33.0</langchain4j.version></properties><dependencies><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>${langchain4j.version}</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>${langchain4j.version}</version></dependency><dependency><groupId>org.tinylog</groupId><artifactId>tinylog-impl</artifactId><version>2.6.2</version></dependency><dependency><groupId>org.tinylog</groupId><artifactId>slf4j-tinylog</artifactId><version>2.6.2</version></dependency></dependencies>    

官网链接: OpenAI | LangChain4j

2、文本转向量

向量是数学中的一个基本概念,表示具有大小(gpt的向量长度是1536位)和方向的量。在深度学习中,向量通常用于表示数据点或特征。

向量数据库是一种专门用于存储和查询向量数据的数据库系统。它能够高效地处理高维向量数据,支持基于向量相似性的搜索。

OpenAiEmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo").build();Response<Embedding> embeddingResponse = embeddingModel.embed("hello word");String string = embeddingResponse.content().toString();System.out.println(string);System.out.println('length:' + embeddingResponse.content().vector().length);

控制台输出:

Embedding { vector = [-0.014903838, 0.0013317588, -0.018488139, -0.031072723, -0.024273094, 0.0075046294, -0.023034403, -0.0010262037, -0.012795426, -0.022441411,
… … …
0.020333, 0.0042761234, -0.023324309, -0.034920577, 0.0142844925, 5.39457E-4, -0.0304402, -0.0035184128, -0.011095519] }
length:1536

3、保存向量

RAG(Retrieval-Augmented Generation,检索增强生成) 技术是一种结合信息检索(Retrieval)和生成(Generation)的混合模型方法,旨在通过检索相关信息来增强生成模型的性能。 RAG技术的核心思想是在生成回复时,不仅依赖模型自身的语言理解能力,还通过检索外部知识库(如产品手册等)来增强回复的准确性和丰富性。

基于客服系统需要涉及企业内部私有的信息,需要事先转为向量存储在向量数据库

向量数据库有很多,在LangChain4j中,EmbeddingStore表示向量数据库,它有20个实现类:

  1. AstraDbEmbeddingStore
  2. AzureAiSearchEmbeddingStore
  3. CassandraEmbeddingStore
  4. ChromaEmbeddingStore
  5. ElasticsearchEmbeddingStore
  6. InMemoryEmbeddingStore
  7. InfinispanEmbeddingStore
  8. MemoryIdEmbeddingStore
  9. MilvusEmbeddingStore
  10. MinimalEmbeddingStore
  11. MongoDbEmbeddingStore
  12. Neo4jEmbeddingStore
  13. OpenSearchEmbeddingStore
  14. PgVectorEmbeddingStore
  15. PineconeEmbeddingStore
  16. QdrantEmbeddingStore
  17. RedisEmbeddingStore
  18. VearchEmbeddingStore
  19. VespaEmbeddingStore
  20. WeaviateEmbeddingStore

比如redis,使用docker安装

docker run --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest

官网链接:https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/

删除索引和数据命令

redis-cli FT.DROPINDEX embedding-index DD

文档:https://redis.io/docs/latest/commands/ft.dropindex/#examples

maven中引入相关包

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-redis</artifactId><version>${langchain4j.version}</version>
</dependency>

以下以客服电话举例

OpenAiEmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo").build();RedisEmbeddingStore embeddingStore = RedisEmbeddingStore.builder().host("47.xxx.xxx.16").port(6379).dimension(1536)// 不设置默认:embedding-index
//                .indexName("test").build();TextSegment textSegment1 = TextSegment.textSegment("客服电话:95152");TextSegment textSegment2 = TextSegment.textSegment("客服时间:周一至周日 08:30-22:00");TextSegment textSegment3 = TextSegment.textSegment("违法和不良信息举报电话:400-140-2108");Response<Embedding> embed1 = embeddingModel.embed(textSegment1);Response<Embedding> embed2 = embeddingModel.embed(textSegment2);Response<Embedding> embed3 = embeddingModel.embed(textSegment3);// 把向量和对应的文本一并存入embeddingStore.add(embed1.content(), textSegment1);embeddingStore.add(embed2.content(), textSegment2);embeddingStore.add(embed3.content(), textSegment3);

查询,看下是否保存成功

redis-cli FT.SEARCH embedding-index "*" LIMIT 0 1

redis-cli FT.SEARCH embedding-index "*" LIMIT 0 1
1) (integer) 3
2) "embedding:c013b1ff-e20a-4124-895b-ebfc1abdca23"
3) 1) "$"2) "{\"vector\":[0.0077204346,-0.011896749,-0.0042433655,0.001396096,-0.017382152,0.018825343,-0.00072119647,0.011034666,-0.007969481............"

java查询

OpenAiEmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo").build();RedisEmbeddingStore embeddingStore = RedisEmbeddingStore.builder().host("47.xxx.xxx.16").port(6379).dimension(1536).build();Response<Embedding> embed = embeddingModel.embed("客服电话多少");List<EmbeddingMatch<TextSegment>> result = embeddingStore.findRelevant(embed.content(), 3);for (EmbeddingMatch<TextSegment> embeddingMatch : result){System.out.println(embeddingMatch.embedded().text() + ",分数为:" + embeddingMatch.score());}

代码指定了查询3条,第一条匹配度最高

控制台输出如下:

客服电话:95152,分数为:0.9283385276795
客服时间:周一至周日 08:30-22:00,分数为:0.924619972706
违法和不良信息举报电话:400-140-2108,分数为:0.912132680416

以上介绍了如何把文字转为向量,并存入数据库中

4、客服系统实现

4.1 知识库数据处理

假设知识是如下格式(myDocument.txt),一个问题紧接着一个答案,每个问答之间有一个空行

Q:余额提现到账时间是多久?
1-7个工作日内可退回您的支付账户。由于银行处理可能有延迟,具体以账户的到账时间为准。Q:申请退款后,商家拒绝了怎么办?
申请退款后,如果商家拒绝,此时回到订单页面点击“退款申诉”,美团客服介入处理。Q:怎么取消退款呢?
请在订单页点击“不退款了”,商家还会正常送餐的。
4.1.1 解析文件为document对象
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentParser;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.TextDocumentParser;
....
Document document;
// 读取文本
Path documentPath = Paths.get("src/main/resources/myDocument.txt");
DocumentParser documentParser = new TextDocumentParser();
document = FileSystemDocumentLoader.loadDocument(documentPath, documentParser);
4.1.2 使用正则\\s*\\R\\s*\\R\\s*切分文件

先实现DocumentSplitter接口

class CustomerServiceDocumentSplitter implements DocumentSplitter {@Overridepublic List<TextSegment> split(Document document) {List<TextSegment> segments = new ArrayList<>();String[] parts = split(document.text());for (String part : parts){segments.add(TextSegment.from(part));}return segments;}public String[] split(String text) {return text.split("\\s*\\R\\s*\\R\\s*");}}

调用方法切分

import dev.langchain4j.data.segment.TextSegment;
....
CustomerServiceDocumentSplitter splitter = new CustomerServiceDocumentSplitter();
List<TextSegment> segments = splitter.split(document);

TextSegment对象有个属性text存储了我们的问答对

4.2 问答对向量存储

把知识库的文本向量化并存储至向量数据库中

// 文本向量化
EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
.apiKey("demo")
.baseUrl("http://langchain4j.dev/demo/openai/v1")
.build();
List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
System.out.println("向量化完毕");// 存redis
EmbeddingStore<TextSegment> embeddingStore = RedisEmbeddingStore.builder()
.host("47.xxx.xxx.16")
.port(6379)
.dimension(1536)
.build();
embeddingStore.addAll(embeddings, segments);
System.out.println("向量存储完毕");

4.3 从向量库中检索内容

创建了一个ContentRetriever对象,用于从向量库中检索内容

 // 内容查找ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()// 指定模型.embeddingModel(embeddingModel)// 指定向量库.embeddingStore(embeddingStore)// 最多返回5条数据.maxResults(5)// 最低匹配分数为0.8.minScore(0.8).build();Query query = Query.from("余额什么时候到账?");
List<Content> retrieve = contentRetriever.retrieve(query);
// 输出检索到的内容数量:5
System.out.println("size:" + retrieve.size());
// 打印第一条检索结果的文本内容
System.out.println(retrieve.get(0).textSegment().text());

4.4 借助大模型和向量数据库查询答案

根据以上知识,使用AiServices编写代码
AiServices基础参考

    interface CustomerServiceAgent {String answer(String question);// 利用AiServices创建一个CustomerServiceAgent的代理对象static CustomerServiceAgent create() {// 构造ChatMemory,用来保存历史聊天记录ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder().apiKey("demo").baseUrl("http://langchain4j.dev/demo/openai/v1").build();EmbeddingStore<TextSegment> embeddingStore = RedisEmbeddingStore.builder().host("47.xxx.xxx.16").port(6379).dimension(1536).build();ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder().embeddingModel(embeddingModel).embeddingStore(embeddingStore).maxResults(3).minScore(0.8).build();ChatLanguageModel model = OpenAiChatModel.builder().apiKey("demo").baseUrl("http://langchain4j.dev/demo/openai/v1").build();return AiServices.builder(CustomerServiceAgent.class).chatLanguageModel(model).chatMemory(chatMemory).contentRetriever(contentRetriever).build();}}

写个main函数测试

    public static void main(String[] args) {String answer = CustomerServiceAgent.create().answer("余额什么时候到账?");System.out.println("-------answer:" +answer);}

控制台输出:

-------answer:余额提现到账时间是1-7个工作日内,具体以账户的到账时间为准。

这篇关于Java基于大模型实现客服系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124257

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入