目录

  • Using ActionQueryKnowledgeBase
    • 创建知识数据库(Create a Knowledge Base)
    • 定义NLU数据(Define the NLU Data)
    • 构建自己的知识库查询操作(Create an Action to Query your Knowledge Base)
  • 如何工作(How It Works)
    • 根据对象查询知识库--Query the Knowledge Base for Objects
    • 根据对象的某一属性查询知识库--Query the Knowledge Base for an Attribute of an Object
    • Resolve Mentions
      • 有序提及(Ordinal Mentions)
      • 其它提及(Other Mentions)
  • 自定义--Customization
    • Customizing ActionQueryKnowledgeBase
    • Creating Your Own Knowledge Base Actions
    • Customizing the InMemoryKnowledgeBase
    • Creating Your Own Knowledge Base
  • 参考

在开源bot框架Rasa中,在对话过程中通过使用 ActionQueryKnowledgeBase利用知识库中的信息。
知识库操作使您能够处理以下类型的对话:


会话人工智能中的一个常见问题是,用户不仅通过名称引用特定对象,而且使用“第一个”或“它”等引用术语。我们需要跟踪所提供的信息,以解决这些提到的正确对象。
此外,用户可能希望在交谈中获得有关物品的详细信息,例如,餐厅是否有外置座位,或者价格如何。为了响应这些用户请求,需要了解餐厅定义域。由于信息可能会发生变化,因此硬编码信息并不是解决方案。
为了应对上述挑战,Rasa可以与知识库集成。要使用此集成,可以创建从ActionQueryKnowledgeBase继承的自定义操作,这是一个预先编写的自定义操作,包为了查询含对象及其属性所进行的查询知识库的逻辑。
您可以在examples/knowledgebasebot(knowledge base bot)中找到完整的示例,以及下面实现此自定义操作的说明。

Using ActionQueryKnowledgeBase

创建知识数据库(Create a Knowledge Base)

用于回答用户请求的数据将存储在知识库中。知识库可以用来存储复杂的数据结构。我们建议您开始使用InMemoryKnowledgeBase。一旦您想开始处理大量数据,就可以切换到自定义知识库(请参阅创建自己的知识库)。

要初始化InMemoryKnowledgeBase,需要在json文件中提供数据。以下示例包含有关餐厅和酒店的数据。json结构应该包含每个对象类型的键,即“restaurant”和“hotel”。每个对象类型都映射到一个对象列表–这里我们有一个包含3个餐厅和3个酒店的列表。

{"restaurant": [{"id": 0,"name": "Donath","cuisine": "Italian","outside-seating": true,"price-range": "mid-range"},{"id": 1,"name": "Berlin Burrito Company","cuisine": "Mexican","outside-seating": false,"price-range": "cheap"},{"id": 2,"name": "I due forni","cuisine": "Italian","outside-seating": true,"price-range": "mid-range"}],"hotel": [{"id": 0,"name": "Hilton","price-range": "expensive","breakfast-included": true,"city": "Berlin","free-wifi": true,"star-rating": 5,"swimming-pool": true},{"id": 1,"name": "Hilton","price-range": "expensive","breakfast-included": true,"city": "Frankfurt am Main","free-wifi": true,"star-rating": 4,"swimming-pool": false},{"id": 2,"name": "B&B","price-range": "mid-range","breakfast-included": false,"city": "Berlin","free-wifi": false,"star-rating": 1,"swimming-pool": false},]
}

一旦在json文件(例如data.json)中定义了数据,您就可以使用这个数据文件创建InMemoryKnowledgeBase,它将被传递给查询知识库的操作。
知识库中的每个对象都应该至少有“name”和“id”字段以使用默认实现。如果没有,你就必须定制你的InMemoryKnowledgeBase

定义NLU数据(Define the NLU Data)

