把握行业变革关键节点,12 月 19 日 - 20 日,AICon北京站即将重磅启幕! 了解详情
写点什么

轻量机器人框架 – Segnavi

  • 2019-11-24
  • 本文字数:3644 字

    阅读完需:约 12 分钟

轻量机器人框架 – Segnavi

这些是否困扰你?

当你想到智能客服问答的时候,你是否第一反应它一定要与人工智能有关?

你是否只是想要一个开箱即用,简答上手,无需复杂的人工智能知识和机器学习规则的智能客服系统?

你是否想让你的智能问答系统不单单满足于问答场景,还希望它可以执行更多的动作?

那么,从今天开始,我们开发的 Segnavi 框架将满足以上所说的这些全部内容,它并不需要你了解人工智能、机器学习方面的知识,就像写脚本一样快速轻松的构建属于你的智能问答系统。

化繁为简,开箱即用

当你不再重复性的为各业务的同学解答相同问题,不再被重复的问题所打扰,一杯咖啡,静下心来,去专心思考和研究更深入的问题时,不得不说这的确是最理想的工作方式了。


从今天开始,只需一杯咖啡的时间,即可立刻构造属于你的智能问答系统。Segnavi 本身的体积十分小巧,无需依赖任何数据库即可运行。基于 python 开发,就像些脚本一样的轻松使用。我们将知识库从常见的数据库存储,转换为本地代码文件存储,所以严格意义上来讲 Segnavi 是一个机器人对话的框架。我们将框架尽可能设计的足够简单、轻量、灵活且功能强大。


我们将传统机器人对话中的意图理解和槽概念转换为 Python 在面向对象状态下的两种可继承类,通过这个继承类生成的对象可以取得全部的对话与槽特性。简化在任务型对话中的槽类型、槽字段等相关概念,取而代之是对象内的属性和方法。你可以像写脚本一样简单快速的使用到框架的全部功能。


在进一步的介绍之前,先简单了解一下任务型对话中槽的概念:在任务型对话中,我们的要完成某一个动作,需要各种的条件满足一个任务的触发,这种对话就叫任务型对话,触发的条件就是槽。当然你可以把槽理解为传递触发条件的参数,我们所做的就是简化机器人中的逻辑。


通俗的讲,类似于 http 请求中传递的参数。这种参数是通过多轮问答的形式来实现的。


下面我将用“40 行代码”来举例说明。

强大的功能

最简化设计

我们设计了两种任务型对话,以满足不同场景的多轮对话需求,一种为 Question 类,一种为 Operation 类。为了简化结构和方便理解,我们将两种不同的任务型对话转换成树形结构,我们管这棵树叫“问题树“。


Question 的每一个问题就相当于树的每一个分支,树的子节点可以继续是 Question,也可以是 Operation 类。而 Operation 类是负责任务型对话中槽位的填充,其为树的最终子节点。可以理解成红黑树中的黑树,且不再有任何子节点。


除了为了满足不同多轮对话场景需求而设计的 Question 类和 Operation 类,我们还设计了一个 Word 类,改类的目的为注册不同的词或语句绑定在一个 Question 或 Operation 的子类中。


举个例子


【代码】



QuestionTree1 类为 Question 类,它是作为问题树的结构体,方便用户做出进一步的选择,也是一类在多轮对话中槽位的填充。这其中 Word.registe()为注册的词,我们可以注册两个词"hello"和"WelcomeList"等任意个词,这其中 WelcomeList 为引导词,你也可以在配置文件里面随意设置你的引导词,当用户达到配置中连续未任何命中的时候,就会执行引导词。


Question.register() 用于注册任务型对话中负责询问的部分,在 Segnavi 展示中,为问题树的选项。为了方便使用,Segnavi 会将 Question.register()注册的内容,通过 1,2,3,4…这类数字作为选项引导。对于超过 2 层的 Question(Question 的子节点还是 Question)Segnavi 会自动生成 “返回上一级” 的选项。q3 中的 handle='我是问题树 1’代表当用户选择 3 这个选项,实际 Segnavi 会内部执行 “我是问题树 1” 这个词。在 Segnavi 中,默认状态下,用户选择了哪个选项就相当于对系统说了哪个选项的 text 文本,当然这个也是可以改的。就像 q3 这样。


