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

一、项目介绍

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.yml
  profiles:
    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的key
    private final String MQAQuestion2idKey = "MQA_question2id";
    //redis中用户对话状态的key前缀
    private final String DialogueStatusKeyPrefix = "dialogue_status_userId_";
    //redis中热点数据的question映射id的key
    private final String HotDataQuestion2idKey = "hot_data_question2id";
    //redis中热点数据的key前缀
    private final String HotDataKeyPrefix = "hot_data_";

    @Data
    public static class ConfidenceRank {
        private Integer size;
        private Weights weights;
        private Float threshold;

        @Data
        public static class Weights {
            private Float relevanceWeight;
            private Float similarityWeight;
        }
    }

    @Data
    public static class Status {
        private Integer expireTime;
    }

    @Data
    public static class MultiRoundQa {
        private String path;
    }

    @Data
    public 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所对应的qaId
    private Integer qaId;
    //当前节点的问题
    private String question;
    //当前节点的回答
    private String answer;
    //当前节点的子节点
    private List<MultiQaTreeNode> childNodes;
}

五、总结

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

faq检索式问答系统可以作为毕业设计的一部分。faq检索式问答系统是一种基于简单问题和回答的系统,常用于电子商务网站、客服平台等。作为毕业设计的一部分,可以选择该领域的相关问题和答案作为知识库,设计开发出一个功能完善的问答系统。 毕业设计设计开发过程包括以下几个步骤:需求分析、系统设计、编码实现和系统测试。在需求分析阶段,需要明确系统的功能和特性,并确定系统所要解决的问题。设计阶段即是设计系统的整体框架,包括数据库设计、系统架构设计等。在编码实现阶段,可以选择使用合适的编程语言和开发框架来实现系统的各个功能模块。最后,在系统测试阶段,可以进行功能测试、性能测试和用户测试等,确保系统的稳定和可靠性。 对于faq检索式问答系统的开发,需要熟悉相关的技术,如自然语言处理、机器学习、数据库管理等。同时,还需要有良好的系统设计和编程能力。在毕业设计中,可以扩展系统的功能,如用户注册和登录模块,管理员后台管理模块等,提升系统的实用性和完整性。 总之,faq检索式问答系统是可以作为毕业设计的一部分,并且可以根据个人的兴趣和需求进行功能扩展。对于计算机相关专业的学生,通过设计开发faq检索式问答系统可以提升自己的技术能力和实践经验,为日后的就业或进修打下良好的基础。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值