资讯详情

前沿重器[21-25] | 合集:两万字聊对话系统

本专栏主要与您分享各种大型工厂和顶级会议的论文和分享,从中提取关键本质与您分享,并与您一起掌握前沿技术。具体介绍:仓颉特别:我会飞机炮,我还有锋利的武器心法。

最近,我又总结了我的历史文章,积累了50篇w文字,100多篇文章,有兴趣可以看看,获取方式:七夕清流,100多篇文章共50篇w文章合集发布。

往期回顾

  • 前沿重器[16] | 美团搜索ner技术启示(上)

  • 前沿重器[17] | 美团搜索ner技术启示(下)

  • 前沿重器[18] | KDD21-淘宝向量检索

  • 前沿重器[19] | 预训练在美团搜索广告中的应用

  • 前沿重器[20] | 文本分类和意图识别研究

最后,一个多月后,系统整理了对话系统的相关内容。在这里,我们将谈谈我们在这段时间里接触到的一些理解,主要涵盖以下内容:

  • 前沿重器[21] | 谈谈对话系统:概述-谈谈他的概念和一些核心技术点

  • 前沿重器[22] | 谈谈对话系统:技术架构-对话系统是如何运行和处理的

  • 前沿重器[23] | 谈谈对话系统:query理解-理解对方说的话NLU

  • 前沿重器[24] | 谈谈对话系统:内容输出-回复对方的内容是如何产生的

  • 前沿重器[25] | 谈谈对话系统:多轮对话-对话系统的特点任务,多轮问题

五篇文章已经完成。您可以直接点击链接或查看以下全文。除了介绍,没有区别。我直接粘贴了[狗头]。

概述篇

对话系统是什么?

事实上,对话系统很容易理解。对话系统是人机对话的界面。当人们与他交谈时,他们可以给出一定的反馈,甚至完成一定的任务。例如,淘宝的客户服务更为常见。如果你问一些问题,一些有机器人背景的人会给出一些初步回复。虽然有一些沙雕,但总能完成一些简单常见的问题,在一定程度上满足用户的需求,从而降低劳动力成本。

Q:您的货物通常何时发货。A:同日发货亲。

这个非常常见的简单问题可以通过客户服务系统直接回答,简单方便。答案很多,答案也很多样化,如何给出适当的答案,这是对话系统需要解决的核心问题。

事实上,在使用场景方面,它远没有你想象的那么不受欢迎。也许你在互联网行业,或者你每天看到的是互联网,并且受到这些信息的限制。事实上,对话系统非常常见。除了上述客户服务外,还有智能家居、智能助手等场景,事实上,我非常依赖良好的对话系统来完成各种复杂的任务,我认为最快乐的是冬天天气很冷,在床上玩手机,只需要一句帮我关掉卧室的灯就可以关掉,背后有对话系统。此外,我最近收到了一些流调的电话,其中许多是机器人提问和记录的。

因此,我实际上觉得对话系统并不像我想象的那么难以忍受。很多人认为对话系统不赚钱,没有未来。我并不悲观。当然,对话系统的核心技术点——NLP,也因为同样的原因,其实不见得就“没前途”。

对话系统的类型划分

根据类型进行拆解,大家能够更好理解对话系统内部的本质,很多人可能都会听说类似“闲聊型”、“任务型”之类的,很多样,这里我按照我的理解做一些分类,让大家更好地理解对话系统以及其内部的一些技术思路。

说到分类,一定要提到分类标准,不同的分类标会得到不同的分类结果。

根据结果输出的方式进行分类

我把它分为检索式、生成式和混合式。

顾名思义,通过查询获得最终答案。大部分检索答案都是有人提前整理存储在特定的库中,对用户query理解后,可以根据结果找到适合用户的标准答案。这里的查询可以是文本层面的查询,比如更基本的ES,也可能是潮了一段时间,现在被认为是baseline向量召回,甚至现在更时尚的知识地图,都可以被视为检索。这种方式在对话系统中可能已经很老了,但仍然是对话系统着陆场景中最重要的方式。它具有很强的可干预性和稳定性。结果是给予的,没有风险。可以保证结果的正确性,NLP只需要注意理解和匹配问题,不能太在意答案内容,相比之下会简单很多。

生成应该是你现在看到和分享最多的,因为它更前沿,生成是通过模型或规则生成回复,这可以说是一个非常智能的解决方案。一般来说,聊天场景非常常见。我最近看到的分享是小布助手的生成式聊天(小布助手聊天生成式算法),它可以直接根据用户query生成结果。这种方法的优点是泛化能力强。他也可以回答那些没有提前准备答案和知识点没有覆盖的内容,但缺点也很明显,即可控性低,缺乏知识的生成可能是严肃的胡说八道(从北京到深圳只需2公里,这句话的流畅性没有错,但逻辑上有问题,即使是GPT这种模型也很容易出现问题)。

混合是两者的混合。这里的混合是指结果上的混合。检索可以找到一些分散的信息,整个结果可以拼接成更完整、更像人话的回复。

根据交互次数

这个划分很简单。如果只回复一次就结束对话,上下文之间不考虑相关性,那就是单轮对话。相反,它是多轮对话。毫无疑问,多轮对话比单轮对话更难。单轮对话中遇到的问题基本上是多轮的,而多轮对话更难考虑上下文。

目前,多轮对话的结构和思路已经形成了一定的共识,即需要DM模块(dialog management)管理对话内容,无论是对方还是机器,都需要维护,以确保一致性,即DST(dialog state tracking),然后根据对话的进展和对话管理下的内容进行综合评价,给出最终回复,即DP(dialog policy),或对话策略(dialog strategy)。

来几个多轮对话的例子,我直接举翻车的例子。

Q:今天的天气怎么样?A:今天,20度到25度。Q:明天呢。A:明天你想问什么?

Q:你今年多大了?A:我今年才3岁。Q:你在哪所幼儿园?A:我已经上班了。

前者没有记录用户说的话,后者也没有与自己的结果保持统一。为了确保这些事情,我们需要改进和维护对话内容。

领域范围

