FAQ智能问答系统设计与实现

article/2025/11/6 18:53:43

一、项目介绍

FAQ(FAQ,frequently-asked questions)问答系统表示常见问题问答系统,常用于一些特定领域的智能客服,将用户经常问到的高频问答对索引起来,当新的提问命中时可以快速回答,准确而高效。
本文介绍一个简单的FAQ问答系统实现。基于检索和排序的两阶段框架,检索阶段基于Elasticsearch检索引擎、排序阶段基于语义匹配深度学习模型。后端基于SpringBoot系列框架。

1.1 最简单的FAQ问答系统示意图

FAQ问答大概的对话流程示意图如下:
请添加图片描述

1.2 系统架构

系统的大致框架如下图所示:

请添加图片描述

以对话为例说一下系统各个模块的协同:

  • 客户端带着用户问题向后台发送HTTP请求;
  • 后台接受到请求,对用户问题进行ES检索,返回N(可配置)个相关的初始候选集;
  • 后台通过HTTP请求调用相似度计算服务,对用户问题和N个候选句子一一成对进行相似度计算,返回它们的相似度;
  • 后台结合ES相关度和模型相似度进行综合排序,取综合得分最高的结果对应的答案返回给前端;
  • 前端显示;

值得一提的是,Redis的作用是对话状态管理,即每一个用户于系统交互都会在Redis中创建一个与之对应的对话状态(dialogue status),这个对话状态可以用来区分不同用户,也可以用来进行多轮对话(保存上一步对话的节点数据)。

二、功能说明

2.1 对话

对话是核心功能,提供一问一答的交互式方式。

人机对话:用户提出问题,系统给出回答。

2.2 数据同步

FAQ问答对持久化保存在MySQL中,管理员只需维护MySQL中的数据。但是在对话时,系统不会去访问MySQL,而是通过ES检索引擎进行检索。因此,保证MySQL和ES的数据一致非常重要。

全量同步:将MySQL中的问答对数据全部同步到ES索引中。
更新多轮问答树:多轮问答基于多轮JSON,逻辑上为树的组织结构,需要将JSON文件读取到Redis中存起来。

三、演示

3.1 接口测试

打开浏览器访问http://localhost:1234/faq/swagger-ui/可以查看全部接口并进行测试。
请添加图片描述

3.2 界面测试

打开ui/dialogue.html进行界面交互。以下显示了单轮对话和多轮对话的简单示例。
(值得一提的,前端ui用的是Alibaba开源的对话框架,感觉非常实用,只需要懂点JS就可以调了。)
请添加图片描述
请添加图片描述

四、设计细节

4.1 数据库设计

整个FAQ问答系统就用了一张表,faq问答对,名称为faq_pair,表结构如下:

字段名字段类型是否可为空注释
idint(11)NOPRI
qa_idint(11)NOUNI标准问-标准答的唯一标识id
standard_questiontextNO标准问,表示高频问题
standard_answertextNO标准答,表示高频问题对应的回答

4.2 状态码设计

该系统配置一些自定义的状态码和说明,用一个枚举类CodeMsg表示。
这些状态码可以用于定位问题所在,也可以让前端区分不同的返回值代表的含义等等。

public enum CodeMsg {//通用状态码10000系列,模块异常ELASTICSEARCH_EXCEPTION(10001, "elasticsearch异常"),MYSQL_EXCEPTION(10002, "mysql异常"),SIMILARITY_NULL_EXCEPTION(10003, "相似度计算模型异常"),//通用状态码20000系列,有返回值,无异常SUCCESS(20000, "success"),SUCCESS_SINGLE(20001, "success-->单轮"),SUCCESS_MULTI(20002, "success-->多轮"),//通用状态码30000系列,中间状态OPTIONS_NOT_HIT(30001, "处于多轮问答中,但未命中多轮问答的选项,此时将重新检索用户问题"),//通用状态码40000系列,无返回值FAILED(40000, "failed"),UNRECOGNIZED_QUESTION(40001, "failed-->无法识别的问题"),MULTI_ROUND_QA_NOT_FOUND(40002, "failed-->没有找到对应的多轮问答树"),MULTI_ROUND_QA_NULL(40003, "failed-->redis中多轮问答树为空"),MULTI_ROUND_QA_CHILD_NODE_NULL(40004, "failed-->多轮问答树子节点为空");
}

