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:
- ekspresi adaptif
- daftar nilai teks variasi satu per kondisi
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:
- dalam fungsi bawaan
- dalam kondisi dalam templat respons bersyarkat
- ke panggilan resolusi templat
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
- Referensi API C#
- Referensi API JavaScript
- Baca Debug dengan Alat Adaptif untuk mempelajari cara menganalisis dan men-debug file .lg.