根据不同的领域范围,将其分为开放域和封闭域,后者为垂直域。不谈机器和技术,就谈人的对话。事实上,它有一个背景或一个先验知识,这将导致不同的人在不同的场景不同的理解。同样的说法,上号!,在游戏圈的背景下,就是去相应的游戏,在技术群里说一句话,也许就是去leetcode[狗头],这是一个封闭的领域。在这个封闭的领域下,每个人都有很多先验信息。每个人都会清楚地判断这个简单的词。然而,如果你在公共场合大喊大叫,估计很多人会认为你不正常。这是一个开放的领域。每个人都认为你的话是模糊的。之后,谈谈对话系统。这类似于搜索系统。如果在封闭领域下有一些非常明确的词,它可能在开放领域非常模糊。对于电信客服来说,如何处理手机卡的理解是处理手机卡业务。对于手机客服来说,第一个理解可能是手机卡。当然,手机卡的处理可能会被怀疑,但如果开放领域是一个恰当的歧义句。

因此,对于开放域和封闭域,有一些特定的技术手段来确保结果的准确性。例如,开放域将花费大量精力进行意图识别,而封闭域可能更倾向于根据补充一些信息直接给出答案。

说一些特殊类型

这里有一些特殊的场景类型。

首先是聊天。聊天应该是很多人接触到的第一个场景。顾名思义,这是人们随意聊天的场景。这个场景很小,但绝对不限于此。聊天一直是一个非常复杂的问题。首先,这个对话肯定要是正常的对话,但是人正不正常不好说,很多引导性的、涉黄涉政涉暴的,要从容应对可不简单,机器人被要求友好,被骂了骂回去可不见的合适,很多时候,是需要检索式来支持的,甚至是避不开的需要;第二,有的人喜欢娱乐明星,有的人喜欢政治军事,有的人喜欢二次元,有的人喜欢打游戏,有些人喜欢机器学习,背后可能有很多知识,知识依赖性很高;第三,多轮问题,理解,甚至设置问题(相应的身份,年龄做相应的事情,这是设置)。

然后是客户服务。客户服务应该是一个非常常见的场景,淘宝,然后有一些类似的医疗咨询,银行证券,也需要客户服务,检索应该非常常见和关键的技术解决方案,因为确保答案准确可控,但客户服务可能不局限于此,一些多轮对话策略实际上支持许多客户服务系统,以增强用户体验,但这实际上是一个非常先进的功能。

任务型。应该是典型的对话系统。通过不断的问答和记录,我们最终完成了特定的任务。让我们举个例子。

Q:我要订机票。A:决定从哪里开始机票?Q:从深圳,到北京的。A:好的。希望什么时候出发?Q:明天上午10点左右吧。A:好的,系统给你找到XXX航班,明天10点05分起飞,预计13点到达,请问是否合适?Q:可以的。A:已经为您预定XXX航班,请点击付款完成最终操作。记得提前办理值机手续哟。

这里,通过一连串的追问获取信息,引导用户完成一个完整的订机票流程,这就是任务型,这也是多轮最典型的案例,需要记录信息并且最终完成一个任务,NER和意图识别要把对话中的要素提取,对话管理内需要维护好用户这一系列的信息,追问是一个答案生成的过程,最终还要完成这个任务。

对话推荐。这里的推荐不是指疑似问和相关问题(当然这也是一个研究的领域了),而是至一种带有一定推荐性质的对话。来一个电商场景的吧:

Q:我想买一台电脑,大概6000元,有什么推荐的吗?A:为你找到6000左右的电脑,你看这些合适吗?Q:有没有游戏本?A:为你找到6000左右的游戏本,你看有合适的吗?Q:这台XXX有没有别的配置,只有i5吗,有没有i7的。A:有的,这是XXX-i7版的。

这段对话内,是一个给用户推荐商品的过程,用户会有一些商品需求,需要根据用户的需求找到符合用户需求的产品,这里其实更像是带条件的搜索了,而如果是能考虑到用户画像和习惯,甚至可以做一些个性化,形成一个推荐系统,这里的问题就更热闹了,而其特点就在于,是带有用户条件的,这里其实更像是个性化搜索,不过是对话系统场景了,从产品上,我们不仅要考虑推荐的内容,还需要考虑生成的回复话术,简单的可以考虑是固定的,但都是复杂的可能还会有一些结合产品特定的生成或者拼接。

技术架构

先来几个案例

架构是一个抽象的概念,而实际的落地应用则是架构的现实体现,所以相比直接把结论喂出来,我更想先和大家讨论下现在业界的一些架构和设计思路。

平安智能问答

之前有写过文章讨论过:前沿重器[3] | 平安智能问答系统。这里再抽出关键点讲一下。平安的技术架构可以用这个图来解释:

20c0cdbe4b0b6baa67f013805e8a9fd7.png

这个架构图是按照处理流程来画的,即预处理、检索、知识图谱和信息处理、排序、结果输出等。整个对话系统就覆盖了这些内容。

  • 预处理:包括分词、词性、实体推荐、纠错、多意图、句子匹配等等,在别的领域可能更多叫query理解了,就是对句子进行一些预处理,并且提取一些关键信息。

  • 检索。这里的检索包括ES的检索和孪生网络,说白了就是文本检索和语义检索。

  • 知识图谱和信息处理。说白了也是一种检索的过程,只是这里涉及到语料和图谱的管理罢了。

  • 排序。针对多路召回的答案,根据语义、关键词、编辑距离等因素进行综合排序,最后甚至还有一些利用用户画像的操作。

微软小冰

这篇文章其实我也讲过,甚至更早:前沿重器[1] | 微软小冰-多轮和情感机器人的先行者,文章中我对小冰的评价非常高。主要是因为小冰起步的真的挺早的,而且现有很多技术和思想也很前沿,撑得起“先行者”之名吧,我们可以参考一下小冰的技术架构:

这个是按照模块划分的,告诉了我们他们是怎么切分的。

首先是有客户端,接受各个入口来的用户信息,主要是query,但这里看其实还有很多多模态的输入,声音、文本、图片、视频等,这个入口无疑也是多元化的。

中间是我们非常关心的对话系统层,里面包括了闲聊、技能、情感计算、和对话管理模块。

  • 即使是闲聊,也按照通用闲聊和领域闲聊,拆解比较细致,领域闲聊里无疑还有很多知识维护的工作,有知识支撑的闲聊应该也是现在比较潮的技术话题了。

  • 技能是为了让小冰具有完成特定任务和需求的能力,这里包括任务完成等很实用的技能,能帮助人完成一些基础工作。

  • 情感计算应该是小冰比较特色的能力,一方面能理解用户的情感,另一块能有一定的社交能力,形成小冰自己的“人设”,从而产生一定的情感“反馈”,这个到现在也还是比较牛的场景落地。

  • DM是多轮对话标志性的模块,要对整个对话管理起来,细分下,就是对话状态跟踪和对话策略,说白了就是一个处理输入和生成输出。

