Formato di file .lg

SI APPLICA A: SDK v4

Il file con estensione lg descrive i modelli di generazione del linguaggio con riferimenti alle entità e la relativa composizione. Questo articolo illustra i vari concetti espressi con il formato di file con estensione lg.

Caratteri speciali

Commenti

Usare > per creare un commento. Tutte le righe con questo prefisso verranno ignorate dal parser.

> This is a comment.

Carattere di escape

Usare \ come carattere di escape.

# TemplateName
- You can say cheese and tomato \[toppings are optional\]

Matrici e oggetti

Creare una matrice

Per creare una matrice, usare la sintassi ${[object1, object2, ...]} . Ad esempio, questa espressione:

${['a', 'b', 'c']}

Restituisce la matrice ['a', 'b', 'c'].

Creare un oggetto

Per creare un oggetto, usare la sintassi ${{key1:value1, key2:value2, ...}} . Ad esempio, questa espressione:

${{user: {name: "Wilson", age: 27}}}

Restituisce l'oggetto JSON seguente:

{
  "user": {
    "name": "Wilson",
    "age": 27
  }
}

Modelli

I modelli rappresentano la base del sistema di generazione del linguaggio. Ogni modello è costituito da un nome e da uno degli elementi seguenti:

  • Un elenco di valori di testo a variante singola
  • Una definizione di contenuto strutturato
  • una raccolta di condizioni, ognuna con:

Nomi di modello

I nomi dei modelli fanno distinzione tra maiuscole e minuscole e possono contenere solo lettere, caratteri di sottolineatura e numeri. Di seguito è riportato un esempio di modello denominato TemplateName.

# TemplateName

I modelli non possono iniziare con un numero e qualsiasi parte di un nome di modello diviso per non può iniziare con un numero.

Varianti di risposta del modello

Le varianti sono espresse sotto forma di elenco Markdown. È possibile anteporre un prefisso a ogni variante usando il carattere -, ' o +.

# Template1
- text variation 1
- text variation 2
- one
- two

# Template2
* text variation 1
* text variation 2

# Template3
+ one
+ two

Modello di risposta semplice

Un modello di risposta semplice include una o più varianti di testo usate per la composizione e l'espansione. Una delle varianti specificate verrà selezionata in modo casuale dalla libreria di generazione del linguaggio.

Ecco un esempio di un modello semplice che include due varianti.

> Greeting template with two variations.
# GreetingPrefix
- Hi
- Hello

Modello di risposta condizionale

I modelli di risposta condizionale consentono di creare contenuti selezionati in base a una condizione. Tutte le condizioni sono espresse tramite espressioni adattive.

Importante

I modelli condizionali non possono essere annidati in un singolo modello di risposta condizionale. Usare la composizione in un modello di risposta strutturato per annidare istruzioni condizionali.

Modello IF ELSE

Il modello IF ELSE consente di creare un modello che seleziona una raccolta in base a un ordine di condizioni a cascata. La valutazione viene eseguita dall'alto verso il basso e viene arrestata quando una condizione restituisce true o viene raggiunto il blocco ELSE.

Le espressioni condizionali sono racchiuse tra parentesi graffe ${}. Ecco un esempio in cui viene illustrata una definizione di modello di risposta condizionale IF ELSE semplice.

> time of day greeting reply template with conditions.
# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
    - good morning
- ELSE:
    - good evening

Ecco un altro esempio in cui viene illustrata una definizione di modello di risposta condizionale IF ELSE. Si noti che è possibile includere riferimenti ad altri modelli di risposta semplici o condizionali nella variante di qualsiasi condizione.

# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
    - ${morningTemplate()}
- ELSEIF: ${timeOfDay == 'afternoon'}
    - ${afternoonTemplate()}
- ELSE:
    - I love the evenings! Just saying. ${eveningTemplate()}

Modello SWITCH

Il modello SWITCH consente di progettare un modello che abbina il valore di un'espressione a una clausola CASE e produce l'output in base a tale caso. Le espressioni della condizione sono racchiuse tra parentesi graffe ${}.

Ecco come è possibile specificare un blocco SWITCH CASE DEFAULT nella generazione del linguaggio.

# TestTemplate
- SWITCH: ${condition}
- CASE: ${case-expression-1}
    - output1
