Bagikan melalui


Format file .lg

BERLAKU UNTUK: SDK v4

File .lg menjelaskan templat pembuatan bahasa dengan referensi entitas dan komposisinya. Artikel ini membahas berbagai konsep yang dinyatakan dengan format file .lg.

Karakter Khusus

Komentar

Gunakan > untuk membuat komentar. Semua baris yang memiliki awalan ini akan dilewati oleh pengurai.

> This is a comment.

Karakter escape

Gunakan \ sebagai karakter escape.

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

Array dan objek

Membuat array

Untuk membuat array, gunakan sintaks ${[object1, object2, ...]} . Misalnya, ekspresi ini:

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

Mengembalikan array ['a', 'b', 'c'].

Membuat objek

Untuk membuat objek, gunakan sintaks ${{key1:value1, key2:value2, ...}} . Misalnya, ekspresi ini:

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

Mengembalikan objek JSON berikut:

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

Templat

Templat adalah konsep inti dari sistem pembuatan bahasa. Setiap templat memiliki nama dan salah satu hal berikut ini:

  • daftar nilai teks variasi satu
  • definisi konten terstruktur
  • kumpulan kondisi, masing-masing dengan:

Nama templat

Nama templat peka huruf besar/kecil dan hanya dapat berisi huruf, garis bawah, dan angka. Berikut ini adalah contoh templat bernama TemplateName.

# TemplateName

Templat tidak dapat dimulai dengan angka, dan bagian mana pun dari nama templat yang dibagi dengan . tidak dapat dimulai dengan angka.

Variasi respons templat

Variasi dinyatakan sebagai daftar Markdown. Anda dapat mengawali setiap variasi menggunakan -karakter , ', atau + .

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

# Template2
* text variation 1
* text variation 2

# Template3
+ one
+ two

Templat respons sederhana

Templat respons sederhana mencakup satu atau beberapa variasi teks yang digunakan untuk komposisi dan perluasan. Salah satu variasi yang disediakan akan dipilih secara acak oleh pustaka LG.

Berikut adalah contoh templat sederhana yang menyertakan dua variasi.

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

Templat respons bersyarah

Templat respons kondisional memungkinkan Anda menulis konten yang dipilih berdasarkan kondisi. Semua kondisi dinyatakan menggunakan ekspresi adaptif.

Penting

Templat kondisional tidak dapat disarangkan dalam satu templat respons kondisional. Gunakan komposisi dalam templat respons terstruktur untuk menumpuk kondisional.

Templat If-else

Templat if-else memungkinkan Anda membuat templat yang memilih koleksi berdasarkan urutan kondisi yang bertahap. Evaluasi adalah top-down dan berhenti ketika kondisi mengevaluasi ke true atau blok ELSE terbentur.

Ekspresi bersyukur diapit dalam tanda kurung kurawal ${}. Berikut adalah contoh yang memperlihatkan definisi templat respons bersyarah IF ELSE sederhana.

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

Berikut adalah contoh lain yang memperlihatkan definisi templat respons bersyarah if-else. Perhatikan bahwa Anda dapat menyertakan referensi ke templat respons sederhana atau bersyarah lainnya dalam variasi untuk salah satu kondisi.

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

Beralih templat

Templat sakelar memungkinkan Anda merancang templat yang cocok dengan nilai ekspresi dengan klausa CASE dan menghasilkan output berdasarkan kasus tersebut. Ekspresi kondisi diapit kurung kurawal ${}.

Berikut adalah cara Anda dapat menentukan blok SWITCH CASE DEFAULT di LG.

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

Berikut adalah contoh SWITCH CASE DEFAULT yang lebih rumit:

> 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()}

Catatan

Seperti templat kondisional, beralih templat tidak dapat ditumpuk.

Templat respons terstruktur

Templat respons terstruktur memungkinkan Anda menentukan struktur kompleks yang mendukung fungsionalitas LG utama, seperti templat, komposisi, dan penggantian, sambil meninggalkan interpretasi respons terstruktur hingga pemanggil pustaka LG.

Untuk aplikasi bot, kami secara asli mendukung:

  • definisi aktivitas
  • definisi kartu

Baca tentang templat respons struktur untuk informasi selengkapnya.

Komposisi dan ekspansi templat

Referensi ke templat