最底层,就是对话层,数据的重要性毋庸置疑,对我们算法来说这点我们更有感触,而小冰的底层数据,除了我们熟知的基础物料(知识),还有比较有特色的小冰画像(人设知识)、用户画像(用于个性化)。

美团智能问答技术

美团智能问答技术这块我没写文章讲解,原文在这里:https://mp.weixin.qq.com/s/IN-xzbrjjV2XgrGLPS5wRw

这个图也比较简单,对于对话系统本身,对话系统主要就是对应问题理解和问题解决,问题推荐属于另一个业务问题,这里先不聊。

在问题理解模块,主要覆盖了意图识别、实体识别等基础的NLU理解为,也有一些澄清这种对话系统比较特色的技术(模糊意图下形成向用户澄清的话术,例如“你说的啥?”),也有一些类似时效识别之类的场景特色的技术点。

至于问题解决,就是根据问题理解的结果,去生成回复,这个生成的方式很多,可以走图谱,可以走阅读理解,可以走任务型多轮,可以从社区问答里面找,甚至还有非常直观能够想到的文本生成,最终就是从多个回复中进行筛选和排序甚至是融合,最终解决问题。

案例小结

看完这几个工业界大厂的技术设计,其实大家都能从中找到一些共性,无论是计算流程,还是模块拆解划分,都有一个初步的了解,也能发现一些共性,对话系统在工业界的使用,思路就明确了。

对话系统的架构

流程架构针对的是整个对话系统的处理流程,即用户从提交query到最终获取回复的流程,基本流程就是这些:

  • Query理解。覆盖意图识别、实体识别/提槽、语义表征等共性的NLP处理技术,也有一些涉及拒识、澄清、盘全等技术。

  • 对话管理。针对多轮对话,需要将历史的对话内容甚至是用户画像构造并维护起来,并根据现在的现状,总结出当前最优的对话策略。

  • 结果生成。根据Query理解和对话管理的结果,获取特定的答案,这里有检索、排序等和推荐系统还比较相似的操作。

针对Query理解,相信大家在读我的公众号多的情况下,已经有一些了解了,有兴趣可以翻翻我的历史文章。

对话管理,虽说学术界在这块研究的还算前沿,但是在工业界的发展并没有想象中顺利,无论是技术实现上,还是用户需求的复杂性上,都为多轮的落地实施带来巨大挑战,一方面多轮的信息的存储和处理,另一方面是根据先有信息和状态进行对话策略的生成,从而为下游答案筛选和排序提供依据,当然了,一些复杂的功能,例如主动对话、对话是推荐这种比较新潮也比较智能的技术,都需要依赖对话策略的设计来实现,如果策略做的不好,用户很可能会认为这是“答非所问”。

结果生成,这个过程其实和搜索非常类似,即是根据上游得到的结果,进行结果的召回,这里的召回思路打开,可以有很多:

  • 文本召回。检索式对话那套最简单的模式,进行q-q,q-a匹配做结果召回。

  • 语义向量召回。对query进行语义向量表征,进行向量召回。

  • 知识图谱的识别和推理。

  • 文本生成。很多多种信息进行受控的结果生成,生成特定的回复。

多路召回后,结合多种信息进行排序,这里的排序的学问也不少,相比搜索,会多很多对话相关的信息,相比推荐,也有很多的query处理的信息。

架构背后的考量

技术架构的设计背后其实就是一个系统工程,一个合理的架构和模块拆解能让系统在运行、维护、迭代过程更加流畅。我们在理解了对话系统整体架构的设计之后,可以进一步探索一下。

首先,Query理解成为比较稳定的独立模块。我们知道,对句子本身的理解,虽说部分内容可能会涉及人的认知会有些偏差,但是总体其实是比较固定的,把用户的内容充分理解后,也可以做很多事,特别的其实很多不同类型的文本都需要做理解,很多细节其实是业务无关的,那么Query理解就有必要独立化,另外在迭代上,他的迭代更多不来源于产品需求,而是一些意图召回、实体召回的效果提升,独立出来有利于降低对其他模块的影响。这点其实和搜索也非常类似,意图识别、NER任务独立化以后,能独立确定迭代的节奏。

第二个关键点,对话管理模块的设计,在现实落地的场景下,对话管理需要单独维护起来,主要原因是在计算机网络架构下,多轮对话背后其实对应用户的多次请求,多次请求但是对应多一批对话需要依赖类似sessionid的方法是实时维护,这不仅是算法的活,还需要大幅度依赖工程和数据方面的技术,形成一个综合的,交叉最多的技术点。诚然多轮的技术非常复杂,很多步骤其实都可以需要多轮信息,但是把各种多轮的操作都集中在这,显然是有大量的工程操作考虑的,举个例子,用户意图大都是上下相关的,如果把多轮信息的处理放在Query理解了,那工作量会骤然增大(想想打断、转移之类的凑在哦),加上多意图,这里的处理逻辑会很多,所以适当拆解,Query理解只负责把多种可能算出来,在对话管理模块再来筛选,会更合适。

第三,召回和排序的处理。对话系统的答案生成技术逐步多元化,让我们有了很多答案生成的模式,然而我们知道,不同的结果产生方案会对应很多场景,他们不是完全意义的平替关系,例如客服系统其实更倾向于检索式,毕竟答案可维护而且可控,生成的使用会比较谨慎,所以我们会把答案获取得到这个模块做成和搜索推荐相似的多路召回思路,所有可能得到答案的路径都会尝试去查查。这里,一方面是算法需要构造合理的表征进行计算,另一方面是工程需要在这里去搭建多种不同的数据中间件以满足不同的搜索需求,因此有了这种召回层的设计,而紧接着,就需要一个综合排序来找出最合适的方案。

架构和项目阶段的关系

