Advertisement
Guest User

Untitled

a guest
Jun 16th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.88 KB | None | 0 0
  1. Here are notes from building a proof of concept around integrating Watson Retrieve and Rank service into an Alexa skill. I'm still learning, so this may not be the best way to do it. This is simply an approach that worked for me. I'm hoping this overview will illustrate how simple it can be to leverage these two complicated sounding platforms together. If I can sort it out, surely someone as clever as yourself can too.
  2.  
  3. ## Retrieve and Rank
  4. You can sign up for a free bluemix account. I'm not sure the terms or pricing as I used credentials provided by work. You can definitely kick the tires for free, but I'm not sure how far you can get with that. The underlying technology is really impressive, but the web interface and general user experience need some love.
  5.  
  6. ### Create a Cluster
  7.  
  8. This dubiously named step fires up a solr instance to which you'll upload documents. You can upload a variety of formats to the `Documents` tab that will be used as source material to answer questions. By default, html documents are broken up into something called "Answer Units" based on the placement of Header tags. So, if you have non-semantic html, your milage will vary. Also, the more content you have between header tags, the more verbose your answer will be. You probably want your answer to be fairly terse since they will ultimately be consumbed via a robotic voice.
  9.  
  10. In the `Questions` tab you can upload a plain text list of training questions. After some questions have been uploaded, this tab will also be used to pair questions with relavant "Answer Units" in the uploaded documents. As I understand it, before training, you get solr responses. Then, you rate the answers on a 4 star rating which adds some meta data to enhance the search results.
  11.  
  12. ## Simple node.js cli
  13.  
  14. Now that my data was trained, I wanted to test it in the simplest way possible. So I built a tiny node.js app to hit the service from my command line. IBM released a node module that enabled me to do this in about 20 lines of code.
  15.  
  16. ```
  17. var RetrieveAndRankV1 = require('watson-developer-cloud/retrieve-and-rank/v1');
  18. var retrieve = new RetrieveAndRankV1({
  19. username: '',
  20. password: '',
  21. });
  22. var solrClient = retrieve.createSolrClient({
  23. cluster_id: '',
  24. collection_name: ''
  25. });
  26. // search all documents
  27. var query = solrClient.createQuery();
  28. query.q(process.argv[2]);
  29. solrClient.search(query, function(err, searchResponse) {
  30. if(err) {
  31. console.log('Error searching for documents: ' + err);
  32. } else {
  33. console.log("The best answer I have to: ", process.argv[2]);
  34. console.log(JSON.stringify(searchResponse.response.docs[0].body, null, 2));
  35. }
  36. });
  37. ```
  38. With that I could fire off requests via `node index.js "How many cups of sugar does it take to get to the moon?"` and Watson's answers would print to the command line.
  39.  
  40. ## Alexa Skill
  41.  
  42. Armed with the ego boost of a successful HelloWorld, I converted that cli into a module like so:
  43.  
  44. ```
  45. var RetrieveAndRankV1 = require('watson-developer-cloud/retrieve-and-rank/v1');
  46.  
  47. var retrieve = new RetrieveAndRankV1({
  48. username: '',
  49. password: '',
  50. });
  51.  
  52. var solrClient = retrieve.createSolrClient({
  53. cluster_id: '',
  54. collection_name: ''
  55. });
  56. function watsonHelper() {
  57. }
  58. watsonHelper.prototype.query = function(question) {
  59. // search all documents
  60. var query = solrClient.createQuery();
  61. query.q(question);
  62. solrClient.search(query, function(err, searchResponse) {
  63. if(err) {
  64. console.log('Error searching for documents: ' + err);
  65. return '';
  66. } else {
  67. console.log(JSON.stringify(searchResponse.response.docs[0].body, null, 2));
  68. }
  69. }).then(function(){
  70. return JSON.stringify(searchResponse.response.docs[0].body, null, 2);
  71. });
  72. };
  73. module.exports = watsonHelper;
  74. ```
  75. I then required that helper in an alexa app heavily based on based on a template app provided by Alexa.
  76.  
  77. ```
  78. 'use strict';
  79. var _ = require('lodash');
  80. var Alexa = require('alexa-app');
  81. var app = new Alexa.app('NameOfYourSkill');
  82. var WatsonHelper = require('./watson_helper');
  83.  
  84. app.launch(function(req, res) {
  85. var prompt = 'Ask me questions, I'll answer them from the Cloud.';
  86. res.say(prompt).reprompt(prompt).shouldEndSession(false);
  87. });
  88.  
  89. app.intent('askQuestion', {
  90. 'slots': {
  91. 'QUESTION': 'QUESTION_LIST'
  92. },
  93. 'utterances': ['{QUESTION}']
  94. },
  95. function(req, res) {
  96. //get the slot
  97. var question = req.slot('QUESTION');
  98. var reprompt = 'Sorry, not an instant win! Please try again.';
  99.  
  100. if (_.isEmpty(question)) {
  101. var prompt = 'I didn\'t hear a question that I know. Please ask differently.';
  102. res.say(prompt).reprompt(reprompt).shouldEndSession(false);
  103. return true;
  104. } else {
  105. var watsonHelper = new WatsonHelper();
  106. var answer = watsonHelper.query(question);
  107. res.say(answer).send();
  108. }
  109. });
  110.  
  111. //hack to support custom utterances in utterance expansion string
  112. console.log(app.utterances().replace(/\{\-\|/g, '{'));
  113. module.exports = app;
  114. ```
  115.  
  116. I uploaded that to lambda and went throught the alexa config wizards and all was well.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement