baidu-chelianwang / dm-kit
DM-Kit for php.
Requires
- php: >=7.0
- guzzlehttp/guzzle: 6.3.3
- monolog/monolog: 1.23.0
- symfony/yaml: 2.8.45
Requires (Dev)
- phpunit/phpunit: >=4.8
This package is not auto-updated.
Last update: 2024-09-25 15:50:09 UTC
README
简介
参考c++版本的unit-dmkit,完全兼容c++版本的policies配置文件,但是不能反向兼容。
在任务型对话系统(Task-Oriented Dialogue System)中,一般包括了以下几个模块:
- 自动语音识别(ASR),即语音识别模块,将音频转化为文本输入。
- 自然语言理解(NLU),即自然语言理解模块,通过分析文本输入,解析得到对话意图与槽位(Intent + Slots)。
- 对话管理器(DM),即对话管理模块,根据NLU模块分析得到的意图+槽位值,结合当前对话状态,执行对应的动作并返回结果。其中执行的动作可能涉及到对内部或外部知识库的查询。
- 自然语言生成(NLG),即自然语言生成。目前一般采用模板的形式。
- 文本转语音(TTS),即文字转语音模块,将对话系统的文本输出转化为音频。
DM Kit关注其中的对话管理模块(Dialog Manager),解决对话系统中状态管理、对话逻辑处理等问题。在实际应用中,单个垂类下对话逻辑一般都是根据NLU结果中意图与槽位值,结合当前对话状态,确定需要进行处理的子流程。子流程或者返回固定话术结果,或者根据NLU中槽位值与对话状态访问内部或外部知识库获取资源数据并生成话术结果返回,在返回结果的同时也对对话状态进行更新。我们将这部分对话处理逻辑进行抽象,提供一个通过配置快速构建对话流程,可复用的对话管理模块,即Reusable Dialog Manager。
如何使用
安装
使用composer安装
composer require baidu-chelianwang/dm-kit
使用
try{
//botId为unit botid,confPath为配置文件地址,暂时只支持json格式
$policyManager = PolicyManagerFactory::getInstance($botId, $confPath);
$policyManager
->setRequestParams($arrInput) //设置客户端传入参数,必须有cuid字段,用来保存session
->setQuResults($quResults); //设置nlu召回结果,对应的parser会做解析,支持unit直接返回结果
//output即为召回结果,返回false则无召回
$output = $policyManager->output();
}catch(DmException $e) {
}
测试
- 运行composer update,安装依赖库
- 在百度unit平台上创建bot,具体参考UNIT配置指南
- 将bot_id和access_token填入app/config/bots.json文件中,cellular_data为流量查询bot,quota_adjust为额度调整bot,access_token获取参考http://ai.baidu.com/docs#/Auth/top
- 运行php src/Tests/speak.php,查看bot效果
详细配置说明
本节详细介绍实现垂类功能的配置语法。所有垂类的配置均位于模块源码app/conf目录下。
垂类注册
bot类
如果需要调用自定义函数,则需要定义bot类,并继承Baidu\Iov\DmKit\Bot\Bot。
在bot子类中,可以使用函数:
- setSessionContext($key, $value),设置session字段
- getSessionContext($key),获取session字段
- getSlot($key),获取Slot对象
- setState($state),设置下一个state,设置为空则对话结束
垂类配置
单个垂类配置文件包括了一系列policy,每个policy字段说明如下:
触发器
每个policy有且仅有一个trigger,trigger定义了policy的触发条件,有4种条件,intent,slots,changed_slots和state,四种条件中间是且的关系,必须所有条件都符合,才会进入当前policy
intent
intent为NLU解析结果中返回的intent,配置的intent需要等于NLU返回的intent。如果配置的intent为空,则匹配NLU结果无召回情况。
假设有一个音乐bot,当前正在询问用户:"你想听什么歌?",NLU可能无法解析某些歌曲名称,为了保证召回率,可以在dm模块中查询第三方资源接口,如果能找到资源,则也可以认为用户说的query是一首歌,并召回正确结果。
- 需慎重使用,避免过召。
state
state为对话的当前状态,如果是第一轮对话,则当前状态为dm_init,配置的state可以为string或者array
- state为string时,对话的当前状态需要等于配置的state。
- state为array时,对话的当前状态需要包含在配置的array中
slots
槽位名称数组。slots为NLU结果中返回的slots,配置的所有slots都需要出现在NLU解析结果中,只验证词槽是否存在,不验证词槽的值。 如果需要验证词槽的值,需要在param中增加一个slot_val并在output中的assertion中判断。
changed_slots
发生变化的槽位名称数组。changed_slots为当前轮次中,词槽值发生了改变的词槽,配置的changed_slots中的所有槽位都需要发生改变,否则不触发policy。
当满足多个policy时,会按优先级取出一个匹配度最高的policy,具体规则如下:
- 如果一个policy中匹配规则含有intent,另一个不含有,则取含有intent的policy
- 如果一个policy钟匹配规则含有state,另一个不含有,则取含有state的policy
- 如果两个policy的slots条件分别含有m和n个slot(m >= 0, n >= 0),如果m > n,则取含有m个slot的policy
- 如果两个policy的slots条件分别含有m和n个changed_slot(m >= 0, n >= 0),如果m > n,则取含有m个changed_slot的policy
Param
param为参数列表,每个policy中可以定义一系列参数,在output中使用,可用于assertion,session.context及result.value,param可以为string或者object。单个policy中的参数名称不能重复。
使用方法
一个policy中可以有多个param,在param中定义的参数,可以使用{%param_name%}在output中表示,会自动替换为真实值
- 当param为string时,{%param_name%}将会被替换为目标字符串
#假设param的值为字符串test result: type: tts value: {%param_name%} #这个会被转换成如下形式 result: type: tts value: test
- 当param为json object时,{%param_name%}将会被替换为object
#假设param的值为object name: 忘情水 artist: 刘德华 url: www.baidu.com #result,只有当type=json时,才会递归所有子数组进行替换 result: type: json value: music: {%param_name%} #这个会被转换成如下形式 result: type: json value: music: name: 忘情水 artist: 刘德华 url: www.baidu.com
params中变量类型列表及其说明:
http_request使用示例:
{ "name": "http_response", "type": "http_request", "value": "www.baidu.com", "options": { "method": "post", "json": { "query": "示例" }, "header": {"Cookie": "a=a"} } }
json_extractor使用示例:
{ "name": "result", "type": "json_extractor", "value": "{%http_response%},body.results.0.data" }
用户可以自定义param handler,需要继承Baidu\Iov\DmKit\Policy\ParamHandler\AbstractHandler。
output
在一个policy中可以有多个output,每个output有零至多个assertion,每个assertion之间是且的关系,所有assertion都满足的时候,会输出定义的result。
output按顺序判断,当一个output中的一个assertion满足后,不会继续判断之后的assertion
assertion类型说明:
逗号前后不能添加空格
用户可以自定义assertion类,需要实现Baidu\Iov\DmKit\Policy\Output\Assertion\AssertionInterface接口,并实现assert函数。type中传递assertion类名即可。
result
result定于了dm-kit返回的数据,可以为object或者string
-
为object时,需要包含type和value字段
-
为string时,需要是函数名,函数需要定义在bot类中,dm-kit会调用该函数,输出函数返回结果
高级用法
dm-kit包含ConfLoader,Logger,Parser,Session几个组件,每种组件都做出了简单实现,可以直接使用,如果有个性化需求,可以自定义组件
ConfLoader
配置文件载入组件,用来载入配置文件,目前支持json和yaml格式文件。 可配置cache模块,需要实现CacheInterface接口,可以将配置文件读入缓存,避免大量磁盘I/O
$loader = ['loader' => [ 'type' => 'json', //json或者yaml, 'cache_class' => '' //cache类名,如不需要cache可为空, ]]; $policyManager = PolicyManagerFactory::getInstance($botId, $confPath, $loader);
Logger
使用monolog,详情见https://github.com/Seldaek/monolog
-
handler名称及映射关系:
-
stream handler示例:
#输出到std logger: handler: stream args: ["php://stderr", "critical"] #输出到文件 logger: handler: stream args: ["/tmp/monolog.log", "critical"]
Parser
将语义解析结果转为QuResult对象,目前支持Unit bot api和unit hub api, 可以实现ParserInterface接口自定义Parser
Session
储存state和context,仅支持文件方式存储,只能用于单台构架系统, 可以实现AbstractSession自定义Session。