当然了,抛开需求谈架构绝对是不合适的,这3个案例其实都建立在流程比较完善,业务也比较稳定的情况下了,但是初期,其实我们并没有太大必要切分那么细。来举个例子吧。

  • 例如,做检索式问答系统,那召回的链路就会比较简单,甚至只有一个,此时我们完全没必要把召回和排序拆开,只需要在查回结果后,直接根据相似度等因素进行排序即可。

  • 再例如,在系统比较简单的情况下,甚至是不需要很重的query理解的,例如意图识别,甚至可以不做,直接去进行检索排序都行。这里要明确意图识别存在的意义,主要是在用户需求非常分散的情况下,通过意图识别识别用户意图,从而方便进行一些不一样的设计,例如百科知识和音乐播放,最终给的结果形式都不同,此时有一个意图识别,能为下游做不同的操作提供一定的空间。

所以,上面的架构只是提供技术上的一些拆解思考,做出一些设计建议,也让大家了解到对话系统中涉及的算法技术有哪些,从而对对话系统在技术层面有一个宏观的认识。

query理解

query理解应该是我这里聊的最多的内容了,无论是涉及的技术还是一些细节的技术方案,其实有,这次适逢重新聊这个对话理解技术,我这里也按着流程和思路去聊,但是涉及重复的展开的,我会引导大家去我的历史文章里的,而这篇,我也考虑讲一些其他的,然后还有一些现实应用中容易遇到的问题。

这里,我先把我上次聊query理解的文章先放出来,已经是很久之前的事了:

  • 心法利器[34] | 报告小结:query理解概述

  • R&S[24] | 浅谈Query理解和分析

query理解是干什么的

上一期在给出的美团智能问答技术的架构中说到了问题理解,这里所谓的问题理解就是我说的query理解,在这一步中,我们需要做的就是把用户提出的内容充分理解,从而让我们后续的回复能更精准,这点和我们日常的对话是符合的,只有理解对方说的话,我们的回复才有意义。

这里聊清了他的意义,但是具体做的事情其实并不清晰,而具体要做什么,我们首先要考虑的是,说query理解是为了最终的回复结果,是指就是为了下游的结果生成服务的,这也意味着,query理解的任务很大程度上和下游的需求有关,下游需要什么,我们提取什么。

query理解的具体任务

这时候,依旧是要看例子。

美团智能问答技术

  • 先来看看上次提到的美团,看看他们在做什么:前沿重器[22] | 聊聊对话系统:技术架构

可以看到,主要是6个部分,我这里先解释下,当然了有些是联合在一起起作用的我就合在一起了:

  • 领域意图识别:主要用于识别query的话题意图,下游针对不同的意图是有不同的资源或者是处理方式,所以这个意图识别非常重要。

  • 领域路由和意图澄清:和搜索不同的是,在多意图上的处理,对话系统在只能给一个结果的情况下只能转为澄清或者取一个概率明显高的,这个判断的工作则要由领域路由来判断然后做这个意图澄清。

  • 实体识别和链接:实体的抽取和链接,下游如果是KBQA或者是文本检索,其实是非常需要实体信息的。

  • 时效识别:应该是美团场景特有的一个点了,就是识别某个实体或者活动的时效性,例如有些活动结束了,那应该是需要给拒绝的回复了。

  • 实体澄清:这个和多意图其实类似,举个例子大家就明白了——“苹果”。

  • 句式识别:顾名思义,就是识别整个句式,这个具体的用法很多,例如有的时候有了句式,能快速识别意图或者是实体。

  • 槽位填充:槽位填充和实体识别很类似,很多地方的说法会不太一直,就槽位而言,主要是看指的是向用户追问还是用户提出的槽位问题需要对话系统来填。

这些任务,都是旨在从query中抽取甚至是推理出一些信息,这些信息是有利于我们给出回复的,例如意图识别我们是探索用户的需求是什么,ner则是给出用户更加细粒度的要求或者是用户的一些先决条件,当用户给出的内容我们感到模糊的时候,也可以适时返回一些澄清意图,引导用户更好地描述他的问题,从而让我们进一步回答。

平安对话系统

看完美团的,回头看看平安的,其实相比之下,平安的对话系统会稍微简单一些:

这里的细节里可以看到,整个理解被看做是整个预处理模块,这个可能和下游的处理复杂度有关,他这里下游主要是ES检索和向量检索,从而那张可以多少看到,对多轮的要求不多,而是个性化等方面会比较多,所以在query理解上就会相对简单了。

共性query理解任务

从上面的两个例子可以看到一些比较共性的任务:

  • 意图识别。

  • 实体识别。

而另一方面,也会有一些针对业务定制化的任务和根据下游数据需求去做的任务,前者有美团的时效识别,后者又有类似实体链接之类的任务。

其他的多少要么就是细节内容,我平时讲的语义匹配或者相似度问题,但是这个可能会不放在这里,而一般放在检索之类的里面,这个我放在下一篇讲吧。

query和下游任务之间的关系

上面我不停地强调,query理解要做的是理解query,但不能局限于此,而还应该考虑下游要怎么用我们的东西,而不能我们擅自去划分,而这里进一步展开,我们可以考虑的因素有这些,我分段展开描述。

对于检索式,下游利用我们的意图识别的方式是什么。直接的,是字段检索构造语义向量的特征,如果是字段检索,那都有哪些字段,类目体系如何,类目之间的边界是什么,这些都是需要我们去明确和了解的,同样是大类小说,但是类目下有小说名。作者、发布时间等,甚至有些模糊的直接带了些标签,例如“最新”、“恐怖”、“爱情”等等,底层的数据结构是什么样的,我们只有充分了解,才能让下游更好的利用起来,如果我们自顾自的做了一版,效果还很好,但就是不好用,那肯定是不行的。

对于生成式,我们也要考虑生成式里需要用到的信息有哪些,毕竟我们肯定不想要言而无物的万能回复,带一些信息的回复总不至于把天聊死,所以我们提供的信息就非常重要,此时就要看下游用的信息是用到什么粒度,例如是只需要实体,还是要详细到实体类型的实体信息,下游要根据意图变化给出一些对话策略,那我们的意图体系也要尽可能和下游的意图对话策略对齐。

所以,回到query理解任务下,我们是需要充分了解下游任务的需求,才来去做query理解,合理划分任务,才能做好这颗在整个系统中的螺丝钉。

query任务解释

这块我已经写了无数的文章来汇总了,虽说技术日新月异,但是任务本身的变化并不太大差异,而且从日常实践的经验来看,我们更多关注的不应该用什么模型,而是具体设计的思路以及具体的数据,数据集的优化往往是大幅提升效果的快速方式,真心的,大部分情况,textcnn和bert没有太多效果的差异。

意图识别

