Basit Anwer commited on
Commit
d288445
1 Parent(s): 64a5bab

Reviewed code.

Browse files
Files changed (12) hide show
  1. .gitignore +4 -0
  2. .gitignore/.gitignore +0 -2
  3. README +0 -39
  4. README.md +159 -0
  5. actions/actions.py +24 -56
  6. config.yml +0 -3
  7. data/nlu.yml +0 -6
  8. data/rules.yml +0 -5
  9. domain.yml +0 -4
  10. requirements.txt +2 -1
  11. server.py +0 -13
  12. tests/test_stories.yml +9 -74
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ *.tar.gz
2
+ *.pyc
3
+ results/
4
+ models/
.gitignore/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- *.tar.gz
2
- *.pyc
 
 
 
README DELETED
@@ -1,39 +0,0 @@
1
- # Readme
2
-
3
- The source code in this repository shows a simple rasa chatbot fallback mechanism, which can get relavent information from Zir-AI search platform.
4
-
5
- ## Data
6
-
7
- reviews.db contains the hotel reviews, its generated by using repo https://github.com/amin3141/zir-souffle
8
-
9
- # How-to
10
-
11
- First you need to have the rasa shell installed. You can do that by following the rasa tutorials https://rasa.com/docs/rasa/installation
12
-
13
- Next is training the model
14
-
15
- ```
16
- rasa train
17
- ```
18
-
19
- Then to run in one terminal you need to run
20
-
21
- ```
22
- rasa run --credentials ./credentials.yml --enable-api --auth-token XYZ123 --model ./models --endpoints ./endpoints.yml --cors "*"
23
- ```
24
-
25
- And in the background or in another terminal run
26
-
27
- ```
28
- rasa run actions
29
- ```
30
-
31
- Lastly, to view the bot in the UI either simply load the `www/index.html` file in the browser or run `python3 server.py` and open `localhost:8080` in browser.
32
-
33
- You could also just run the two commands and talk with the bot in shell
34
-
35
- ```
36
- rasa run actions &
37
- rasa shell
38
- ```
39
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--lint disable no-literal-urls-->
2
+ <p align="center">
3
+ <a href="https://zir-ai.com/">
4
+ <img
5
+ alt="Zir AI"
6
+ src="https://zir-ai.com/static/media/logo-light.637c616a.svg"
7
+ width="400"
8
+ />
9
+ </a>
10
+ </p>
11
+
12
+ # Readme
13
+
14
+ The source code in this repository shows a simple Rasa chatbot fallback
15
+ mechanism, which gets relevant information from ZIR Semantic Search.
16
+
17
+ # Table of contents
18
+
19
+ - [Rasa Bot & Zir](#why)
20
+ - [Setup & Play](#setup-play)
21
+ - [Set-up Rasa](#setup-rasa)
22
+ - [Set-up repo](#setup-demo)
23
+ - [Running the demo](#run-demo)
24
+ - [Customizing the bot](#bot-customization)
25
+ - [Data](#data)
26
+ - [Rasa Custom Action](#rasa-cust-action)
27
+
28
+ ## Rasa Bot & Zir
29
+
30
+ [Rasa](https://rasa.com/) is the leading conversational AI platform, for
31
+ personalized conversations at scale. Developers provide the questsions they
32
+ expect the end customer to ask and Rasa bot, using AI, predicts and matches the
33
+ what the customer intended to ask. With this information at hand, developers can
34
+ easily match what the bot should respond.
35
+
36
+ This is all well unless when the customer asks a valid question the developer
37
+ did not expect, for such a scenario Rasa provides a
38
+ [fallback mechanism](https://rasa.com/docs/rasa/fallback-handoff#fallbacks).
39
+
40
+ > Although Rasa will generalize to unseen messages, some messages might receive
41
+ > a low classification confidence. Using Fallbacks will help ensure that these
42
+ > low confidence messages are handled gracefully, giving your assistant the
43
+ > option to either respond with a default message or attempt to disambiguate the
44
+ > user input.
45
+
46
+ Using the mechanism the bot can ask fallback and search through the reviews
47
+ uploaded in [Zir-AI](https://zir-ai.com) with the help of
48
+ [custom actions](https://rasa.com/docs/rasa/custom-actions). If the reviews have
49
+ the relavent information, it is shown as a result otherwise if the confidence of
50
+ the question to review matching is low, we fallback to a generic statement.
51
+
52
+ The end results sums up to be this:
53
+
54
+ ## Setup & Play
55
+
56
+ You'll need to have Rasa installed and this repository. You might want to create
57
+ a [virtual environment](#https://docs.python.org/3/library/venv.html) to isolate
58
+ the dependencies rasa requires.
59
+
60
+ ### Set-up Rasa
61
+
62
+ Follow the
63
+ [rasa installation instrcutions](#https://rasa.com/docs/rasa/installation) or
64
+ copy paste the following commands in terminal
65
+
66
+ ```bash
67
+ pip3 install -U pip
68
+ pip3 install rasa
69
+ rasa --version
70
+ ```
71
+
72
+ This should print the rasa version similar to follow
73
+
74
+ ```bash
75
+ Rasa Version : 2.7.0
76
+ Minimum Compatible Version: 2.6.0
77
+ Rasa SDK Version : 2.7.0
78
+ Rasa X Version : None
79
+ Python Version : 3.8.5
80
+ Operating System : Linux
81
+ Python Path : /bin/python3
82
+ ```
83
+
84
+ > Windows & WSL works too
85
+
86
+ ### Set-up repo
87
+
88
+ To install dependecies for this repository to work install python dependencies
89
+ from requirements.txt
90
+
91
+ ```bash
92
+ pip install -r requirements.txt
93
+ python3 -m spacy download en_core_web_md
94
+ ```
95
+
96
+ This will install the spacy model `en_core_web_md` this bot is configured with.
97
+ Now you'll need to train the rasa bot
98
+
99
+ ```bash
100
+ rasa train
101
+ ```
102
+
103
+ ### Running the demo
104
+
105
+ While running the model, you are require to run the rasa action server along
106
+ with the rasa bot. So in one terminal run
107
+
108
+ ```bash
109
+ rasa run actions
110
+ ```
111
+
112
+ In another terminal you can either play with the bot in your `shell` or on the
113
+ browser.
114
+
115
+ To talk to the bot in shell run
116
+
117
+ ```bash
118
+ rasa shell
119
+ ```
120
+
121
+ Or to talk to the bot in the browser run
122
+
123
+ ```bash
124
+ rasa run --credentials ./credentials.yml --enable-api --auth-token XYZ123 --model ./models --endpoints ./endpoints.yml --cors "*"
125
+ ```
126
+
127
+ Now, open the `index.html` in your browser to talk to the bot.
128
+
129
+ ## Customizing the bot
130
+
131
+ Use the following information to customize the bot and the source of data.
132
+
133
+ ### Data
134
+
135
+ Data for the bot is sourced from [OpinRank](https://github.com/kavgan/OpinRank/)
136
+ and reviews for Hotel Jumeirah is specifically used for this bot. Reviews are
137
+ parsed from https://github.com/amin3141/zir-souffle. Use `hotels.py` to generate
138
+ the output `json` and the `reviews.db`.
139
+
140
+ Create a corpus on [Zir AI](http://zir-ai.com) and upload all the `json` files.
141
+ Create an api key for access and note down the following information
142
+
143
+ - Api key
144
+ - corpus id
145
+ - customer id
146
+
147
+ ## Rasa Custom Action
148
+
149
+ Use the above collected information and replace the information in
150
+ `actions/actions.py` and you're good to go.
151
+
152
+ ```python
153
+ customer_id = "1835841754"
154
+ corpus_id = 1
155
+ header = {
156
+ "customer-id": customer_id,
157
+ "x-api-key": "zqt_WvU_2atFHgqYxxT2sQswwIUgogI8K3QeWs0oqA"
158
+ }
159
+ ```
actions/actions.py CHANGED
@@ -1,31 +1,3 @@
1
- # This files contains your custom actions which can be used to run
2
- # custom Python code.
3
- #
4
- # See this guide on how to implement these action:
5
- # https://rasa.com/docs/rasa/custom-actions
6
-
7
-
8
- # This is a simple example for a custom action which utters "Hello World!"
9
-
10
- # from typing import Any, Text, Dict, List
11
- #
12
- # from rasa_sdk import Action, Tracker
13
- # from rasa_sdk.executor import CollectingDispatcher
14
- #
15
- #
16
- # class ActionHelloWorld(Action):
17
- #
18
- # def name(self) -> Text:
19
- # return "action_hello_world"
20
- #
21
- # def run(self, dispatcher: CollectingDispatcher,
22
- # tracker: Tracker,
23
- # domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
24
- #
25
- # dispatcher.utter_message(text="Hello World!")
26
- #
27
- # return []
28
-
29
  from typing import Any, Text, Dict, List
30
  import json
31
  import requests
@@ -37,10 +9,17 @@ from rasa_sdk import Action, Tracker
37
  from rasa_sdk.events import UserUtteranceReverted
38
  from rasa_sdk.executor import CollectingDispatcher
39
 
 
40
  class ActionDefaultFallback(Action):
41
  """Executes the fallback action and goes back to the previous state
42
  of the dialogue"""
43
 
 
 
 
 
 
 
44
  con = None
45
 
46
  def name(self) -> Text:
@@ -63,22 +42,19 @@ class ActionDefaultFallback(Action):
63
  "num_results": number_results,
64
  "corpus_key": [
65
  {
66
- "customer_id": "1526022105",
67
- "corpus_id": 40
68
  }
69
  ]
70
  }
71
  ]
72
  }
73
- header = {
74
- "customer-id": "1526022105",
75
- "x-api-key": "zqt_WvU_2atFHgqYxxT2sQswwIUgogI8K3QeWs0oqA"
76
- }
77
  payload = json.dumps(data_dict)
78
  response = requests.post(f"https://h.serving.zir-ai.io:443/v1/query",
79
  data=payload,
80
  verify=True,
81
- headers=header,
82
  timeout=10)
83
  parsed = json.loads(response.text)
84
  first_resp = parsed["responseSet"][0]["response"][0]
@@ -87,21 +63,22 @@ class ActionDefaultFallback(Action):
87
  print(last_resp["score"])
88
  print(first_resp["score"])
89
  if last_resp["score"] < 0.3 or first_resp["score"] < 0.3:
90
- textQuery.append("I'm sorry, I can't help you.")
 
91
  else:
92
  textQuery = print_responses(parsed["responseSet"][0], self.cur)
93
- # items = [d['text'] for d in parsed["responseSet"][0]["response"]]
94
- textQuery.insert(0, "\n" )
95
- textQuery.insert(0, "This is what i found in the reviews:" )
96
  textQuery = "\n".join(textQuery)
97
  dispatcher.utter_message(text=textQuery)
 
98
  # Revert user message which led to fallback.
99
  return [UserUtteranceReverted()]
100
 
101
 
102
  def print_responses(response_set, sqlite_cursor):
103
  """Print responses to the console."""
104
- textList = []
105
  for result in response_set["response"]:
106
  doc = response_set["document"][result["documentIndex"]]
107
  query = f"""
@@ -110,26 +87,17 @@ def print_responses(response_set, sqlite_cursor):
110
  """
111
  for row in sqlite_cursor.execute(query):
112
  title, date, hotel, fulltext = row
113
- textList.append("**" + title + "**")
114
  if is_title(result):
115
- textList.append(f"{head(fulltext)}")
116
  else:
117
  t = result["text"]
118
- textList.append(f"{highlight(fulltext, t)}")
119
- textList.append("*" + f"{hotel_name(hotel)} reviewed on {date}" + "*")
120
- textList.append("\n")
 
121
  break
122
- return textList
123
-
124
- def hotel_name(hotel):
125
- """Returns a human-readable name for a hotel."""
126
- if hotel == "sheraton_fisherman_s_wharf_hotel":
127
- return "Sheraton Fisherman's Wharf Hotel"
128
- if hotel == "the_westin_st_francis":
129
- return "The Westin St. Francis San Francisco on Union Square"
130
- if hotel == "best_western_tuscan_inn_fisherman_s_wharf_a_kimpton_hotel":
131
- return "Best Western Fishermans Wharf"
132
- return hotel
133
 
134
 
135
  def highlight(fulltext, snippet):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from typing import Any, Text, Dict, List
2
  import json
3
  import requests
 
9
  from rasa_sdk.events import UserUtteranceReverted
10
  from rasa_sdk.executor import CollectingDispatcher
11
 
12
+
13
  class ActionDefaultFallback(Action):
14
  """Executes the fallback action and goes back to the previous state
15
  of the dialogue"""
16
 
17
+ customer_id = "1835841754"
18
+ corpus_id = 1
19
+ header = {
20
+ "customer-id": customer_id,
21
+ "x-api-key": "zqt_WvU_2atFHgqYxxT2sQswwIUgogI8K3QeWs0oqA"
22
+ }
23
  con = None
24
 
25
  def name(self) -> Text:
 
42
  "num_results": number_results,
43
  "corpus_key": [
44
  {
45
+ "customer_id": self.customer_id,
46
+ "corpus_id": self.corpus_id
47
  }
48
  ]
49
  }
50
  ]
51
  }
52
+
 
 
 
53
  payload = json.dumps(data_dict)
54
  response = requests.post(f"https://h.serving.zir-ai.io:443/v1/query",
55
  data=payload,
56
  verify=True,
57
+ headers=self.header,
58
  timeout=10)
59
  parsed = json.loads(response.text)
60
  first_resp = parsed["responseSet"][0]["response"][0]
 
63
  print(last_resp["score"])
64
  print(first_resp["score"])
65
  if last_resp["score"] < 0.3 or first_resp["score"] < 0.3:
66
+ textQuery.append(
67
+ "I'm sorry, I don't have any information about that.")
68
  else:
69
  textQuery = print_responses(parsed["responseSet"][0], self.cur)
70
+ textQuery.insert(0, "\n")
71
+ textQuery.insert(0, "This is what i found in the reviews:")
 
72
  textQuery = "\n".join(textQuery)
73
  dispatcher.utter_message(text=textQuery)
74
+
75
  # Revert user message which led to fallback.
76
  return [UserUtteranceReverted()]
77
 
78
 
79
  def print_responses(response_set, sqlite_cursor):
80
  """Print responses to the console."""
81
+ text_list = []
82
  for result in response_set["response"]:
83
  doc = response_set["document"][result["documentIndex"]]
84
  query = f"""
 
87
  """
88
  for row in sqlite_cursor.execute(query):
89
  title, date, hotel, fulltext = row
90
+ text_list.append("**" + title + "**")
91
  if is_title(result):
92
+ text_list.append(f"{head(fulltext)}")
93
  else:
94
  t = result["text"]
95
+ text_list.append(f"{highlight(fulltext, t)}")
96
+ text_list.append(
97
+ "*" + f"{" > \"Jumeirah Hotels & Resorts\" reviewed on {date}" + " *")
98
+ text_list.append("\n")
99
  break
100
+ return text_list
 
 
 
 
 
 
 
 
 
 
101
 
102
 
103
  def highlight(fulltext, snippet):
config.yml CHANGED
@@ -3,9 +3,6 @@
3
  language: en
4
 
5
  pipeline:
6
- # # No configuration for the NLU pipeline was provided. The following default pipeline was used to train your model.
7
- # # If you'd like to customize it, uncomment and adjust the pipeline.
8
- # # See https://rasa.com/docs/rasa/tuning-your-model for more information.
9
  - name: SpacyNLP
10
  - name: SpacyTokenizer
11
  - name: SpacyFeaturizer
 
3
  language: en
4
 
5
  pipeline:
 
 
 
6
  - name: SpacyNLP
7
  - name: SpacyTokenizer
8
  - name: SpacyFeaturizer
data/nlu.yml CHANGED
@@ -92,9 +92,3 @@ nlu:
92
  - Rooms available
93
  - Book a room
94
  - Need a place to stay for the night
95
-
96
- - intent: out_of_scope
97
- examples: |
98
- - I want to order food
99
- - What is 2 + 2?
100
- - Who's the US President?
 
92
  - Rooms available
93
  - Book a room
94
  - Need a place to stay for the night
 
 
 
 
 
 
data/rules.yml CHANGED
@@ -11,8 +11,3 @@ rules:
11
  steps:
12
  - intent: nlu_fallback
13
  - action: zir_action_fallback
14
-
15
- - rule: out of scope
16
- steps:
17
- - intent: out_of_scope
18
- - action: zir_action_fallback
 
11
  steps:
12
  - intent: nlu_fallback
13
  - action: zir_action_fallback
 
 
 
 
 
domain.yml CHANGED
@@ -19,10 +19,6 @@ responses:
19
  utter_greet:
20
  - text: "Hey! How are you?"
21
 
22
- utter_cheer_up:
23
- - text: "Here is something to cheer you up:"
24
- image: "https://i.imgur.com/nGF1K8f.jpg"
25
-
26
  utter_did_that_help:
27
  - text: "Did that help you?"
28
 
 
19
  utter_greet:
20
  - text: "Hey! How are you?"
21
 
 
 
 
 
22
  utter_did_that_help:
23
  - text: "Did that help you?"
24
 
requirements.txt CHANGED
@@ -1,2 +1,3 @@
1
  sqlite3
2
- textwrap
 
 
1
  sqlite3
2
+ textwrap
3
+ spacy
server.py DELETED
@@ -1,13 +0,0 @@
1
- import http.server
2
- import socketserver
3
- import os
4
-
5
- PORT = 8080
6
-
7
- web_dir = os.path.join(os.path.dirname(__file__), 'web')
8
- os.chdir(web_dir)
9
-
10
- Handler = http.server.SimpleHTTPRequestHandler
11
- httpd = socketserver.TCPServer(("0.0.0.0", PORT), Handler)
12
- print("serving at port", PORT)
13
- httpd.serve_forever()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/test_stories.yml CHANGED
@@ -1,91 +1,26 @@
1
  #### This file contains tests to evaluate that your bot behaves as expected.
2
  #### If you want to learn more, please see the docs: https://rasa.com/docs/rasa/testing-your-assistant
3
-
4
  stories:
5
- - story: happy path 1
6
- steps:
7
- - user: |
8
- hello there!
9
- intent: greet
10
- - action: utter_greet
11
- - user: |
12
- amazing
13
- intent: mood_great
14
- - action: utter_happy
15
-
16
- - story: happy path 2
17
- steps:
18
- - user: |
19
- hello there!
20
- intent: greet
21
- - action: utter_greet
22
- - user: |
23
- amazing
24
- intent: mood_great
25
- - action: utter_happy
26
- - user: |
27
- bye-bye!
28
- intent: goodbye
29
- - action: utter_goodbye
30
 
31
- - story: sad path 1
32
  steps:
33
  - user: |
34
  hello
35
  intent: greet
36
  - action: utter_greet
37
  - user: |
38
- not good
39
- intent: mood_unhappy
40
- - action: utter_cheer_up
41
- - action: utter_did_that_help
42
- - user: |
43
- yes
44
- intent: affirm
45
- - action: utter_happy
46
 
47
- - story: sad path 2
48
  steps:
49
  - user: |
50
  hello
51
  intent: greet
52
  - action: utter_greet
53
  - user: |
54
- not good
55
- intent: mood_unhappy
56
- - action: utter_cheer_up
57
- - action: utter_did_that_help
58
- - user: |
59
- not really
60
- intent: deny
61
- - action: utter_goodbye
62
-
63
- - story: sad path 3
64
- steps:
65
- - user: |
66
- hi
67
- intent: greet
68
- - action: utter_greet
69
- - user: |
70
- very terrible
71
- intent: mood_unhappy
72
- - action: utter_cheer_up
73
- - action: utter_did_that_help
74
- - user: |
75
- no
76
- intent: deny
77
- - action: utter_goodbye
78
-
79
- - story: say goodbye
80
- steps:
81
- - user: |
82
- bye-bye!
83
- intent: goodbye
84
- - action: utter_goodbye
85
-
86
- - story: bot challenge
87
- steps:
88
- - user: |
89
- are you a bot?
90
- intent: bot_challenge
91
- - action: utter_iamabot
 
1
  #### This file contains tests to evaluate that your bot behaves as expected.
2
  #### If you want to learn more, please see the docs: https://rasa.com/docs/rasa/testing-your-assistant
 
3
  stories:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ - story: A basic story test
6
  steps:
7
  - user: |
8
  hello
9
  intent: greet
10
  - action: utter_greet
11
  - user: |
12
+ Book a room for two please.
13
+ intent: reservations
14
+ - action: utter_reservation
15
+
 
 
 
 
16
 
17
+ - story: Fallback test
18
  steps:
19
  - user: |
20
  hello
21
  intent: greet
22
  - action: utter_greet
23
  - user: |
24
+ Can we play golf?
25
+ intent: nlu_fallback
26
+ - action: zir_action_fallback