- CASE: ${case-expression-2}
    - output2
- DEFAULT:
   - final output

Ecco un esempio più complesso di blocco SWITCH CASE DEFAULT:

> Note: Any of the cases can include reference to one or more templates.
# greetInAWeek
- SWITCH: ${dayOfWeek(utcNow())}
- CASE: ${0}
    - Happy Sunday!
-CASE: ${6}
    - Happy Saturday!
-DEFAULT:
    - ${apology-phrase()}, ${defaultResponseTemplate()}

Nota

Come i modelli condizionali, i modelli switch non possono essere annidati.

Modello di risposta strutturata

I modelli di risposta strutturata consentono di definire una struttura complessa che supporta la maggior parte delle funzionalità generazione del linguaggio, come la creazione di modelli, la composizione e la sostituzione, lasciando l'interpretazione della risposta strutturata al chiamante della libreria di generazione del linguaggio.

Le definizioni supportate in modo nativo per le applicazioni bot sono:

  • Definizione dell'attività
  • Definizione della scheda

Per altre informazioni, vedere Modelli di risposta strutturati.

Composizione ed espansione del modello

Riferimenti ai modelli

Il testo della variante può includere riferimenti a un altro modello denominato per facilitare la composizione e la risoluzione di risposte complesse. I riferimenti ad altri modelli denominati vengono indicati usando parentesi graffe, ad esempio ${<TemplateName>()}.

> Example of a template that includes composition reference to another template.
# GreetingReply
- ${GreetingPrefix()}, ${timeOfDayGreeting()}

# GreetingPrefix
- Hi
- Hello

# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
    - good morning
- ELSEIF: ${timeOfDay == 'afternoon'}
    - good afternoon
- ELSE:
    - good evening

Chiamando il modello GreetingReply, viene generata una delle risoluzioni di espansione seguenti:

Hi, good morning
Hi, good afternoon
Hi, good evening
Hello, good morning
Hello, good afternoon
Hello, good evening

Entità

Quando vengono usati direttamente all'interno di un testo a variante singola, i riferimenti alle entità sono racchiusi tra parentesi graffe, ad esempio $ {entityName}; se invece sono usati come parametro, non presentano parentesi graffe.

Le entità possono essere usate come parametro:

Uso di funzioni predefinite nelle varianti

le funzioni predefinite supportate da espressioni adattive possono essere usate anche inline nel testo a variante singola per rendere più efficace la composizione del testo. Per usare un'espressione inline, è sufficiente racchiuderla tra parentesi graffe.

# RecentTasks
- IF: ${count(recentTasks) == 1}
    - Your most recent task is ${recentTasks[0]}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) == 2}
    - Your most recent tasks are ${join(recentTasks, ', ', ' and ')}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) > 2}
    - Your most recent ${count(recentTasks)} tasks are ${join(recentTasks, ', ', ' and ')}. You can let me know if you want to add or complete a task.
- ELSE:
    - You don't have any tasks.

Nell'esempio precedente si usa la funzione predefinita join per elencare tutti i valori nella raccolta recentTasks.

I modelli e le funzioni predefinite condividono la stessa firma di chiamata, un nome di modello non può essere uguale a quello di un nome di funzione predefinito.

Un nome di modello non deve corrispondere a un nome di funzione predefinito. La funzione predefinita ha la precedenza. Per evitare tali conflitti, è possibile anteporre il prefisso lg. quando si fa riferimento al nome del modello. Ad esempio:

> Custom length function with one parameter.
# length(a)
- This is use's customized length function

# myfunc1
> will call prebuilt function length, and return 2
- ${length('hi')}

# mufunc2
> this calls the lg template and output 'This is use's customized length function'
- ${lg.length('hi')}

Testo su più righe nelle varianti

Ogni variante singola può includere un testo su più righe racchiuso tra virgolette triple.

# MultiLineExample
    - ```This is a multiline list
        - one
        - two
        ```
    - ```This is a multiline variation
        - three
        - four
    ```

La variante a più righe può richiedere l'espansione del modello e la sostituzione dell'entità racchiudendo l'operazione richiesta tra parentesi graffe, ovvero ${}.