在本节中:

  • 我们将介绍一个新的意图,query_knowledge_base
  • 我们将对提及(mention)实体进行注释,以便我们的模型能够检测到像“第一个”这样的间接提及对象
  • 我们将广泛使用同义词

为了让bot理解用户想要从知识库中检索信息,您需要定义一个新的意图。我们称之为query_knowledge_base
我们将ActionQueryKnowledgeBase可以处理的请求分为两类:(1)用户希望获得特定类型的对象列表;或者(2)用户希望了解对象的特定属性。意图应包含这两个请求的许多变体:

nlu:
- intent: query_knowledge_baseexamples: |- what [restaurants]{"entity": "object_type", "value": "restaurant"} can you recommend?- list some [restaurants]{"entity": "object_type", "value": "restaurant"}- can you name some [restaurants]{"entity": "object_type", "value": "restaurant"} please?- can you show me some [restaurants]{"entity": "object_type", "value": "restaurant"} options- list [German](cuisine) [restaurants]{"entity": "sobject_type", "value": "restaurant"}- do you have any [mexican](cuisine) [restaurants]{"entity": "object_type", "value": "restaurant"}?- do you know the [price range]{"entity": "attribute", "value": "price-range"} of [that one](mention)?- what [cuisine](attribute) is [it](mention)?- do you know what [cuisine](attribute) the [last one]{"entity": "mention", "value": "LAST"} has?- does the [first one]{"entity": "mention", "value": "1"} have [outside seating]{"entity": "attribute", "value": "outside-seating"}?- what is the [price range]{"entity": "attribute", "value": "price-range"} of [Berlin Burrito Company](restaurant)?- what about [I due forni](restaurant)?- can you tell me the [price range](attribute) of [that restaurant](mention)?- what [cuisine](attribute) do [they](mention) have?

上面的例子只是展示了与餐馆领域相关的例子。您应该将知识库中存在的每个对象类型的示例添加到相同的query_knowledge_base意图中。
除了为每个查询类型添加各种训练示例外,还需要在训练示例中指定和注释以下实体:

  • object_type:每当培训示例引用知识库中的特定对象类型时,该对象类型应标记为实体。使用同义词,例如,将restaurants映射到restaurant,正确的对象类型列为知识库中的一个键。
  • mention:如果用户通过“第一个”、“那个”或“它”引用对象,则应将这些术语标记为mention。我们还使用同义词将一些提及映射到符号。你可以在resolving mentions中了解到这一点。
  • attribute:知识库中定义的所有属性名称都应在NLU数据中标识为attribute。同样,使用同义词将属性名称的变体映射到知识库中使用的名称。

请记住将这些实体添加到domain.yml文件中(作为实体和插槽):

entities:- object_type- mention- attributeslots:object_type:type: unfeaturizedmention:type: unfeaturizedattribute:type: unfeaturized

构建自己的知识库查询操作(Create an Action to Query your Knowledge Base)

要创建自己的知识库操作,需要继承ActionQueryKnowledgeBase,并将知识库传递给ActionQueryKnowledgeBase的构造函数。

from rasa_sdk.knowledge_base.storage import InMemoryKnowledgeBase
from rasa_sdk.knowledge_base.actions import ActionQueryKnowledgeBaseclass MyKnowledgeBaseAction(ActionQueryKnowledgeBase):def __init__(self):knowledge_base = InMemoryKnowledgeBase("data.json")super().__init__(knowledge_base)

无论何时创建ActionQueryKnowledgeBase,都需要将KnowledgeBase传递给构造函数。它可以是InMemoryKnowledgeBase,也可以是您自己的KnowledgeBase实现(请参阅创建您自己的知识库)。您只能从一个知识库中提取信息,因为不支持同时使用多个知识库。
这是此操作的全部代码!操作的名称是action_query_knowledge_base。不要忘记将其添加到domain.yml文件:

actions:
- action_query_knowledge_base

