.lg 檔案格式
適用于: SDK v4
.lg 檔案描述具有實體參考及其組合的語言產生範本。 本文涵蓋以 .lg 檔案格式表示的各種概念。
特殊字元
註解
使用 > 來建立批註。 剖析器將會略過具有此前置詞的所有行。
> This is a comment.
逸出字元
使用 \ 作為逸出字元。
# TemplateName
- You can say cheese and tomato \[toppings are optional\]
陣列和物件
建立陣列
若要建立陣列,請使用 ${[object1, object2, ...]} 語法。 例如,此運算式:
${['a', 'b', 'c']}
傳回陣列 ['a', 'b', 'c']
。
建立 物件
若要建立物件,請使用 ${{key1:value1、key2:value2、...}} 語法。 例如,此運算式:
${{user: {name: "Wilson", age: 27}}}
傳回下列 JSON 物件:
{
"user": {
"name": "Wilson",
"age": 27
}
}
範本
範本 是語言產生系統的核心概念。 每個範本都有一個名稱和下列其中一個:
- 一組變化文字值的清單
- 結構化內容定義
- 條件集合,每個都有:
- 調 適型運算式
- 每個條件一個變化文字值的清單
範本名稱
範本名稱會區分大小寫,而且只能包含字母、底線和數位。 以下是名為 TemplateName
的範本範例。
# TemplateName
範本不能以數位開頭,而且由 分割 的範本名稱的任何部分都不能以數位開頭。
範本回應變化
變化會以 Markdown 清單表示。 您可以使用 、 或 + 字元,在每個變化 - 前面加上前置詞。
# Template1
- text variation 1
- text variation 2
- one
- two
# Template2
* text variation 1
* text variation 2
# Template3
+ one
+ two
簡單回應範本
簡單的回應範本包含一或多個用於組合和展開的文字變化。 LG 程式庫會隨機選取其中一個變化。
以下是包含兩種變化的簡單範本範例。
> Greeting template with two variations.
# GreetingPrefix
- Hi
- Hello
條件式回應範本
條件式回應範本可讓您撰寫根據條件選取的內容。 所有條件都會使用 調適型運算式 來表示。
重要
條件式範本不能巢狀于單一條件式回應範本中。 在結構化回應範本 中使用 組合來巢狀條件。
If-else 範本
if-else 範本可讓您建置範本,以根據條件的串聯順序挑選集合。 評估是由上而下,當條件評估為 true
或被叫用 ELSE 區塊時停止。
條件運算式會以大括弧 $ {} 括住。 以下範例顯示簡單的 IF ELSE 條件式回應範本定義。
> time of day greeting reply template with conditions.
# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
- good morning
- ELSE:
- good evening
以下是另一個示範 if-else 條件式回應範本定義的範例。 請注意,您可以在任何條件的變化中包含其他簡單或條件式回應範本的參考。
# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
- ${morningTemplate()}
- ELSEIF: ${timeOfDay == 'afternoon'}
- ${afternoonTemplate()}
- ELSE:
- I love the evenings! Just saying. ${eveningTemplate()}
切換範本
參數範本可讓您設計符合運算式值與 CASE 子句的範本,並根據該案例產生輸出。 條件運算式會以大括弧 $ {} 括住。
以下是您可以在 LG 中指定 SWITCH CASE DEFAULT 區塊的方式。
# TestTemplate
- SWITCH: ${condition}
- CASE: ${case-expression-1}
- output1
- CASE: ${case-expression-2}
- output2
- DEFAULT:
- final output
以下是更複雜的 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()}
注意
如同條件式範本,切換範本無法巢狀化。
結構化回應範本
結構化回應範本可讓您定義支援主要 LG 功能的複雜結構,例如範本化、組合和替代,同時將結構化回應的解譯留給 LG 程式庫的呼叫端。
針對 Bot 應用程式,我們原生支援:
- 活動定義
- 卡片定義
如需 詳細資訊,請參閱結構回應範本 。
範本組合和擴充
範本參考
變化文字可以包含另一個具名範本的參考,以協助組合和解決複雜的回應。 其他具名範本的參考會以大括弧表示,例如 ${ < 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
GreetingReply
呼叫範本可能會導致下列其中一個展開解析度:
Hi, good morning
Hi, good afternoon
Hi, good evening
Hello, good morning
Hello, good afternoon
Hello, good evening
實體
直接在單一變化文字內使用時,實體參考會以大括弧括住它們,例如 ${ entityName
},或在做為參數時不使用大括弧來表示。
實體可以當做參數使用:
在變化中使用預先建置的函式
調適型運算式 支援的 預先建置函 式也可以內嵌在一組變化文字中,以達到更強大的文字組合。 若要使用內嵌運算式,只需將它包裝在大括弧中即可。
# 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.
上述範例會使用 聯 結預先建置函式來列出集合中的所有 recentTasks
值。
假設範本和預建函式共用相同的調用簽章,範本名稱不能與預先建置的函式名稱相同。
範本名稱不應該符合預先建置的函式名稱。 預先建置的函式優先。 若要避免這類衝突,您可以在參考範本名稱時加上前面 lg.
。 例如:
> 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')}
變化中的多行文字
每個變化都可以包含以三引號括住的多行文字。
# MultiLineExample
- ```This is a multiline list
- one
- two
```
- ```This is a multiline variation
- three
- four
```
多行變化可以藉由以大括弧 $ {} 括住要求的作業來要求範本擴充和實體替代。
# MultiLineExample
- ```
Here is what I have for the order
- Title: ${reservation.title}
- Location: ${reservation.location}
- Date/ time: ${reservation.dateTimeReadBack}
```
透過多行支援,您可以讓語言產生子系統完全解析複雜的 JSON 或 XML(例如 SSML 包裝文字來控制 Bot 的口語回復)。
範本參數化
為了協助內容可重複使用性,可以參數化範本。 範本的不同呼叫端可以傳入不同的值,以用於擴充解析。
# timeOfDayGreetingTemplate (param1)
- IF: ${param1 == 'morning'}
- good morning
- ELSEIF: ${param1 == 'afternoon'}
- good afternoon
- ELSE:
- good evening
# morningGreeting
- ${timeOfDayGreetingTemplate('morning')}
# timeOfDayGreeting
- ${timeOfDayGreetingTemplate(timeOfDay)}
匯入外部參考
您可以將語言產生範本分割成個別的檔案,並從另一個檔案參考範本。 您可以使用 Markdown 樣式連結匯入另一個檔案中定義的範本。
[Link description](filePathOrUri)
系統會提取目標檔案中定義的所有範本。 請確定您的範本名稱在提取的檔案之間是唯一的(或具有 # \<namespace>.\<templatename>
命名空間的)。
[Shared](../shared/common.lg)
LG 插入的函式
自適性運算式 可讓您插入一組自訂函式。 如需詳細資訊,請閱讀 從 LG 程式庫 插入的函式。
選項。
開發人員可以設定剖析器選項,以進一步自訂輸入的評估方式。 > !#
使用標記法來設定剖析器選項。
重要
檔案中找到的最後一個設定會優先于相同檔中找到的任何先前設定。
Strict 選項
不想允許 Null 評估結果 Null 結果的開發人員可以實 作 strict 選項。 以下是簡單 strict 選項的範例:
> !# @strict = true
# template
- hi
如果 strict 選項開啟,Null 錯誤將會擲回易記訊息。
# welcome
- hi ${name}
如果 name 為 null,診斷會 評估為 null。[歡迎]評估 '- hi ${name}' 時發生錯誤。 如果 strict 設定為 false 或未設定,則會提供相容的結果。 上述範例會產生 hi null 。
replaceNull 選項
開發人員可以使用 replaceNull 選項,建立委派來取代評估運算式 中的 Null 值:
> !# @replaceNull = ${path} is undefined
在上述範例中,變數中的 path
Null 輸入會以 ${path} 取代 為未定義 。 下列輸入,其中 user.name
為 null: :
hi ${user.name}
會導致 hi user.name 未定義 。
lineBreakStyle 選項
開發人員可以使用 lineBreakStyle 選項來設定 LG 系統如何轉譯換 行符的選項。 目前支援兩種模式:
default
:多行文字中的分行符號會建立一般分行符號。markdown
:多行文字中的分行符號會自動轉換成兩行,以建立分行符號
下列範例示範如何將 lineBreakStyle 選項設定為 markdown
:
> !# @lineBreakStyle = markdown
命名空間選項
您可以註冊要匯出之 LG 範本的命名空間。 如果沒有指定命名空間,命名空間將會設定為沒有副檔名的檔案名。
下列範例示範如何將命名空間選項設定為 foo
:
> !# @Namespace = foo
匯出選項
您可以指定要匯出的 LG 範本清單。 匯出的範本可以像預先建置的函式一樣呼叫。
下列範例示範如何將匯出選項設定為 template1, template2
:
> !# @Namespace = foo
> !# @Exports = template1, template2
# template1(a, b)
- ${a + b}
# template2(a, b)
- ${join(a, b)}
用來 foo.template1(1,2), foo.template2(['a', 'b', 'c'], ',')
呼叫這些匯出的範本。
快取範圍
快 取範圍 選項可讓您控制 LG 評估工具何時重新評估之前和儲存和使用快取結果的運算式。
- 全域快取 在評估的生命週期中有效。 LG 會快取所有評估結果,如果範本名稱和參數相同,則會從快取傳回結果。
- 本機快取 範圍是預設值。 在同一層中,如果先前的範本已使用相同的範本名稱和相同的參數呼叫,則會直接傳回快取的結果。
- 無快取範圍會停用所有快 取範圍,而且每次傳回新的結果。
> !# @cacheScope= global // global cache
> !# @cacheScope= local // local cache
> !# @cacheScope= none // none cache
> !# @cacheScope= xxx // fallback to local cache
請注意,快取範圍選項不區分大小寫。
> !# @cacheScope= global // ok
> !# @CACHESCOPE= global // ok
> !# @cachescope= global // ok
請注意,快取範圍遵循 Microsoft Entrance .lg 檔案的範圍。
假設您有兩個檔案: a.lg
和 b.lg
,如下所示:
a.lg
> !# @cacheScope= global
[import](b.lg)
b.lg
> !# @cacheScope= none
# template1
- ${template2()} ${template2()}
# template2
- ${rand(1, 10000000)}
如果您執行下列程式碼,您會發現 template2
使用第一個評估結果的快取結果,因為 global
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
重新執行標記影響
如果範本名稱以 「!」結尾,範本會強制重新執行。 不論快取範圍為何,此結果都不會新增至快取。
假設您有下列範本:
# template2
- ${template1()} ${template1!()} ${template1()}
template1!()
引發 ,並將結果新增至快取。 第二 template1()
個擷取第一個 template1()
的結果。 最終呼叫會使用儲存在快取中的結果。
全域快取範圍範例
假設您有下列範本:
# template1
- ${template2()} ${template3()}
# template2
- ${rand(1, 10)}
- abc
- hi
# template3
- ${template2()}
template2
會評估一次,而 中的 template3
第二個執行會套用第一個快取。
另一個範例位於下列程式碼片段中:
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});
使用 Templates.ParseFile()
函式剖析範本,範本評估結果會儲存在 中 result1
。 請注意,第二個評估結果 result2
會卸載先前快取的所有結果。
本機快取範圍範例
下列範例顯示本機快取範圍何時運作且無法運作。 假設 t()
和 subT()
是採用參數的範本:
> 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)}
其他資源
- C# API 參考
- JavaScript API 參考
- 若要瞭解如何分析及偵錯 .lg 檔案,請閱讀 使用 Adaptive Tools 進行偵錯。