Lex alone is not designed to dynamically handle open-ended questions without predefined utterances.
Here's how to capture arbitrary user questions and pass them to your Lambda function using a workaround approach:
Create a Catch-All Intent in Lex (e.g., FallbackIntent
or CatchAllQuestionIntent
).
Enable Lambda Fulfillment on that intent.
Extract User Input in Lambda and use it to search your knowledge base.
Respond Dynamically with the relevant answer.
Step-by-Step Instructions
1. Create a Catch-All Intent
Use this intent to catch anything that doesn't match other specific intents:
intents:
- name: CatchAllQuestionIntent
fulfillmentCodeHook:
enabled: true
sampleUtterances:
- "I have a question"
- "Can you tell me something?"
- "What is {UserQuestion}"
- "Tell me about {UserQuestion}"
- "Explain {UserQuestion}"
slots:
- name: UserQuestion
slotType: AMAZON.SearchQuery
valueElicitationSetting:
slotConstraint: Required
promptSpecification:
messageGroupsList:
- message:
plainTextMessage:
value: "What would you like to know?"
maxRetries: 2
slotCaptureSetting: {}
2. Use the AMAZON.SearchQuery
Slot Type
This allows the user to type in anything freely and captures their question as-is.
In your Lambda function, extract the UserQuestion
slot and query your knowledge base:
def lambda_handler(event, context):
question = event['sessionState']['intent']['slots']['UserQuestion']['value']['interpretedValue']
# Your logic to search the YAML-based knowledge base
answer = search_kb(question)
return {
"sessionState": {
"dialogAction": {
"type": "Close"
},
"intent": {
"name": event['sessionState']['intent']['name'],
"state": "Fulfilled"
}
},
"messages": [
{
"contentType": "PlainText",
"content": answer
}
]
}