注意
如果覆盖默认操作名称action_query_knowledge_base,则需要向域文件中添加以下三个非特征化插槽:knowledge_base_objectsknowledge_base_last_objectknowledge_base_last_object_typeActionQueryKnowledgeBase在内部使用这些插槽。如果保留默认操作名称,则会自动为您添加这些插槽。

您还需要确保将一个故事添加到您的故事文件中,其中包括意图query_knowledge_base和操作action_query_knowledge_base。例如:

stories:
- story: knowledge base happy pathsteps:- intent: greet- action: utter_greet- intent: utter_greet- action: action_query_knowledge_base- intent: goodbye- action: utter_goodbye

最后一件事就是在你的域文件中定义响应utter_ask_rephrase。如果操作不知道如何处理用户的请求,它将使用此响应请求用户重新措辞。例如,将以下响应添加到域文件:

responses:utter_ask_rephrase:- text: "Sorry, I'm not sure I understand. Could you rephrase it?"- text: "Could you please rephrase your message? I didn't quite get that."

在添加所有相关的部分之后,该操作现在可以查询知识库。

如何工作(How It Works)

ActionQueryKnowledgeBase查看请求中提取的实体以及之前设置的插槽,以决定要查询的内容。

根据对象查询知识库–Query the Knowledge Base for Objects

为了查询任何类型对象的知识库,用户的请求需要包含对象类型。让我们看一个例子:

你能说出一些餐馆的名字吗?
这个问题包括感兴趣的对象类型:“restaurant”。bot需要获取这个实体以形成一个查询-否则操作将不知道用户感兴趣的对象是什么。

当用户说:
我在柏林有什么意大利餐馆可供选择?
用户希望获得一份餐厅列表,其中:(1)有意大利料理;(2)位于柏林。如果NER(Named Entity Recognition,命名实体识别)在用户的请求中检测到这些属性,该操作将使用这些属性来筛选知识库中找到的餐馆。
为了让bot检测这些属性,您需要在NLU数据中将“意大利料理”和“柏林”标记为实体:

intents:
- intent: query_knowledge_baseexamples: |- What [Italian](cuisine) [restaurant](object_type) options in [Berlin](city) do I have?.

属性的名称,“cuisine”和“city”应该与知识库中使用的名称相同。您还需要将这些作为实体和插槽添加到域文件中。

根据对象的某一属性查询知识库–Query the Knowledge Base for an Attribute of an Object

如果用户想要获得关于某个对象的特定信息,那么请求应该同时包含感兴趣的对象和属性。例如,如果用户提出如下问题:

柏林Burrito公司的菜式是什么?
用户希望获得餐厅“柏林Burrito公司”(兴趣对象)的“cuisine”(兴趣属性)。
感兴趣的属性和对象应标记为NLU训练数据中的实体:

intents:
- intent: query_knowledge_baseexamples: |- What is the [cuisine](attribute) of [Berlin Burrito Company](restaurant)?

确保将对象类型“restaurant”作为实体和插槽添加到domain.yml文件中。

Resolve Mentions

按照上面的例子,用户可能并不总是用他们的名字来指代餐馆。用户可以通过名称引用感兴趣的对象,例如“柏林Burrito公司”(对象的表示字符串),也可以通过提及引用先前列出的对象,例如:

你提到的第二家餐馆的菜是什么?
我们的action是能够解决这些提到的实际对象在知识库。更具体地说,它可以解析两种mention类型:(1)有序提及,如“第一个”;(2)无序提及,如“它”或“那一个”。

有序提及(Ordinal Mentions)

当用户根据对象在列表中的位置引用对象时,称为顺序引用。举个例子:

  • 用户:你知道柏林的什么餐馆?
  • 机器人:找到了“餐厅”类型的以下对象:1:I due forni 2:PastaBar 3:Berlin Burrito Company
  • 用户:第一个有外面的座位吗?

