This sample consists of a simple API.AI agent, a node.js server and a web interface that together demonstrate an approach for handing text-based conversations from an API.AI agent to a human operator.
This extensively commented sample is designed as a learning tool and a platform for experimentation, not a finished solution.
- Agent will escalate to a human operator on-demand
- Agent will escalate to a human operator after repeated failure to match an intent
- Server routes conversation between agent and human operator depending on context
- Server supports multiple concurrent conversations between customer, agent and operator
- Customer web client supports real-time chat with agent or operator
- Operator web client supports real-time observation and participation in multiple customer conversations
- Operator web client demonstrates alerting of operator in case of customer escalation
- There is no authentication of customers or operators. In this limited demonstration, communication between users is not secure. This code is provided as an example, not a finished solution.
- Active conversations are stored in-memory with no on-disk persistence (though code could easily be modified to support this).
- Operators can only monitor and communicate with customers that have subsequently connected. Previously connected customers are ignored.
- User interface is very rudimentary.
- API.AI
- Node.js v6.9.1+
- Express.js
- Socket.IO
- JQuery
- Log in to the API.AI Console.
- Create a new agent using the dropdown at the top of the left hand menu, next to the gear icon. If the menu is not visible, click the icon with three horizontal lines to open it.
- Type a name for your agent. Any name will work, but
agent-human-handoff-sample
is suggested. - Click
Save
to save the project, and wait for it to complete. - Click the gear icon near the top of the menu to see the project settings.
- Click the
Export and Import
tab. - Click
RESTORE FROM ZIP
. Follow the directions to restore from the HumanHandoffDemonstrationAgent.zip in this repo.
- Clone or download the contents of this repo to a location on disk.
- Ensure at least Node.js v6.9.1 is installed.
- Within the repo directory, type
npm install
to install all of the project's dependencies. - To connect to your agent, you will need your API.AI client access token. To obtain it, open the project you
created in Part A in the API.AI console. Click the gear icon near the top of the menu to see the
project settings. Copy the
Client access token
from theAPI keys
section of theGeneral
tab. - To start the server, enter
APIAI_ACCESS_TOKEN=<client access token> node app.js
from within the repo directory, where<client access token>
is replaced with the access token you copied in the previous step. - You should see the text
Listening on *:3000
. The server is now ready to use.
Note: If you see the error Error: listen EADDRINUSE :::3000
when starting the server, there is
already a process listening on port 3000 on your system. Identify and close that process, or edit app.js
to connect to a different port.
- With the server running, open http://localhost:3000/operator in your browser to open the Operator interface. You should see a mostly empty page with the word 'Operator' and a chat form.
- In another browser tab, open http://localhost:3000/customer. After loading, the client should immediately connect to the API.AI agent. You'll see the welcome message from the agent appear beneath the Customer title.
- Return to the Operator interface. You will see that a tab has appeared that represents the conversation with this customer. It will currently be empty.
- Return to the Customer interface. You can use the form to chat with the agent by clicking
Send
or hitting return. To demonstrate functional conversation, try asking itwhat is your purpose?
. - Open the Operator interface. You will see the history of messages between the customer and the agent. If you attempt to enter a message, you will see a warning that the customer has not yet been escalated.
- Open the Customer interface. To request an operator, ask a variation of
let me talk to a person
. The Operator interface will pop up a dialog box to alert the operator that a new escalation has occurred. - If the Operator interface took control as a result of alert dialog, return to the Customer interface. You will see the system has responded with an introduction message from the operator. After this point, the operator can respond to the customer's messages freely.
- Still on the Customer interface, send another message (for example,
I'm having difficulty with my product
). - Open the Operator interface. You will see the customer's message. You can use the form to respond.
- Switch back to the Customer interface. If you responded to their message in the previous step, you will see your response in the chat log.
- Open a new browser tab and go to http://localhost:3000/customer.
- In this new Customer interface, ask the agent something it doesn't understand (e.g.
I would like to book a flight
). The agent will ask for clarification. - Switch to the Operator interface. You will see that a second tab has appeared, representing the second customer. Click this tab to view the conversation logs.
- Switch back to the new Customer interface and enter another arbitrary statement (e.g.
I want to book a flight
). With the agent unable to determine the customer's intent twice in a row, it will automatically escalate to an operator.
- The server communicates with the clients via Socket.IO. It initially sends all customer messages to API.AI and returns the responses to the customer.
- The server monitors the
context
property of API.AI's response for a specific context named 'operator_request'. When it sees this context, it stops routing this customer's messages to API.AI and allows the operator to respond. - The API.AI agent can apply this context in two modes.
- In one mode, it is applied to the
Output contexts
of theOperator Request
intent, thus switching the customer to an operator when they explicitly ask for it. - In the other mode, it is applied to the
Output contexts
of the intentDefault Fallback Intent - fallback
. To see this intent in the API.AI interface, click the downward arrow on the intent namedDefault Fallback Intent
. Because this intent is specified as the fallback intent for the default fallback intent, it will be triggered only if the user has failed to provide a matchable input twice in a row. The first unmatched input triggers theDefault Fallback Intent
. The second unmatched input triggersDefault Fallback Intent - fallback
. This causes theoperator_request
context to be applied, triggering escalation by the server.
- In one mode, it is applied to the
You can modify this sample as a basis for your own implementation, but please be aware of the limitations expressed above.
When creating your own API.AI agent, you may wish to make use of the Support prebuilt agent. This agent provides a framework for answering common support-related inquiries and providing a channel for users to contact you.
- If you find any issues, please open a bug here on GitHub.
- Questions are answered on StackOverflow.
Please read and follow the steps in the CONTRIBUTING.md.
See LICENSE.md.
Your use of this sample is subject to, and by using or downloading the sample files you agree to comply with, the Google APIs Terms of Service.