意图识别可以看做是一个文本分类任务,因为这个任务实质上就是把query识别到特定的类目上去,与常规nlp任务不同的主要是这几个特点:

  • 类目边界不明确,这块其实难度不小。

  • 数据质量大部分情况都不高,需要花大量时间操纵数据,这也是很多情况模型效果diff不明显的原因了。

  • 空间分布可能会比较零散,这个其实会一定程度影响我们的方案设计的,模型上也要考虑多空间的承载能力。

  • 数据会具有一些场景特色,如名词性场景、口语化问题等。

意图识别应该是我自己而言比较擅长的一个领域了,虽说意图识别可以被看做是一个文本分类的任务,但我们不局限于用文本分类的方法来解决这个文本分类的问题,与之对应的,我更建议是把他当做一个完整的系统来进行处理:

  • 心法利器[29] | 把文本分类任务做成一个系统

  • 前沿重器[20] | 文本分类和意图识别调研思考

  • 心法利器[26] | 以搜代分:文本多分类新思路

  • 心法利器[11] | 任务方案思考:文本分类篇

实体识别

实体识别的本质就是一个NER问题,而且可以是一个比较传统的NER问题,在大部分情况不太需要考虑嵌套、连接之类的问题,在早起版本我们可以把一些复杂的问题放到相对不关键的位置,关键点还是抽取出实体,这一方面是让我们不需要考虑太过复杂的ner模型,另一方面也给了传统地词典匹配足够的生存空间。

这里再仔细聊聊对话场景相比一般场景的NER特点:

  • 大部分对话场景,有一定的时效性,这个时效性体现在一些新热词汇的抽取,基本上都要给这个问题留空间,所以词表肯定是要留着的,必须做。

  • 短句问题,同样可能需要词典来处理,尤其是光杆名词的时候,词典效果是最好的,毕竟没有上下文,模型很难生效。

  • 上面提的分类的口语化问题难做,但其实NER反而好做一点。

具体的方法可以看我这些文章吧:

  • 心法利器[12] | 任务方案思考:序列标注(NER)篇

  • NLP.TM[29] | 近期做NER的反思

  • NLP.TM[31] | 2018年的一篇NER综述笔记

  • NLP.TM[18] | 搜索中的命名实体识别

其他的工作

query理解的工作主要是这些,而另外的,则是一些场景特点或者是下游任务需求去增加的了,例如纠错、实体连接、时效性之类的,甚至包括关键词抽取或者是词权重,这种要根据任务需求来进行设计和优化了,此时尤其要明确好需求。

举个例子,关键词抽取,在很多讲解中,大部分是根据任务需求来整的,有的时候关键词是那些名词的词汇,有的时候则是动词的词汇,而反推过来,其实所谓的关键词,是要看对谁关键,有的时候,是需要作为关键词给用户看的,有的时候则是给相似度模型看的,这直接导致了抽取方式需要有所取舍判断,此处对于对话系统,其实和搜索系统类似,都是抽取“对相似度模型有利”的词汇,这个就是所谓任务设计根据需求来设计了。

对话系统特别场景的应对

如果仅仅从NLP角度出发,可能对话系统中拆解得到的很多任务都非常成熟,但是一旦到了落地场景,其实问题绝对不是NLP任务那么简单,我们是需要考虑到这个场景下的用户习惯的,这些习惯直接导致的是用户的query具有特定的风格,而这些风格,不见得模型能够简单的解决,而需要更多辅助措施才能解决。我在日常遇到了不少,这里我聊一些。

时效性问题

类似热点话题、新品迭代比较快的电商平台,这些场景下,都会有很多时效性很多的产品,举个例子,公司出了新品,先不论下游的检索,就是上游的ner和意图识别,都需要快速更新,一般的分类和实体识别模型去做的话,意味着要更新模型,更新模型这个事无论是在效果的稳定性上还是在更新及时性上都有很大风险,而相反,通过词典和模板的方式来处理则无论是在稳定性还是效果上都有稳定的保证。

口语化问题

对话系统本身给用户的感知就是一个聊天框或者一个完整的对话系统,所以相比搜索,用户给出的query会更加口语化,也会更加偏向于完整的句子,更严谨的说,就是完整句子的占比会比搜索高一些,这也就让我们不得不重视这个问题了。

有关这个问题,其实有文章专门聊过:心法利器[52] | 口语化句子解析问题。这里简单说一下,就两个角度,模型角度和数据角度。

  • 数据层面是收益比较大的,这里通过定向的补充样本进行优化,就能有比较好的效果了。

  • 模型层面,则是使用对抗学习、r-dropout之类的方式对模型进行一定的扰动,毕竟口语化本质还是对句子的信息扰动,所以增强模型鲁棒性,能一定程度缓解这个问题。

当然了,这个口语化的问题,可以一定程度描述为长句问题,其实解决的思路和这个类似,所以长句问题不赘述了,但是短句,还是要拿出来的。

短句问题

长短句之前我同样聊过(心法利器[51] | 长短句语义相似问题探索),不过是在语义相似度上的,其实在综合的query理解也会有类似的问题,但是更多是在短句上,这点和搜索是类似的,这个和口语化可以说是两个极端了,对于短句的问题,主要是两个情况比较多吧:

  • 有意义的短句,例如“维修”,意义就很明确。

  • 无意义的断句,在一些场景下,用户可能给的短句含义不是很多或者表意不明,例如“请问”,也有一些在特定场景,可能类似"你好"也是无意义词,但是有些场景可能会认为是有意义的,就看你有没有设计“欢迎”意图了。

常规的,句子短信息少,信息少会导致两种情况,分别是无意义和模糊。一般这种问题的解决思路是这样的:

  • 意图识别在做的时候,需要考虑短句,常规情况,短句模型是可以覆盖的,尤其是高频的,没见过的理论上应该拒绝。

  • 对于新词,就该延续时效性问题那块的处理,用词典来解决,很方便。

  • 一般地,被意图识别统一识别为负类的,自然就是无意义的,这样无意义的能被摘出来,而对于困难的,黑名单自然可以安排,短句其实要挖掘覆盖起来难度不会很高的。

意图识别模块的把关其实还好,而对于多意图,此时则需要通过一定的规则和置信度,来调整排序,甚至是,可以在多意图情况下给用户一个澄清,这个在美团那个案例里就有聊到澄清的问题,例如“你是想要问下面的哪个问题”,这个需要和产品一起沟通最佳体验的回复,当然这个是短句引申出来的问题,但是这本质上应该是一个模糊澄清的处理问题,而非短句了。

