插槽配置#

插槽是可从查询中提取的有意义的键值对,可用于任何自定义操作(如插件)。ACE Agent 使用名为 slots.yaml 的文件来简化插槽的检测和处理。您可以定义要支持的插槽,以及诸如内存和规则之类的属性,用于插槽标记和/或插槽操作。

定义插槽#

插槽可以在 slots.yaml 文件中定义。插槽的不同参数可以分为不同的类别,如下图所示。

Slot Definitions overview

插槽可以使用以下 .yaml 格式的语法定义

# Syntax to define different types of slot
slots:
- name:  location
    entity: [destinationplace, weatherplace]
    memory: shortterm
    default: 'santa clara, USA'

- name: poisortcriteria
    lookup: ['distance', 'price', 'best match']
    default: 'best match'
    memory: longterm

- name: region
    lookup: ["usa", "europe", "others"]
    synonyms:
    usa : ["united states", "us", "united states of america"]
    europe : ["eu"]

- name: gpu_type
    validity:
    lookup: ["quadro", "tegra", "ampere", "volta", "hopper"]
    regex: ["[rtx]+", "[geforce]+"]

# Slot resolution enabled slots
- name:  ingredients
    enable_resolution: true
    lookup: ["garlic", "bacon", ...]

- name:  food_name
    enable_resolution: true
    lookup: ["french fries", "cheeseburger", "./food_list.txt"]
    ambiguous_slots: ['ingredients', "toppings", ...]
    synonyms:
    cola: ['coke']
    diet cola: ['diet coke']
    regular cola: ['regular coke']

# Composite slot to group concurrent food attributes together
- name: food_details
    child_slots: # The slots which will be grouped together
    - food_name
    - food_quantity
    - food_size

# Predefined System slots
- name: system.color
- name: system.phone_number

在上面的示例中,有针对 locationpoisortcriteriaregiongpu_typeingredientsfood_detailsfood_name 的插槽定义。每个插槽可以具有以下字段来描述其属性

  • name [type: string] - 强制字段,描述插槽的名称。此名称用作唯一标识符,用于存储和检索对话状态中的值。

  • entity [type: list of strings, default: slot name] - 表示应映射到此插槽的任何 NLP 模型返回的实体标签。在上面的示例中,weather placedestination place 是 NLU 返回的两个不同的实体,但聊天引擎会将它们的值都存储在名为 location 的通用标识符下。这从对话中抽象出模型特定的实体标签依赖性。如果未提及插槽的 entity 标签,则默认情况下,slot name 将设置为 entity 标签。

  • default [type: string, integer or float] - 可选字段,定义插槽的默认值。如果插槽定义了默认值,则会自动填充其默认值。

添加查找和正则表达式规则#

