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

相关文章

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是