小结

本文着重去聊的,主要是这几个点:

  • 整个query理解都有哪些关键的组件,不同的业界还往这里面塞了什么有特点的东西。

  • 重点的query理解任务,都是怎么做的。

  • 对话系统中的任务,和常规的NLP,在数据和场景上有什么特点,以及如何应对。

希望对大家有用吧。

内容输出

核心思路和架构情况

一般的,我会把整体思路分为两种,检索式和生成式,当然现在也有很多方法其实算是两者结合的方法。

  • 检索式重在检索,根据query理解的结果,在特定的库中进行查询,找到答案后输出,或者在找到之后通过组装完成输出。

  • 生成式则是根据query理解的效果去生成特定的回复,基本使用的是文本生成的方案了。

而对于整体架构而言,这两者往往不是完全独立的,而是两者互相辅助互为补充,或者可以理解为多路召回,后续根据对话策略进行筛选排序,找到最优解。

下面先来详细聊聊检索式和生成式的主要技术方案吧。

检索式

检索式对话这种模型相信很多人都不陌生了,我也专门写过文章聊过(NLP.TM[38] | 对话系统经典:检索式对话),随着技术的逐步迭代,检索的方式其实也逐步丰富化。

检索式的基本方法

首先,大家可以看看检索能有什么比较流行的方式:文本/结构化检索,表征式向量检索,知识图谱推理。

文本/结构化检索。比较传统的检索方式了,基本的是类似ES之类的检索,当然有些非常明确的抽取,mysql也可。这种检索对query理解的要求不小,因为检索时的最优方案是,特定字段搜特定内容,有一些类似“你们有卖5000元左右的电脑吗”之类的疑问,我们甚至需要识别5000是一个价格,从而针对性的进行检索。当然了,有一些比较粗暴的方式是把所有内容拼接然后构造倒排索引,这个会对query理解要求降低,但是相比之下对相似度计算的要求会提升,这个需要权衡,例如如果特外特征很多很杂,这个时候对query理解的难度很大,拼接的方式更简单,例如购物场景的对话,而如果特征不多但是比较集中,此时query理解抽取出来可能更好,例如小说场景的对话,基本都围绕那几个关键槽位,如小说名、作者等。

表征式向量检索。这个好像是大家目前最容易想到的办法了,之前有专门聊过这个问题(心法利器[16] | 向量表征和向量召回),把query等特征进行表征,然后用向量索引做召回,这个详细聊过这里就不赘述了。

知识图谱推理。对自己来说多少算一些超纲,但是确实是逐步成为一个比较重要的技术了,毕竟可解释性和可控性比模糊泛化要好很多,知识结构也更容易定义,而最突出的,其实是他能体现人类文明的逻辑型,这点是常规的生成模型所很难具备的,哪怕强如GPT模型,回答的流畅性应该没什么问题,但是逻辑型可能就很难保证,而知识图谱是能解决这个问题的。

检索式知识库的来源

所谓的检索式就是查,而查的一大前提就是有库的支持,然后我们才可能找到结果从而返回,这就如米之于炊,没有米就做不了饭了,所以,这里检索库的知识点就需要大量的资源来构建,这里提供集中比较常见的方式,也强调下这个的重要性。

  • 人工维护。在很多对话机器人的场景,例如客服,是要确保知识的正确性、官方性、稳定性、可控性,有一个可供维护的能力,其实对对话机器人很重要。

  • 在线开源资源。在允许的情况下从三方或者是网上获取。

  • 结合日常人工的对话,进行挖掘和抽取,这也是个很好的方法。

总之,检索式对内容的要求其实不低,我们往往是需要花费一些时间去整理和结构化,才能支撑到在线的使用。

检索的匹配度问题

库很大,查询的本质是让我们从中找到一些比较接近的,可能是结果的答案,这里依赖相似度来做排序和截断,常规的字面和语义相似度都是比较好的方法,具体的就是我们熟知的那些相似度模型,字面的有jaccard、cqr/ctr、BM25,语义的就是DSSM系列、sentence-bert等的表征式和ESIM等的交互式还有一些更复杂的模型,但是在实践中,单一的相似度可能并不完善,有的时候会结合一些query理解、内容质量等信息会有更好的效果,此时可以组装出一些很实用的大型模型来统一处理。

生成式

em...,这个应该也是我的知识盲区,最近是有在看一些,所以初步讨论下我的想法吧。

首先,生成式在一段时间内而且在特定场景下是一个很实用的方案,尤其是闲聊,而且在一定情况下收益还是不小的——这个,应该是大部分人对生成式的直观理解,但是在现实应用真的是这样吗?

在近期看的一篇有关生成式闲聊的文章中(小布助手闲聊生成式算法),我发现,生成式和闲聊之间的关系没有想象的那么简单,主要还有下面这些问题:

  • 可控性不足,对特定的问题或者回复,需要风控。(政治敏感、涉黄涉暴等)

  • 常规的闲聊,回复内容比较直接,对于闲聊这种多轮倾向比较重的回复,很容易把天聊死,所以需要控制。

  • 万能回复,例如“不知道”、“你说呢”这种,需要约束和控制。

  • 一致性问题。换个问法,可能回复就不同,但是对于有些情况是需要一致的,例如“你多少岁了”和“你几岁”。

  • 知识缺失。就是上面说的通顺但不符合逻辑的回复。

上面的问题基本都是现有生成式的一些主要问题,上面的部分问题可以通过检索式解决,也有一些可以通过上下游的信息输入来完成条件生成。

业界的方法

一图流,基本没什么好说的。

而重点在于,我们需要集中一些精力,来解决上面的问题。

生成式的使用方式

针对可控性不足的问题,解决思路如下:

  • 对于敏感问题和回复,一方面从上游的过滤来处理,有些可能有问题的query就不能进入到这一层来,在上游用规则等方式过滤;另一方面,在生成的过程,业务要对该类型的答案进行惩罚,这点在万能回复里也需要做这个工作。

  • 容易把天聊死的问题,可以结合主动对话的对话策略,来推动聊天更容易聊下去。

  • 一致性问题和知识缺失问题,本质上都是依赖一个统一地知识库,结合这个知识库,能让生成的结果更加受控,这也是我前面聊的结合检索的生成式。

