Format file .lg

BERLAKU UNTUK: SDK v4

File .lg menjelaskan templat generasi 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 garis yang memiliki prefiks ini akan dilewati oleh pemilah.

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

Template

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 bisa berisi huruf, garis bawah, dan angka. Berikut ini adalah contoh templat TemplateNamebernama .

# TemplateName

Templat tidak bisa dimulai dengan angka, dan bagian mana pun dari nama templat yang dipisahkan oleh . tidak bisa dimulai dengan angka.

Variasi respons templat

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

# 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 menyertakan 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 bersyarah memungkinkan Anda menulis konten yang dipilih berdasarkan kondisi. Semua kondisi dinyatakan menggunakan ekspresi adaptif.

Penting

Templat bersyarah tidak bisa ditumpuk dalam satu templat respons bersyarah. Gunakan komposisi dalam templat respons terstruktur untuk menumpuk kondisional.

Templat if-else

Templat if-else memungkinkan Anda menyusun templat yang memilih koleksi berdasarkan urutan kondisi bertingkat. Evaluasi berada di atas ke bawah dan berhenti ketika kondisi mengevaluasi ke true atau blok ELSE terbentur.

Ekspresi bersyarah diapit 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 contoh lain yang memperlihatkan definisi templat respons bersyarah if-else. Perhatikan bahwa Anda bisa menyertakan referensi ke templat respons sederhana atau bersyarah lainnya dalam variasi untuk kondisi apa pun.

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

Beralih templat

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

Berikut cara menentukan blok DEFAULT SWITCH CASE di LG.

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

Berikut adalah contoh DEFAULT SWITCH CASE 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 bersyarah, beralih templat tidak bisa 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 penelepon pustaka LG.

Untuk aplikasi bot, kami secara asli mendukung:

  • definisi aktivitas
  • definisi kartu

Baca tentang templat respons struktur untuk informasi selengkapnya.

Komposisi dan perluasan 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 tanda 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 bisa menghasilkan salah satu resolusi ekspansi berikut ini:

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

Entitas

Ketika digunakan secara langsung dalam satu variasi teks, referensi entitas ditandai dengan memasukkannya dalam kurung kurawal, seperti ${entityName}, atau tanpa kurung kurawal ketika 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 variasi teks untuk mendapatkan komposisi teks yang lebih kuat. Untuk menggunakan ekspresi sebaris, cukup bungkus dalam 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.

Dengan templat dan fungsi bawaan yang memiliki tanda tangan invokasi yang sama, nama templat tidak boleh sama dengan nama fungsi bawaan.

Nama templat tidak boleh cocok dengan nama fungsi bawaan. Fungsi bawaan diutamakan. Untuk menghindari konflik seperti itu, Anda bisa menangguhkan lg. saat mereferensikan nama templat Anda. Misalnya:

> 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 tanda kutip tiga.

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

Variasi multiline dapat meminta perluasan templat dan penggantian entitas dengan memasukkan 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 mengatasi JSON atau XML yang kompleks (seperti teks yang dibungkus SSML untuk mengontrol balasan lisan bot).

Parametrizasi templat

Untuk membantu penggunaan kembali kontekstual, templat dapat dilumpuhkan. Penelepon yang berbeda ke templat bisa 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 menjadi file terpisah dan mereferensikan templat dari satu file di file lain. Anda bisa menggunakan link gaya Markdown untuk mengimpor templat yang ditentukan dalam file lain.

[Link description](filePathOrUri)

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

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

Fungsi yang disuntikkan oleh LG

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

Pilihan

Pengembang dapat mengatur opsi pemilah untuk lebih mengustomisasi cara input dievaluasi. > !# Gunakan notasi untuk mengatur opsi pemilah.

Penting

Pengaturan terakhir yang ditemukan dalam file mengacaukan 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 memberikan pesan yang mudah dikenali.

# welcome
- hi ${name}

Jika name is null, the diagnostic would be 'name' evaluated to null. [Selamat datang] Terjadi kesalahan ketika mengevaluasi '- hai ${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 menggunakan opsi replaceNull :

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

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

hi ${user.name}

Akan mengakibatkan user.name hai tidak terdefinis.

opsi gayatabel garis

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

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

Contoh di bawah ini memperlihatkan cara mengatur opsi lineBreakStyle menjadi markdown:

> !# @lineBreakStyle = markdown

Opsi Ruang nama

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

Contoh di bawah ini memperlihatkan cara mengatur opsi ruang nama menjadi foo:

> !# @Namespace = foo

Opsi Ekspor

Anda dapat menentukan daftar templat LG untuk diekspor. Templat yang diekspor dapat disebut seperti fungsi bawaan.

Contoh di bawah ini memperlihatkan cara mengatur opsi ekspor menjadi 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.

Cache lingkup

Opsi cache lingkup memungkinkan Anda mengontrol kapan evaluator LG merevalidasi ekspresi yang telah dilihatnya sebelum dan kapan menyimpan dan menggunakan hasil singgahan.

  • Cache global efektif dalam siklus hidup evaluasi. LG menyinggahkan semua hasil evaluasi, dan jika nama templat dan parameternya sama, mengembalikan hasil dari singgahan.
  • Cache lingkup lokal adalah default. Di lapisan yang sama, jika templat sebelumnya telah disebut dengan nama templat yang sama dan parameter yang sama, hasil singgahan langsung dikembalikan.
  • Tidak ada cache lingkup menonaktifkan semua cache lingkup, dan setiap kali mengembalikan hasil baru.

Misalnya, lihat contoh 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 cache lingkup tidak peka huruf besar kecil.

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

Perhatikan bahwa cache lingkup mengikuti lingkup file .lg masuk.

Katakanlah Anda memiliki dua file: a.lg dan b.lg, diperlihatkan 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 singgahan dari hasil pertama yang template2 dievaluasi karena global opsi cache lingkup 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 diakhiri dengan "!", templat memaksa eksekusi ulang. Hasil ini tidak akan ditambahkan ke singgahan terlepas dari lingkup singgahan.

Katakanlah Anda memiliki templat berikut:

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

template1!() api dan hasilnya ditambahkan ke singgahan. Kloning kedua template1() hasil dari yang pertama template1(). Panggilan terakhir menggunakan hasil yang disimpan dalam singgahan.

Contoh lingkup cache global

Katakanlah Anda memiliki templat berikut ini:

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

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

# template3
- ${template2()}

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

Contoh lain adalah dalam potontan kode berikut ini:

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 diurutkan menggunakan fungsi, Templates.ParseFile() dan hasil evaluasi templat disimpan di result1. Perhatikan bahwa hasil evaluasi kedua, result2, menjatuhkan semua hasil yang sebelumnya disinggahkan.

Contoh cache lingkup lokal

Contoh berikut ini memperlihatkan ketika lingkup 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