Фреймворк для разработки приложений чат-ботов.
Убедитесь, что у вас установлены node и npm. На данный момент этот модуль был протестирован на версии узла 0.12 в конвейере Travis CI.
Просто запустите команду 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
или how are you doing
, а также how is it going
но распознавать help
по теме, когда текст выглядит так: how can you help
или i need some help
а также how can you assist me
. Вот как вы будете обучать бота.
Метод trainAll
принимает массив объектов TrainingDocument
, а также функцию обратного вызова. Конструктор объекта TrainingDocument
принимает два параметра. Это topicName
и trainingData
. Параметр topicName
— это название темы, для которой вы хотите обучить trainingData
, а trainingData
— это предложение, которое вы передаете боту в качестве обучающих данных. topicName
позже будет сопоставлено с реальными навыками, на которые бот может ответить.
Обратный вызов метода trainAll
— это функция, которую бот может вызвать после завершения обучения. Если у вас слишком много обучающих данных, вам следует реализовать это правильно. В этом примере, поскольку обучающих данных не так много, мы передали пустую function
.
Излишне говорить, что бот становится лучше с большим количеством обучающих данных. В этом уроке мы используем классификатор по умолчанию, которым в настоящее время является классификатор LogisticRegression
из библиотеки talkify-natural-classifier. Для начала этому классификатору обычно требуется немного больше обучающих данных, но в большинстве условий он более точен, чем другие.
После того, как вы обучили бота некоторым темам, вам нужно добавить некоторые навыки. Навыки — это действия, которые бот выполнит, когда распознает тему. Таким образом, темы и навыки соотносятся 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
является классификатором по умолчанию. Если вы предпочитаете реализовать BayesClassifier
из talkify-natural-classifier
, вы можете сделать следующее:
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
} ) ;
Ядро бота создаст экземпляр вашего объекта стратегии разрешения навыков при инициализации и будет использовать его как один экземпляр во всех разрешениях.
Чтобы обеспечить собственную реализацию стратегии разрешения тем, просто передайте определение функции в объект конфигурации следующим образом:
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
. Пока эти методы предоставлены, боту все равно, откуда берется значение поля 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 | +---> +--------------+
+------------+
Стратегия разрешения тем позволяет вам подключить пользовательскую логику для решения темы с учетом данных классификации. При подключении собственной стратегии разрешения тем ядро бота ожидает передачи определения функции вместо результата ее выполнения. Это связано с тем, что объект стратегии разрешения темы создается с использованием new
для каждого вызова метода resolve
.
Процесс разрешения темы состоит из двух частей:
Первым этапом процесса решения темы является этап сбора. Здесь ядро бота отправляет классификацию для каждого набора классификаций, возвращаемого классификатором, вместе с любым необходимым контекстом. Ядро бота также передает функцию обратного вызова, которую необходимо вызвать, чтобы сообщить ядру бота об успешном вызове.
+------------------+ +
| Classification | |
+------------------+ |
| +-----------+
+--------> Collect |
| +-----------+
+-----------+ |
| Context | |
+-----------+ +
Второй этап – этап разрешения. Здесь ядро бота ожидает возврата списка классификаций. Разрешение вызывается только после завершения выполнения всех коллекций.
+-----------+ +---------+-+-+
| Resolve +---->+ Topic | | |
+-----------+ +---------+ | |
|-----------+ |
+-------------+
Объект стратегии разрешения тем должен предоставлять два метода:
Метод сбора вызывается каждый раз, когда классификатор возвращает классификацию(и). Он вызывается с classification, context, callback
. Объект classification
содержит классификацию, возвращаемую классификатором (или набором классификаторов при использовании кворумов). Объект context
— это объект, содержащий контекст запроса. Последний callback
параметра — это функция, которую необходимо вызвать, чтобы сообщить ядру бота о том, что вы завершили сбор переданных параметров.
Метод разрешения вызывается один раз после того, как ядро бота завершает вызов метода collect
по вашей стратегии разрешения темы. Это последний вызов ядра бота, предназначенный для сбора информации о разрешении темы. Метод resolve
вызывается с параметром callback
. Это функция обратного вызова, которую необходимо вызвать с error, topics
. Параметр error должен быть определен как объект ошибки на случай, если при разрешении темы произошла ошибка. В любом другом случае этот объект должен быть undefined
. Второй параметр topics
должен представлять собой массив тем, разрешенных стратегией разрешения.
Более подробную информацию можно найти в руководстве по участию.