# MultiLineExample
    - ```
        Here is what I have for the order
        - Title: ${reservation.title}
        - Location: ${reservation.location}
        - Date/ time: ${reservation.dateTimeReadBack}
    ```

Con il supporto per più righe è possibile impostare il sottosistema di generazione del linguaggio in modo che risolva completamente codice JSON o XML complesso, ad esempio testo con wrapping SSML per controllare la risposta vocale del bot.

Parametrizzazione dei modelli

Per facilitare la riusabilità contestuale, è possibile parametrizzare i modelli. I diversi chiamanti del modello possono passare valori diversi da usare per la risoluzione dell'espansione.

# timeOfDayGreetingTemplate (param1)
- IF: ${param1 == 'morning'}
    - good morning
- ELSEIF: ${param1 == 'afternoon'}
    - good afternoon
- ELSE:
    - good evening

# morningGreeting
- ${timeOfDayGreetingTemplate('morning')}

# timeOfDayGreeting
- ${timeOfDayGreetingTemplate(timeOfDay)}

Importazione dei riferimenti esterni

È possibile dividere i modelli di generazione del linguaggio in file separati e fare riferimento a un modello da un file in un altro. Per importare modelli definiti in un altro file, è possibile usare i collegamenti in stile Markdown.

[Link description](filePathOrUri)