某些插槽可以通过简单的方法(如关键字检测或正则表达式)进行标记。可以为每个插槽定义查找和正则表达式,以分别完成基于关键字和正则表达式的标记。

  • lookup [type: list of strings] - 可选字段,可用于使用字符串匹配来注释查询中的插槽。对于上面的示例,由于为 poisortcriteriaregion 插槽定义了查找。

    对于用户查询

    What is the distance to the USA?
    

    您可以在 Bot Launcher 的调试模式下看到以下插槽被标记为调试信息的一部分

    slots: {"poisortcriteria": ["distance"], "region": ["USA"]
    

    此功能可用于快速定义基于规则的插槽标记,而联合意图和插槽模型未经过此类值的训练。

    注意

    • 基于查找的插槽标记不区分大小写。

    • 查找列表接受指向包含查找词的 .txt 文件的路径。.txt 文件应包含以换行符分隔格式的查找词。

      Hamburger
      Double protein burger
      Onion rings
      Pepsi
      Cola
      Sandwich
      ...
      
  • regex [type: key-value pairs.Values can be a list of strings] - 可选字段,可用于使用 Python 的基于 RegEx 的表达式来注释插槽。例如,如果定义了插槽 citystate

    - name: citystate
            regex: ["[a-z]+:[a-z]+"]
    

    对于用户查询

    What is the distance from houston:Texas to San Diego?
    

    您可以在 Bot Launcher 的调试模式下看到以下插槽被标记为调试信息的一部分

    slots: {citystate: ["houston:texas]"}
    

除了标记插槽值之外,查找和正则表达式还可用于验证由其他来源标记的插槽值。您可以使用插槽的 validity 字段来提及当前插槽的有效查找和/或正则表达式。如果标记的插槽值与有效的查找或正则表达式项不匹配,则会将其丢弃。如果未为插槽定义 validity 字段,则将接受所有标记的插槽值。

  • validity [type: key-value pairs. Values can be a list of strings] - 可选字段,用于验证插槽的值。通过字符串匹配或正则表达式来验证插槽值。validity 可以包含以下两个字段

    • lookup - 此字段中提及的字符串列表是您的插槽允许拥有的唯一值。如果填充了插槽的任何其他值,则聊天引擎会忽略它。

    • regex - 此字段中提及的字符串被视为 Python RegEx 表达式。如果此处指定的任何表达式与插槽的值匹配,则 validity 将被视为成功。

向插槽添加同义词#

一个常见的用例是,当两个或多个插槽值含义相同并且可以互换使用时。插槽配置允许您定义一个同义词字段,该字段将某些插槽值映射到同义词列表。如果标记了任何同义词,它将被配置中的词根替换。

  • synonyms [type: key-value pairs.Values can be a list of strings] - 可选字段,允许您为插槽定义同义词。插槽值的所有相似或变体都可以映射到单个值。当您希望插槽的特定值可用于插件处理时,这非常有用。例如,如果您为 region 插槽和值 USA 定义了同义词

    synonyms:
        USA : ["United States", "US", "United States of America"]
    

    然后,在内存中,如果 United StatesUSUnited States of America 被查找、正则表达式或任何其他模型标记为区域,则插槽值为 USA

    slots: {"region": ["USA"]}
    

定义插槽内存#

您可以为每个插槽定义一个内存组件。这定义了插槽的范围、插槽在内存中保留的时间、它有效的对话轮数以及何时应重置或删除它。

  • memory [type: string] - 可选字段,表示插槽的内存类型。它可以是两个预定义的字符串之一作为其值:shorttermlongterm

    • shortterm 插槽表示它在内存中存储特定持续时间或只要会话处于活动状态。

    • longterm 插槽在用户的会话中可用。这些类型的插槽通常用于捕获用户信息,例如用户的偏好或个性,如家庭住址、喜欢的颜色等等,用户只需提供一次。

    如果未提及 memory 字段,则假定该插槽是没有内存的插槽。它只会为当前查询保留其状态。

  • max turn [type: integer, default: value of shortterm_memory_max_turns in configurations field of slots.yaml file] - 此字段表示此插槽在内存中可用的最大对话轮数。

  • max duration [type: integer, default: shortterm_memory_timeout] - 此字段表示此插槽在内存中可用的持续时间(以秒为单位)。

    注意

    只有当插槽的内存定义为 shortterm 时,max_turnmax_duration 才适用。

使用复合插槽对插槽进行分组#

复合插槽以分层格式将多个插槽组合在一起。例如,当必须将多个食品项组合在一起时,可以在预构建的食品订购机器人中使用这种类型的插槽。考虑以下示例

I would like three cheeseburgers and two large Pepsi's.

此处,从联合意图和插槽模型中推导出的插槽信息将是

food_name: [cheeseburgers, pepsi]
food_size: [large]
food_quantity: [three, two]

如果此信息传达给插件端点,则无法理解 large 是否链接到芝士汉堡或百事可乐。

为了处理这种情况,聊天引擎提供了定义复合插槽的功能,可以将插槽关联在一起。在预构建的食品订购机器人中,food_details 是一个复合插槽,它在 slots.yaml 文件中定义。

# Composite slots to group concurrent food attributes together
- name: food_details
    child_slots: # The slots which will be grouped together
    - food_name
    - food_quantity
    - food_size

根据 child_slots 的位置,如果它们彼此并发,则聊天引擎会将它们组合到一个结构中,该结构传达它们的关联性。对于我们的示例查询,food_details 插槽将类似于以下示例。使用此结构,自定义插件操作可以制定正确的请求,以从菜单服务中提取和验证这些项目。

"food_details": [
    {
    "food_name": [
        "cheeseburgers"
    ],
    "food_quantity": [
        "three"
    ]
    },
    {
    "food_name": [
        "pepsi"
    ],
    "food_quantity": [
        "two"
    ],
    "food_size": [
        "large"
    ]
    }
]

使用插槽解析更正插槽#

插槽解析模块负责根据可用的静态查找列表(如果适用)修改可用的插槽名称和插槽值。它是一个后处理块,在从标记的实体获得查询的所有插槽值后执行。

可以通过将 enable_resolution 设置为 true 在插槽级别启用和禁用此功能。例如

slots:
# All ingredients from food items in the menu.
- name:  ingredients
    enable_resolution: true
    lookup: [“garlics”, “bacon”, ]

- name:  food_name
    enable_resolution: true
    lookup: [“fence fries”, “cheeseburger”, ]
    ambiguous_slots: ['ingredients', “toppings”, ]
    synonyms:
    cola: ['coke']
    diet cola: ['diet coke']
    regular cola: ['regular coke']

考虑以下示例,其中插槽标签和值已标记

I would like a {fence fries}[food_name] with {garlics}[food_name].

如果为插槽启用了插槽解析,则聊天引擎将按顺序执行以下步骤,以检查和修改其每个插槽值的插槽值

  • 首先,聊天引擎检查插槽值(fence friesgarlics)是否出现在与其标记的插槽的查找列表中,即我们的示例中的 food_name。如果存在,则不进行任何更改。

  • 如果插槽值未出现在其查找列表中,即 food_name,则聊天引擎使用编辑距离搜索匹配项。通常,会处理单数/复数映射和轻微的拼写错误。例如,fence fries 在此阶段更正为 french fries

  • 如果在其查找列表中未找到某些插槽的解析,则会逐个检查 ambiguous_slots 的查找列表。如果在任何 ambiguous_slots 的查找表中找到匹配项,则插槽值和插槽标签都会更改。例如,food_name: garlics 更改为 ingredients: garlic,因为 garlic 出现在 ingredients 插槽的查找列表中,它是 food_nameambiguous_slots 之一,并且它通过编辑距离与 garlics 匹配。

将插槽链接到相似的插槽值#

当从查找列表中查找密切匹配的插槽值时,实体链接非常有用。一个示例是在食品订购机器人的用例中。

在食品订购机器人中,有时用户会要求一个项目或类别,但该项目或类别与菜单数据库中的任何条目都不匹配。使用标记的插槽值,机器人将无法满足用户的查询,并且很可能会给出回退响应,因为机器人将无法找到相关项目。

实体链接是查找在含义或语义相似性方面与标记的插槽值密切匹配的查找值的过程。此模块在以下情况下触发

  • 当且仅当通过将 enable_resolution 标志设置为 true 为标记的插槽启用插槽解析时。

  • 如果语义相似性模型部署在 NLP 服务器中。

    • 如果机器学习模型(例如,联合意图和插槽以及 NER 模型)标记的插槽值与查找值不匹配。

    • 如果插槽解析未能更正插槽标签或值。

语义相似性模型创建插槽值和插槽查找的嵌入。查找值(其嵌入与插槽值的嵌入具有最高的余弦相似度,同时也超过了预定义的置信度阈值)被认为是原始插槽值的链接值。

与插槽解析模块不同,模糊插槽会一次性全部与标记的插槽值进行比较。最相似的插槽值链接到标记的值,无论它在模糊插槽列表中位于何处。

实体链接允许通过提出建议来更好地处理未知项目,如从食品订购机器人中看到的那样。

Entity Linking

注意

  • 实体链接的结果作为上下文变量的一部分发送到自定义插件,位于 linked_slots 字段下,相关项目可以在其中进行处理。

  • 链接值也可以在响应模板中访问。