用于开发聊天机器人应用程序的框架。
确保您已安装 Node 和 npm。截至目前,该模块已在 Travis CI 管道中针对 0.12 节点版本进行了测试。
只需运行npm install
命令即可安装:
npm install --save talkify
需要主模块、类型和依赖项。以下命令从模块加载您需要的所有内容。
// Core dependency
const talkify = require ( 'talkify' ) ;
const Bot = talkify . Bot ;
// Types dependencies
const BotTypes = talkify . BotTypes ;
const Message = BotTypes . Message ;
const SingleLineMessage = BotTypes . SingleLineMessage ;
const MultiLineMessage = BotTypes . MultiLineMessage ;
// Skills dependencies
const Skill = BotTypes . Skill ;
// Training dependencies
const TrainingDocument = BotTypes . TrainingDocument ;
加载依赖项后,您可以初始化机器人核心。
const bot = new Bot ( ) ;
Bot()
构造函数还接受配置对象形式的参数。在这里,您可以传入配置开关值或ContextStore
和Classifier
等的替代实现。稍后我们将在“配置选项”部分中介绍这一点。
机器人初始化后,您应该做的第一件事就是训练它。要一次同步训练一个文档,可以使用train
方法:
bot . trainAll ( [
new TrainingDocument ( 'how_are_you' , 'how are you' ) ,
new TrainingDocument ( 'how_are_you' , 'how are you going' ) ,
new TrainingDocument ( 'how_are_you' , 'how is it going' ) ,
new TrainingDocument ( 'help' , 'how can you help' ) ,
new TrainingDocument ( 'help' , 'i need some help' ) ,
new TrainingDocument ( 'help' , 'how could you assist me' )
] , function ( ) { } ) ;
上面的代码训练机器人在文本看起来像how are you
或how are you doing
以及how is it going
时识别主题how_are_you
,但在文本看起来像how can you help
或i need some help
”时识别主题“ help
以及how can you assist me
。这就是训练机器人的方式。
trainAll
方法接受TrainingDocument
对象数组以及回调函数。 TrainingDocument
对象构造函数接受两个参数。它们是topicName
和trainingData
。 topicName
参数是您要为其训练trainingData
主题的名称, trainingData
是您将其作为训练数据提供给机器人的句子。 topicName
稍后将映射到机器人可以响应的实际技能。
trainAll
方法的回调是机器人在训练完成时可以调用的函数。如果你的训练数据太多,你应该正确实施。在这个例子中,由于没有太多训练数据,我们传入了一个空function
。
不用说,随着更多的训练数据,机器人会变得更好。在本教程中,我们使用默认分类器,目前是 talkify-natural-classifier 库中的LogisticRegression
分类器。该分类器通常需要更多的训练数据来开始,但在大多数情况下比其他分类器更准确。
一旦您针对某些主题训练了机器人,您就需要添加一些技能。技能是机器人识别主题时将执行的操作。所以主题和技能是 1:1 对应的。
要添加技能,您需要先创建它。一项技能需要三件事。机器人独有的技能名称。该名称用于稍后在上下文中关联技能。它映射到的主题以及机器人将调用以执行技能的函数。该函数将采用四个参数,即: context, request, response, next
。 context
参数用于存储该技能的任何有用的上下文信息。 request
参数包含有关请求的信息, response
也相同。 next
参数是一个函数,您可以调用该函数让机器人知道您已完成处理。技能如下所示:
var howAction = function ( context , request , response , next ) {
response . message = new SingleLineMessage ( 'You asked: "' + request . message . content + '". I'm doing well. Thanks for asking.' ) ;
next ( ) ;
} ;
var helpAction = function ( context , request , response , next ) {
response . message = new SingleLineMessage ( 'You asked: "' + request . message . content + '". I can tell you how I'm doing if you ask nicely.' ) ;
next ( ) ;
} ;
var howSkill = new Skill ( 'how_skill' , 'how_are_you' , howAction ) ;
var helpSkill = new Skill ( 'help_skill' , 'help' , helpAction ) ;
注意:技能名称可以是未定义的。但是,请注意,这样做意味着机器人在响应给定查询的置信度为 0 时就会执行该技能。
定义了一些技能后,您需要将它们添加到机器人中。将技能添加到机器人中,如下所示:
bot . addSkill ( howSkill ) ;
bot . addSkill ( helpSkill ) ;
添加后,您现在可以要求机器人解决某些问题。这是您用句子查询机器人的地方,它将异步响应一条消息。解析函数接受三个参数: contextId, text, callback
。 contextId
帮助机器人解析之前任何对话的上下文。 text
是机器人需要解释和响应的问题或自然语言字符串。最后, callback
是机器人将使用err, messages
参数调用的回调函数,以指示错误(如果有)及其回复消息。
var resolved = function ( err , messages ) {
if ( err ) return console . error ( err ) ;
return console . log ( messages ) ;
} ;
bot . resolve ( 123 , 'Assistance required' , resolved ) ;
像简单的节点文件一样运行它,它应该在控制台中打印以下内容。
[ { type: 'SingleLine',
content: 'You asked: "Assistance required". I can tell you how I'm doing if you ask nicely.' } ]
尝试将bot.resolve
更改为此并注意响应的变化。
bot . resolve ( 456 , 'How's it going?' , resolved ) ;
让我们同时问两件事。再次将bot.resolve
更改为:
bot . resolve ( 456 , 'How's it going? Assistance required please.' , resolved ) ;
当您运行代码时,您应该收到两条消息:
[ { type : 'SingleLine' ,
content : 'You asked: "How's it going? Assistance required please.". I'm doing well. Thanks for asking.' } ,
{ type : 'SingleLine' ,
content : 'You asked: "How's it going? Assistance required please.". I can tell you how I'm doing if you ask nicely.' } ]
目前train
、 addSkill
和resolve
方法是可链接的。这意味着您可以创建 Bot 对象和级联方法,如下所述。
new Bot ( ) . train ( topic , sentence ) . addSkill ( skill ) . resolve ( ... . )
机器人核心还接受内置上下文存储的替代实现。有关更多详细信息,请参阅上下文管理。
您还可以向机器人提供您自己版本的分类器。此选项主要用于使测试更容易,但是,如果您有更好版本的内置分类器,它仍然可以在生产中使用。
内置分类器是 talkify-natural-classifier。该分类器提供了两种实现方式:
LogisticRegressionClassifier
BayesClassifier
LogisticRegressionClassifier
是默认分类器。如果您更喜欢从talkify-natural-classifier
实现BayesClassifier
,您可以执行以下操作:
var BayesClassifier = require ( 'talkify-natural-classifier' ) . BayesClassifier ;
var bot = new Bot ( { classifier : new BayesClassifier ( ) } ) ;
如果您更喜欢使用 IBM Watson 的自然语言处理分类器,则应该使用 talkify-watson-classifier 库。请参阅 Github 存储库页面上的指南,了解有关如何使用该分类器的更多详细信息。
如果您认为您的效果更好,请给我留言!我很高兴知道并可能致力于在核心模块中实现它。
要提供您自己的技能解决策略实现,只需在配置对象中传递函数定义,如下所示:
var mySkillResolutionStrategy = function ( ) {
this . addSkill = function ( skill , options ) { ... } ;
this . getSkills = function ( ) { ... } ;
this . resolve = function ( err , resolutionContext , callback ) {
...
} ;
return this ;
} ;
var bot = new Bot ( {
skillResolutionStrategy : mySkillResolutionStrategy
} ) ;
机器人核心将在 init 上创建技能解析策略对象的实例,并将其用作所有解析的单个实例。
要提供您自己的主题解析策略实现,只需在配置对象中传递函数定义,如下所示:
var myTopicResolutionStrategy = function ( ) {
this . collect = function ( classification , classificationContext , callback ) { callback ( ) } ;
this . resolve = function ( callback ) { callback ( [ { name : "topic_name" , confidence : 0.5 ] ) } ;
return this ;
} ;
var bot = new Bot ( {
topicResolutionStrategy : myTopicResolutionStrategy
} ) ;
机器人核心将为它收到的解析方法的每个调用创建一个主题解析策略的新实例。
默认情况下,机器人核心使用其内置版本的 ContextStore。如果您查看 lib/ContextStore.js,您会发现这是一个非常简单的实现,其中上下文存储在一个简单的内存映射中,其中contextId
是键,上下文对象是值。当然,当您部署它时,内置上下文存储将非常有限。
扩展上下文存储非常容易。在配置中,您可以为 ContextStore 对象提供您自己的实现。以下代码提供了一个非常简单的实现,只需将值记录到控制台。
var myContextStore = {
put : function ( id , context , callback ) {
console . info ( 'put' ) ;
console . info ( id ) ;
console . info ( context ) ;
} ,
get : function ( id , callback ) {
console . info ( 'get' ) ;
console . info ( id ) ;
} ,
remove : function ( id , callback ) {
console . info ( 'remove' ) ;
console . info ( id ) ;
}
}
var bot = new Bot ( { contextStore : myContextStore } ) ;
ContextStore
的当前规范需要实现三个函数。这些是put, get and remove
。只要提供了这些方法,机器人就不会关心 config 中contextStore
字段的值来自哪里。
如果您要运行带有某些查询解析的代码,您会发现删除函数永远不会被调用。这是一项正在进行的工作,因为目前对于必须记住上下文的时间没有限制。
如前所述,机器人使用的默认分类器来自 talkify-natural-classifier 库。您可以自由编写自己的分类器并在您的应用程序中使用它。为此,您需要扩展 talkify-classifier 库中定义的分类器接口。
成功扩展该实现后,您可以向机器人提供分类器,如下所示:
var myClassifier = new MyAwesomeClassifier ( ) ;
var bot = new Bot ( { classifier : myClassifier } ) ;
我很想看看您对 talkify 分类器的实现。如果您扩展了接口并成功实现了分类器,请给我留言!我很高兴了解您使用该库的体验。
从版本 2.1.0 开始,您可以为机器人指定多个分类器。有关更多信息,请参阅有关分类器的文档。
技能解析策略是能够在给定解析上下文的情况下输出技能的组件。解决上下文是由主题列表和原始句子组成的对象,是解决技能所需的基本要素。
+-------------+
| Topic | | |
+---------+ | +----> +--------------+
|-----------+ | | |
+-------------+ | Skill | +---------+
| Resolution +----> | Skill |
| Strategy | +---------+
+------------+ | |
| Sentence | +---> +--------------+
+------------+
主题解析策略允许您插入自定义逻辑来解析给定分类数据的主题。当插入自定义主题解析策略时,机器人核心期望传入函数定义而不是函数执行结果。这是因为主题解析策略对象是在每次调用resolve
方法时使用new
构造的。
主题解析的过程分为两部分:
主题解析过程的第一阶段是收集阶段。在这里,机器人核心发送从分类器返回的每个分类集的分类以及任何所需的上下文。机器人核心还传入一个回调函数,需要调用该函数才能让机器人核心知道调用成功。
+------------------+ +
| Classification | |
+------------------+ |
| +-----------+
+--------> Collect |
| +-----------+
+-----------+ |
| Context | |
+-----------+ +
第二阶段是解决阶段。在这里,机器人核心期望返回一个分类列表。仅当所有集合执行完毕后才会调用该决议。
+-----------+ +---------+-+-+
| Resolve +---->+ Topic | | |
+-----------+ +---------+ | |
|-----------+ |
+-------------+
主题解析策略对象必须公开两个方法:
每当分类器返回分类时都会调用收集方法。它是通过classification, context, callback
签名来调用的。 classification
对象包含从分类器(或一组分类器,如果使用仲裁)返回的分类。 context
对象是包含请求上下文的对象。最后一个参数callback
是必须调用的函数,以使机器人核心知道您已完成收集传入参数。
在机器人核心完成对主题解析策略的collect
调用后,将调用一次解析方法。这是机器人核心的最终调用,旨在收集主题解析信息。使用callback
参数调用resolve
方法。这是必须使用两个参数error, topics
调用的回调函数。 error 参数必须定义为错误对象,以防解析主题时发生错误。在任何其他情况下,该对象必须是undefined
。第二个topics
参数必须是由解析策略解析的主题数组。
请参阅贡献指南了解更多详细信息。