You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2022/10/14 08:36:59 UTC
[incubator-nlpcraft-website] branch NLPCRAFT-513 created (now 726c2b0)
This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a change to branch NLPCRAFT-513
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft-website.git
at 726c2b0 WIP.
This branch includes the following new commits:
new 726c2b0 WIP.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[incubator-nlpcraft-website] 01/01: WIP.
Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a commit to branch NLPCRAFT-513
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft-website.git
commit 726c2b0907f2cfb7175038f2f2928c69b88a1e83
Author: skhdl <sk...@gmail.com>
AuthorDate: Fri Oct 14 12:36:49 2022 +0400
WIP.
---
examples/light_switch.html | 410 ++++++++++++++-------------------------------
1 file changed, 123 insertions(+), 287 deletions(-)
diff --git a/examples/light_switch.html b/examples/light_switch.html
index 81fbaa3..d60700d 100644
--- a/examples/light_switch.html
+++ b/examples/light_switch.html
@@ -40,137 +40,111 @@ fa_icon: fa-cube
<section id="new_project">
<h2 class="section-title">Create New Project <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
<p>
- You can create new Scala projects in many ways - we'll use <a href="/tools/script.html">NLPCraft CLI</a>
+ You can create new Scala projects in many ways - we'll use SBT
to accomplish this task:
</p>
- <nav>
- <div class="nav nav-tabs" role="tablist">
- <a class="nav-item nav-link active" data-toggle="tab" href="#nav-prj-cmd" role="tab">Command</a>
- <a class="nav-item nav-link" data-toggle="tab" href="#nav-prj-out" role="tab">Output <i class="fa fa-desktop output"></i></a>
- </div>
- </nav>
- <div class="tab-content">
- <div class="tab-pane fade show active" id="nav-prj-cmd" role="tabpanel">
- <pre class="brush: bash">
- $ bin/nlpcraft.sh gen-project --baseName=LightSwitch --outputDir=~ --pkgName=demo --lang=scala
- </pre>
- <p>
- <b>NOTES:</b>
- </p>
- <ul>
- <li>
- New project created in <code>/home/LightSwitch</code> directory.
- </li>
- <li>
- <code>gen-project</code> command defaults to Java and Maven as its built tool.
- </li>
- <li>
- Run <code class="script">bin/nlpcraft.sh help --cmd=gen-project</code> to get a full help on <code>gen-project</code> command.
- </li>
- <li>
- <a href="/tools/script.html">NLPCraft CLI</a> is available as <code>nlpcraft.sh</code> for
- <i class="fab fa-fw fa-linux"></i> and <code>nlpcraft.cmd</code>
- for <i class="fab fa-fw fa-windows"></i>.
- </li>
- </ul>
- </div>
- <div class="tab-pane fade show" id="nav-prj-out" role="tabpanel">
- <p></p>
- <img alt="" class="img-fluid" src="/images/light_switch_fig1.png">
- </div>
- </div>
+ <pre class="brush: js, highlight: []">
+ ThisBuild / version := "0.1.0-SNAPSHOT"
+ ThisBuild / scalaVersion := "3.1.3"
+ lazy val root = (project in file("."))
+ .settings(
+ name := "NLPCraft LightSwitch Example",
+ version := "1.0.0",
+ libraryDependencies += "org.apache.nlpcraft" % "nlpcraft" % "1.0.0",
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.14" % "test"
+ )
+ </pre>
+ <p> Make in prepared project following files: </p>
+ <ul>
+ <li><code>lightswitch_model.yaml</code> - YAML configuration file, which contains model description.</li>
+ <li><code>LightSwitchScalaModel.scala</code> - scala class, model representation.</li>
+ <li><code>NCModelValidationSpec.scala</code> - scala tests class, which allows to test your model.</li>
+ </ul>
+ <p> Look at the result SBT project files structure below: </p>
+ <pre class="brush: js, highlight: [10, 18, 27]">
+ C:.
+ | build.sbt
+ |
+ +---project
+ | build.properties
+ |
+ \---src
+ +---main
+ | +---resources
+ | | lightswitch_model.yaml
+ | |
+ | \---scala
+ | \---demo
+ | LightSwitchScalaModel.scala
+ |
+ \---test
+ \---scala
+ \---demo
+ NCModelValidationSpec.scala
+ </pre>
</section>
<section id="model">
- <h2 class="section-title">Data Model <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
+ <h2 class="section-title">Data Model Description<a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
<p>
We are going to start with declaring the static part of our model using YAML which we will later load using
- <code>NCModelFileAdapter</code> in our Scala-based model implementation. Open <code>src/main/resources/<b>light_switch.yaml</b></code>
+ <code>NCModelAdapter</code> in our Scala-based model implementation.
+ Open <code>src/main/resources/<b>light_switch.yaml</b></code>
file and replace its content with the following YAML:
</p>
- <pre class="brush: js, highlight: [6, 22, 23, 26, 33, 41, 52]">
-id: "nlpcraft.lightswitch.ex"
-name: "Light Switch Example Model"
-version: "1.0"
-description: "NLI-powered light switch example model."
-
-macros:
- - name: "<ACTION>"
- macro: "{turn|switch|dial|let|set|get|put}"
- - name: "<KILL>"
- macro: "{shut|kill|stop|eliminate}"
- - name: "<ENTIRE_OPT>"
- macro: "{entire|full|whole|total|_}"
- - name: "<FLOOR_OPT>"
- macro: "{upstairs|downstairs|{1st|2nd|3rd|4th|5th|top|ground} floor|_}"
- - name: "<TYPE>"
- macro: "{room|closet|attic|loft|{store|storage} {room|_}}"
- - name: "<LIGHT>"
- macro: "{all|_} {it|them|light|illumination|lamp|lamplight}"
-
-enabledBuiltInTokens: []
-
-permutateSynonyms: true
-sparse: true
-
-elements:
- - id: "ls:loc"
- description: "Location of lights."
- synonyms:
- - "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}"
- - "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}"
- - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
-
- - id: "ls:on"
- groups:
- - "act"
- description: "Light switch ON action."
- synonyms:
- - "<ACTION> {on|up|_} <LIGHT> {on|up|_}"
- - "<LIGHT> {on|up}"
-
- - id: "ls:off"
- groups:
- - "act"
- description: "Light switch OFF action."
- synonyms:
- - "<ACTION> <LIGHT> {off|out}"
- - "{<ACTION>|<KILL>} {off|out} <LIGHT>"
- - "<KILL> <LIGHT>"
- - "<LIGHT> <KILL>"
- - "no <LIGHT>"
-
-intents:
- - "intent=ls term(act)={has(tok_groups, 'act')} term(loc)={# == 'ls:loc'}*"
+ <pre class="brush: js, highlight: [1, 10, 17, 25]">
+ macros:
+ "<ACTION>" : "{turn|switch|dial|let|set|get|put}"
+ "<KILL>" : "{shut|kill|stop|eliminate}"
+ "<ENTIRE_OPT>" : "{entire|full|whole|total|_}"
+ "<FLOOR_OPT>" : "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}"
+ "<TYPE>" : "{room|closet|attic|loft|{store|storage} {room|_}}"
+ "<LIGHT>" : "{all|_} {it|them|light|illumination|lamp|lamplight}"
+
+ elements:
+ - id: "ls:loc"
+ description: "Location of lights."
+ synonyms:
+ - "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}"
+ - "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}"
+ - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+
+ - id: "ls:on"
+ groups:
+ - "act"
+ description: "Light switch ON action."
+ synonyms:
+ - "<ACTION> {on|up|_} <LIGHT> {on|up|_}"
+ - "<LIGHT> {on|up}"
+
+ - id: "ls:off"
+ groups:
+ - "act"
+ description: "Light switch OFF action."
+ synonyms:
+ - "<ACTION> <LIGHT> {off|out|down}"
+ - "{<ACTION>|<KILL>} {off|out|down} <LIGHT>"
+ - "<KILL> <LIGHT>"
+ - "<LIGHT> <KILL>"
+ - "{out|no|off|down} <LIGHT>"
+ - "<LIGHT> {out|off|down}"
</pre>
<p>There are number of important points here:</p>
<ul>
<li>
- <code>Line 6</code> defines several macros that are used later on throughout the model's elements
+ <code>Line 1</code> defines several macros that are used later on throughout the model's elements
to shorten the synonym declarations. Note how macros coupled with option groups
shorten overall synonym declarations 1000:1 vs. manually listing all possible word permutations.
</li>
<li>
- <code>Lines 22, 23</code> define model properties that allow for multi-word synonyms in this model
- to be
- <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCModelView.html#isSparse()">sparse</a> and
- <a class="not-code" target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCModelView.html#isPermutateSynonyms()">permutate</a> them for better detection. These two properties generally enable a free-form
- natural language comprehension.
- </li>
- <li>
- <code>Lines 26, 33, 41</code> define three model elements: the location of the light, and actions to turn
+ <code>Lines 10, 17, 25</code> define three model elements: the location of the light, and actions to turn
the light on and off. Action elements belong to the same group <code>act</code> which
- will be used in our intent (<code>line 42</code>). Note that these model elements are defined mostly
+ will be used in our intent, defined in <code>LightSwitchScalaModel</code>. Note that these model elements are defined mostly
through macros we have provided above.
</li>
- <li>
- On <code>line 52</code> we define a non-conversational intent <code>ls</code> that requires
- one action (a token belonging to the group <code>act</code>) and optional list of light locations
- (zero or more tokens with ID <code>ls:loc</code>) - by default we assume the entire house as a default location.
- </li>
</ul>
<p>
- Now that our model is ready let's create a Java class that would load this model and provide the actual
- callback for when the intent <code>ls</code> is detected in the user input.
+ Note that this YAML model elements description is optional and all elements definitions can be provided inside
+ Scala model <code>LightSwitchScalaModel</code>.
</p>
</section>
<section id="code">
@@ -178,47 +152,29 @@ intents:
<p>
Open <code>src/main/scala/demo/<b>LightSwitch.scala</b></code> file and replace its content with the following code:
</p>
- <pre class="brush: scala, highlight: [5, 6, 7, 25, 26, 38]">
-package demo
-
-import org.apache.nlpcraft.model.{NCIntentTerm, _}
-
-class LightSwitch extends NCModelFileAdapter("light_switch.yaml") {
- @NCIntentRef("ls")
- @NCIntentSample(Array(
- "Turn the lights off in the entire house.",
- "Turn off all lights now",
- "Switch on the illumination in the master bedroom closet.",
- "Get the lights on.",
- "Lights up in the kitchen.",
- "Please, put the light out in the upstairs bedroom.",
- "Set the lights on in the entire house.",
- "Turn the lights off in the guest bedroom.",
- "Could you please switch off all the lights?",
- "Dial off illumination on the 2nd floor.",
- "Please, no lights!",
- "Kill off all the lights now!",
- "No lights in the bedroom, please.",
- "Light up the garage, please!",
- "Kill the illumination now!"
- ))
- def onMatch(
- @NCIntentTerm("act") actTok: NCToken,
- @NCIntentTerm("loc") locToks: List[NCToken]
- ): NCResult = {
- val status = if (actTok.getId == "ls:on") "on" else "off"
- val locations =
- if (locToks.isEmpty)
- "entire house"
- else
- locToks.map(_.getOriginalText()).mkString(", ")
-
- // Add HomeKit, Arduino or other integration here.
-
- // By default - return a descriptive action string.
- NCResult.text(s"Lights '$status' in '${locations.toLowerCase}'.")
- }
-}
+ <pre class="brush: scala, highlight: [6, 7, 8, 10, 11, 14, 15, 22]">
+ package demo
+
+ import org.apache.nlpcraft.*
+ import org.apache.nlpcraft.annotations.*
+
+ class LightSwitchScalaModel extends NCModelAdapter(
+ NCModelConfig("nlpcraft.lightswitch.java.ex", "LightSwitch Example Model", "1.0"),
+ new NCPipelineBuilder().withSemantic("en", "lightswitch_model.yaml").build
+ ):
+ @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*")
+ def onMatch(
+ ctx: NCContext,
+ im: NCIntentMatch,
+ @NCIntentTerm("act") actEnt: NCEntity,
+ @NCIntentTerm("loc") locEnts: List[NCEntity]
+ ): NCResult =
+ val status = if actEnt.getId == "ls:on" then "on" else "off"
+ val locations = if locEnts.isEmpty then "entire house" else locEnts.map(_.mkText).mkString(", ")
+
+ // Add HomeKit, Arduino or other integration here.=
+ // By default - just return a descriptive action string.
+ NCResult(s"Lights are [$status] in [${locations.toLowerCase}].")
</pre>
<p>
The intent callback logic is very simple - we return a descriptive confirmation message
@@ -227,160 +183,43 @@ class LightSwitch extends NCModelFileAdapter("light_switch.yaml") {
</p>
<ul>
<li>
- On <code>line 5</code> our class extends <code>NCModelFileAdapter</code> that allows us to load most
- of the model declaration from the external YAML file and only provide functionality that we
- couldn't express in declarative portion in YAML.
- </li>
- <li>
- <code>Line 6</code> annotates method <code>onMatch</code> as a callback for the intent <code>ls</code>
- when it is detected in the user input. Note that intent <code>ls</code> is defined in the <code>light_switch.yaml</code>
- file that was loaded by <code>NCModelFileAdapter</code> class.
+ On <code>line 5</code> our class extends <code>NCModelAdapter</code> that allows us to pass
+ prepared configuration and pipeline into model.
</li>
<li>
- Note the <code>line 7</code> where we use <a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCIntentSample.html">@NCIntentSample</a>
- annotation to provide samples of the user input that this intent should match. Apart from documentation
- purpose these samples will be used when we will be <a href="#testing">testing out model below.</a>
+ On <code>line 6</code> created model configuration with most default parameters.
</li>
<li>
- <code>Lines 25 and 26</code> map terms from detected intent to the formal method parameters of the
- <code>onMatch</code> method.
+ On <code>line 7</code> created pipeline, based on semantic model definition,
+ described in <code>lightswitch_model.yaml</code> file.
</li>
<li>
- On the <code>line 38</code> the intent callback simply returns a confirmation message.
- </li>
- </ul>
- </section>
- <section id="build_project">
- <h2 class="section-title">Build Project <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
- <p>
- Once we have our model ready let's go to <code>~/LightSwitch</code> directory and run the Maven build:
- </p>
- <pre class="brush: bash">
- $ cd ~/LightSwitch
- $ mvn clean package
- </pre>
- <p>
- At this stage we have our project built and we are ready to start testing.
- </p>
- </section>
- <section id="start_server">
- <h2 class="section-title">Start Server <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
- <p>
- Run the following command to start local REST server, if it hasn't been started already, from the NLPCraft installation directory:
- </p>
- <nav>
- <div class="nav nav-tabs" role="tablist">
- <a class="nav-item nav-link active" data-toggle="tab" href="#nav-srv-cmd" role="tab">Command</a>
- <a class="nav-item nav-link" data-toggle="tab" href="#nav-srv-out" role="tab">Output <i class="fa fa-desktop output"></i></a>
- </div>
- </nav>
- <div class="tab-content">
- <div class="tab-pane fade show active" id="nav-srv-cmd" role="tabpanel">
- <pre class="brush: bash">
- $ bin/nlpcraft.sh start-server
- </pre>
- </div>
- <div class="tab-pane fade show" id="nav-srv-out" role="tabpanel">
- <p></p>
- <p>
- <img class="img-fluid" alt="" src="/images/server-fig1.png">
- </p>
- </div>
- </div>
- <p>
- <b>NOTES:</b>
- </p>
- <ul>
- <li>
- <i style="color: #F39C12" class="fa fa-exclamation-triangle"></i> REST server is a "fire-and-forget" component that you generally need to start it only once
- for this and other examples.
+ <code>Lines 10 and 11</code> annotates intents <code>ls</code> and its callback method <code>onMatch</code>.
+ Intent <code>ls</code> requires one action (a token belonging to the group act) and optional list of light locations
+ (zero or more tokens with ID ls:loc) - by default we assume the entire house as a default location.
</li>
<li>
- Run <code class="script">bin/nlpcraft.sh help --cmd=start-server</code> to get a full help on this command.
+ <code>Lines 14 and 15</code> map terms from detected intent to the formal method parameters of the
+ <code>onMatch</code> method.
</li>
<li>
- <a href="/tools/script.html">NLPCraft CLI</a> is available as <code>nlpcraft.sh</code> for
- <i class="fab fa-fw fa-linux"></i> and <code>nlpcraft.cmd</code>
- for <i class="fab fa-fw fa-windows"></i>.
+ On the <code>line 22</code> the intent callback simply returns a confirmation message.
</li>
</ul>
</section>
+
<section id="testing">
<h2 class="section-title">Testing <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
<p>
- Remember the <a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCIntentSample.html">@NCIntentSample</a>
- annotation we have used in our model code next to intent definition?
- </p>
- <p>
- Part of the <a href="/tools/test_framework.html">test framework</a>, the auto-validator class <a
- target="javadoc"
- href="/apis/latest/org/apache/nlpcraft/model/tools/test/NCTestAutoModelValidator.html">NCTestAutoModelValidator</a> takes one or more model IDs
- (or class names) and performs validation. Validation consists of starting an <a href="/tools/embedded_probe.html">embedded probe</a> with a given model,
- scanning for <a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCIntentSample.html">@NCIntentSample</a> and
- <a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCIntentSampleRef.html">@NCIntentSampleRef</a> annotations
- and their corresponding callback methods, submitting each sample input
- sentences from these annotations and checking that resulting intent matches the intent the sample was attached to.
- Note that auto-testing does not require any additional code to be written - the class gathers all required information from the model
- itself.
- </p>
- <p>
- As always, you can launch model auto-validator as any other Java class but we'll use NLPCraft CLI
- to do it more conveniently:
- </p>
- <pre class="brush: bash">
- $ bin/nlpcraft.sh test-model --cp=~/LightSwitch/target/classes --mdls=demo.LightSwitch
- </pre>
- <p>
- <b>NOTES:</b>
- </p>
- <ul>
- <li>
- Run <code class="script">bin/nlpcraft.sh help --cmd=test-model</code> to get a full help on this command.
- </li>
- <li>
- Note that you can use <code>retest-model</code> command in REPL mode to re-run the last model test
- avoiding the retyping of all required parameters.
- </li>
- <li>
- <a href="/tools/script.html">NLPCraft CLI</a> is available as <code>nlpcraft.sh</code> for
- <i class="fab fa-fw fa-linux"></i> and <code>nlpcraft.cmd</code>
- for <i class="fab fa-fw fa-windows"></i>.
- </li>
- </ul>
- <p>
- Look at the output of this command and you will see the test results for all our sample utterances:
- </p>
- <p>
- <img style="max-width: 928px !important;" class="img-fluid" alt="" src="/images/light-switch-test.png">
- </p>
- </section>
- <section id="rinse">
- <h2 class="section-title">Rinse <span class="amp">&</span> Repeat <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
- <p>
- Typical development cycle consists of:
- </p>
- <ul>
- <li>
- <a href="#model">Modifying the model</a>
- </li>
- <li>
- <a href="#build_project">Re-building the project</a>
- </li>
- <li>
- <a href="#testing">Re-running the test</a>
- </li>
- </ul>
- <p>
- All of these operations can be performed from <a href="/tools/script.html">NLPCraft CLI</a> in REPL mode or from any IDE.
- </p>
- <p>
- NOTE: you don't need to restart REST server every time - it only needs to be started once.
+ Simple test defined in <code>NCModelValidationSpec</code> allows to check that all input test sentences are
+ processed expected way and fire intent <code>ls</code>.
+ You can run this test via SBT task <code>ExecuteTests</code> or using IDE.
</p>
</section>
<section>
<h2 class="section-title">Done! 👌 <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
<p>
- You've created light switch data model, started the REST server and tested this model using the built-in test framework.
+ You've created light switch data model and tested it.
</p>
</section>
</div>
@@ -391,10 +230,7 @@ class LightSwitch extends NCModelFileAdapter("light_switch.yaml") {
<li><a href="#new_project">New Project</a></li>
<li><a href="#model">Data Model</a></li>
<li><a href="#code">Model Class</a></li>
- <li><a href="#build_project">Build Project</a></li>
- <li><a href="#start_server">Start Server</a></li>
<li><a href="#testing">Testing</a></li>
- <li><a href="#rinse">Rinse <span class="amp">&</span> Repeat</a></li>
{% include quick-links.html %}
</ul>
</div>