Verranno estratti tutti i modelli definiti nel file di destinazione. Assicurarsi che i nomi dei modelli siano univoci (o con # \<namespace>.\<templatename>) tra tutti i file di cui viene eseguito il pull.

[Shared](../shared/common.lg)

Funzioni inserite dalla generazione di linguaggio

Grazie alle espressioni adattive è possibile inserire un set di funzioni personalizzato. Per altre informazioni, vedere Funzioni inserite dalla libreria di generazione del linguaggio.

Opzioni

Gli sviluppatori possono impostare le opzioni del parser per personalizzare ulteriormente la modalità di valutazione dell'input. Per impostare le opzioni del parser, usare la notazione > !#.

Importante

L'ultima impostazione trovata nel file sostituisce le impostazioni precedenti trovate nello stesso documento.

Opzione strict

Gli sviluppatori che non vogliono consentire un risultato Null per un risultato valutato null possono implementare l'opzione strict . Ecco un esempio di un opzione strict semplice:

> !# @strict = true
# template
- hi

Se l'opzione strict è attiva, gli errori Null genereranno un messaggio descrittivo.

# welcome
- hi ${name}

Se il nome è Null, la diagnostica restituita è 'name' evaluated to null. [welcome] Error occurred when evaluating '- hi ${name}'.. Se strict è impostato su false o non impostato, verrà restituito un risultato compatibile. Con l'esempio precedente viene generato hi null.

Opzione replaceNull

Gli sviluppatori possono creare delegati per sostituire i valori Null nelle espressioni valutate usando l'opzione replaceNull :

> !# @replaceNull = ${path} is undefined

Nell'esempio precedente l'input Null nella variabile path viene sostituito con ${path} is undefined. Con l'input seguente, in cui user.name è Null:

hi ${user.name}

il risultato restituito è hi user.name is undefined.

Opzione lineBreakStyle

Gli sviluppatori possono impostare opzioni per il rendering delle interruzioni di riga nel sistema di generazione del linguaggio usando l'opzione lineBreakStyle. Sono attualmente supportate due modalità:

  • default: le interruzioni di riga nel testo su più righe creano interruzioni di riga normali.
  • markdown: le interruzioni di riga nel testo su più righe verranno convertite automaticamente in due righe per creare una nuova riga.

Nell'esempio seguente viene illustrato come impostare l'opzione lineBreakStyle su markdown:

> !# @lineBreakStyle = markdown

Opzione namespace

È possibile registrare uno spazio dei nomi per i modelli di generazione del linguaggio che si vogliono esportare. Se non è stato specificato alcuno spazio dei nomi, lo spazio dei nomi verrà impostato sul nome file senza estensione.

L'esempio seguente mostra come impostare l'opzione namespace su foo:

> !# @Namespace = foo

Opzione exports

È possibile specificare un elenco di modelli di generazione del linguaggio da esportare. I modelli esportati possono essere definiti anche funzioni predefinite.

L'esempio seguente mostra come impostare l'opzione exports su template1, template2:

> !# @Namespace = foo
> !# @Exports = template1, template2

# template1(a, b)
- ${a + b}

# template2(a, b)
- ${join(a, b)}

Usare foo.template1(1,2), foo.template2(['a', 'b', 'c'], ',') per chiamare questi modelli esportati.

Ambito cache

Le opzioni di ambito della cache consentono di controllare quando l'analizzatore LG rivaluta un'espressione che ha visto in precedenza e quando archivia e usa un risultato memorizzato nella cache.

  • La Cache globale è efficace nel ciclo di vita di una valutazione. LG memorizza nella cache tutti i risultati della valutazione e, se il nome del modello e i parametri sono uguali, restituisce il risultato dalla cache.
  • L'ambito della cache locale è l'impostazione predefinita. Nello stesso livello, se il modello precedente è stato chiamato con lo stesso nome di modello e gli stessi parametri, il risultato memorizzato nella cache viene restituito direttamente.
  • Nessun ambito della cache disabilita tutti gli ambiti della cache e ogni volta restituisce il nuovo risultato.

Per esempi, vedere gli esempi di ambito della cache globale e locale .

> !# @cacheScope= global // global cache
> !# @cacheScope= local // local cache
> !# @cacheScope= none // none cache
> !# @cacheScope= xxx // fallback to local cache

Si noti che l'opzione ambito cache non fa distinzione tra maiuscole e minuscole.

> !# @cacheScope= global // ok
> !# @CACHESCOPE= global // ok
> !# @cachescope= global // ok

Si noti che l'ambito della cache segue l'ambito del file Microsoft Entrance .lg.

Si supponga di avere due file: a.lg e b.lg, come illustrato di seguito:

a.lg

> !# @cacheScope= global
 [import](b.lg)

b.lg

> !# @cacheScope= none
# template1
- ${template2()} ${template2()}

# template2
- ${rand(1, 10000000)}

Se si esegue il codice seguente, si noterà che template2 usa il risultato memorizzato nella cache del primo risultato valutato a causa dell'opzione global di ambito della cache in a.lg:

var templates = Templates.ParseFile("a.lg");
var result = templates.Evaluate("template1"); // the second "template2" would use the cache of the first evaluate result

Re-execute mark influence

Se il nome del modello termina con "!", il modello forza la ripetizione dell'esecuzione. Questo risultato non verrà aggiunto alla cache indipendentemente dall'ambito della cache.

Si supponga di avere il modello seguente:

# template2
- ${template1()} ${template1!()} ${template1()}

template1!() viene generato e il risultato viene aggiunto alla cache. Il secondo template1() blocca il risultato del primo template1()oggetto . La chiamata finale usa i risultati archiviati nella cache.

Esempio di ambito della cache globale

Si supponga di avere i modelli seguenti:

# template1
- ${template2()} ${template3()}

# template2
- ${rand(1, 10)}
- abc
- hi

# template3
- ${template2()}

template2 verrebbe valutata una sola volta e la seconda esecuzione in template3 applicherà la cache del primo.

Un altro esempio è nel frammento di codice seguente:

var templates = Templates.ParseFile("xxx.lg");
var result1 = templates.Evaluate("template", null, new EvaluationOptions { CacheScope = LGCacheScope.Global});

// The second evaluation would drop all the results cached before.
var result2 = templates.Evaluate("template", null, new EvaluationOptions { CacheScope = LGCacheScope.Global});

Un modello viene analizzato usando la Templates.ParseFile() funzione e i risultati della valutazione del modello vengono archiviati in result1. Si noti che i risultati della seconda valutazione, result2, eliminano tutti i risultati precedentemente memorizzati nella cache.

Esempio di ambito della cache locale

Gli esempi seguenti mostrano quando l'ambito della cache locale funziona e non funziona. Si supponga che t() e subT() siano modelli che accettano un parametro:

>  Cache works, the second template call would re-use the first's result.
# template1
- ${t(param)} ${t(param)}

> Cache doesn't work because param1's value is different with param2's. value)
# template2
- ${t(param1)} ${t(param2)}

> Cache doesn't work because of different layers.
# template3
- ${subT(param1)} ${t(param2)}

# subT(param)
- ${t(param)}

Risorse aggiuntive