Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战六
Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战系列博客,简介了ElasticSearch 8.2.0 的基础知识及操作,本文将基于ElasticSearch 8.2.0 ,开发实现Rasa智能对话机器人,实现Rasa智能对话:
- Rasa对话机器人查询图书信息
- Rasa对话机器人查询影视信息
目录
ElasticSearch 导入Rasa电影案例数据
- 数据源:前1000部电影和电视节目数据集,包含与电影相关的信息。
- 数据格式
- 电影案例的数据样本:
Poster_Link,Series_Title,Released_Year,Certificate,Runtime,Genre,IMDB_Rating,Overview,Meta_score,Director,Star1,Star2,Star3,Star4,No_of_Votes,Gross
"https://m.media-amazon.com/images/M/MV5BMDFkYTc0MGEtZmNhMC00ZDIzLWFmNTEtODM1ZmRlYWMwMWFmXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UX67_CR0,0,67,98_AL_.jpg",The Shawshank Redemption,1994,A,142min,Drama,9.3,"Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.",80,Frank Darabont,Tim Robbins,Morgan Freeman,Bob Gunton,William Sadler,2343110,"28,341,469""https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY98_CR1,0,67,98_AL_.jpg",The Godfather,1972,A,175min,"Crime, Drama",9.2,An organized crime dynasty's aging patriarch transfers control of his clandestine empire to his reluctant son.,100,Francis Ford Coppola,Marlon Brando,Al Pacino,James Caan,Diane Keaton,1620367,"134,966,411""https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_UX67_CR0,0,67,98_AL_.jpg",The Dark Knight,2008,UA,152min,"Action, Crime, Drama",9,"When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.",84,Christopher Nolan,Christian Bale,Heath Ledger,Aaron Eckhart,Michael Caine,2303232,"534,858,444""https://m.media-amazon.com/images/M/MV5BMWMwMGQzZTItY2JlNC00OWZiLWIyMDctNDk2ZDQ2YjRjMWQ0XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY98_CR1,0,67,98_AL_.jpg",The Godfather: Part II,1974,A,202min,"Crime, Drama",9,"The early life and career of Vito Corleone in 1920s New York City is portrayed, while his son, Michael, expands and tightens his grip on the family crime syndicate.",90,Francis Ford Coppola,Al Pacino,Robert De Niro,Robert Duvall,Diane Keaton,1129952,"57,300,000""https://m.media-amazon.com/images/M/MV5BMWU4N2FjNzYtNTVkNC00NzQ0LTg0MjAtYTJlMjFhNGUxZDFmXkEyXkFqcGdeQXVyNjc1NTYyMjg@._V1_UX67_CR0,0,67,98_AL_.jpg",12 Angry Men,1957,U,96min,"Crime, Drama",9,A jury holdout attempts to prevent a miscarriage of justice by forcing his colleagues to reconsider the evidence.,96,Sidney Lumet,Henry Fonda,Lee J. Cobb,Martin Balsam,John Fiedler,689845,"4,360,000""https://m.media-amazon.com/images/M/MV5BNzA5ZDNlZWMtM2NhNS00NDJjLTk4NDItYTRmY2EwMWZlMTY3XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX67_CR0,0,67,98_AL_.jpg",The Lord of the Rings: The Return of the King,2003,U,201min,"Action, Adventure, Drama",8.9,Gandalf and Aragorn lead the World of Men against Sauron's army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring.,94,Peter Jackson,Elijah Wood,Viggo Mortensen,Ian McKellen,Orlando Bloom,1642758,"377,845,905""https://m.media-amazon.com/images/M/MV5BNGNhMDIzZTUtNTBlZi00MTRlLWFjM2ItYzViMjE3YzI5MjljXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY98_CR0,0,67,98_AL_.jpg",Pulp Fiction,1994,A,154min,"Crime, Drama",8.9,"The lives of two mob hitmen, a boxer, a gangster and his wife, and a pair of diner bandits intertwine in four tales of violence and redemption.",94,Quentin Tarantino,John Travolta,Uma Thurman,Samuel L. Jackson,Bruce Willis,1826188,"107,928,762""https://m.media-amazon.com/images/M/MV5BNDE4OTMxMTctNmRhYy00NWE2LTg3YzItYTk3M2UwOTU5Njg4XkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_UX67_CR0,0,67,98_AL_.jpg",Schindler's List,1993,A,195min,"Biography, Drama, History",8.9,"In German-occupied Poland during World War II, industrialist Oskar Schindler gradually becomes concerned for his Jewish workforce after witnessing their persecution by the Nazis.",94,Steven Spielberg,Liam Neeson,Ralph Fiennes,Ben Kingsley,Caroline Goodall,1213505,"96,898,818""https://m.media-amazon.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_UX67_CR0,0,67,98_AL_.jpg",Inception,2010,UA,148min,"Action, Adventure, Sci-Fi",8.8,A thief who steals corporate secrets through the use of dream-sharing technology is given the inverse task of planting an idea into the mind of a C.E.O.,74,Christopher Nolan,Leonardo DiCaprio,Joseph Gordon-Levitt,Elliot Page,Ken Watanabe,2067042,"292,576,195""https://m.media-amazon.com/images/M/MV5BMmEzNTkxYjQtZTc0MC00YTVjLTg5ZTEtZWMwOWVlYzY0NWIwXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX67_CR0,0,67,98_AL_.jpg",Fight Club,1999,A,139min,Drama,8.8,"An insomniac office worker and a devil-may-care soapmaker form an underground fight club that evolves into something much, much more.",66,David Fincher,Brad Pitt,Edward Norton,Meat Loaf,Zach Grenier,1854740,"37,030,102""https://m.media-amazon.com/images/M/MV5BN2EyZjM3NzUtNWUzMi00MTgxLWI0NTctMzY4M2VlOTdjZWRiXkEyXkFqcGdeQXVyNDUzOTQ5MjY@._V1_UX67_CR0,0,67,98_AL_.jpg",The Lord of the Rings: The Fellowship of the Ring,2001,U,178min,"Action, Adventure, Drama",8.8,A meek Hobbit from the Shire and eight companions set out on a journey to destroy the powerful One Ring and save Middle-earth from the Dark Lord Sauron.,92,Peter Jackson,Elijah Wood,Ian McKellen,Orlando Bloom,Sean Bean,1661481,"315,544,750""https://m.media-amazon.com/images/M/MV5BNWIwODRlZTUtY2U3ZS00Yzg1LWJhNzYtMmZiYmEyNmU1NjMzXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UY98_CR0,0,67,98_AL_.jpg",Forrest Gump,1994,UA,142min,"Drama, Romance",8.8,"The presidencies of Kennedy and Johnson, the events of Vietnam, Watergate and other historical events unfold through the perspective of an Alabama man with an IQ of 75, whose only desire is to be reunited with his childhood sweetheart.",82,Robert Zemeckis,Tom Hanks,Robin Wright,Gary Sinise,Sally Field,1809221,"330,252,182""https://m.media-amazon.com/images/M/MV5BOTQ5NDI3MTI4MF5BMl5BanBnXkFtZTgwNDQ4ODE5MDE@._V1_UX67_CR0,0,67,98_AL_.jpg","Il buono, il brutto, il cattivo",1966,A,161min,Western,8.8,A bounty hunting scam joins two men in an uneasy alliance against a third in a race to find a fortune in gold buried in a remote cemetery.,90,Sergio Leone,Clint Eastwood,Eli Wallach,Lee Van Cleef,Aldo Giuffrè,688390,"6,100,000""https://m.media-amazon.com/images/M/MV5BZGMxZTdjZmYtMmE2Ni00ZTdkLWI5NTgtNjlmMjBiNzU2MmI5XkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_UX67_CR0,0,67,98_AL_.jpg",The Lord of the Rings: The Two Towers,2002,UA,179min,"Action, Adventure, Drama",8.7,"While Frodo and Sam edge closer to Mordor with the help of the shifty Gollum, the divided fellowship makes a stand against Sauron's new ally, Saruman, and his hordes of Isengard.",87,Peter Jackson,Elijah Wood,Ian McKellen,Viggo Mortensen,Orlando Bloom,1485555,"342,551,365""https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_UX67_CR0,0,67,98_AL_.jpg",The Matrix,1999,A,136min,"Action, Sci-Fi",8.7,"When a beautiful stranger leads computer hacker Neo to a forbidding underworld, he discovers the shocking truth--the life he knows is the elaborate deception of an evil cyber-intelligence.",73,Lana Wachowski,Lilly Wachowski,Keanu Reeves,Laurence Fishburne,Carrie-Anne Moss,1676426,"171,479,930""https://m.media-amazon.com/images/M/MV5BY2NkZjEzMDgtN2RjYy00YzM1LWI4ZmQtMjIwYjFjNmI3ZGEwXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX67_CR0,0,67,98_AL_.jpg",Goodfellas,1990,A,146min,"Biography, Crime, Drama",8.7,"The story of Henry Hill and his life in the mob, covering his relationship with his wife Karen Hill and his mob partners Jimmy Conway and Tommy DeVito in the Italian-American crime syndicate.",90,Martin Scorsese,Robert De Niro,Ray Liotta,Joe Pesci,Lorraine Bracco,1020727,"46,836,394""https://m.media-amazon.com/images/M/MV5BYmU1NDRjNDgtMzhiMi00NjZmLTg5NGItZDNiZjU5NTU4OTE0XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX67_CR0,0,67,98_AL_.jpg",Star Wars: Episode V - The Empire Strikes Back,1980,UA,124min,"Action, Adventure, Fantasy",8.7,"After the Rebels are brutally overpowered by the Empire on the ice planet Hoth, Luke Skywalker begins Jedi training with Yoda, while his friends are pursued by Darth Vader and a bounty hunter named Boba Fett all over the galaxy.",82,Irvin Kershner,Mark Hamill,Harrison Ford,Carrie Fisher,Billy Dee Williams,1159315,"290,475,067""https://m.media-amazon.com/images/M/MV5BZjA0OWVhOTAtYWQxNi00YzNhLWI4ZjYtNjFjZTEyYjJlNDVlL2ltYWdlL2ltYWdlXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UX67_CR0,0,67,98_AL_.jpg",One Flew Over the Cuckoo's Nest,1975,A,133min,Drama,8.7,"A criminal pleads insanity and is admitted to a mental institution, where he rebels against the oppressive nurse and rallies up the scared patients.",83,Milos Forman,Jack Nicholson,Louise Fletcher,Michael Berryman,Peter Brocco,918088,"112,000,000""https://m.media-amazon.com/images/M/MV5BNjViNWRjYWEtZTI0NC00N2E3LTk0NGQtMjY4NTM3OGNkZjY0XkEyXkFqcGdeQXVyMjUxMTY3ODM@._V1_UX67_CR0,0,67,98_AL_.jpg",Hamilton,2020,PG-13,160min,"Biography, Drama, History",8.6,"The real life of one of America's foremost founding fathers and first Secretary of the Treasury, Alexander Hamilton. Captured live on Broadway from the Richard Rodgers Theater with the original Broadway cast.",90,Thomas Kail,Lin-Manuel Miranda,Phillipa Soo,Leslie Odom Jr.,Renée Elise Goldsberry,55291,"https://m.media-amazon.com/images/M/MV5BYWZjMjk3ZTItODQ2ZC00NTY5LWE0ZDYtZTI3MjcwN2Q5NTVkXkEyXkFqcGdeQXVyODk4OTc3MTY@._V1_UX67_CR0,0,67,98_AL_.jpg",Gisaengchung,2019,A,132min,"Comedy, Drama, Thriller",8.6,Greed andclassdiscrimination threaten the newly formed symbiotic relationship between the wealthy Park family and the destitute Kim clan.,96,Bong Joon Ho,Kang-ho Song,Lee Sun-kyun,Cho Yeo-jeong,Choi Woo-sik,552778,"53,367,844""https://m.media-amazon.com/images/M/MV5BOTc2ZTlmYmItMDBhYS00YmMzLWI4ZjAtMTI5YTBjOTFiMGEwXkEyXkFqcGdeQXVyODE5NzE3OTE@._V1_UY98_CR0,0,67,98_AL_.jpg",Soorarai Pottru,2020,U,153min,Drama,8.6,"Nedumaaran Rajangam ""Maara"" sets out to make the common man fly and in the process takes on the world's most capital intensive industry and several enemies who stand in his way.",,Sudha Kongara,Suriya,Madhavan,Paresh Rawal,Aparna Balamurali,54995,"https://m.media-amazon.com/images/M/MV5BZjdkOTU3MDktN2IxOS00OGEyLWFmMjktY2FiMmZkNWIyODZiXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UX67_CR0,0,67,98_AL_.jpg",Interstellar,2014,UA,169min,"Adventure, Drama, Sci-Fi",8.6,A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.,74,Christopher Nolan,Matthew McConaughey,Anne Hathaway,Jessica Chastain,Mackenzie Foy,1512360,"188,020,017""https://m.media-amazon.com/images/M/MV5BOTMwYjc5ZmItYTFjZC00ZGQ3LTlkNTMtMjZiNTZlMWQzNzI5XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX67_CR0,0,67,98_AL_.jpg",Cidade de Deus,2002,A,130min,"Crime, Drama",8.6,"In the slums of Rio, two kids' paths diverge as one struggles to become a photographer and the other a kingpin.",79,Fernando Meirelles,Kátia Lund,Alexandre Rodrigues,Leandro Firmino,Matheus Nachtergaele,699256,"7,563,397""https://m.media-amazon.com/images/M/MV5BMjlmZmI5MDctNDE2YS00YWE0LWE5ZWItZDBhYWQ0NTcxNWRhXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UX67_CR0,0,67,98_AL_.jpg",Sen to Chihiro no kamikakushi,2001,U,125min,"Animation, Adventure, Family",8.6,"During her family's move to the suburbs, a sullen 10-year-old girl wanders into a world ruled by gods, witches, and spirits, and where humans are changed into beasts.",96,Hayao Miyazaki,Daveigh Chase,Suzanne Pleshette,Miyu Irino,Rumi Hiiragi,651376,"10,055,859""https://m.media-amazon.com/images/M/MV5BZjhkMDM4MWItZTVjOC00ZDRhLThmYTAtM2I5NzBmNmNlMzI1XkEyXkFqcGdeQXVyNDYyMDk5MTU@._V1_UX67_CR0,0,67,98_AL_.jpg",Saving Private Ryan,1998,R,169min,"Drama, War",8.6,"Following the Normandy Landings, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action.",91,Steven Spielberg,Tom Hanks,Matt Damon,Tom Sizemore,Edward Burns,1235804,"216,540,909""https://m.media-amazon.com/images/M/MV5BMTUxMzQyNjA5MF5BMl5BanBnXkFtZTYwOTU2NTY3._V1_UX67_CR0,0,67,98_AL_.jpg",The Green Mile,1999,A,189min,"Crime, Drama, Fantasy",8.6,"The lives of guards on Death Row are affected by one of their charges: a black man accused of child murder and rape, yet who has a mysterious gift.",61,Frank Darabont,Tom Hanks,Michael Clarke Duncan,David Morse,Bonnie Hunt,1147794,"136,801,374""https://m.media-amazon.com/images/M/MV5BYmJmM2Q4NmMtYThmNC00ZjRlLWEyZmItZTIwOTBlZDQ3NTQ1XkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UX67_CR0,0,67,98_AL_.jpg",La vita è bella,1997,U,116min,"Comedy, Drama, Romance",8.6,"When an open-minded Jewish librarian and his son become victims of the Holocaust, he uses a perfect mixture of will, humor, and imagination to protect his son from the dangers around their camp.",59,Roberto Benigni,Roberto Benigni,Nicoletta Braschi,Giorgio Cantarini,Giustino Durano,623629,"57,598,247""https://m.media-amazon.com/images/M/MV5BOTUwODM5MTctZjczMi00OTk4LTg3NWUtNmVhMTAzNTNjYjcyXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_UX67_CR0,0,67,98_AL_.jpg",Se7en,1995,A,127min,"Crime, Drama, Mystery",8.6,"Two detectives, a rookie and a veteran, hunt a serial killer who uses the seven deadly sins as his motives.",65,David Fincher,Morgan Freeman,Brad Pitt,Kevin Spacey,Andrew Kevin Walker,1445096,"100,125,643""https://m.media-amazon.com/images/M/MV5BNjNhZTk0ZmEtNjJhMi00YzFlLWE1MmEtYzM1M2ZmMGMwMTU4XkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_UX67_CR0,0,67,98_AL_.jpg",The Silence of the Lambs,1991,A,118min,"Crime, Drama, Thriller",8.6,"A young F.B.I. cadet must receive the help of an incarcerated and manipulative cannibal killer to help catch another serial killer, a madman who skins his victims.",85,Jonathan Demme,Jodie Foster,Anthony Hopkins,Lawrence A. Bonney,Kasi Lemmons,1270197,"130,742,922"
Rasa智能对话机器人从电影数据中获取的电影信息字段:
- “title”: 电影的标题
- “publication_year”: 电影的发行日期
- “genres”: 电影的类别
- “summary”: 电影的摘要信息
- “actors”: 电影的明星演员
- “director”: 电影的导演
使用python代码将影视数据导入ElasticSearch,导入结果:
postman发送get请求https://127.0.0.1:9200/movie,查询索引内容
收到ElasticSearch 的返回信息
{"movie":{"aliases":{},
"mappings":{"properties":{"actors":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"director":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"film_id":{"type":"long"},
"genres":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"publication_year":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"summary":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"title":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}}}},
"settings":{"index":{"routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},
"number_of_shards":"1",
"provided_name":"movie",
"creation_date":"1652924386398",
"number_of_replicas":"1",
"uuid":"9kSFu52hRR6wWRttosQP8Q",
"version":{"created":"8020099"}}}}}
Rasa智能对话机器人从电影数据中获取的评分字段:
- “mean_rating”: 电影评分
- “total_votes”: 电影投票人数 postman发送get请求https://127.0.0.1:9200/rating,查询索引内容 收到ElasticSearch 的返回信息
{"rating":{"aliases":{},
"mappings":{"properties":{"film_id":{"type":"long"},
"mean_rating":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}},
"total_votes":{"type":"text",
"fields":{"keyword":{"type":"keyword",
"ignore_above":256}}}}},
"settings":{"index":{"routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},
"number_of_shards":"1",
"provided_name":"rating",
"creation_date":"1652924386923",
"number_of_replicas":"1",
"uuid":"nttPpGwoQqmCs8y5dGFZeA",
"version":{"created":"8020099"}}}}}
基于 ElasticSearch的Rasa智能对话机器人开发
- 构建电影、图书、评分的DocumentType类型
- 构建 Elasticsearch KnowledgeBase知识库类
- 获取属性词槽。如用户说“What Italian restaurants do you know?”, NER应将“Italian”视为“cuisine”,“cuisine”是对象类型“ restaurants”的一个属性,因此,此方法返回[{‘name’: ‘cuisine’, ‘value’: ‘Italian’}]
- 构建数据存储类,用于Rasa与Elasticsearch的查询交互。
Rasa 3.1.0 KnowledgeBase 源代码分析
- Rasa 框架源代码action.py:
import typing
from typing import Text, Dict, List, Any
from rasa_sdk import Action
from rasa_sdk.events import SlotSet
from rasa_sdk.knowledge_base.utils import(
SLOT_OBJECT_TYPE,
SLOT_LAST_OBJECT_TYPE,
SLOT_ATTRIBUTE,
reset_attribute_slots,
SLOT_MENTION,
SLOT_LAST_OBJECT,
SLOT_LISTED_OBJECTS,
get_object_name,
get_attribute_slots,
)
from rasa_sdk import utils
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.interfaces import Tracker
from rasa_sdk.knowledge_base.storage import KnowledgeBase
if typing.TYPE_CHECKING: # pragma: no cover
from rasa_sdk.types import DomainDict
class ActionQueryKnowledgeBase(Action):
"""
Action that queries the knowledge base for objects and attributes of an object.
The action needs to be inherited and the knowledge base needs to be set.
In order to actually query the knowledge base you need to:
- create your knowledge base
- add mandatory slots to the domain file: 'object_type', 'attribute', 'mention'
- create NLU data where the required objects are annotated
- create a story that includes this action
- add the intent and action to domain file"""
def __init__(
self, knowledge_base: KnowledgeBase, use_last_object_mention: bool = True
) -> None:
self.knowledge_base = knowledge_base
self.use_last_object_mention = use_last_object_mention
def name(self) -> Text:
return"action_query_knowledge_base"
def utter_attribute_value(
self,
dispatcher: CollectingDispatcher,
object_name: Text,
attribute_name: Text,
attribute_value: Text,
):
"""
Utters a response that informs the user about the attribute value of the
attribute of interest.
Args:
dispatcher: the dispatcher
object_name: the name of the object
attribute_name: the name of the attribute
attribute_value: the value of the attribute
"""
if attribute_value:
dispatcher.utter_message(text=f"'{object_name}' has the value '{attribute_value}' for attribute '{attribute_name}'.")
else:
dispatcher.utter_message(text=f"Did not find a valid value for attribute '{attribute_name}' for object '{object_name}'.")
async def utter_objects(
self,
dispatcher: CollectingDispatcher,
object_type: Text,
objects: List[Dict[Text, Any]],
):
"""
Utters a response to the user that lists all found objects.
Args:
dispatcher: the dispatcher
object_type: the object type
objects: the list of objects
"""
if objects:
dispatcher.utter_message(text=f"Found the following objects of type '{object_type}':")
repr_function = await utils.call_potential_coroutine(
self.knowledge_base.get_representation_function_of_object(object_type))for i, obj in enumerate(objects, 1):
dispatcher.utter_message(text=f"{i}: {repr_function(obj)}")
else:
dispatcher.utter_message(text=f"I could not find any objects of type '{object_type}'.")
async def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: "DomainDict",
) -> List[Dict[Text, Any]]:
"""
Executes this action. If the user ask a question about an attribute,
the knowledge base is queried for that attribute. Otherwise, if no
attribute was detected in the request or the user is talking about a new
object type, multiple objects of the requested type are returned from the
knowledge base.
Args:
dispatcher: the dispatcher
tracker: the tracker
domain: the domain
Returns: list of slots
"""
object_type = tracker.get_slot(SLOT_OBJECT_TYPE)
last_object_type = tracker.get_slot(SLOT_LAST_OBJECT_TYPE)
attribute = tracker.get_slot(SLOT_ATTRIBUTE)
new_request = object_type != last_object_type
if not object_type:
# object type always needs to be set as this is needed to query the# knowledge base
dispatcher.utter_message(response="utter_ask_rephrase")return[]if not attribute or new_request:
return await self._query_objects(dispatcher, object_type, tracker)elif attribute:
return await self._query_attribute(
dispatcher, object_type, attribute, tracker
)
dispatcher.utter_message(response="utter_ask_rephrase")return[]
async def _query_objects(
self, dispatcher: CollectingDispatcher, object_type: Text, tracker: Tracker
) -> List[Dict]:
"""
Queries the knowledge base for objects of the requested object type and
outputs those to the user. The objects are filtered by any attribute the
user mentioned in the request.
Args:
dispatcher: the dispatcher
tracker: the tracker
Returns: list of slots
"""
object_attributes = await utils.call_potential_coroutine(
self.knowledge_base.get_attributes_of_object(object_type))# get all set attribute slots of the object type to be able to filter the# list of objects
attributes = get_attribute_slots(tracker, object_attributes)# query the knowledge base
objects = await utils.call_potential_coroutine(
self.knowledge_base.get_objects(object_type, attributes))
await utils.call_potential_coroutine(
self.utter_objects(dispatcher, object_type, objects))if not objects:
return reset_attribute_slots(tracker, object_attributes)
key_attribute = await utils.call_potential_coroutine(
self.knowledge_base.get_key_attribute_of_object(object_type))
last_object = None if len(objects)>1else objects[0][key_attribute]
slots =[
SlotSet(SLOT_OBJECT_TYPE, object_type),
SlotSet(SLOT_MENTION, None),
SlotSet(SLOT_ATTRIBUTE, None),
SlotSet(SLOT_LAST_OBJECT, last_object),
SlotSet(SLOT_LAST_OBJECT_TYPE, object_type),
SlotSet(
SLOT_LISTED_OBJECTS, list(map(lambda e: e[key_attribute], objects))),
]return slots + reset_attribute_slots(tracker, object_attributes)
async def _query_attribute(
self,
dispatcher: CollectingDispatcher,
object_type: Text,
attribute: Text,
tracker: Tracker,
) -> List[Dict]:
"""
Queries the knowledge base for the value of the requested attribute of the
mentioned object and outputs it to the user.
Args:
dispatcher: the dispatcher
tracker: the tracker
Returns: list of slots
"""
object_name = get_object_name(
tracker,
self.knowledge_base.ordinal_mention_mapping,
self.use_last_object_mention,
)if not object_name or not attribute:
dispatcher.utter_message(response="utter_ask_rephrase")return[SlotSet(SLOT_MENTION, None)]
object_of_interest = await utils.call_potential_coroutine(
self.knowledge_base.get_object(object_type, object_name))if not object_of_interest or attribute not in object_of_interest:
dispatcher.utter_message(response="utter_ask_rephrase")return[SlotSet(SLOT_MENTION, None)]
value = object_of_interest[attribute]
object_repr_func = await utils.call_potential_coroutine(
self.knowledge_base.get_representation_function_of_object(object_type))
object_representation = object_repr_func(object_of_interest)
key_attribute = await utils.call_potential_coroutine(
self.knowledge_base.get_key_attribute_of_object(object_type))
object_identifier = object_of_interest[key_attribute]
await utils.call_potential_coroutine(
self.utter_attribute_value(
dispatcher, object_representation, attribute, value
))
slots =[
SlotSet(SLOT_OBJECT_TYPE, object_type),
SlotSet(SLOT_ATTRIBUTE, None),
SlotSet(SLOT_MENTION, None),
SlotSet(SLOT_LAST_OBJECT, object_identifier),
SlotSet(SLOT_LAST_OBJECT_TYPE, object_type),
]return slots
- Rasa storage.py的KnowledgeBase源代码:
import json
import logging
import os
import random
from typing import DefaultDict, Text, Callable, Dict, List, Any, Optional
from collections import defaultdict
from rasa_sdk import utils
logger = logging.getLogger(__name__)
class KnowledgeBase:
def __init__(self) -> None:
self.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],
}
self.key_attribute: DefaultDict[Text, Text]= defaultdict(lambda: "id")
self.representation_function: DefaultDict[
Text, Callable[[Dict[Text, Text]], Text]]= defaultdict(lambda: lambda obj: obj["name"])
async def get_attributes_of_object(self, object_type: Text) -> List[Text]:
"""
Returns a list of all attributes that belong to the provided object type.
Args:
object_type: the object type
Returns: list of attributes of object_type
"""
raise NotImplementedError("Method is not implemented.")
async def get_key_attribute_of_object(self, object_type: Text) -> Text:
"""
Returns the key attribute for the given object type.
Args:
object_type: the object type
Returns: key attribute
"""
return self.key_attribute[object_type]
async def get_representation_function_of_object(
self, object_type: Text
) -> Callable:
"""
Returns a lamdba function that takes the object and returns a string
representation of it.
Args:
object_type: the object type
Returns: lamdba function"""
return self.representation_function[object_type]
def set_ordinal_mention_mapping(self, mapping: Dict[Text, Callable]) -> None:
"""
Overwrites the default ordinal mention mapping. E.g. the mapping that
maps, for example, "first one" to the first element in a list.
Args:
mapping: the ordinal mention mapping
"""
self.ordinal_mention_mapping = mapping
async def get_objects(
self, object_type: Text, attributes: List[Dict[Text, Text]], limit: int =5) -> List[Dict[Text, Any]]:
"""
Query the knowledge base for objects of the given type. Restrict the objects
by the provided attributes, if any attributes are given.
Args:
object_type: the object type
attributes: list of attributes
limit: maximum number of objects to return
Returns: list of objects
"""
raise NotImplementedError("Method is not implemented.")
async def get_object(
self, object_type: Text, object_identifier: Text
) -> Optional[Dict[Text, Any]]:
"""
Returns the object of the given type that matches the given object identifier.
Args:
object_type: the object type
object_identifier: value of the key attribute or the string
representation of the object
Returns: the object of interest
"""
raise NotImplementedError("Method is not implemented.")
class InMemoryKnowledgeBase(KnowledgeBase):
def __init__(self, data_file: Text) -> None:
"""
Initialize the in-memory knowledge base.
Loads the data from the given data file into memory.
Args:
data_file: the path to the file containing the data
"""
self.data_file = data_file
self.data: Dict[Text, Any]={}
self.load()
super().__init__()
def load(self) -> None:
"""
Load the data from the given file and initialize an in-memory knowledge base.
"""
try:
with open(self.data_file, encoding="utf-8") as f:
content = f.read()
except OSError:
raise ValueError(f"File '{self.data_file}' does not exist.")
try:
self.data = json.loads(content)
except ValueError as e:
raise ValueError(
f"Failed to read json from '{os.path.abspath(self.data_file)}'. Error: {e}")
def set_representation_function_of_object(
self, object_type: Text, representation_function: Callable
) -> None:
"""
Set the representation function of the given object type.
Args:
object_type: the object type
representation_function: the representation function"""
self.representation_function[object_type]= representation_function
def set_key_attribute_of_object(
self, object_type: Text, key_attribute: Text
) -> None:
"""
Set the key attribute of the given object type.
Args:
object_type: the object type
key_attribute: the name of the key attribute
"""
self.key_attribute[object_type]= key_attribute
async def get_attributes_of_object(self, object_type: Text) -> List[Text]:
if object_type not in self.data or not self.data[object_type]:
return[]
first_object = self.data[object_type][0]return list(first_object.keys())
async def get_objects(
self, object_type: Text, attributes: List[Dict[Text, Text]], limit: int =5) -> List[Dict[Text, Any]]:
if object_type not in self.data:
return[]
objects = self.data[object_type]# filter objects by attributesif attributes:
objects = list(
filter(
lambda obj: [
obj[a["name"]]== a["value"]forain attributes
].count(False)==0,
objects,
))
random.shuffle(objects)return objects[:limit]
async def get_object(
self, object_type: Text, object_identifier: Text
) -> Optional[Dict[Text, Any]]:
if object_type not in self.data:
return None
objects = self.data[object_type]
key_attribute = await utils.call_potential_coroutine(
self.get_key_attribute_of_object(object_type))# filter the objects by its key attribute, for example, 'id'
objects_of_interest = list(
filter(
lambda obj: str(obj[key_attribute]).lower()== str(object_identifier).lower(),
objects,
))# if the object was referred to directly, we need to compare the representation# of each object with the given object identifierif not objects_of_interest:
repr_function = await utils.call_potential_coroutine(
self.get_representation_function_of_object(object_type))
objects_of_interest = list(
filter(
lambda obj: str(object_identifier).lower()in str(repr_function(obj)).lower(),
objects,
))if not objects_of_interest or len(objects_of_interest)>1:
# TODO:# if multiple objects are found, the objects could be shown# to the user. the user then needs to clarify what object he meant.return None
return objects_of_interest[0]
基于 ElasticSearch的Rasa 对话互动场景
Rasa对话机器人和用户打招呼
用户说:你好
Bot说: 嗨,你好吗?我能为你做些什么?
2022-05-19 15:51:15 INFO root - Rasa server is up and running.
Bot loaded. Type a message and press enter (use '/stop' to exit):
Your input -> hello
Hi, how are you? What can I dofor you?
Rasa对话机器人协助用户查询电影
用户说:请提供一些电影
Bot说: 我发现了以下电影:
1: 1994年的《肖申克的救赎》
2: 1972年的教父
3: 2008年的《黑暗骑士》
4: 《教父》:1974年第二部
5: 1983年的《星球大战6:绝地归来》
Your input -> show some film
I found the following movies :1: The Shawshank Redemption from 19942: The Godfather from 19723: The Dark Knight from 20084: The Godfather: Part II from 19745: Star Wars: Episode VI - Return of the Jedi from 1983
Rasa对话机器人使用序数指代 查询指定电影
用户说:给我看第二个的电影摘要信息
Bot说: 《1972年教父》的摘要是
“An organized crime dynasty’s aging patriarch transfers control of his clandestine empire to his reluctant son.”。
Your input -> show me the summary of the second one
The summary of "The Godfather from 1972" is
"An organized crime dynasty's aging patriarch transfers control of his clandestine empire to his reluctant son.".
Rasa对话机器人协助用户查询图书
用户说:给我看一些图书
Bot说: 我找到了以下几本书:
1: 1945-08-17年的《动物农场》
2: 1962年的《发条橙》
3: 1884年的《哈克贝利·费恩历险记》
4: 1929-01-29年《西线无战事》
5: 1968年的《A Wizard of Earthsea》
Your input -> show me some books
I found the following books :1: Animal Farm from 1945-08-17
2: A Clockwork Orange from 19623: Adventures of Huckleberry Finn from 18844: All Quiet on the Western Front from 1929-01-29
5: A Wizard of Earthsea from 1968
Rasa对话机器人协助用户查询作者
用户说:最终一本书的作者是谁?
Bot说: 1968年《A Wizard of Earthsea》的作者是Ursula K. Le Guin。
Your input ->who is the author of the last one?
The author of "A Wizard of Earthsea from 1968" is
"Ursula K. Le Guin".
Rasa对话机器人查询电影动作片
用户说:请提供一些动作片电影
Bot说: 我发现了以下不同类型的电影动作片:
- 终结者 1984年
- 夺宝奇兵 1981年
- 科拉尔金矿 2018年
- 巴霍巴利王2 2017年
- 蝙蝠侠 2005年
Your input -> show me some action films
I found the following movies with genres: action:
1: The Terminator from 19842: Raiders of the Lost Ark from 19813: K.G.F: Chapter 1 from 20184: Baahubali 2: The Conclusion from 20175: Batman Begins from 2005
Rasa对话机器人 查询指定电影
用户说:你能提供第二个电影的摘要吗?
Bot说: 1981年《夺宝奇兵》的概要是 1936年,考古学家兼冒险家印第安纳·琼斯受聘于美国政府找到约柜。
Your input -> could you please summarize the second one?
The summary of "Raiders of the Lost Ark from 1981" is
""In 1936, archaeologist and adventurer Indiana Jones is hired by the U.S. government to find the Ark of the Covenant before Adolf Hitler's Nazis can obta
in its awesome powers."".
Rasa对话机器人 查询指定年份的电影
用户说:提供2020年拍的电影
Bot说: 我发现了以下电影… 这里没有识别出2020年的电影,原因可能是rasa训练样本的数量不够,这里只提供了几条数据,通常要100条到200条训练样本,但通过rasa interactive测试,发现rasa nlu理解了用户文本的内容,但没有将过滤条件传进去作为条件,没将时间的查询参数提交给ElasticSearch ,定位到问题,就已经成功了95%。
Your input -> show me movies shot in2020
I found the following movies :1: The Shawshank Redemption from 19942: The Godfather from 19723: The Dark Knight from 20084: The Godfather: Part II from 19745: 12 Angry Men from 1957
Rasa对话机器人查询指定电影评分
用户说: 观众如何评价第三个电影?
Bot说: 2008年电影《黑暗骑士》的收视率为10分之9(2303232票)。
Your input -> how did viewer rate the thrid one?
Sorry, I'm not sure I understand. Can you rephrase?
Your input -> how did viewer rate the third one?
9 out of 10(2303232 votes) is the rating for movie The Dark Knight from 2008.
Your input ->
本文参考了Gavin老师Rasa 3.X项目实战:基于ElasticSearch的影视对话机器人课程内容,对课程感兴趣的同学可以联系助教老师(微信:Spark_AI_NLP)
为学犹掘井,井愈深土愈难出,若不快心到底,岂得见泉源乎?
——张九功
Gavin大咖简介
星空智能对话机器人创始人、AI通用双线思考法作者,现工作于硅谷顶级的AI实验室。专精于Conversational AI. 在美国曾先后工作于硅谷最顶级的机器学习和人工智能实验室
Gavin大咖微信:NLP_Matrix_Space
联系电话:+1 650-603-1290
联系邮箱:hiheartfirst@gmail.com
助教老师微信:Spark_AI_NLP
Rasa 智能对话机器人系列博客
- Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战 一
- Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战二
- Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战三
- Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战四
- Rasa 3.x 学习系列-Rasa 3.1+ ElasticSearch 8.2.0 对话机器人实战五
版权归原作者 段智华 所有, 如有侵权,请联系我们删除。