Lex selects one intent for any one-word utterance that doesn't match a valid utterance
For a few months, my team has been working on a Lex-based chatbot that's attached to a marketing website. The bot has a total of 32 intents that handle over 300 utterances right now. In an effort to reduce utterances that invoke error handling responses (and to make the bot more useful and friendly), we've implemented 3 intents in the following order over time:
1) a "Thank You" intent: responds with "you're welcome"-type messages when a user types some variant of "thank you".
2) a "No Answer Available" intent to handle known utterances (from our usability and internal user testing) that the bot isn't currently designed to answer, but that we want to refer the user to a human chat agent (e.g. "I don't have an answer for that, but type 'transfer' to talk to one of our human agents who can help."). This intent currently has the largest set of utterances in the bot.
3) a "No Response" intent that "eats" a small number of utterances from the user that don't really require a response and would probably go to error handling other wise and make the bot look dumb, e.g. "you're welcome", "ok, got it", "cool", "k" etc. IOW, it doesn't return any response for these to the user.
Until we implemented #3 (maybe coincidental?), if a user typed 1 or more nonsense words to the bot, it properly triggered error handling. After implementing #3, a single, alpha-only word of apparently any length that doesn't match a valid utterance is now triggering the "Thank you" intent.
Screenshot: bot says "you're welcome" to a nonsense word
Note that 2 nonsense words triggers the expected error handling messages. Also, single strings that contain symbols or numbers also trigger error handling as expected. Interestingly (and unexpectedly), text-based emoticons typed in the usual direction, e.g. :-) or :) or ;-) also trigger the "thank you" intent, but if you type them in the reverse direction, e.g. (-: they trigger error handling.
Additionally, 2 other intents handle a number of single-word utterances:
1) A "signoff" intent that handles words like: bye, goodbye, later, exit, quit, etc.
2) A "hello" intent that responds to: hi, hello, hey, what's up, what's happening, etc.
So the "Thank you" intent has neither the largest number of utterances in the bot nor the largest number of 1-word utterances (just "thanks", actually) both which I have seen in various forums as reasons why a Lex intent would attract incorrect utterances.
I've tried searching for answers on this phrasing the question any way I can think of and haven't found anything.
So, though it's not a product show-stopper, it's making me a little crazy, and I thought I'd post here to see if anyone has run into anything like this in their Amazon Lex journeys and had any ideas.
Thanks!
See also questions close to this topic
-
Error occurred during build: Command start_install failed while creating Corda Enterprise on AWS
I am creating a single Corda node using AWS Corda template with new VPC configuration in Ohio region. I am facing an issue during build of CordaNodeStack. Below are my system logs from failure:
89.110614] cloud-init[1459]: Error occurred during build: Command start_install failed [ 89.124327] cloud-init[1459]: + cfn_fail [ 89.124653] cloud-init[1459]: + cfn-signal -e 1 --stack Corda-NotaryA-CordaStack-xxxx-CordaNodeStack-xxxx --region us-east-2 --resource CordaInstance [ 89.369313] cloud-init[1459]: + exit 1 [ 89.370188] cloud-init[1459]: Cloud-init v. 18.2 running 'modules:final' at Mon, 18 Feb 2019 12:43:10 +0000. Up 11.40 seconds. [ 89.370632] cloud-init[1459]: 2019-02-18 12:44:28,352 - util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/part-001 [1] [ 89.381955] cloud-init[1459]: 2019-02-18 12:44:28,364 - cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts) [ 89.389311] cloud-init[1459]: 2019-02-18 12:44:28,365 - util.py[WARNING]: Running module scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python3/dist-packages/cloudinit/config/cc_scripts_user.py'>) failed ci-info: +++++++++Authorized keys from /home/ubuntu/.ssh/authorized_keys for user ubuntu++++++++++ ci-info: +---------+-------------------------------------------------+---------+-----------------+ ci-info: | Keytype | Fingerprint (md5) | Options | Comment | ci-info: +---------+-------------------------------------------------+---------+-----------------+ ci-info: | ssh-rsa | xxxxx | - | xxxx | ci-info: | ssh-rsa | xxxxx | - | xxxx | ci-info: +---------+-------------------------------------------------+---------+-----------------+ <14>Feb 18 12:44:28 ec2: <14>Feb 18 12:44:28 ec2: ############################################################# <14>Feb 18 12:44:28 ec2: -----BEGIN SSH HOST KEY FINGERPRINTS----- <SSH Key> <14>Feb 18 12:44:28 ec2: -----END SSH HOST KEY FINGERPRINTS----- <14>Feb 18 12:44:28 ec2: ############################################################# -----BEGIN SSH HOST KEY KEYS----- ecdsa-sha2-nistp256 <hash> root@ip-xx-x-xxx-xxx ssh-ed25519 <hash> root@ip-xx-x-xxx-xxx ssh-rsa <key> root@ip-xx-x-xxx-xxx -----END SSH HOST KEY KEYS----- [ 89.530956] cloud-init[1459]: Cloud-init v. 18.2 finished at Mon, 18 Feb 2019 12:44:28 +0000. Datasource DataSourceEc2Local. Up 89.52 seconds [[0;1;31mFAILED[0m] Failed to start Execute cloud user/final scripts. See 'systemctl status cloud-final.service' for details. [[0;32m OK [0m] Reached target Cloud-init target. Starting Daily apt download activities... [[0;32m OK [0m] Started Daily apt download activities. Starting Daily apt upgrade and clean activities... Stopped Daily apt upgrade and clean activities.
Can anyone help me with this error.
Thank you in advance.
-
S3 registerStreamWrapper and fseek
I am using PHP SDK for AWS and S3. This is part of my code:
$context = stream_context_create(array( 's3' => array( 'seekable' => true ))); $stream = fopen("s3://{$bucketname}/{$key}", 'r',false,$context); $length = $byte_to - $byte_from + 1 ; $speed = 1000*1024 ;//1000KB file_put_contents("test.txt"," before \n",FILE_APPEND); $im = fseek($stream,$byte_from); file_put_contents("test.txt"," im=".$im." \n",FILE_APPEND); while($length>0) { if($length > $speed) $read = $speed ; else $read = $length; $length = $length - $read; echo fread($stream,$read); }
After checking test.txt I saw "before" was saved to test.txt (only).It seems that fseek doesn't work. How can I change this code to a better code?
-
Iterate S3 folder to get to get recent files as per lastmodifieddate
Iterate S3 folder to get to get recent files as per
lastmodifieddate
.We have a S3 bucket having folder structure as below(data coming hourly basis):
s3://my_bucket/stream/yy/mm/dd/hh:
examples:
s3://my_bucket/stream/2019/01/01/00 s3://my_bucket/stream/2019/01/01/01 s3://my_bucket/stream/2019/01/01/02 : : s3://my_bucket/stream/2019/01/02/00 s3://my_bucket/stream/2019/01/02/01
I need to iterate folders with recent files upload as per last modified date in AWS Lambda(python 2.7).
-
Update text responses in dialogflow using api
I want to update (add) responses for a specific intent of a dialogflow agent.
Suppose, there are 3 responses like in the image below, and i want to add 4th response.I used
update_intent
method, but was not able to get it done.client = dialogflow.IntentsClient() intent_name = client.intent_path(project_id, intent_id) intent = client.get_intent(intent_name) response_list = ['text response'] text = dialogflow.types.Intent.Message.Text(text=response_list) message = dialogflow.types.Intent.Message(text=text) intent.messages.extend([message]) response = client.update_intent(intent, language_code='en')
Using above code, my response is added but as a separate text response.
How can i add this as a 4th response?
UPDATE:
I tried adding text field to the Text object of intent.messages but could not find any method to add the text field.intent.messages[0].text
text: "1st response"
text: "2nd response"
text: "3rd response"intent.messages[0].text.add() *** AttributeError: 'Text' object has no attribute 'add' intent.messages[0].text.append() *** AttributeError: 'Text' object has no attribute 'append' intent.messages[0].text = text *** TypeError: Can't set composite field intent.messages[0].Text = '' *** AttributeError: Assignment not allowed (no field "Text" in protocol message object).
-
How to build a chatbot using Angularjs using bootstrap?
I am new to angularjs, please someone has developed the chatbot using angularjs with bootstrap and backend has nodejs. Please, I hope you could post your code this helps me a lot.
I want to get the respone dynamically.I also want to see the time when we are sending and receiving messages.
-
NLP on Chatbot data
I am trying to analyse a conversational chatbot data and I'd like to do a topic modelling. The chatbot data comes in the form of sequence of session ids, the question (what is being asked from the chatbot) and the response (chatbot response).
I am interested to know if there is specific way that I should process and clean the data? for example, should I combine all the questions and responses together and then do the topic modelling or should I separate the questions and responses and then do separate topic modelling on each?
If anyone has done similar work or if there's any specific guide or suggestions as what's the best approach to take dealing with such data?
Thanks in advance
-
Scoring / Confidence of Intents using Amazon-Lex
I try to get a scoring-value or a value for confidence of an intent using amazon-lex (PostText) but there is no response-element in json-file at all. (https://docs.aws.amazon.com/de_de/lex/latest/dg/API_runtime_PostText.html) Is there any level or threshold for a correct identification of an intent which is used by amazon-lex?
Thanks for your help.
-
How can I solve 424 (Failed Dependency) (python) obtained from Amazon lex?
I have written my lambda function and it works perfectly but when I try to communicate with it from Lex I get dependency exception.How can i debug this or solve this issue? The variable REST_END_POINT has been defined. Below is my code please kindly look at it and tell me what I might be doing wrong?
I researched the issue on Amazon Lex doc. And it is mentioned the following:
DependencyFailedException 1. One of the dependencies, such as AWS Lambda or Amazon Polly, threw an exception. For example,
If Amazon Lex does not have sufficient permissions to call a Lambda function.
If a Lambda function takes longer than 30 seconds to execute.
If a fulfillment Lambda function returns a Delegate dialog action without removing any slot values.
HTTP Status Code: 424
These are the actions I have undertaken:
- I have checked that my lambda function does not take more than 30 seconds to execute
- And Amazon Lex has the right permissions to call my lambda function
The third point i don't quite understand but I think its solved too from the code i provided please correct me if am wrong.
def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message, response_card): return { 'sessionAttributes': session_attributes, 'dialogAction': { 'type': 'ElicitSlot', 'intentName': intent_name, 'slots': slots, 'slotToElicit': slot_to_elicit, 'message': message, 'responseCard': response_card } } def confirm_intent(session_attributes, intent_name, slots, message, response_card): return { 'sessionAttributes': session_attributes, 'dialogAction': { 'type': 'ConfirmIntent', 'intentName': intent_name, 'slots': slots, 'message': message, 'responseCard': response_card } } def close(session_attributes, fulfillment_state, message): response = { 'sessionAttributes': session_attributes, 'dialogAction': { 'type': 'Close', 'fulfillmentState': fulfillment_state, 'message': message } } return response def delegate(session_attributes, slots): return { 'sessionAttributes': session_attributes, 'dialogAction': { 'type': 'Delegate', 'slots': slots } } def build_response_card(title, subtitle, options): """ Build a responseCard with a title, subtitle, and an optional set of options which should be displayed as buttons. """ buttons = None if options is not None: buttons = [] for i in range(min(5, len(options))): buttons.append(options[i]) return { 'contentType': 'application/vnd.amazonaws.card.generic', 'version': 1, 'genericAttachments': [{ 'title': title, 'subTitle': subtitle, 'buttons': buttons }] } """ --- Helper Functions --- """ def parse_int(n): try: return int(n) except ValueError: return float('nan') def try_ex(func): """ Call passed in function in try block. If KeyError is encountered return None. This function is intended to be used to safely access dictionary. Note that this function would have negative impact on performance. """ try: return func() except KeyError: return None def isvalid_date(date): try: dateutil.parser.parse(date) return True except ValueError: return False def build_validation_result(is_valid, violated_slot, message_content): return { 'isValid': is_valid, 'violatedSlot': violated_slot, 'message': {'contentType': 'PlainText', 'content': message_content} } def validate_oms_count(oms_type, date): if oms_type: if len(oms_type) == 0 or (oms_type != 'transport' and oms_type != 'overtime'): return build_validation_result(False, 'OmsType', 'I did not recognize that, can I make an overtime request?') if date: if not isvalid_date(date): return build_validation_result(False, 'Date', 'I did not understand that, what date works best for you?') return build_validation_result(True, None, None) def validate_menu_date(date): if date: if not isvalid_date(date): return build_validation_result(False, 'Date', 'I did not understand that, what date works best for you?') return build_validation_result(True, None, None) def get_token(output_session_attributes): token = json.loads(try_ex(lambda: output_session_attributes['token']) or '{}') if not token: try: data = bytes(json.dumps({"username": "admin","password": "Oms2017@","rememberMe": "false"}), 'utf-8') f = urllib.request.urlopen(urllib.request.Request(REST_END_POINT+'/authenticate', data, {'Content-Type': 'application/json'})) result = json.loads(f.read().decode()) output_session_attributes['token'] = result['id_token'] logger.debug('Token {}'.format(result['id_token'])) return result['id_token'] except Exception as e: logger.debug('An error occurred at the backend1 {}'.format(e)) else: return token def build_options(slot, oms_type): """ Build a list of potential options for a given slot, to be used in responseCard generation. """ if slot == 'OmsType': return [ {'text': 'Transport', 'value': 'transport'}, {'text': 'Overtime', 'value': 'overtime'} ] """ --- Functions that control the bot's behavior --- """ def get_menu_of_day(intent_request): """ Performs dialog management and fulfillment for getting the menu of the day. Beyond fulfillment, the implementation for this intent demonstrates the following: 1) Use of elicitSlot in slot validation and re-prompting 2) Use of confirmIntent to support the confirmation of inferred slot values, when confirmation is required on the bot model and the inferred slot values fully specify the intent. """ date = intent_request['currentIntent']['slots']['Date'] source = intent_request['invocationSource'] output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {} data_map = json.loads(try_ex(lambda: output_session_attributes['dataMap']) or '{}') if source == 'DialogCodeHook': # Perform basic validation on the supplied input slots. slots = intent_request['currentIntent']['slots'] validation_result = validate_menu_date(date) if not validation_result['isValid']: slots[validation_result['violatedSlot']] = None return elicit_slot( output_session_attributes, intent_request['currentIntent']['name'], slots, validation_result['violatedSlot'], validation_result['message'], build_response_card( 'Specify {}'.format(validation_result['violatedSlot']), validation_result['message']['content'], build_options(validation_result['violatedSlot'], None) ) ) if not date: slots['Date'] = None return elicit_slot( output_session_attributes, intent_request['currentIntent']['name'], intent_request['currentIntent']['slots'], 'Date', {'contentType': 'PlainText', 'content': 'What date works for you?'}, build_response_card( 'Specify Date', 'What date works for you?', build_options('Date', None) ) ) if date: get_token(output_session_attributes) data_map['date'] = date output_session_attributes['dataMap'] = json.dumps(data_map) return delegate(output_session_attributes, slots) # Send request to the backend service to perform user action. token = get_token(output_session_attributes) extractedMenu = [] try: data_map['date'] = date output_session_attributes['dataMap'] = json.dumps(data_map) params = urllib.parse.urlencode({'day':date}) response = urllib.request.urlopen(urllib.request.Request(REST_END_POINT+'/menuOfdays?'+ params, headers={'Authorization': 'Bearer '+token})) convertedResponse = json.loads(response.read().decode()) extractedMenu = [item['menu']['name'] for item in convertedResponse] logger.debug(extractedMenu) except Exception as e: logger.debug('An error occurred at the backend2 {}'.format(e)) return close( output_session_attributes, 'Fulfilled', { 'contentType': 'PlainText', 'content': 'Menu of the day include: {} '.format(extractedMenu) } ) """ --- Intents --- """ def dispatch(intent_request): """ Called when the user specifies an intent for this bot. """ logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name'])) intent_name = intent_request['currentIntent']['name'] # Dispatch to your bot's intent handlers if intent_name == 'GetMenuOfDay': return get_menu_of_day(intent_request) raise Exception('Intent with name ' + intent_name + ' not supported') """ --- Main handler --- """ def lambda_handler(event, context): """ Route the incoming request based on intent. The JSON body of the request is provided in the event slot. """ # By default, treat the user request as coming from the America/New_York time zone. os.environ['TZ'] = 'America/New_York' time.tzset() logger.debug('event.bot.name={}'.format(event['bot']['name'])) return dispatch(event)
If everything works, when the question What is the menu for {Date} is asked, the response is: Menu of the day include
a list of menu items
-
Storing/Saving user's question and bot's response using AWS Lex
I have created a bot using the AWS console. I am looking for capabilities in AWS Lex for me to store the chat conversations. Currently, I could see just the Bot's response shown on the console. How do I capture the user's query in the first place.
Below is the response capture on the AWS lex console. The 'message' shown in the response from the bot. But the users query - "tell me more about the company" is not captured here.
RequestID: ac7be9e5-xxxxx { "dialogState": "Fulfilled", "intentName": "Aboutus", "message": "Here is the information you are looking for: https://demo/about-us/", "messageFormat": "PlainText", "responseCard": null, "sessionAttributes": {}, "slotToElicit": null, "slots": {} }