方案的选择与决策

方法总有很多,在技术的迭代发展商,无论是生成还是检索,都还有很大的使用空间,肯定是建议大家都去学的,但是在实践过程,我们总要进行取舍,这个取舍,不仅是实践过程中的方案实施的抉择,还有在线预测阶段的结果筛选排序,都是需要我们进行决策的。

方案选择的思路

检索式因为物料本身的可控性,为结果的精准度带来很高的下限,只要query理解和匹配没问题,最终的结果就不会太差,就取决于物料质量了,所以一般情况,尤其是企业级的对话机器人,例如淘宝的客服,其实非常乐意去整检索式,甚至连一些客套话、闲聊场景也会用检索式来处理一些高频的问题,毕竟他是真的稳。但缺点也是在这个库上,低质量的库或者是覆盖率不足的库,体验会很差甚至形同虚设,无论是算法还是运营、数据、工程都要为这个数据库维护花费不少精力,但是一旦建立了起来,绝对起飞。

而生成式,其他点就在于泛化性强,库里面没有或者是有但是泛化能力不足的话,生成式是可以轻松解决的,另一方面,生成式本身的句子流畅性高,在用户感知上会更像人,这给用户体验上带来很大的提升,然而缺点在上面提到了,确实很多不稳定的问题,如果要上,很多辅助措施也是要跟着建立起来。

所以该怎么选?如果是给我操作,检索式会是更高优的选择,至少黑白名单之类的方案还是需要考虑有的,系统的可控性全靠这个,此时只需要花时间整理,检索式总能提供一个稳定可用的版本,尤其是知识型要求非常重的,例如客服型,咨询的问题大都是固定而且专业的,检索式的优势可以说是能充分发挥了。

而在后期,针对长尾的问题,包括闲聊,到了收官时刻,开始处理长尾问题的时候,生成式的需要会逐步明显起来,他的泛化能力能让系统能回复更多更长尾的问题,即使是缓兵之计,“我不太清楚哟,我们来聊聊别的吧,今天晚上打算吃什么”这种回复也会体验好不少,毕竟别说机器人了,每个个体人类都有一定的知识上限,所以真的不奇怪。

排序层的结果筛选

不把鸡蛋放在一个篮子里,随着系统逐步完善,系统内肯定会有多种结果召回,我们需要从中找到最优的方案返回,这点其实和搜索很相似,就是一个多路召回+排序的过程,然而在对话系统中,却有一些非常具有特色的难点:

  • 大部分对话系统没有点击之类的用户交互数据,顶多是类似客服场景的“满足/不满足”之类的,但这个占比很少。

  • 搜索系统多半结果是多条,而且要关注多样性,而对话系统一般只有一个回复,而且要求精准,对于多意图顶多是用“我猜你想问这些问题”这种疑似问的方式来引导,总之最终结合对话策略,只有一条回复。

针对第一个问题,其实对话场景,其实很难有类似推荐或者搜索的排序模型来进行筛选,毕竟是真的没数据,而针对第二个问题,则对结果的精准度有了更高的要求,上游的意图识别和下游的排序层压力都会很大,毕竟结果精准性要求很难。

针对这两个问题,在多意图多内容召回的这个问题下,对话系统很可能采用基于策略和规则来进行综合排序,一方面考虑多个意图或者之间的关系,例如优先信任检索式甚至是kv查询的结果,另一方面,考虑各个结果的置信度(或者结果内和query的相似度)做一个排序从而进行筛选会更为合理。

而如果规则逐渐复杂,系统的维护逐渐存在困难前,可以慢慢往机器学习转,结合各种结果和相似度、匹配度等做一些机器学习的计算,也会有一定效果,当然了,这里用机器学习也是为了避免太过复杂的特征输入,从而降低数据成本,这个方案可供参考。

小结

这篇给大家讲了对话系统的结果怎么来的,检索式应该算我比较擅长的东西了,但是后者生成式写的其实挺吃力的,年后才开始慢慢看然后现在只是有个认识,也找过一些做这块的朋友聊过一些经验,所以才总结出来,希望大家看不出来什么破绽吧[狗头]。

下一篇,也是我自己比较挑战的一篇,聊聊对话场景最有特色的模块——多轮,为了处理多轮问题,我们需要构造一个完整模块来应对,那就是DM——对话管理,这里具体做了那些事,这些任务怎么完成的,让我们拭目以待。

多轮对话

多轮的核心——对话管理

人能够进行多轮对话,很大程度和我们能记住并且使用沟通过程产生的信息和共识,这里值得注意的是,有两个关键的能力,一个是记住,另一个是使用。而现有的大量技术也都是围绕着这两点来搭建的,甚至,比较统一的形成了一个“对话管理模块”,即Dialog Management,DM。

对话管理承担了多轮对话中信息的记录和使用,所谓的记录,就是对话过程的跟踪,一般被称为"Dialog State Tracking","DST"对话状态跟踪,而所谓的使用,有一个跟有意思的说法,叫做对话策略,"Dialog Policy",DP。这点和我们日常的聊天很像,我们在对话过程中,一方面是能接收双方交换的信息,另一方面也会根据自己的目标或者想法制定不同的对话策略,从而达到自己的目标。

当然了,这里的拆解的部分,在现实应用中并不一定是独立拆分开的,可能是组合而成的端到端形式,也可能是拆解分开的形式,这个是根据现实情况来进行选择的。

  • 端到端,从经验上,往往具有很强的泛化能力,在DSTC之类的比赛中,AB榜上端到端的情况似乎会更加稳定,但是缺点是模型内可控性比较差,而且对数据质量和数量的依赖性会比较高。

  • 拆分式在设计上会更简单,而且具有较强的可拓展性,拼装起来可控性也比较高,但是泛化能力会比较差。

拆分式的对话管理

因为把整个对话管理模块进行了拆解,因此整个对话从信息的梳理存储到对话策略的制定都会很明确,大家看起来也会非常好理解,这里先讲这个。

先用最常见的就是任务型对话作为例子,这个例子前面是提到过的:

Q:我要订机票。A:要订从哪里出发的机票呢?Q:从深圳,到北京的。A:好的。希望什么时候出发?Q:明天上午10点左右吧。A:好的,系统给你找到XXX航班,明天10点05分起飞,预计13点到达,请问是否合适?Q:可以的。A:已经为您预定XXX航班,请点击付款完成最终操作。记得提前办理值机手续哟。