4.3 配置参数读取

项目定义了用户配置文件application-user.yml,通过在SpringBoot默认配置文件application.yml中配置以下参数引入该配置文件

spring:#引入自定义配置,application-user.ymlprofiles:include:- user

application-user.yml中自定义了一些参数,可以根据需要随时修改而不用改源码,如对话相关的参数:

#对话配置
dialogue:#置信度排序confidence-rank:#返回的置信度最高的doc的个数size: 5#置信度计算权重weights:#相关度权重relevance-weight: 0.3#相似度权重similarity-weight: 0.7#用户对话状态status:#过期时间(单位: minute)expire-time: 2#多轮问答树multi-turn-qa:path: data/multi_turn_qa#redis热点数据缓存hot-data:#是否开启open: true#过期时间(单位: minute)expire-time: 5

对话相关参数的配置类如下:

@Configuration
@ConfigurationProperties(prefix = "dialogue")
@Data
public class DialogueConfig {private ConfidenceRank confidenceRank;private Status status;private MultiRoundQa multiTurnQa;private HotData hotData;//redis中多轮问答树的key前缀private final String MQATreeKeyPrefix = "MQATreeNode_";//redis中question映射id的keyprivate final String MQAQuestion2idKey = "MQA_question2id";//redis中用户对话状态的key前缀private final String DialogueStatusKeyPrefix = "dialogue_status_userId_";//redis中热点数据的question映射id的keyprivate final String HotDataQuestion2idKey = "hot_data_question2id";//redis中热点数据的key前缀private final String HotDataKeyPrefix = "hot_data_";@Datapublic static class ConfidenceRank {private Integer size;private Weights weights;private Float threshold;@Datapublic static class Weights {private Float relevanceWeight;private Float similarityWeight;}}@Datapublic static class Status {private Integer expireTime;}@Datapublic static class MultiRoundQa {private String path;}@Datapublic static class HotData {private Boolean open;private Integer expireTime;}
}

用的也是推荐的依赖包,引入的pom依赖如下:

<!--        更推荐的读取配置文件的处理器-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

4.4 对话流程设计

对话流程表示从用户问题输入,到找到答案输出的流程,流程图如下。

请添加图片描述

4.5 多轮对话设计

多轮对话按规则执行,逻辑上组织为一棵树,示意图如下:
请添加图片描述

一颗多轮对话树在物理上为一个json文件,在更新多轮对话树时json文件将被转换成数据对象MultiQaTreeNode,然后添加到redis中。

{"qaId": 3,"question": "推荐一个景点","answer": "好的,请问对景点评分有要求吗","childNodes": [{"question": "没要求","answer": "好的,请问景点票价可接受范围?","childNodes": [{"question": "免费","answer": "附近好多公园呢,比如xxx,今天天气不错,可以去转转。","childNodes": []},{"question": "50元以内","answer": "这个xx不错,自然风光秀丽,离您也不远。","childNodes": []},{"question": "无所谓,不差钱","answer": "推荐xxx景点给您呢,该景点绝对符合您的气质","childNodes": []}]},{"question": "3分以上","answer": "可玩的就比较多了,有xx...","childNodes": []},{"question": "5分","answer": "在xx那有一处5A景区,评分有5分呢,推荐您去玩哈。","childNodes": []}]
}

MultiQaTreeNode类如下:

