Framework para desenvolvimento de aplicativos de chat bot.
Certifique-se de ter o node e o npm instalados. A partir de agora, este módulo foi testado na versão 0.12 do nó dentro do pipeline Travis CI.
Basta executar o comando npm install
para instalar:
npm install --save talkify
Exigir o módulo principal, tipos e dependências. O comando a seguir carrega tudo o que você precisa do módulo.
// 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 ;
Depois que as dependências forem carregadas, você poderá inicializar o núcleo do bot.
const bot = new Bot ( ) ;
O construtor Bot()
também aceita parâmetros na forma de objeto de configuração. Aqui você pode passar valores de chave de configuração ou implementações alternativas para coisas como ContextStore
e Classifier
etc. Abordaremos isso posteriormente na seção Opções de configuração.
Depois que o Bot for inicializado, a primeira coisa que você deve fazer é treiná-lo. Para treinar um documento por vez de forma síncrona, você pode usar o método 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 ( ) { } ) ;
O código acima treina o bot para reconhecer o tópico how_are_you
quando o texto se parece com how are you
ou how are you doing
bem como how is it going
, mas para reconhecer help
do tópico quando o texto se parece com how can you help
ou i need some help
bem como how can you assist me
. É assim que você treinaria o bot.
O método trainAll
aceita uma matriz de objetos TrainingDocument
bem como uma função de retorno de chamada. O construtor do objeto TrainingDocument
aceita dois parâmetros. Estes são topicName
e trainingData
. O parâmetro topicName
é o nome do tópico para o qual você deseja treinar o trainingData
e o trainingData
é a frase que você está alimentando o bot como seus dados de treinamento. O topicName
será posteriormente mapeado para habilidades reais às quais o bot pode responder.
O retorno de chamada do método trainAll
é uma função que o bot pode chamar quando o treinamento for concluído. Se você tiver muitos dados de treinamento, deverá implementar isso corretamente. Neste exemplo, como não há muitos dados de treinamento, passamos uma function
vazia.
Escusado será dizer que o bot fica melhor com mais dados de treinamento. Neste tutorial estamos usando o classificador padrão, que atualmente é o classificador LogisticRegression
da biblioteca talkify-natural-classifier. Esse classificador normalmente precisa de um pouco mais de dados de treinamento para começar, mas é mais preciso do que outros na maioria das condições.
Depois de treinar o bot para alguns tópicos, você precisa adicionar algumas habilidades. Habilidades são ações que o bot executará ao reconhecer um tópico. Portanto, os tópicos e as habilidades são mapeados para 1:1.
Para adicionar uma habilidade, você precisa criá-la primeiro. Uma habilidade requer três coisas. Nome da habilidade exclusiva do bot. O nome é usado para relacionar habilidades posteriormente dentro do contexto. Um tópico para o qual ele mapeia e uma função que o bot chamará para executar a habilidade. Esta função terá quatro parâmetros, a saber: context, request, response, next
. O parâmetro context
é usado para armazenar qualquer informação contextual útil dessa habilidade. O parâmetro request
contém informações sobre a solicitação, o mesmo para response
. O next
parâmetro é uma função que você pode chamar para informar ao bot que o processamento foi concluído. Esta é a aparência de uma habilidade:
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 ) ;
Nota: O nome de uma habilidade pode ser indefinido. No entanto, esteja ciente de que isso significará que o bot executará essa habilidade sempre que seu nível de confiança for 0 para responder a uma determinada consulta.
Depois de definir algumas habilidades, você precisa adicioná-las ao bot. Adicione a habilidade ao bot assim:
bot . addSkill ( howSkill ) ;
bot . addSkill ( helpSkill ) ;
Uma vez adicionado, agora você pode pedir ao bot para resolver alguma coisa. É aqui que você consulta o bot com uma frase e ele responderá com uma mensagem de forma assíncrona. A função resolve recebe três parâmetros: contextId, text, callback
. O contextId
ajuda o bot a resolver o contexto de qualquer conversa anterior. O text
é a pergunta ou trecho de linguagem natural que o bot precisa interpretar e responder. Por último, o callback
é a função de retorno de chamada que o bot chamará com err, messages
para indicar um erro (se houver) e suas mensagens de resposta.
var resolved = function ( err , messages ) {
if ( err ) return console . error ( err ) ;
return console . log ( messages ) ;
} ;
bot . resolve ( 123 , 'Assistance required' , resolved ) ;
Execute-o como um arquivo de nó simples e ele deverá imprimir o seguinte no console.
[ { type: 'SingleLine',
content: 'You asked: "Assistance required". I can tell you how I'm doing if you ask nicely.' } ]
Tente alterar bot.resolve
para isso e observe a mudança na resposta.
bot . resolve ( 456 , 'How's it going?' , resolved ) ;
Vamos perguntar duas coisas ao mesmo tempo. Altere bot.resolve
novamente para:
bot . resolve ( 456 , 'How's it going? Assistance required please.' , resolved ) ;
Ao executar seu código, você deverá receber duas mensagens de volta:
[ { 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.' } ]
Atualmente os métodos train
, addSkill
e resolve
são encadeados. Isso significa que você pode criar objetos Bot e métodos em cascata como mencionado abaixo.
new Bot ( ) . train ( topic , sentence ) . addSkill ( skill ) . resolve ( ... . )
O núcleo do bot também aceita uma implementação alternativa para o armazenamento de contexto integrado. Consulte Gerenciamento de contexto para obter mais detalhes.
Você também pode fornecer sua própria versão do classificador ao bot. Esta opção foi usada principalmente para facilitar os testes, no entanto, ela ainda pode ser usada na produção se você tiver uma versão melhor do classificador integrado.
O classificador integrado é o classificador talkify-natural. Este classificador fornece duas implementações:
LogisticRegressionClassifier
BayesClassifier
O LogisticRegressionClassifier
é o classificador padrão. Se preferir implementar o BayesClassifier
de talkify-natural-classifier
, você pode fazer o seguinte:
var BayesClassifier = require ( 'talkify-natural-classifier' ) . BayesClassifier ;
var bot = new Bot ( { classifier : new BayesClassifier ( ) } ) ;
Se preferir usar o Natural Language Processing Classifier do IBM Watson, você deverá usar a biblioteca talkify-watson-classifier. Consulte o guia na página do repositório do Github para obter mais detalhes sobre como usar esse classificador.
Se você acha que o seu funciona melhor, me avise! Eu ficaria muito feliz em saber e possivelmente trabalhar para implementá-lo no módulo principal.
Para fornecer sua própria implementação da Estratégia de Resolução de Habilidades, basta passar a definição da função no objeto de configuração da seguinte maneira:
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
} ) ;
O núcleo do bot criará uma instância do seu objeto de estratégia de resolução de habilidades no init e o usará como instância única em todas as resoluções.
Para fornecer sua própria implementação da Estratégia de Resolução de Tópicos, basta passar a definição da função no objeto de configuração da seguinte forma:
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
} ) ;
O núcleo do bot criará uma nova instância de sua estratégia de resolução de tópicos para cada chamada recebida no método de resolução.
Por padrão, o núcleo do bot usa sua versão integrada do ContextStore. Se você examinar lib/ContextStore.js, descobrirá que é uma implementação muito simples, onde o contexto é armazenado em um mapa simples na memória, com contextId
sendo a chave e o objeto de contexto sendo o valor. É claro que quando você implantar isso, o armazenamento de contexto integrado será muito limitante.
Estender o armazenamento de contexto é muito fácil. Dentro da configuração, você pode fornecer sua própria implementação para o objeto ContextStore. O código a seguir fornece uma implementação muito trivial que simplesmente registra os valores no console.
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 } ) ;
A especificação atual do ContextStore
requer a implementação de três funções. Estes são put, get and remove
. Contanto que esses métodos sejam fornecidos, o bot não se importa de onde vem o valor do campo contextStore
na configuração.
Se você executar esse código com alguma resolução de consulta, descobrirá que a função remove nunca será chamada. Este é um trabalho em andamento, pois atualmente não há limite de quanto tempo um contexto deve ser lembrado.
Como mencionado antes, o classificador padrão usado pelo bot é da biblioteca talkify-natural-classifier. Você é livre para escrever seu próprio classificador e usá-lo em sua aplicação. Para fazer isso, você precisa estender a interface do classificador definida na biblioteca talkify-classifier.
Depois de estender essa implementação com sucesso, você pode fornecer seu classificador ao bot da seguinte forma:
var myClassifier = new MyAwesomeClassifier ( ) ;
var bot = new Bot ( { classifier : myClassifier } ) ;
Eu adoraria ver sua implementação do classificador talkify. Se você estendeu a interface e implementou seu classificador com sucesso, avise-me! Ficarei muito feliz em saber sua experiência usando esta biblioteca.
Desde a versão 2.1.0, você pode especificar vários classificadores para o seu bot. Consulte a documentação sobre classificador para obter mais informações.
Uma estratégia de resolução de habilidades é um componente capaz de produzir uma habilidade, dado um contexto de resolução. Um contexto de resolução é um objeto composto por uma lista de tópicos e a frase original, ingredientes essenciais necessários para resolver uma habilidade.
+-------------+
| Topic | | |
+---------+ | +----> +--------------+
|-----------+ | | |
+-------------+ | Skill | +---------+
| Resolution +----> | Skill |
| Strategy | +---------+
+------------+ | |
| Sentence | +---> +--------------+
+------------+
Uma estratégia de resolução de tópicos permite conectar uma lógica personalizada para resolver um tópico, com base nos dados de classificação. Ao conectar uma estratégia de resolução de tópico personalizada, o núcleo do bot espera que a definição da função seja transmitida em vez do resultado da execução da função. Isso ocorre porque o objeto de estratégia de resolução de tópicos é construído usando o método new
for each call to resolve
.
O processo de resolução de tópicos funciona em duas partes:
A primeira etapa do processo de resolução do tópico é a fase de coleta. Aqui, o núcleo do bot envia a classificação para cada conjunto de classificação retornado do classificador junto com qualquer contexto necessário. O núcleo do bot também passa uma função de retorno de chamada que deve ser invocada para que o núcleo do bot saiba que a invocação foi bem-sucedida.
+------------------+ +
| Classification | |
+------------------+ |
| +-----------+
+--------> Collect |
| +-----------+
+-----------+ |
| Context | |
+-----------+ +
A segunda etapa é a fase de resolução. Aqui, o núcleo do bot espera que uma lista de classificações seja retornada. A resolução é chamada somente após a execução de todas as coleções.
+-----------+ +---------+-+-+
| Resolve +---->+ Topic | | |
+-----------+ +---------+ | |
|-----------+ |
+-------------+
Um objeto de estratégia de resolução de tópicos deve expor dois métodos:
O método collect é chamado sempre que um classificador retorna classificações. É chamado com classification, context, callback
. O objeto classification
contém a classificação retornada do classificador (ou conjunto de classificadores se estiver usando quóruns). O objeto context
é o objeto que contém o contexto da solicitação. O último callback
de parâmetro é a função que deve ser invocada para informar ao núcleo do bot que você concluiu a coleta dos parâmetros passados.
O método resolve é chamado uma vez depois que o núcleo do bot termina de chamar collect
em sua estratégia de resolução de tópico. Esta é a chamada final do núcleo do bot e tem como objetivo coletar informações de resolução de tópicos. O método resolve
é chamado com um parâmetro callback
. Esta é a função de retorno de chamada que deve ser chamada com error, topics
. O parâmetro error deve ser definido como um objeto de erro caso tenha ocorrido algum erro na resolução do tópico. Em qualquer outro caso, este objeto deve ser undefined
. O segundo parâmetro topics
deve ser uma matriz de tópicos resolvidos pela estratégia de resolução.
Consulte o guia de contribuição para obter mais detalhes.