基于FAQ的智能问答(一): Elasticsearch的调教

📅 2026/8/16 13:56:20
基于FAQ的智能问答(一): Elasticsearch的调教
背景对话领域是当前最热门的一个NLP的方向之一无论在学术界还是在工业界。由此衍生出来的产品包括通用形态的苹果siri微软小冰小米的小爱同学等以及各个行业领域的智能助手智能客服等。 这些产品基本可以看成下一代人机自然语言交互的雏形。具体而言人机对话又可以拆分为以下几种形式(1)FAQ-Bot: 基于常见问答对的问答也是运用最为广泛的智能问答技术可以认为是最朴素的一种对话。抽象出来是一个信息检索的问题给定用户的问题在由{问答答案}组成的知识库中检索相似的问题最后将与用户相似问法问题的答案作为结果返回给用户。(2)MRC-Bot: 基于机器阅读的智能问答一般运用在开放域的问答中。给定用户的问题具体分成召回和机器阅读两个阶段先从知识库中检索出可能存在答案的文档再针对文档做机器阅读确定答案。在实际落地中也很有前景相比FAQ-Bot用户不需要耗费很大力气构建知识库只需要上传产品文档即可。但是目前机器阅读的准确性还不够效果不稳定还不能直接将机器阅读的结果作为答案返回给用户。(3)KG-Bot: 基于知识图谱的问答一般用于解答属性型的问题比如“北京的市长是谁”。给定用户的问题需要先解析成知识图谱查询语句再到知识图谱中检索答案。这种问答一般回答的准确率非常高但是能回答的问题也非常局限同时构建知识图谱非常耗费人力。(4)Task-Bot: 任务型对话是面向特定场景的多轮对话比如“查天气”“订机票”。Task oriented dialogue在学术和工业界都已经有了很深入的研究分成pipeline和end-to-end两种思路。在实地落地过程中难得是如何让用户自主的灵活配置一个任务型对话场景训练语料可能只有一两条如何训练出一个NER的槽位(5)Chat-Bot: 闲聊对话一般用于提高机器人的趣味性比如“你是谁”“你是机器人吗”等。在学术上一般基于end-to-end的方案可以支持多轮但是回复结果不可控。所以在实际落地中还是会转换成FAQ-Bot预先构建一个寒暄库转换成检索的任务。机器人类型知识库结构核心技术落地难度FAQ-Bot{问题:答案}信息检索低MRC-Bot文档信息检索机器阅读中KG-Bot知识三元组知识图谱构建/检索高Task-Bot槽位/对话策略对话状态跟踪/管理高Chat-Bot{寒暄语:回复}信息检索低总结目前最简单最切合实际的落地方式还是基于FAQ-Bot而目前“智能客服”等产品采用的技术也大都基于此。所以本系列文章将系统分享FAQ-Bot是如何进行产品化落地在实际落地过程中踩过的坑以及我们自己的一些微创新。这是本系列的第一篇文章Elasticsearch的调教Elasticsearch的搭建基于FAQ的智能问答本质是一个信息检索任务而Elasticsearch真是这个领域的必备的工具Elasticsearch官方分布式搜索和分析引擎 | ElasticElasticsearch官方分布式搜索和分析引擎 | Elastic​www.elastic.co/cn/elasticsearch/正在上传…重新上传取消贴一段官网上的介绍速度Elasticsearch 很快快到不可思议可扩展性可以在笔记本电脑上运行。也可以在承载了 PB 级数据的上千台服务器上运行。相关度搜索所有内容找到所需的具体信息简单的说将问答对{q:a}存入ES中以后给定一个用户的问题(query)ES可以快速返回有序的相似问题。具体在搭建ES的过程中还有几点需要注意(1) 版本推荐使用7.x版本ES的7.x版本的核心安全功能免费提供了意味不用去破解x-pack获取密码登陆的功能了...同时7.x版本配套的kibana整体风格也更明快同时也多了“机器学习”等新的模块。ES 7.8版本的Kibana(2) 安装: docker推荐使用docker快速安装elasticsearch和kibanaInstall Elasticsearch with Docker​www.elastic.co/guide/en/elasticsearch/reference/current/docker.html正在上传…重新上传取消需要注意的是基于docker安装需要在宿主机器上额外设置virtual memorysysctl -w vm.max_map_count262144Virtual memory | Elasticsearch Reference [7.10] | Elastic​www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html正在上传…重新上传取消如果基于k8s启动则需要配置一个初始化容器initContainers: - name: increase-vm-max-map image: busybox command: [ sysctl, -w, vm.max_map_count262144 ] securityContext: privileged: true(3) 分词:中文场景下需要使用分词的插件一般常用的就是 IK 分词器安装时候需要选择对应的ES版本。https://github.com/medcl/elasticsearch-analysis-ik​github.com/medcl/elasticsearch-analysis-ik如果基于docker启动的es则可以自己构建一个包含了IK分词器的docker镜像。与MySQL的数据同步一般业务数据知识库中的问答对都存储在MySQL中所以ES的数据来源是MySQL并且如果数据发生了变化增删改查需要及时的从MySQL同步到ES中。调研了一圈ES与MySQL的同步方案最终选择阿里的canal 运行至今也一直非常稳定。canal架构图canal [kənæl]译意为水道/管道/沟渠主要用途是基于 MySQL 数据库增量日志解析提供增量数据订阅和消费canal具体分成server与client两端server端监控MySQL并将接收到的binlog数据投递到MQclient端负责从MQ中消费binlog数据并处理后写入到ES中.如果通过容器启动需要启动server和client两个服务。需要注意的是该同步服务是增量同步也就是一旦client处理错误或者server不稳定丢了binlogbinlog就不会再次同步了。所以会进行定期的MySQL和ES全量数据同步一般在每天深夜进行。支持首字母与拼音检索经过上面两个步骤启动了ES从MySQL中同步了数据就已经具备了检索的功能了query: 公务员考试search_result: 公务员考试省考与国考题型区别大吗?“公务员考试”搜索结果这时候希望额外支持对首字母拼音以及混合的检索即支持:query: gongwuyuan考试 , gwyks, 公务员ks , 公务员考试search_result: 公务员考试省考与国考题型区别大吗?这时候就需要引入另外一个分词器: medcl/elasticsearch-analysis-pinyin安装以后具体还需要额外配置(1) 配置默认分词器为ik分词器并引入pinyin分词器analysis: { analyzer: { default:{ tokenizer:ik_max_word }, pinyin_analyzer: { type: custom, tokenizer: custom_pinyin, filter: [word_delimiter] } }, tokenizer: { custom_pinyin : { type : pinyin, keep_first_letter:true, keep_separate_first_letter : false, keep_full_pinyin : true, keep_original : false, limit_first_letter_length : 16, lowercase : true } } }(2) 对于需要支持拼音检索的字段配置拼音分词question : { type : text, analyzer : ik_max_word, boost : 20 fields : { pinyin : { type : text, term_vector : with_positions_offsets, analyzer : pinyin_analyzer, boost : 10 } } }(3) 同时支持拼音和汉字检索通过multi_match的检索可以同时对quesiton和quesiton.pinyin两个字段进行检索{ query: { multi_match: { type:most_fields, query:公务员ks, fields:[quesiton, quesiton.pinyin] } } }当然还可以配置更精细的检索规则例如如果query中包含中文则必须包含在返回的结果中等。自定义词典如果引入了IK分词器会自动引入一个中文的词典elasticsearch-analysis-ik/config/main.dic但是这个词表还是有局限的。针对例子: 美甲上门服务, 以下是ik的分词结果美甲上门服务 的IK分词结果可以看到切出了一个很奇怪的词语: 甲上, 而最新的词的美甲是没有被正确切分的。所以检索“美甲”检索到的结果会很靠后只有“美” 命中。同时“美甲”不能高亮显示。经查证“甲上”确实是IK中自带的一个词IK的词典所以需要根据自己的业务场景配置领域词典对于该例配置词典“美甲”即可。IK分词器支持配置远程扩展字典所以产品上可以支持由用户自己在前端配置领域词典。停用词IK分词器也自带了停用词如下所示IK的停用词这个默认的词典只有33个英文自然的想法是我们一般都是中文的场景所以这33个英文停用词是远远不够。而Github上刚好也由一份相对完备的中文停用词表2K starhttps://github.com/goto456/stopwords​github.com/goto456/stopwords所以会尝试在自己的项目中直接用仓库中整理的停用词表例如“baidu_stopwords”停用词达到了1300多个但是实际场景中会造成很大的误伤例如配置了baidu_stopwords检索 “附近有哪些药店”因为 “附近”是停用词有是停用词“哪些”是停用词“”是停用词这样经过停用词处理以后只有“药店”相比原本的query丢失了很多的信息所以我们最后自己维护了一份停用词表只有标点符号和最基本的语气词包括吗,呢等甚至有的场景下没有配置停用词实际效果也没有下降。最后ES在IR领域是非常“宝藏”的工具在信息检索中绝大多数业务功能“输入联想”“分组查询”“分页查询”“基于GIS附近的人”等都有了很好的支持同时ES的社区非常活跃版本也在持续更新维护。所以了解学习ES可以做到遇事不慌快速搭建出一个能用的baseline基于FAQ的智能问答(一): Elasticsearch的调教 - 知乎