这是一段订机票的任务型对话,这段任务型对话其实并不复杂,目标很明确,就是要引导用户把所有信息都填充清楚后,进行订机票的操作,列举下来就这几件事:

  • 开头的意图识别,识别为订机票的意图,进入多轮。

  • 拉出需要填写的信息列表,并且引导用户填写这些信息:

    • Query理解持续提取用户回复的信息。

    • 对话状态记录用户的填表信息。

    • 对话策略确认仍然缺少的信息,选择追问策略和完成策略,当然还包括一些打断后的策略。

显然,这种方式是非常规则化简单化的,而随着逐渐复杂,对话策略也就会逐步复杂,逐步迭代为一些类似类似用树或者用有限状态自动机来对这些规则进行合理化管理。

既然是拆解,那我们就拆解来看这些任务怎么做。

对话流程中的DST

DST主要用于对对话过程中的内容就进行管理维护,这是为了下一步对话策略进行分析做基础的,最简单的方式其实就是直接用缓存把对话内容记下来,形成可解释的部分,如下面一个格式,只列举部分字段:

{
  "destination": "北京",
  "originator": "深圳",
  "takeoff_time_date": ""
}

而后对话策略根据缺失的信息进行追问即可。

而后,随着内容逐渐丰富,场景逐渐复杂,甚至因为轮数增加部分信息也有了更新和变化,这种固定格式的并不一定能够满足我们的需求,于是有了更多的改进措施,也逐步向模型、泛化的方式进行。

首先是对话状态的表示,不难看出对话状态数跟意图和槽值对的数成指数关系,因此需要考虑构造合理的模式来实现,例如隐含信息状态、贝叶斯更新等。然后是状态的更新和转移,这种随着任务逐步复杂,是最快进行模型化的,从CRF到RNN,甚至用到迁移学习等,也从单一任务或者槽位的跟踪逐步升级为多任务多目标的跟踪,在DSTC大型赛事中被验证具有很好的效果。此处已经是一个非常完整的体系了,我也并不专业,这里不展开,大家可以看看其他大佬的博客,我这里列举一些好文章吧:

  • 任务型对话系统中状态追踪(DST):https://zhuanlan.zhihu.com/p/51476362

  • 一起来看看最新的对话状态追踪(DST)模型:https://zhuanlan.zhihu.com/p/115019681

  • 多轮对话状态追踪(DST)--模型介绍篇:https://zhuanlan.zhihu.com/p/40988001

对话流程中的DP

DP就是对话策略,对话策略是根据现有的query理解和DST,制定对话返回策略的部分,这部分一旦敲定,其实最终的回复也就差不多了,所以重要性也可想而知。

常见的对话策略都还比较简单,例如上面的任务型,其实就是比较简单的用一些规则,根据缺失的信息制定回复策略进行追问即可,这里甚至不需要很多复杂的操作,规则即可,但这也就仅限在一些比较简单任务了,对于复杂的任务,进行复杂的策略分析和预测就显得非常必要,DPL(对话策略学习)应运而生。

考虑到很多对话策略的文章直接就本着强化学习去聊了,但是我个人其实并不太想直奔那块,而是想把对话策略先当成分类来去聊(虽然我也知道,强化学习某种意义上其实和分类问题很像),即在现有信息下,我们把策略的选择当成是一个分类问题来去看,有了消息,我们该采取哪种策略,这点来看他实打实就是一个分类问题,主要原因是,它涉及的信息很多,最重要把他们综合起来,在各种策略中找到一个比较好的,这无疑就是一个分类问题,再升级一下,可能就是一个召回+TOP1排序的问题:

  • 选择的依据很多,DST信息,现有Query的信息,用户画像,甚至机器人的画像(人设信息),还有一些策略规则等。

  • 策略上,先默认现在的机器人没有自己生成新的回复风格的能力,那如无人工添加,就是从现有策略进行选择了。

  • 可用的策略并不唯一,例如用户说了个模糊的结果,可以是追问(特殊疑问句,如你说的是啥)、可以是疑似问(猜测你要问啥)、甚至是调侃(没想到你说的我居然没听懂,是不是我没学好)、转移话题(啊,你说的我不懂,要不我们聊聊XX吧)等等,哪个比较好,是需要通过排序之类的思路来进一步筛选出来的。

毫无疑问,想到这里,分类问题很合适,甚至适合在这里构造一个完整的分类系统,从模型分类到召回-排序的模式来做,都没有问题。

而后,由于本身DP就是一个决策问题,甚至是一个多次决策的问题,因此把问题交给强化学习可能更好,于是强化学习就开始成为DP的重要手段了。说到强化学习,必须提到的就是强化学习本身需要的元素,即状态、动作、奖励,在多轮对话里,状态就可以理解为DST中的信息,动作就是采取的对话策略,奖励就是采取行动会得到的奖励,我们所希望的就是全局,也就是整次对话下来,奖励最高,多轮对话无疑是符合这个模式的。

和DST一样,我这里不展开说,有兴趣大家可以自己进行深入阅读,我这里放一些我觉得比较好的文章吧:

  • 一文看懂任务型对话中的对话策略学习(DPL):https://zhuanlan.zhihu.com/p/52692962

  • 深度学习对话系统理论篇--Deep Reinforcement Learning for Dialogue Generation:https://zhuanlan.zhihu.com/p/31829823

端到端式的对话管理

端到端式的对话管理大部分出现在学术界中,用过特定的模型完成多轮信息的整合和对话策略的决策,甚至从输入开始进行串联,从输入直接到输出完成全局的端到端结果回复。

检索式多轮

没错,检索式其实也有多轮,也能做多轮,而且其实研究还不少,其本质就是把历史的对话信息和当前的回复都放到模型的输入中,形成端到端的模式,不过从社区目前的关注度来看,关注度其实并不太高,列出一些文章供大家参考下:

  • 多轮检索式对话系统小结:https://zhuanlan.zhihu.com/p/84163773

  • 检索式多轮问答系统模型总结:https://zhuanlan.zhihu.com/p/46366940

生成式多轮

与检索式对应的生成式多轮,生成式的灵活性可想而知。简单的方案其实很早就有了,seq2seq就是最经典的操作,直接将这些对话信息放入模型,这种操作方式和编码器类似,能直接生成一些基本的多轮回复,这种方式虽然简单,但终究算是一

标签: 电连接器接触件的固定结构

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台