構造化された応答テンプレート

この記事の対象: SDK v4

構造化された応答テンプレートにより、開発者は、構造化された応答の解釈を LG ライブラリの呼び出し元に任せながら、テンプレート作成、コンポジションなどの言語の生成 (LG) の広範な機能をサポートする複雑な構造を定義できます。

ボット アプリケーションでは、次のようなサポートが提供されます。

Bot Framework アクティビティ テンプレートには、カスタマイズ可能なフィールドがいくつか含まれています。 次のプロパティは最もよく使用されており、アクティビティ テンプレート定義を使用して構成できます。

プロパティ ユース ケース
テキスト チャネルによって視覚的にレンダリングするために使用されるテキストを表示します
Speak チャネルによって音声でレンダリングするために使用される音声テキスト
Attachments 添付ファイルとそれらの種類の一覧。 チャネルによって UI カードまたはその他の汎用添付ファイルの種類としてレンダリングするために使用されます。
SuggestedActions ユーザーへの提案としてレンダリングされるアクションの一覧。
InputHint 音声入力をサポートするデバイスでオーディオ キャプチャ ストリームの状態を制御します。 指定できる値は、acceptingexpecting、または ignoring などです。

テンプレート リゾルバーによって実装される既定のフォールバック動作はありません。 プロパティが指定されていない場合、未指定のままになります。 たとえば、Text プロパティのみが指定されている場合、Text プロパティとして Speak プロパティが自動的に割り当てられません。

定義

構造化されたテンプレートの定義を次に示します。

# TemplateName
> this is a comment
[Structure-name
    Property1 = <plain text> .or. <plain text with template reference> .or. <expression>
    Property2 = list of values are denoted via '|'. e.g. a | b
> this is a comment about this specific property
    Property3 = Nested structures are achieved through composition
]

基本的なテキスト テンプレートの例を次に示します。

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
]

# GetAge
- how old are you?
- what is your age?

推奨されるアクションを含むテキストの例を次に示します。 リストを示すには、| を使用します。

> With '|' you are making attachments a list.
# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    SuggestedActions = 10 | 20 | 30
]

ヒーロー カード定義の例を次に示します。

# HeroCard
[Herocard
    title = Hero Card Example
    subtitle = Microsoft Bot Framework
    text = Build and connect intelligent bots to interact with your users naturally wherever they are, from text/sms to Skype, Slack, Office 365 mail and other popular services.
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

Note

LG は、カード定義に多少の変動を持たせており、それらは SDK カード定義に合うように変換されます。 たとえば、SDK カード定義では images しかサポートされていない場合でも、LG のすべてのカード定義では image フィールドと images フィールドの両方がサポートされます。

HeroCard またはサムネイル カード内のすべての image フィールドと images フィールドで定義された値は結合され、生成されたカードの画像リストに変換されます。 その他の種類のカードでは、テンプレートで最後に定義された値が image フィールドに割り当てられます。 image/images フィールドに割り当てる値には、文字列、アダプティブ式、または | を使用した形式の配列を使用できます。

前のテンプレートの組み合わせを次に示します。

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
    Attachments = ${HeroCard()}
    SuggestedActions = 10 | 20 | 30
    InputHint = expecting
]

# GetAge
- how old are you?
- what is your age?

# HeroCard
[Herocard
    title = Hero Card Example
    subtitle = Microsoft Bot Framework
    text = Build and connect intelligent bots to interact with your users naturally wherever they are, from text/sms to Skype, Slack, Office 365 mail and other popular services.
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

既定で、すべてのテンプレート参照は、構造化されたテンプレートの評価時に 1 回評価されます。

たとえば、# AskForAge.prompt では、SpeakText の両方のプロパティに対して、同じ解決テキストを返します。

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
]

# GetAge
- how old are you?
- what is your age?

<TemplateName>!() を使用して、構造化されたテンプレート内の各参照に対して新しい評価を要求できます。

次の例では、各インスタンスで GetAge が再評価されるため、SpeakText の解決テキストが異なる可能性があります。

[Activity
    Text = ${GetAge()}
    Speak = ${GetAge!()}
]

# GetAge
- how old are you?
- what is your age?