public class MultiQaTreeNode implements Serializable {//对应的qaId,一棵多轮问答树不同层节点的qaId是相同的,都为根节点question所对应的qaIdprivate Integer qaId;//当前节点的问题private String question;//当前节点的回答private String answer;//当前节点的子节点private List<MultiQaTreeNode> childNodes;
}

五、总结

系统是简化版的,基本只保留了人机对话功能,问答对也只用了一张表,实际上对于一个高频问题,可以多生成一些与之相似的问题用于扩大搜索范围。另外,如果需要增加问答对,需要对MySQL数据表增加行数据,然后使用同步功能在ES建对应索引即可。
该项目源码如下:
GitHub
Gitee
另外,为了学习微服务相关技术栈,对单体架构进行了升级,而且增加了问答对管理的一些功能。
微服务版地址为:
Gitee
GitHub


http://chatgpt.dhexx.cn/article/wwNCt10J.shtml

相关文章

react全家桶实战

整个目录结构如下&#xff1a; package.json代码如下&#xff1a; {"name": "active","version": "0.1.0","private": true,"dependencies": {"react": "^16.4.1","react-dom"…

React全家桶学习

来源&#xff1a;尚硅谷视频教程 - 张天禹 一、React简介 1 react特点 React&#xff1a;用于构建用户界面的javascript库。是一个将数据渲染为HTML视图的开源JavaScript库。 react的特点&#xff1a; 1.采用组件化模式、声明式编码&#xff0c;提高开发效率及组件复用率。…

react全家桶实战(千峰教育)

说明&#xff1a;本笔记为本人基于千锋教育2022版React全家桶教程_react零基础入门到项目实战完整版的学习笔记&#xff0c;知识点不清或不全&#xff0c;可以到视频教程中学习 文章目录 一、安装create-react-app&#xff0c;新建react项目1、安装脚手架create-react-app<s…

搭建react全家桶

1.安装react项目 ①使用webpack安装 npx create-react-app my-app cd my-app npm start ②使用vite安装 创建Vite项目 npm create vitelatest my-vue-app --template react cd my-app npm run dev 配置vite.config.js import { defineConfig } from vite import react from vit…

React 全家桶

文章目录 前言一、React是什么&#xff1f;二、基础内容1. React 相关 js 库2. React 开发者调试工具3. JSX语法规则4. 模块与组件、模块化与组件化5. 类的基本知识 三、React 面向组件编程1. 函数式组件2. 类式组件3. 组件实例的三个核心属性&#xff1a; state、refs、props-…

React全家桶

文章目录 第1章&#xff1a;React入门1.1. React简介1.1.1. 官网1.1.2. 介绍描述1.1.3. React的特点1.1.4. React高效的原因 1.2. React的基本使用1.2.1. 效果1.2.2. 相关js库1.2.3. 创建虚拟DOM的两种方式1.2.4. 虚拟DOM与真实DOM 1.3. React JSX1.3.1. 效果1.3.2. JSX1.3.3. …

react全家桶有哪些?(详细)

一 、 create-react-app脚手架 对于现在比较流行的三大框架都有属于自己的脚手架&#xff08;目前这些脚手架都是使用node编写的&#xff0c;并且都是基于webpack的&#xff09;&#xff1a; Vue的脚手架&#xff1a;vue-cliAngular的脚手架&#xff1a;angular-cliReact的脚手…

React全家桶详细讲解-图文并茂

文章目录 前言一、React-表单处理受控组件使用步骤多表单元素优化非受控组件 二、React-组件综合案例需求分析搭建任务的模板渲染列表添加任务删除任务 三、React-组件进阶组件通讯介绍组件的props 四、react-组件通讯的三种方式react-父组件传递数据给子组件react-子组件传递数…

【尚硅谷React】——React全家桶笔记

文章目录 第1章 React简介1.1 React的特点1.2 引入文件1.3 JSX1.3.1 为什么要用JSX1.3.2 JSX语法规则 1.4 虚拟DOM1.5 模块与组件1.5.1 模块1.5.2 组件 第2章 React面向组件编程2.1 创建组件2.1.1 函数式组件2.1.2 类式组件 2.2 组件实例的三大属性2.2.1 state属性2.2.2 props属…