OperationHandle1、OperationHandle2 分别代表两个最终子节点,Operation.register() 相当于进入该对话时槽位的填充,这里的槽位我们可以限制指定词的类型,也可以不限制词的类型,词的类型我们在稍后会介绍。当槽位被填满(满足所有条件时),Segnavi 会触发 Operation 子类中定义的 _ handle _ 方法 ,这个方法内你可以执行任何代码,或者只是返回一句简单的 hello world。


【运行后的结果】




超强的纠错能力


在传统的规则匹配型语义理解模块中,最难维护的是你词规则是否是唯一,且规则中是否存在互斥,死锁,循环等问题。在 Segnavi 中这些作为使用者无需考虑。因为我们在系统启动时会有全面的自检程序,防止此类情况的发生。当 Question.register() 中注册的 text 文本是一个不可被理解的词(其他类未注册的词),或者会被理解成两个不同的选项时(多个类同时注册一个词,或一个词指向了两个不同的类),系统此时是无法启动的。


比如我们将 q2 的 text 文本改成一个不存在的词时:



系统启动时的自检程序将会报错:



将机器对话的复杂度降低至小学水平的知识


在传统机器对话模型中,会通常设置自然语言处理和语义处理模块,来处理用户的提问,并起到语义理解,与槽位的识别功能。通常情况下,自然语言处理和语义模块是在一起的。


Segnavi 也有自己的语义理解模块,和自然语言处理系统。但我们为了简化逻辑,将自然语言处理和语义理解模块拆开。对话过程只保留语义理解中的分词功能。将自然语言处理的逻辑由用户输入时的触发变为逆向的先行触发。


我们会在系统启动时,会预先对所有 Word.register(),Question.register(),Operation.register() 内所有的 text 文本进行自然语言处理,和切词操作。并构造一个大型词典的结构体,这个结构体内包含了词的 text 文本、自然语言处理后的切词、词的类型、词的动作、词的权重等等内部的参数。


当一个词未被理解时,我们会根据在系统启动时构造的 NLP 词典进行反查,达到联想和猜测的功能。然而这些操作都是作为使用者无需关心的,你只需维护一个简单的 text 知识库即可。


上面我们刚刚提到了在 Operation.register() 内可以设置槽位的类型为指定词的类型,我们采用了基于规则理解方法来解决槽提取以及槽填充的问题。我们将 程序主目录/handle 作为所有词和知识库的存储。handle 目录下的 一级目录名 为词的类型,词的类型类似我们上小学时候学的动词、名词这种,它起到对词进行归类并打标识的作用。就好比我们说跑、跳、走这类词是动词,文具、铅笔、橡皮这类词是名词一样。在 Segnavi 中,槽填充和槽提取也会依赖对词类型的检测。


例如 num 目录下的所有文件,注册的词,它们的类型都是 num 类型。ip 目录下注册的所有词类型都是 ip。这个我们已经预先设置好,可以不用做任何的修改,开箱即用。



我们预先设置好的词:




灵活的运用和极少的资源使用

Segnavi 可以应用在任何系统中,我们曾经接入过 Qtalk、微信、QQ,可以说只要是 IM 系统都可以接入 Segnavi 作为处理引擎调用方式仅为 http 的 post 请求而已。我们会在内部维护 session,无需调用方维护。


同时我们还会提供一个 webui 供测试使用。后台日志和分析功能,可以还原当时的会话场景,并按照指定日期进行词频、动作、理解程度等维度进行综合分析。还支持通过关键词在所有会话内进行查找,并支持导出至 excel。


经过我们测试,每 10,000 个 session,平均占用 100MB 内存。我们在高峰时可以同时处理超过 500 个对话,并且只用一台主机即可。因为是非 cpu 密集型程序,即使是 500 个对话,cpu 的使用水平依旧可以保持一个很低的水平。

写在最后

目前 Segnavi 已经在公司内部开源使用。现在 OPS 值班热线、CM 热线、JIRA 热线都已接入。我们在设计 Segnavi 之初,跟大家一样也曾尝试过别人的机器人框架,当初想法很简单,只是想做一个运维相关的机器人而已,我们的需求也很简单同时能满足有多轮问答的场景,和满足直接使用命令行操作,并且当用户不知道选项时最好能提供一个菜单。但调研了一圈框架后发现,要不就是框架过于复杂,要不就是功能不完全。最后不得已只能自己造轮子,其实早在 18 年 11 月的时 OPS 内部就已经将机器人切换至 Segnavi 框架了。从目前的状态来看 Segnavi 运行的还是比较稳定。