カードのカルーセルを表示する方法を次に示します。

# AskForAge.prompt
[Activity
> Defaults to carousel layout in case of list of cards
    Attachments = ${foreach($cardValues, item, HeroCard(item)}
]

# AskForAge.prompt_2
[Activity
> Explicitly specify an attachment layout
    Attachments = ${foreach($cardValues, item, HeroCard(item)}
    AttachmentLayout = list
]

# HeroCard (title, subtitle, text)
[Herocard
    title = ${title}
    subtitle = ${subtitle}
    text = ${text}
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

\ をエスケープ文字として使用します。

> You can use '\' as an escape character
> \${GetAge()} would not be evaluated as expression, would be parsed as '${getAge()}' string
# AskForAge.prompt
[Activity
        Text = \${GetAge()}
        SuggestedActions = 10 \| cards | 20 \| cards
]

構造化されたテンプレートのコンポジション

構造化されたテンプレートでは、次のコンポジション動作がサポートされています。

  • コンポジションは構造コンテキストに対応しています。 参照されているターゲット テンプレートも構造化されたテンプレートである場合は、構造の型が一致している必要があります。 たとえば、ActivityTemplate は別の ActivityTemplate で参照できます。
  • シンプルな応答テンプレートまたは条件付き応答テンプレートへの参照は、構造化されたテンプレート内のどこでも存在できます。

次のテンプレートがあるとします。

# T1
[Activity
    Text = ${T2()}
    Speak = foo bar ${T3().speak}
]

# T2
- This is awesome

# T3
[Activity
    Speak = I can also speak!
]

evaluateTemplate('T1') を呼び出すと、次の内部構造になります。

[Activity
    Text = This is awesome
    Speak = I can also speak!
]

別の構造化されたテンプレートへの完全な参照

別の構造化されたテンプレートへの参照を、別の構造化されたテンプレートにプロパティとして、または別のシンプルな応答テンプレートまたは条件付き応答テンプレートに参照として、含めることができます。

別の構造化されたテンプレートへの完全な参照の例を次に示します。

# ST1
[MyStruct
    Text = foo
    ${ST2()}
]
# ST2
[MyStruct
    Speak = bar
]

このコンテンツでは、evaluateTemplate('ST1') を呼び出すと、次の内部構造になります。

[MyStruct
    Text = foo
    Speak = bar
]

呼び出し元のテンプレートと呼び出し先のテンプレートの両方に同じプロパティが存在する場合、呼び出し元のコンテンツによって、呼び出し先のテンプレートのすべてのコンテンツが上書きされます。

次に例を示します。

# ST1
[MyStruct
    Text = foo
    ${ST2()}
]
# ST2
[MyStruct
    Speak = bar
    Text = zoo
]

このコンテキストでは、evaluateTemplate('ST1') を呼び出すと、次の内部構造になります。

[MyStruct
    Text = foo
    Speak = bar
]

このスタイルのコンポジションはルート レベルにのみ存在できることに注意してください。 プロパティ内に別の構造化されたテンプレートへの参照がある場合、解決はそのプロパティのコンテキストに従います。

構造化された添付ファイルの外部ファイル参照

外部でファイルを参照するために使用する 2 つの事前構築された関数があります

  1. fromFile(fileAbsoluteOrRelativePath) は指定されたファイルを読み込みます。 この関数によって返されるコンテンツは、コンテンツの評価をサポートします。 テンプレート参照、プロパティ、および式が評価されます。
  2. コンテンツにまだ指定されていない場合、ActivityAttachment(content, contentType)contentType を設定します。

これらの 2 つの事前構築済み関数を使用すると、すべてのカードの種類を含む、外部で定義された任意のコンテンツをプルできます。 アクティビティを構成するには、次の構造化 LG を使用します。

# AdaptiveCard
[Activity
                Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'adaptiveCard')}
]

# HeroCard
[Activity
                Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'heroCard')}
]

次に示すように、添付ファイルを使用することもできます。

# AdaptiveCard
[Attachment
    contenttype = adaptivecard
    content = ${json(fromFile('../../card.json'))}
]

# HeroCard
[Attachment
    contenttype = herocard
    content = ${json(fromFile('../../card.json'))}
]

追加情報