React全家桶(收藏吃灰必备!)

文章目录 ECMAScript61、ES6简介1.1、什么是ES61.2、ECMAScript和JavaScript的关系1.3、为什么要学习ES6&#xff1f; 2、ES6环境搭建2.1、前期准备2.2、ES6环境搭建 3、let与const3.1、let命令3.2、const命令 4、ES6解构赋值4.1、解构赋值概述4.2、解构模型4.3、数组的解构赋值…

Neurosynth元分析——认知解码工具,软件包安装以及使用

Neurosynth元分析——认知解码工具,软件包安装以及使用 NeuroSynth 基本简介基本原理例子Neurosynth package安装及使用创建虚拟环境安装Dependencies:安装neurosynthNeurosynth使用加载必要的包下载neurosynth数据参考如上图所示。NeuroSynth 元分析感兴趣的区域沿功能连接梯…

编码和解码

概念 字符的三种形态 图片来自&#xff1a;https://zhuanlan.zhihu.com/p/25435644 编码&#xff1a;将字符转为字节序列&#xff08;abcdefg-------------> 0101010…10010&#xff09; 解码&#xff1a;将字节序列转为字符&#xff08;1001010…10010110------> abcd…

编码器和解码器

1.编码器—解码器&#xff08;seq2seq&#xff09; 编码器的作用是把一个不定长的输入序列变换成一个定长的背景变量c&#xff0c;并在该背景变量中编码输入序列信息。常用的编码器是循环神经网络。 编码器可以是一个单向的循环神经网络&#xff0c;每个时间步的隐藏状态只取决…

二维码解码工具

http://tool.chinaz.com/qrcode/?jdfwkeyweexu

编解码工具

支持各种文件摘要&#xff08;Hash&#xff09;、Base64编码、Hex编码、国密sm2加密、Rsa加密&#xff0c;以及各种对称加密算法的小工具 下载地址&#xff1a;https://pan.baidu.com/s/1AJwUaVizzk5HeLa_8Q5AqA 提取码&#xff1a;4567

编码与解码

什么是编码与解码 电脑是由电路板组成&#xff0c;电路板里面集成了无数的电阻和电容&#xff0c; 交流电经过电容的时候&#xff0c;电压比较低 记为低电平 &#xff0c; 用0表示&#xff0c;交流电流过电阻的时候&#xff0c;电压比较高&#xff0c;记为高电平&#xff0c;用…

Encoder编码器、Decoder解码器

知乎用户对编码器解码器的理解 Encoder&#xff1a; 本身其实就是一连串的卷积网络。该网络主要由卷积层&#xff0c;池化层和BatchNormalization层组成。卷积层负责获取图像局域特征&#xff0c;池化层对图像进行下采样并且将尺度不变特征传送到下一层&#xff0c;而BN主要对…

Protobuf在线解码工具推荐

P1: CyberChef 地址&#xff1a;CyberChef 非常灵活&#xff0c;支持各种导入格式可以直接转成json支持导入.proto文件 P2: protobuf-decoder 地址&#xff1a;protobuf-decoder 有对齐问题 P3: protogen 地址&#xff1a;protogen 有乱码问题 P4: PB-JCE-Decoder&…

在线JWT Token解析解码工具

1&#xff1a;JWT Token在线解析解码 - ToolTT在线工具箱 2&#xff1a; 3&#xff1a;

密码解码常用工具网站汇总

xssee:http://web2hack.org/xssee xssee:http://evilcos.me/lab/xssee 在线编码解码(多种并排):http://bianma.911cha.com 在线加密解密(多种):http://encode.chahuo.com Unicode转中文:http://www.bejson.com/convert/unicode_chinese 栅栏密码 && 凯撒密码 &&…