用户用“第一个”这个词来称呼“I due forni”。其他顺序提到可能包括“第二个”、“最后一个”、“任何”或“3”。
有序提及通常在向用户呈现对象列表时使用。为了解决对实际对象的提到,我们使用在KnowledgeBase类中设置的序号提及映射。默认映射如下所示:

{"1": lambda l: l[0],"2": lambda l: l[1],"3": lambda l: l[2],"4": lambda l: l[3],"5": lambda l: l[4],"6": lambda l: l[5],"7": lambda l: l[6],"8": lambda l: l[7],"9": lambda l: l[8],"10": lambda l: l[9],"ANY": lambda l: random.choice(l),"LAST": lambda l: l[-1],
}

有序提及映射将字符串(如“1”)映射到列表中的对象,例如lambda l:l[0],表示索引0处的对象。
例如,由于序数提及映射不包含“第一个”的条目,因此使用实体同义词将NLU数据中的“第一个”映射到“1”是很重要的:

intents:
- intent: query_knowledge_baseexamples: |- Does the [first one]{entity: "mention", value": 1} have [outside seating]{entity: "attribute", value": "outside-seating"}

NER(命名实体识别)将“first one”检测为mention实体,但将“1”放入mention槽中。因此,我们的操作可以将mention槽与顺序mention映射结合起来,将“第一个”解析为实际对象“I due forni”。
您可以通过调用KnowledgeBase中实现的函数set_ordinal_mention_mapping()覆盖序数提及映射(请参见自定义InMemoryKnowledgeBase)。

其它提及(Other Mentions)

请看以下对话:

  • 用户:PastaBar的菜肴是什么?
  • 机器人:PastaBar有意大利菜。
  • 用户:有wifi吗?
  • 机器人:是的。
  • 用户:你能给我一个地址吗?

在问题“Does it have wifi?”中,用户使用“it”一词来指代“PastaBar”。如果NER检测到实体mention的“it”,那么知识库操作将把它解析为会话中最后提到的对象“PastaBar”。

在下一个输入中,用户间接引用对象“PastaBar”,而不是显式地提及它。知识库操作将检测到用户想要获取特定属性的值,在本例中是地址。如果NER未检测到任何mention或对象,则该操作假定用户引用的是最近提及的对象“PastaBar”。

初始化操作时,可以通过将use_last_object_mention设置为False来禁用此行为。

自定义–Customization

Customizing ActionQueryKnowledgeBase

如果您想自定义bot对用户说的话,可以覆盖ActionQueryKnowledgeBase的以下两个函数:

  • utter_objects()
  • utter_attribute_value()

当用户请求对象列表时,使用utter_objects()。一旦bot从知识库中检索到对象,默认情况下,它将向用户发送一条消息,格式如下:
找到“餐厅”类型的以下对象:1: I due forni 2: PastaBar 3: Berlin Burrito Company

或者,如果找不到对象,
我找不到任何“餐馆”类型的东西。

如果要更改话语格式,可以重写操作中的方法utter_objects()

函数utter_attribute_value()确定当用户请求有关对象的特定信息时bot发出的信息。
如果在知识库中找到感兴趣的属性,bot将用以下语句进行响应:
“Berlin Burrito Company”的“cuisine”属性值为“墨西哥菜”。

如果找不到请求属性的值,bot将用
找不到对象“Berlin Burrito Company”的属性“cuisine”的有效值。

如果要更改bot语句,可以重写方法utter_attribute_value()

注意
在我们的博客上有一个关于如何在自定义操作中使用知识库的教程。本教程详细解释了ActionQueryKnowledgeBase背后的实现。

Creating Your Own Knowledge Base Actions

ActionQueryKnowledgeBase应该允许您轻松开始将知识库集成到操作中。但是,该操作只能处理两种用户请求:

  • 用户希望从知识库中获取对象列表
  • 用户希望获取特定对象的属性值

操作无法比较对象或考虑知识库中对象之间的关系。此外,在谈话中将任何mention解析为最后提到的对象可能并不总是最佳的。