由于篇幅有限,其实在文章中只能介绍 Segnavi 框架的最基础功能,我们还支持例如转人工、层级索引、模糊猜测、命令式的直接槽位提取等等。我们没有为 Segnavi 配置机器学习的模块,但已经预留出插件接口。其实作为运维工程师来讲,目前的 Segnavi,已经能够满足 OPS 的全部需求了。接下来如果有精力,我们期望能将 Segnavi 的对话和 session 改造成中间件式的可插拔插槽。


我们始终期望创造一个开箱即用,简单逻辑的机器人应用,减轻学习成本,方便快速使用。最后,如果你希望使用 Segnavi 欢迎与我取得联系。


作者介绍


王欣宇,2018 年加入去哪儿 OPS 团队,负责运维自动化相关的工作,保障了公司每日数十万的自动化任务执行,让海量服务器共舞。


本文转载自公众号 Qunar 技术沙龙(ID:QunarTL)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzA3NDcyMTQyNQ==&mid=2649263128&idx=1&sn=b616b27b85290e8c7d8008abd0efcd4b&chksm=87675de6b010d4f04ebc8e031646de7f4d1e702325ae355bca73142645b9981a87930b2213c7&token=2032634643&lang=zh_CN#rd


2019-11-24 08:002477

评论

发布
暂无评论
发现更多内容

G1收集器概述

Nick

Java GC G1垃圾回收器 6月月更 Garbage-First Collector

物联网低代码平台如何查询授权信息?

AIRIOT

物联网 低代码开发

【涨姿势】你没用过的BadgeDrawable

yechaoa

android 6月月更 material design BadgeDrawable

Docker常用命令总结

乌龟哥哥

6月月更

数组(二)

Jason199

数组 js 数组操作 6月月更

比Postman更适合国人的接口调试工具

伤心的辣条

程序员 自动化测试 接口测试 Python自动化 程序员程序人生

攻防演练中六条安全体系建议

穿过生命散发芬芳

6月月更 攻防演练

gRPC C++开发环境搭建

赖猫

c c++ gRPC

MobX 获取网络数据来渲染酷炫的曲线

岛上码农

flutter ios 前端 安卓 6月月更

黄硕:百度飞桨文心大模型在语音文本审核中的应用

RTE开发者社区

RTC Dev Meetup 生态专栏 语音处理

leetcode 310. Minimum Height Trees 最小高度树(中等)

okokabcd

LeetCode 搜索 数据结构与算法

改造微服务的三个时机

阿泽🧸

微服务 6月月更

Android ShapeableImageView使用详解,告别shape、三方库

yechaoa

android 6月月更 material design ShapeableImageView

【Java Web系列】Cookie的原理分析和使用细节

倔强的牛角

Java javaWeb Cookie 6月月更

Python代码自动提取Win10内置的锁屏壁纸

宇宙之一粟

Python 6月月更

快速实现微信登录第三方小程序快捷方式

Geek_99967b

小程序 小程序转app

Vue3 Composition API如何替换Vue Mixins

源字节1号

前端开发 小程序开发

SQL优化

工程师日月

6月月更

线程的创建方法

卢卡多多

线程池 线程安全 6月月更

架构实战营模块 8 作业

热猫

flutter系列之:flutter中常用的ListView layout详解

程序那些事

flutter 程序那些事 6月月更

静态链接,静态分派,动态链接

北洋

android 6月月更

模块四(千万级学生管理系统的考试试卷存储方案)

Geek_701557

【愚公系列】2022年06月 通用职责分配原则(一)-信息专家原则

愚公搬代码

6月月更

人人都在搞数据治理

奔向架构师

数据治理 数据管理 6月月更

前端uni框架学习day_2

恒山其若陋兮

前端 6月月更

vue监听器

小恺

6月月更

浅谈隐私计算与数据安全

I

学习笔记 数据安全 隐私计算 可信安全计算

读书笔记之:认知觉醒

甜甜的白桃

读书 书单 阅读 6月月更

软件测试需要学习什么?好学吗?需要学多久?到底是报班好还是自学好?

伤心的辣条

程序员 程序人生 软件测试 自动化测试 Python自动化

数据库每日一题---第11天:合作过至少三次的演员和导演

知心宝贝

数据库 前端 后端 6月月更

轻量机器人框架 – Segnavi_AI&大模型_王欣宇_InfoQ精选文章