Teks variasi dapat menyertakan referensi ke templat bernama lain untuk membantu komposisi dan resolusi respons canggih. Referensi ke templat bernama lainnya ditandai menggunakan kurung kurawal, seperti ${<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

Memanggil GreetingReply templat dapat menghasilkan salah satu resolusi ekspansi berikut:

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

Entitas

Saat digunakan langsung dalam satu teks variasi, referensi entitas ditandai dengan mengapitnya dalam kurung kurawal, seperti ${entityName}, atau tanpa kurung kurawal saat digunakan sebagai parameter.

Entitas dapat digunakan sebagai parameter:

Menggunakan fungsi bawaan dalam variasi

Fungsi bawaan yang didukung oleh ekspresi adaptif juga dapat digunakan sebaris dalam satu teks variasi untuk mencapai komposisi teks yang lebih kuat. Untuk menggunakan ekspresi sebaris, cukup bungkus dengan kurung kurawal.

# 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.

Contoh di atas menggunakan fungsi bawaan gabungan untuk mencantumkan recentTasks semua nilai dalam koleksi.

Templat dan fungsi bawaan yang diberikan berbagi tanda tangan pemanggilan yang sama, nama templat tidak boleh sama dengan nama fungsi bawaan.

Nama templat tidak boleh cocok dengan nama fungsi bawaan. Fungsi bawaan lebih diutamakan. Untuk menghindari konflik tersebut, Anda dapat melakukan prepend lg. saat mereferensikan nama templat Anda. Contohnya:

> 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')}

Teks multibaris dalam variasi

Setiap variasi dapat menyertakan teks multibaris yang diapit dalam tanda kutip tiga kali lipat.

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

Variasi multibaris dapat meminta ekspansi templat dan penggantian entitas dengan menyertakan operasi yang diminta dalam kurung kurawal, ${}.

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

Dengan dukungan multibaris, Anda dapat memiliki sub-sistem Generasi Bahasa sepenuhnya menyelesaikan JSON atau XML yang kompleks (seperti teks yang dibungkus SSML untuk mengontrol balasan lisan bot).

Parametrizasi templat

Untuk membantu menggunakan kembali kontekstual, templat dapat diparmetriskan. Pemanggil yang berbeda ke templat dapat meneruskan nilai yang berbeda untuk digunakan dalam resolusi ekspansi.

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

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

# timeOfDayGreeting
- ${timeOfDayGreetingTemplate(timeOfDay)}

Mengimpor referensi eksternal

Anda dapat membagi templat pembuatan bahasa Anda menjadi file terpisah dan mereferensikan templat dari satu file di file lain. Anda dapat menggunakan tautan bergaya Markdown untuk mengimpor templat yang ditentukan dalam file lain.

[Link description](filePathOrUri)

Semua templat yang ditentukan dalam file target akan ditarik masuk. Pastikan nama templat Anda unik (atau dinamai dengan # \<namespace>.\<templatename>) di seluruh file yang ditarik.

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

Fungsi yang disuntikkan oleh LG

Ekspresi adaptif memberikan kemampuan untuk menyuntikkan sekumpulan fungsi kustom. Baca fungsi yang disuntikkan dari pustaka LG untuk informasi selengkapnya.

Opsi

Pengembang dapat mengatur opsi pengurai untuk menyesuaikan lebih lanjut bagaimana input dievaluasi. > !# Gunakan notasi untuk mengatur opsi pengurai.

Penting

Pengaturan terakhir yang ditemukan dalam file meniru pengaturan sebelumnya yang ditemukan dalam dokumen yang sama.

Opsi ketat

Pengembang yang tidak ingin mengizinkan hasil null untuk hasil yang dievaluasi null dapat menerapkan opsi ketat . Di bawah ini adalah contoh opsi ketat sederhana:

> !# @strict = true
# template
- hi

Jika opsi ketat aktif, kesalahan null akan melemparkan pesan yang ramah.

# welcome
- hi ${name}

Jika nama null, diagnostik akan menjadi 'nama' yang dievaluasi ke null. [selamat datang] Kesalahan terjadi saat mengevaluasi '- hi ${name}'.. Jika ketat diatur ke false atau tidak diatur, hasil yang kompatibel akan diberikan. Sampel di atas akan menghasilkan hi null.

opsi replaceNull

Pengembang dapat membuat delegasi untuk mengganti nilai null dalam ekspresi yang dievaluasi dengan menggunakan opsi replaceNull :

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

Dalam contoh di atas, input null dalam path variabel akan diganti dengan ${path} tidak ditentukan. Input berikut, di mana user.name null: :

hi ${user.name}

Akan mengakibatkan hi user.name tidak ditentukan.

opsi lineBreakStyle

Pengembang dapat mengatur opsi tentang bagaimana sistem LG merender hentian baris menggunakan opsi lineBreakStyle . Dua mode saat ini didukung:

  • default: pemisah baris dalam teks multibaris membuat hentian baris normal.
  • markdown: pemisah baris dalam teks multibaris akan secara otomatis dikonversi menjadi dua baris untuk membuat baris baru

Contoh di bawah ini menunjukkan cara mengatur opsi lineBreakStyle ke markdown:

> !# @lineBreakStyle = markdown

Opsi namespace

Anda dapat mendaftarkan namespace untuk templat LG yang ingin Anda ekspor. Jika tidak ada namespace yang ditentukan, namespace akan diatur ke nama file tanpa ekstensi.

Contoh di bawah ini menunjukkan cara mengatur opsi namespace ke foo:

> !# @Namespace = foo

Opsi ekspor

Anda dapat menentukan daftar templat LG yang akan diekspor. Templat yang diekspor dapat dipanggil seperti fungsi bawaan.

Contoh di bawah ini menunjukkan cara mengatur opsi ekspor ke template1, template2:

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

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

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

Gunakan foo.template1(1,2), foo.template2(['a', 'b', 'c'], ',') untuk memanggil templat yang diekspor ini.

Cakupan cache

Opsi cakupan cache memungkinkan Anda mengontrol kapan evaluator LG mengevaluasi ulang ekspresi yang telah dilihatnya sebelum dan kapan menyimpan dan menggunakan hasil yang di-cache.

  • Cache global efektif dalam siklus hidup evaluasi. LG menyimpan semua hasil evaluasi, dan jika nama templat dan parameter sama, mengembalikan hasil dari cache.
  • Cakupan cache lokal adalah default. Di lapisan yang sama, jika templat sebelumnya telah dipanggil dengan nama templat yang sama dan parameter yang sama, hasil yang di-cache langsung dikembalikan.
  • Tidak ada cakupan cache yang menonaktifkan semua cakupan cache, dan setiap kali mengembalikan hasil baru.

Misalnya, lihat contoh cakupan cache global dan lokal .

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

Perhatikan bahwa opsi cakupan cache tidak peka huruf besar/kecil.

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

Perhatikan bahwa cakupan cache mengikuti cakupan file .lg Masuk Microsoft.

Katakanlah Anda memiliki dua file: a.lg dan b.lg, yang ditunjukkan di bawah ini:

a.lg

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

b.lg

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

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

Jika Anda menjalankan kode berikut, Anda akan melihat bahwa menggunakan hasil cache dari hasil pertama yang template2 dievaluasi karena global opsi cakupan cache di 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

Menjalankan kembali pengaruh tanda

Jika nama templat berakhir dengan "!", templat memaksa eksekusi ulang. Hasil ini tidak akan ditambahkan ke cache terlepas dari cakupan cache.

Katakanlah Anda memiliki templat berikut:

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

template1!() api dan hasilnya ditambahkan ke cache. template1() Kedua mengkloning hasil dari yang pertama template1(). Panggilan akhir menggunakan hasil yang disimpan di cache.

Contoh cache global

Katakanlah Anda memiliki templat berikut:

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

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

# template3
- ${template2()}

template2 akan dievaluasi sekali, dan eksekusi kedua di template3 akan menerapkan cache yang pertama.

Contoh lain adalah dalam cuplikan kode berikut:

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});

Templat diurai menggunakan Templates.ParseFile() fungsi , dan hasil evaluasi templat disimpan di result1. Perhatikan bahwa hasil evaluasi kedua, result2, menghilangkan semua hasil yang sebelumnya di-cache.

Contoh cache lokal

Contoh berikut menunjukkan kapan cakupan cache lokal tidak berfungsi dan tidak berfungsi. Asumsikan bahwa t() dan subT() merupakan templat yang mengambil parameter:

>  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)}

Sumber Daya Tambahan