How to have your ODA search blogs and other documentation sites as a fallback strategy

books in black wooden book shelf
Photo by Pixabay on Pexels.com

Typically we design Skills and Digital Assistants to handle specific tasks and provide information based on user input. When users make requests that fall outside the assistant’s intended use case, the assistant may fail to understand the user’s intention and we take the dialog path that was defined for an “unresolved Intent”.

Sometimes the assistant simply was not designed to handle a particular query, or queries, even if they are within domain. Especially now with the prominence of Large Language Models (LLM), users may feel frustrated when not being understood.

We can implement a couple of easy solutions to address that while keeping in control of the core use cases the assistant was developed for.

Out-of-domain search

We can do a google search for out-of-domain requests, and that process is explained in this post. This works well, and it is easy to set up. On top of that, you can even choose the topics you want to allow to be searched. For example, you can pass the user utterance via the OCI AI-Language service to classify the text, and then based on that classification, you can choose to allow a search or not. As a business, you would not want the user to have results for any topic right? This approach opens the internet for out-of-domain searches while keeping control of the allowed topics.

In-domain search

In this post, I will show how to leverage documentation and blogs to provide a safety net for in-domain questions the user may have.

For everything that is unresolved, we first do an in-domain search, meaning that we search the relevant sources of knowledge, like documentation sites, blog pages, or any other source that offers us an API for search.

We will need a custom component, that will call an API to retrieve potential results.

The Custom Component

First, we have 2 input parameters, a mandatory one – input – that will have the value of the user query, and an optional one – resultVar – that later in the code will be populated with a list of results.

Then we will use the fetch module to call our API. In this case, I will be searching the articles published on the site techtrantor.com – which offers us a WordPress API to search posts.

When we receive the results we need to iterate over each element and store the data we want. In this case, we store the title, description, and URL(link) for the post.

All of that is stored in a list variable called results.

The final step is to use the method setVariable to copy results into resultVar – and this is the variable available in the dialog flow.

The Skill

In this skill, there are no intents, just the default unresolvedIntent flow, that we will use to perform the search.

The flow will call the search and then display the results with a common response component to display cards.

We need to create a flow variable called resultVar (type List), and we pass the user message as input.

Then in the common response component, we define horizontal cards with an iterator over the resultVar list.

Then at runtime…

another example…

What about searching in the documentation?

The principle is exactly the same, it just changes the URL and the handling of the response as it will have a different format. For example, we can search the oracle digital assistant documentation with the following URL where the ${searchTerm} is replaced with the user query.

https://docs.oracle.com/apps/ohcsearchclient/api/v1/search/pages?q='${searchTerm}'&showfirstpage=false&size=6&product=en/cloud/paas/digital-assistant

The end result would be the same!

In this case, we would need to strip the HTML markup from the description

Can we join multiple sources?

Yes, you can, and that’s fairly straightforward, you make the 2 API calls and populate the variable resultsVar which will then be available in the dialog flow.

Looks at this example and the resultVar list with all the articles.

The first result
The second result
list of all the returned mixed results (techtrantor and docs.oracle.com)

Note:

Note that the code here is just a working sample, and not meant for production.

Also published in the Oracle Digital Assistant Blog