This is an automated email from the ASF dual-hosted git repository. aradzinski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft-website.git
The following commit(s) were added to refs/heads/master by this push: new 419d8b3 WIP. 419d8b3 is described below commit 419d8b3c3a11ceab6c459ed55b82a85bdbf2fc05 Author: Aaron Radzinski <aradizn...@apache.org> AuthorDate: Tue Jul 27 20:26:39 2021 -0700 WIP. --- blogs/nlpcraft-idl-intent-definition-language.html | 9 +- blogs/short_term_memory.html | 8 +- intent-matching.html | 153 +++++--- short-term-memory.html | 413 ++++++++++++++++++++- 4 files changed, 503 insertions(+), 80 deletions(-) diff --git a/blogs/nlpcraft-idl-intent-definition-language.html b/blogs/nlpcraft-idl-intent-definition-language.html index d2c6994..d6f625e 100644 --- a/blogs/nlpcraft-idl-intent-definition-language.html +++ b/blogs/nlpcraft-idl-intent-definition-language.html @@ -113,7 +113,6 @@ publish_date: June 3, 2021 <pre class="brush: idl"> intent=xb flow=/#flowModelMethod/ - ordered=true term(a)=/org.mypackage.MyClass#termMethod/? fragment(frag) </pre> @@ -174,7 +173,7 @@ publish_date: June 3, 2021 NLPCraft IDL has only 10 keywords: <code>flow, fragment, import, intent, meta, ordered, term, true, false, null.</code> </p> <ul class="fixed"> - <li><code>intent, flow, fragment, meta, ordered, term</code> are parts of the intent definition.</li> + <li><code>intent, flow, fragment, meta, options, term</code> are parts of the intent definition.</li> <li><code>fragment</code> keyword is also can be used to create named terms lists to include in intent definitions (a-la macros).</li> <li><code>import</code> - required for including external files with fragment, intent or imports statements.</li> <li><code>true, false, null</code> - used when working with built-in functions.</li> @@ -418,12 +417,6 @@ publish_date: June 3, 2021 Optional element. A additional dataset that can be used by term predicates presented in JSON format. </p> </li> - <li> - <p><b>Ordered Flag</b></p> - <p> - Optional element. The default is <code>false</code>. Defines whether or not the order of the terns in the intent is important. - </p> - </li> </ul> </section> <section> diff --git a/blogs/short_term_memory.html b/blogs/short_term_memory.html index b661bd7..3ef977c 100644 --- a/blogs/short_term_memory.html +++ b/blogs/short_term_memory.html @@ -107,10 +107,10 @@ publish_date: July 26, 2019 </ul> <div class="bq info"> <div style="display: inline-block; margin-bottom: 20px"> - <a style="margin-right: 10px" target="opennlp" href="https://opennlp.apache.org"><img src="/images/opennlp-logo.png" height="32px" alt=""></a> - <a style="margin-right: 10px" target="google" href="https://cloud.google.com/natural-language/"><img src="/images/google-cloud-logo-small.png" height="32px" alt=""></a> - <a style="margin-right: 10px" target="stanford" href="https://stanfordnlp.github.io/CoreNLP"><img src="/images/corenlp-logo.gif" height="48px" alt=""></a> - <a style="margin-right: 10px" target="spacy" href="https://spacy.io"><img src="/images/spacy-logo.png" height="32px" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://opennlp.apache.org"><img src="/images/opennlp-logo-h32.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://cloud.google.com/natural-language/"><img src="/images/google-cloud-logo-small-h32.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://stanfordnlp.github.io/CoreNLP"><img src="/images/corenlp-logo-h48.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://spacy.io"><img src="/images/spacy-logo-h32.png" alt=""></a> </div> <p> Note that NLPCraft provides <a href="/integrations.html">support</a> for wide variety of named entities (with all built-in ones being properly normalized) diff --git a/intent-matching.html b/intent-matching.html index 85f9fcb..4dc8f3f 100644 --- a/intent-matching.html +++ b/intent-matching.html @@ -32,20 +32,20 @@ id: intent_matching <section id="intent"> <h2 class="section-title">Intent <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> <p> - The goal of the data model implementation is to take the input utterance and + The goal of the data model implementation is to take the user input text and match it to a specific user-defined code that will execute for that input. The mechanism that provides this matching is called an <em>intent</em>. </p> <p> - The intent refers to the goal that the end-user had in mind when speaking or typing the input utterance. - The intent has a <em>declarative part or template</em> written in <a href="#idl">Intent Definition Language</a> that describes - a particular form or type of the input utterance. + The intent generally refers to the goal that the end-user had in mind when speaking or typing the input utterance. + The intent has a <em>declarative part or template</em> written in <a href="#idl">Intent Definition Language</a> that strictly defines + a particular form the user input. Intent is also <a href="#binding">bound</a> to a callback method that will be executed when that intent, i.e. its template, is detected as the best match - for a given input utterance. A typical data model will have multiple intents defined for each form of the expected user input + for a given input input. A typical data model will have multiple intents defined for each form of the expected user input that model wants to react to. </p> <p> - For example, a data model for banking chat bot or analytics application can have multiple intents for each domain-specific group of utterances such as + For example, a data model for banking chat bot or analytics application can have multiple intents for each domain-specific group of input such as opening an account, closing an account, transferring money, getting statements, etc. </p> <p> @@ -58,7 +58,7 @@ id: intent_matching <h2 class="section-title">IDL - Intent Definition Language <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> <p> NLPCraft intents are written in Intent Definition Language (IDL). - IDL is a relatively straightforward and simple language. For example, + IDL is a relatively straightforward declarative language. For example, here's a simple intent <code>x</code> with two terms <code>a</code> and <code>b</code>: </p> <pre class="brush: idl"> @@ -67,40 +67,12 @@ id: intent_matching term(b)={has(tok_groups(), "my_group")} </pre> <p> - IDL intent defines a match between the parsed input utterance, i.e. the collection of + IDL intent defines a match between the parsed user input represented as the collection of <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken.html">tokens</a>, - and the user-define callback method. To accomplish that, IDL through its <a href="#idl_functions">functions</a> provides - access to the following information: + and the user-define callback method. IDL intents are <a href="#binding">bound</a> to their callbacks via <a href="#binding">Java + annotation</a> and can be <a href="#idl_location">located</a> in the same Java annotations or placed in model YAML/JSON file + as well as in external <code>*.idl</code> files. </p> - <ul> - <li> - Basic <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken.html">token properties</a> such as token ID, - group membership, aliases, token parent and ancestry hierarchy, - token's constituent part tokens, abstract flag, etc. - </li> - <li> - NLP <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken.html">token properties</a> - stem, - lemma, PoS tag, and variety of computed boolean flags - such as stop word, swear word, free word, known dictionary word, - bracketed, quoted, etc. - </li> - <li> - <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken.html">Information</a> about - how particular token was found in the input, i.e. its sparsity value, permutation - flag, synonym value, indices in the original text, etc. - </li> - <li> - Additional token metadata provided by NER providers. For example, for geographical token additional metadata - can provide population, postal codes, latitude and longitude coordinates, and other demographic information. - </li> - <li> - Additional metadata about user and company that made the input request like admin status, signup date, - first and last names, avatars, emails, company name, website, address, etc. - </li> - <li> - System information such as current date and time, OS properties, system and environment variables. - </li> - </ul> <p> You can review the formal <a target="github" href="https://github.com/apache/incubator-nlpcraft/blob/master/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIdl.g4">ANTLR4 grammar</a> for IDL, @@ -133,7 +105,7 @@ id: intent_matching Numeric literals use Java string conversions. </li> <li> - IDL has only 10 reserved keywords: <code>flow fragment import intent meta ordered term true false null</code> + IDL has only 10 reserved keywords: <code>flow fragment import intent meta options term true false null</code> </li> <li> Identifiers and literals can use the same Unicode space as Java. @@ -180,8 +152,14 @@ id: intent_matching } intent=xb + options={ + 'ordered': false, + 'unused_free_words': true, + 'unused_sys_toks': true, + 'unused_usr_toks': false, + 'allow_stm_only': false + } flow=/#flowModelMethod/ - ordered=true term(a)=/org.mypackage.MyClass#termMethod/? fragment(frag, {'p1': 25, 'p2': {'a': false}}) </pre> @@ -195,19 +173,78 @@ id: intent_matching <code>xa</code> and <code>xb</code> are the mandatory intent IDs. Intent ID is any arbitrary unique string matching the following lexer template: <code>(UNI_CHAR|UNDERSCORE|LETTER|DOLLAR)+(UNI_CHAR|DOLLAR|LETTER|[0-9]|COLON|MINUS|UNDERSCORE)*</code> </dd> - <dt><code>ordered=true</code> <sup><small>line 14</small></sup></dt> + <dt><code>options={...}</code> <sup><small>line 13</small></sup></dt> <dd> <em>Optional.</em> - Whether or not this intent is ordered. Default is <code>false</code>. - For ordered intent the specified order of terms is important for matching this intent. - If intent is unordered its terms can be found in any order in the input text. - Note that ordered intent significantly limits the user input it can match. In most cases - the ordered intent is only applicable to processing of a formal grammar (like a programming language) - and mostly unsuitable for the natural language processing. + Matching options specified as JSON object. Entire JSON object as well as each individual JSON field is optional. Allows + to customize the matching algorithm for this intent: + <table class="gradient-table"> + <thead> + <tr> + <td>Option</td> + <td>Description</td> + <td>Default Value</td> + </tr> + </thead> + <tbody> + <tr> + <td><code>ordered</code></td> + <td> + Whether or not this intent is ordered. + For ordered intent the specified order of terms is important for matching this intent. + If intent is unordered its terms can be found in any order in the input text. + Note that ordered intent significantly limits the user input it can match. In most cases + the ordered intent is only applicable to processing of a formal grammar (like a programming language) + and mostly unsuitable for the natural language processing. + </td> + <td><code>false</code></td> + </tr> + <tr> + <td><code>unused_free_words</code></td> + <td> + Whether or not free words - that are unused by intent matching - should be + ignored (value <code>true</code>) or reject the intent match (value <code>false</code>). + Free words are the words in the user input that were not recognized as any user or system + token. Typically, for the natural language comprehension it is safe to ignore free + words. For the formal grammar, however, this could make the matching logic too loose. + </td> + <td><code>true</code></td> + </tr> + <tr> + <td><code>unused_sys_toks</code></td> + <td> + Whether or not unused <a href="/data-model.html#builtin">system tokens</a> should be + ignored (value <code>true</code>) or reject the intent match (value <code>false</code>). + By default, tne unused system tokens are ignored. + </td> + <td><code>true</code></td> + </tr> + <tr> + <td><code>unused_usr_toks</code></td> + <td> + Whether or not unused user-defined tokens should be + ignored (value <code>true</code>) or reject the intent match (value <code>false</code>). + By default, tne unused user tokens are not ignored since it is assumed that user would + defined his or her own tokens on purpose and construct the intent logic appropriate. + </td> + <td><code>false</code></td> + </tr> + <tr> + <td><code>allow_stm_only</code></td> + <td> + Whether or not the intent can match when all of the matching tokens came from STM. + By default, this special case is disabled (value <code>false</code>). However, in specific intents + designed for free-form language comprehension scenario, like, for example, SMS messaging - you + may want to enable this option. + </td> + <td><code>false</code></td> + </tr> + </tbody> + </table> </dd> <dt> <code>flow="^(?:login)(^:logout)*$"</code> <sup><small>line 2</small></sup><br/> - <code>flow=/#flowModelMethod/</code> <sup><small>line 13</small></sup> + <code>flow=/#flowModelMethod/</code> <sup><small>line 20</small></sup> </dt> <dd> <p> @@ -276,7 +313,7 @@ id: intent_matching <code style="padding-left: 20px">@usrTypes = meta_model('user_types')</code><br> <code style="padding-left: 20px">(tokId == 'order' || tokId == 'order_cancel') && has_all(@usrTypes, list(1, 2, 3))</code><br> <code>}</code><br> - <code>term(a)=/org.mypackage.MyClass#termMethod/?</code> <sup><small>line 15</small></sup> + <code>term(a)=/org.mypackage.MyClass#termMethod/?</code> <sup><small>line 21</small></sup> </dt> <dd> <p> @@ -392,7 +429,7 @@ id: intent_matching </p> </dd> <dt> - <code>fragment(frag, {'p1': 25, 'p2': {'a': false}})</code> <sup><small>line 16 </small></sup><br> + <code>fragment(frag, {'p1': 25, 'p2': {'a': false}})</code> <sup><small>line 22 </small></sup><br> </dt> <dd> <p> @@ -507,7 +544,7 @@ id: intent_matching </p> <h2 class="section-sub-title">Intent Examples <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> <p> - Here's number of intent examples with explanations: + Here's few of intent examples with explanations: </p> <p> <b>Example 1:</b> @@ -526,10 +563,13 @@ id: intent_matching Intent uses default conversational support (<code>true</code>) and default order (<code>false</code>). </li> <li> - Intent has two conversational terms that have to be found for the intent to match. Note that second + Intent has two conversational terms (<code>~</code>) that have to be found for the intent to match. Note that second term is optional as it has <code>[0,2]</code> quantifier. </li> <li> + Both terms have to be found in the user input for the intent to match. + </li> + <li> First term matches any single token with ID <code>x:id</code>. </li> <li> @@ -564,7 +604,10 @@ id: intent_matching <code>id2</code> somewhere in the history of previously matched intents in the course of the current conversation. </li> <li> - Intent has two non-conversational terms. Both terms have to be present only once (their implicit quantifiers are <code>[1,1]</code>). + Intent has two non-conversational terms (<code>=</code>). Both terms have to be present only once (their implicit quantifiers are <code>[1,1]</code>). + </li> + <li> + Both terms have to be found in the user input for the intent to match. </li> <li> First term should be a token with ID <code>mytok</code> and have metadata property <code>score</code> of type @@ -632,7 +675,7 @@ id: intent_matching <tr><td><code>java.lang.Boolean</code></td><td><code>Boolean</code></td><td>You can use <code><b>true</b></code> or <code><b>false</b></code> literals.</td></tr> <tr><td><code>java.util.List<T></code></td><td><code>List[T]</code></td><td>Use <code>list(...)</code> IDL function to create new list.</td></tr> <tr><td><code>java.util.Map<K,V></code></td><td><code>Map[K,V]</code></td><td></td></tr> - <tr><td><code><a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken">NCToken</a></code></td><td><code>Token</code></td><td></td></tr> + <tr><td><code><a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCToken.html">NCToken</a></code></td><td><code>Token</code></td><td></td></tr> <tr><td><code>java.lang.Object</code></td><td><code>Any</code></td><td>Any of the supported types above. Use <code><b>null</b></code> literal for null value.</td></tr> </tbody> </table> diff --git a/short-term-memory.html b/short-term-memory.html index 9d182a6..255294b 100644 --- a/short-term-memory.html +++ b/short-term-memory.html @@ -24,20 +24,12 @@ id: short_term_memory <div id="short-term-memory" class="col-md-8 second-column"> <section id="stm"> <h2 class="section-title">Conversation <span class="amp">&</span> STM <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> - <div class="bq info"> - <b>Short-Term Memory</b> - <p> - Read more in-depth explanation about maintaining conversational context and - Short-Term Memory in this <a href="/blogs/short_term_memory.html">blog.</a> - </p> - </div> - <p> - NLPCraft provides automatic conversation management right out of the box. - Conversation management is based on the idea of short-term memory (STM). STM is automatically - maintained by NLPCraft per each user and data model. Essentially, NLPCraft "remembers" - the context of the conversation and can supply the currently missing elements from its memory (i.e. from STM). - STM implementation is also fully integrated with intent matching. + NLPCraft provides automatic conversation management right out of the box that is fully integrated with + <a href="/intent-matching.html">intent matching</a>. Conversation management is based on the idea of short-term memory (STM). STM is automatically + maintained by NLPCraft per each user and data model combination. Essentially, NLPCraft "remembers" + the context of the conversation and can supply the currently missing elements from STM + to the intent matching algorithm for the conversational terms. </p> <p> Maintaining conversation state is necessary for effective context resolution, so that users @@ -120,6 +112,401 @@ id: short_term_memory via <a href="https://github.com/apache/incubator-nlpcraft/blob/master/openapi/nlpcraft_swagger.yml" target="github">REST API</a>. </p> </section> + <section> + {% include latest_ver_blog_warn.html %} + <p> + In this blog, I'll try to give a high-level overview of STM - Short-Term Memory, a technique used to + maintain conversational context in NLPCraft. Maintaining the proper conversation context - remembering + what the current conversation is about - is essential for all human interaction and thus essential for + computer-based natural language understanding. To my knowledge, NLPCraft provides one of the most advanced + implementations of STM, especially considering how tightly it is integrated with NLPCraft's unique + intent-based matching (Google's <a target=google href="https://cloud.google.com/dialogflow/">DialogFlow</a> is very similar yet). + </p> + <p> + Let's dive in. + </p> + </section> + <section> + <h2 class="section-title">Parsing User Input <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + One of the key objectives when parsing user input sentence for Natural Language Understanding (NLU) is to + detect all possible semantic entities, a.k.a <em>named entities</em>. Let's consider a few examples: + </p> + <ul> + <li> + <code>"What's the current weather in Tokyo?"</code><br/> + This sentence is fully sufficient for the processing + since it contains the topic <code>weather</code> as well as all necessary parameters + like time (<code>current</code>) and location (<code>Tokyo</code>). + </li> + <li> + <code>"What about Tokyo?"</code><br/> + This is an unclear sentence since it does not have the subject of the + question - what is it about Tokyo? + </li> + <li> + <code>"What's the weather?"</code><br/> + This is also unclear since we are missing important parameters + of location and time for our request. + </li> + </ul> + <p> + Sometimes we can use default values like the current user's location and the current time (if they are missing). + However, this can lead to the wrong interpretation if the conversation has an existing context. + </p> + <p> + In real life, as well as in NLP-based systems, we always try to start a conversation with a fully defined + sentence since without a context the missing information cannot be obtained and the sentenced cannot be interpreted. + </p> + </section> + <section> + <h2 class="section-title">Semantic Entities <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + Let's take a closer look at the named entities from the above examples: + </p> + <ul> + <li> + <code>weather</code> - this is an indicator of the subject of the conversation. Note that it indicates + the type of question rather than being an entity with multiple possible values. + </li> + <li> + <code>current</code> - this is an entity of type <code>Date</code> with the value of <code>now</code>. + </li> + <li> + <code>Tokyo</code> - this is an entity of type <code>Location</code> with two values: + <ul> + <li><code>city</code> - type of the location.</li> + <li><code>Tokyo, Japan</code> - normalized name of the location.</li> + </ul> + </li> + </ul> + <p> + We have two distinct classes of entities: + </p> + <ul> + <li> + Entities that have no values and only act as indicators or types. The entity <code>weather</code> is the + type indicator for the subject of the user input. + </li> + <li> + Entities that additionally have one or more specific values like <code>current</code> and <code>Tokyo</code> entities. + </li> + </ul> + <div class="bq info"> + <div style="display: inline-block; margin-bottom: 20px"> + <a style="margin-right: 10px" target=_ href="https://opennlp.apache.org"><img src="/images/opennlp-logo-h32.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://cloud.google.com/natural-language/"><img src="/images/google-cloud-logo-small-h32.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://stanfordnlp.github.io/CoreNLP"><img src="/images/corenlp-logo-h48.png" alt=""></a> + <a style="margin-right: 10px" target=_ href="https://spacy.io"><img src="/images/spacy-logo-h32.png" alt=""></a> + </div> + <p> + Note that NLPCraft provides <a href="/integrations.html">support</a> for wide variety of named entities (with all built-in ones being properly normalized) + including <a href="/integrations.html">integrations</a> with + <a target="spacy" href="https://spacy.io/">spaCy</a>, + <a target="stanford" href="https://stanfordnlp.github.io/CoreNLP">Stanford CoreNLP</a>, + <a target="opennlp" href="https://opennlp.apache.org/">OpenNLP</a> and + <a target="google" href="https://cloud.google.com/natural-language/">Google Natural Language</a>. + </p> + </div> + </section> + <section> + <h2 class="section-title">Incomplete Sentences <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + Assuming previously asked questions about the weather in Tokyo (in the span of the ongoing conversation) one + could presumably ask the following questions using a <em>shorter, incomplete</em>, form: + </p> + <ul> + <li> + <code>"What about Kyoto?</code><br/> + This question is missing both the subject and the time. However, we + can safely assume we are still talking about current weather. + </li> + <li> + <code>"What about tomorrow?"</code><br/> + Like above we automatically assume the weather subject but + use <code>Kyoto</code> as the location since it was mentioned the last. + </li> + </ul> + <p> + These are incomplete sentences. This type of short-hands cannot be interpreted without prior context (neither + by humans or by machines) since by themselves they are missing necessary information. + In the context of the conversation, however, these incomplete sentences work. We can simply provide one or two + entities and rely on the <em>"listener"</em> to recall the rest of missing information from a + <em>short-term memory</em>, a.k.a conversation context. + </p> + <p> + In NLPCraft, the intent-matching logic will automatically try to find missing information in the + conversation context (that is automatically maintained). Moreover, it will properly treat such recalled + information during weighted intent matching since it naturally has less "weight" than something that was + found explicitly in the user input. + </p> + </section> + <section> + <h2 class="section-title">Short-Term Memory <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + The short-term memory is exactly that... a memory that keeps only small amount of recently used information + and that evicts its contents after a short period of inactivity. + </p> + <p> + Let's look at the example from a real life. If you would call your friend in a couple of hours asking <code>"What about a day after?"</code> + (still talking about weather in Kyoto) - he'll likely be thoroughly confused. The conversation is timed out, and + your friend has lost (forgotten) its context. You will have to explain again to your confused friend what is that you are asking about... + </p> + <p> + NLPCraft has a simple rule that 5 minutes pause in conversation leads to the conversation context reset. However, + what happens if we switch the topic before this timeout elapsed? + </p> + </section> + <section> + <h2 class="section-title">Context Switch <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + Resetting the context by the timeout is, obviously, not a hard thing to do. What can be trickier is to detect + when conversation topic is switched and the previous context needs to be forgotten to avoid very + confusing interpretation errors. It is uncanny how humans can detect such switch with seemingly no effort, and yet + automating this task by the computer is anything but effortless... + </p> + <p> + Let's continue our weather-related conversation. All of a sudden, we ask about something completely different: + </p> + <ul> + <li> + <code>"How much mocha latter at Starbucks?"</code><br/> + At this point we should forget all about previous conversation about weather and assume going forward + that we are talking about coffee in Starbucks. + </li> + <li> + <code>"What about Peet's?"</code><br/> + We are talking about latter at Peet's. + </li> + <li> + <code>"...and croissant?"</code><br/> + Asking about Peet's crescent-shaped fresh rolls. + </li> + </ul> + <p> + Despite somewhat obvious logic the implementation of context switch is not an exact science. Sometimes, you + can have a "soft" context switch where you don't change the topic of the conversation 100% but yet sufficiently + enough to forget at least some parts of the previously collected context. NLPCraft has a built-in algorithm + to detect the hard switch in the conversation. It also exposes API to perform a selective reset on the + conversation in case of "soft" switch. + </p> + </section> + <section> + <h2 class="section-title">Overriding Entities <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + As we've seen above one named entity can replace or override an older entity in the STM, e.g. <code>"Peet's"</code> + replaced <code>"Starbucks"</code> in our previous questions. <b>The actual algorithm that governs this logic is one + of the most important part of STM implementation.</b> In human conversations we perform this logic seemingly + subconsciously — but the computer algorithm to do it is not that trivial. Let's see how it is done in NLPCraft. + </p> + <p> + One of the important supporting design decision is that an entity can belong to one or more groups. You can think of + groups as types, or classes of entities (to be mathematically precise these are the categories). The entity's + membership in such groups is what drives the rule of overriding. + </p> + <p> + Let's look at the specific example. + </p> + <p> + Consider a data model that defined 3 entities: + </p> + <ul> + <li> + <code>"sell"</code> (with synonym <code>"sales"</code>) + </li> + <li> + <code>"buy"</code> (with synonym <code>"purchase"</code>) + </li> + <li> + <code>"best_employee"</code> (with synonyms like <code>"best"</code>, <code>"best employee"</code>, <code>"best colleague"</code>) + </li> + </ul> + <p> + Our task is to support for following conversation: + </p> + <ul> + <li> + <code>"Give me the sales data"</code><br/> + We return sales information since we detected <code>"sell"</code> entity by its synonym <code>"sales"</code>. + </li> + <li> + <code>"Who was the best?"</code><br/> + We return the best salesmen since we detected <code>"best_employee"</code> and we should pick <code>"sell"</code> entity from the STM. + </li> + <li> + <code>"OK, give me the purchasing report now."</code><br/> + This is a bit trickier. We should return general purchasing data and not a best purchaser employee. + It feels counter-intuitive but we should NOT take <code>"best_employee"</code> entity from STM and, in fact, we should remove it from STM. + </li> + <li> + <code>"...and who's the best there?"</code><br/> + Now, we should return the best purchasing employee. We detected <code>"best_employee"</code> entity and we should pick <code>"buy"</code> entity from STM. + </li> + <li> + <code>"One more time - show me the general purchasing data again"</code><br/> + Once again, we should return a general purchasing report and ignore (and remove) <code>"best_employee"</code> from STM. + </li> + </ul> + </section> + <section> + <h2 class="section-title">Overriding Rule <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + Here's the rule we developed at NLPCraft and have been successfully using in various models: + </p> + <div class="bq success"> + <div class="bq-idea-container"> + <div><div>💡</div></div> + <div> + <b>Overriding Rule</b> + <p> + The entity will override other entity or entities in STM that belong to the same group set or its superset. + </p> + </div> + </div> + </div> + <p> + In other words, an entity with a smaller group set (more specific one) will override entity with the same + or larger group set (more generic one). + Let's consider an entity that belongs to the following groups: <code>{G1, G2, G3}</code>. This entity: + </p> + <ul> + <li> + WILL override existing entity belonging to <code>{G1, G2, G3}</code> groups (same set). + </li> + <li> + WILL override existing entity belonging to <code>{G1, G2, G3, G4}</code> groups (superset). + </li> + <li> + WILL NOT override existing entity belonging to <code>{G1, G2}</code> groups. + </li> + <li> + WIL NOT override existing entity belonging to <code>{G10, G20}</code> groups. + </li> + </ul> + <p> + Let's come back to our sell/buy/best example. To interpret the questions we've outlined above we need to + have the following 4 intents: + </p> + <ul> + <li><code>id=sale term={tok_id() == 'sale'}</code></li> + <li><code>id=best_sale_person term={tok_id() == 'sale'} term={tok_id() == best_employee}</code></li> + <li><code>id=buy term={tok_id() == 'buy'}</code></li> + <li><code>id=buy_best_person term={tok_id() == 'buy'} term={tok_id() == best_employee}</code></li> + </ul> + <p> + (this is actual <a href="/intent-matching.html">Intent Definition Language</a> (IDL) used by NLPCraft - + <code>term</code> here is basically what's often referred to as a slot in other systems). + </p> + <p> + We also need to properly configure groups for our entities (names of the groups are arbitrary): + </p> + <ul> + <li>Entity <code>"sell"</code> belongs to group <b>A</b></li> + <li>Entity <code>"buy"</code> belongs to group <b>B</b></li> + <li>Entity <code>"best_employee"</code> belongs to groups <b>A</b> and <b>B</b></li> + </ul> + <p> + Let’s run through our example again with this configuration: + </p> + <ul> + <li> + <code>"Give me the sales data"</code> + <ul> + <li>We detected entity from group <b>A</b>.</li> + <li>STM is empty at this point.</li> + <li>Return general sales report.</li> + <li>Store <code>"sell"</code> entity with group <b>A</b> in STM.</li> + </ul> + </li> + <li> + <code>"Who was the best?"</code> + <ul> + <li>We detected entity belonging to groups <b>A</b> and <b>B</b>.</li> + <li>STM has entity belonging to group <b>A</b>.</li> + <li><b>{A, B}</b> does NOT override <b>{A}</b>.</li> + <li>Return best salesmen report.</li> + <li>Store detected <code>"best_employee"</code> entity.</li> + <li>STM now has two entities with <b>{A}</b> and <b>{A, B}</b> group sets.</li> + </ul> + </li> + <li> + <code>"OK, give me the purchasing report now."</code> + <ul> + <li>We detected <code>"buy"</code> entity with group <b>A</b>.</li> + <li>STM has two entities with <b>{A}</b> and <b>{A, B}</b> group sets.</li> + <li><b>{A}</b> overrides both <b>{A}</b> and <b>{A, B}</b>.</li> + <li>Return general purchasing report.</li> + <li>Store <code>"buy"</code> entity with group <b>A</b> in STM.</li> + </ul> + </li> + </ul> + <p> + And so on... easy, huh 😇 In fact, the logic is indeed relatively straightforward. It also follows + common sense where the logic produced by this rule matches the expected human behavior. + </p> + </section> + <section> + <h2 class="section-title">Explicit Context Switch <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + In some cases you may need to explicitly clear the conversation STM without relying on algorithmic behavior. + It happens when current and new topic of the conversation share some of the same entities. Although at first + it sounds counter-intuitive there are many examples of that in day to day life. + </p> + <p> + Let’s look at this sample conversation: + </p> + <ul> + <li> + <b>Q</b>: <code>"What the weather in Tokyo?"</code><br/> + <b>A</b>: Current weather in Tokyo... + </li> + <li> + <b>Q</b>: <code>"Let’s do New York after all then!"</code><br/> + <b>A</b>: Without an explicit conversation reset we would return current New York weather 🤔 + </li> + </ul> + <p> + The second question was about going to New York (booking tickets, etc.). In real life - your + counterpart will likely ask what you mean by "doing New York after all" and you’ll have to explain + the abrupt change in the topic. + You can avoid this confusion by simply saying: "Enough about weather! Let’s talk about this weekend plans" - after + which the second question becomes clear. That sentence is an explicit context switch which you can also detect + in the NLPCraft model. + </p> + <p> + In NLPCraft you can also explicitly reset conversation context through API or by switching the model on the request. + </p> + </section> + <section> + <h2 class="section-title">Summary <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2> + <p> + Let’s collect all our thoughts on STM into a few bullet points: + </p> + <ul> + <li> + Missing entities in incomplete sentences can be auto-recalled from STM. + </li> + <li> + Newly detected type/category entity is likely indicating the change of topic. + </li> + <li> + The key property of STM is its short-time storage and overriding rule. + </li> + <li> + The explicit context switch is an important mechanism. + </li> + </ul> + <div class="bq info"> + <b> + Short-Term Memory + </b> + <p> + It is uncanny how properly implemented STM can make conversational interface <b>feel like a normal human + conversation</b>. It allows to minimize the amount of parasitic dialogs and Q&A driven interfaces + without unnecessarily complicating the implementation of such systems. + </p> + </div> + </section> </div> <div class="col-md-2 third-column"> <ul class="side-nav">