如果您想处理更复杂的用例,可以编写自己的自定义操作。我们向rasa_sdk.knowledge_base.utils ()添加了一些帮助函数link to code,以帮助您实现自己的解决方案。我们建议使用KnowledgeBase接口,以便您仍然可以在新的自定义操作的同时使用ActionQueryKnowledgeBase

如果你写了一个知识库操作来处理上面的一个用例或者一个新的用例,一定要在论坛上告诉我们!

Customizing the InMemoryKnowledgeBase

InMemoryKnowledgeBase继承KnowledgeBase。您可以通过重写以下函数自定义InMemoryKnowledgeBase

  • get_key_attribute_of_object():为了跟踪用户最后谈论的对象,我们将key属性的值存储在一个特定的槽中。每个对象都应该有一个唯一的键属性,类似于关系数据库中的主键。默认情况下,每个对象类型的键属性的名称都设置为id。通过调用get_key_attribute_of_object(),可以重写特定对象类型的键属性的名称。

  • get_representation_function_of_object():让我们关注以下餐厅:

    {"id": 0,"name": "Donath","cuisine": "Italian","outside-seating": true,"price-range": "mid-range"
    }
    

    当用户要求bot列出任何意大利餐馆时,它不需要餐馆的所有细节。相反,您希望提供一个有意义的名称来标识餐厅——在大多数情况下,对象的名称就可以了。函数get_representation_function_of_object()返回一个lambda函数,该函数将上述餐厅对象映射到其名称。

    lambda obj: obj["name"]
    

    每当bot谈论一个特定的对象时,就使用这个函数,这样用户就可以得到一个有意义的对象名。
    默认情况下,lambda函数返回对象的“name”属性的值。如果对象没有“name”属性,或者对象的“name”不明确,则应通过调用set_representation_function_of_object()为该对象类型设置新的lambda函数。

  • set_ordinal_mention_mapping():将ordinal mention(如“第二个”)解析为列表中的对象需要ordinal mention mapping(有序提及映射)。默认情况下,ordinal mention mapping如下所示:

    {"1": lambda l: l[0],"2": lambda l: l[1],"3": lambda l: l[2],"4": lambda l: l[3],"5": lambda l: l[4],"6": lambda l: l[5],"7": lambda l: l[6],"8": lambda l: l[7],"9": lambda l: l[8],"10": lambda l: l[9],"ANY": lambda l: random.choice(l),"LAST": lambda l: l[-1],
    }
    

    您可以通过调用函数set_ordinal_mention_mapping()来覆盖它。如果您想了解有关如何使用此映射的更多信息,请查看Resolve Mentions。

有关InMemoryKnowledgeBase的示例实现,请参见示例,该InMemoryKnowledgeBase使用方法set_representation_function_of_object()覆盖对象类型“hotel”的默认表示形式。InMemoryKnowledgeBase本身的实现可以在rasa-sdk包中找到。

Creating Your Own Knowledge Base

如果您有更多的数据,或者想要使用更复杂的数据结构(例如,涉及不同对象之间的关系),则可以创建自己的知识库实现。只需继承KnowledgeBase并实现方法get_objects()get_object()get_attributes_of_object()。知识库代码提供了关于这些方法应该做什么的更多信息。

您还可以通过调整定制InMemoryKnowledgeBase一节中提到的方法,进一步定制知识库。

参考

  1. 官方文档

Rasa SDK中特殊Action类型:Knowledge Base Actions相关推荐

  1. Semantic Parsing via Staged Query Graph Generation: Question Answering with Knowledge Base(笔记)

    introduction 组织世界上的事实并且把它们存储成结构化的数据逐渐变成开源域问答的重要资源,例如:DBPedia (Auer et al., 2007) and Freebase (Bolla ...

  2. 论文浅尝 | 知识图谱问答中的层次类型约束主题实体识别

    Citation:Qiu, Y., Li, M., Wang, Y., Jia, Y., & Jin, X.(2018). Hierarchical Type Constrained Topi ...

  3. 文献阅读课10-Neural Relation Extraction for Knowledge Base Enrichment(提取+嵌入+消歧+规范化联合模型,实体已知,仅关系抽取,多词实体)

    文章目录 Abstract 1.Introduction 2. 相关工作 2.2 Entity-aware Relation Extraction 3.提出的模型 3.1 Solution Frame ...

  4. 论文翻译:《Improved Neural Relation Detection for Knowledge Base Question Answering》

    该论文于2017年发表在ACL,主要讲了智能问答在sq和wq两个数据集上的性能提升,本人研究生方向为这个,故翻译此论文,希望对大家有用. 论文地址:Improved Neural Relation D ...

  5. [nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)...

    :由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . ...

  6. CyberSecurity Knowledge Base笔记

    CSKB: A Cyber Security Knowledge Base Based on Knowledge Graph阅读笔记 Purpose Background Ontology Const ...

  7. 微信SDK中含有的支付功能怎么去掉?

    一.说在前面的话 这两天遇到一个特别让我DT的问题,估计大家通过标题就能知道问题了.没错,就是在应用中集成了微信SDK后,它自动支持了微信分享.登录.收藏.支付等功能.这一点没啥,TM的关键点就是在上 ...

  8. 论文笔记Improving Multi-hop Knowledge Base Question Answering by Learning Intermediate Supervision Signa

    Improving Multi-hop Knowledge Base Question Answering by Learning Intermediate Supervision Signals 引 ...

  9. Entity Linking with a Knowledge Base:Issues, Techniques, and Solutions笔记

    Entity Linking with a Knowledge Base:Issues, Techniques, and Solutions笔记 阅读文献笔记 1 引言 1.1 动机 1. 网络数据的 ...

最新文章

  1. python基础课程_学习笔记13:标准库:有些收藏夹——sys
  2. Linux -- userdel
  3. 协程,又称微线程和纤程
  4. Spring学习笔记之Design of DispatcherServlet
  5. jQuery获取元素索引值index()方法
  6. python代码-你见过哪些令你瞠目结舌的 Python 代码技巧?
  7. Mybatis的简单增删查改(CRUD)
  8. 猎豹网c 语言程序设计,[C/C++基础] 猎豹网校 C++ Primer初级/中级/高级合集发布 猎豹网校Primer视频教程...
  9. 在Linux下安装rarlinux
  10. LaTeX引用参考文献——BibTex参考文献格式大全
  11. matlab时频工具箱简介,matlab时频工具箱
  12. html+div+动画效果,CSS3效果:animate实现点点点loading动画效果(一)
  13. ImproperlyConfigured: mysqlclient 1.4.0 or newer is required; you have 0.10.1.
  14. 《Kotin 极简教程》第14章 使用 Kotlin DSL
  15. 如何吸引全球级「AI大咖」,BAT等大佬怎么说?
  16. devtools,不要下载旧的devtools
  17. 漫谈程序员(二)程序员保值的4个秘密
  18. C语言实现链表的创建
  19. Iris微服务框架_golang web框架_完整示例Demo
  20. 记录一些值得一读的好书

热门文章

  1. Spring中的bean是什么
  2. 如何在电脑上浏览手机网页
  3. 微信小程序:获取用户手机号码的过程
  4. UICollectionView 实现整页翻动(每页3个cell)
  5. XMLHttpRequest详解
  6. Apollo 配置中心
  7. powerdesigner导出表到word,不是正常的表格格式
  8. 准备学习下GOOGLE地图
  9. Android应用程序是如何请求SurfaceFlinger服务渲染一个Surface的?
  10. Hadoop详解(三)——MapReduce原理和执行过程,远程Debug,Writable序列化接口,MapReduce程序编写