实时机器人数据库聊天对话数
by Mark Watson
马克·沃森(Mark Watson)
您是否与聊天机器人进行过有关图形数据结构的“对话”? (Have you had “The Talk” with your chatbot about graph data structures?)
数据库模型的成熟故事 (A coming-of-age story for your database model)
Graph databases are a great way to store conversational data. A simple dialog tree can add depth to character interactions in a video game. A knowledge graph can extract more meaning from dialog to better understand how user intent relates to an application’s data.
图形数据库是存储对话数据的好方法。 一个简单的对话框 树可以增加视频游戏中角色交互的深度。 知识 图可以从对话框中提取更多含义,以更好地了解用户意图与应用程序数据之间的关系。
In this article, I’ll show you a basic graph model for capturing chatbot interactions and how to persist them using the Apache TinkerPop framework. I’ll also show you some Gremlin queries for adding a recommendation feature to the chatbot. The source code and setup instructions for my example “Recipe Bot” are on GitHub.
在本文中,我将向您展示一个基本的图形模型,用于捕获聊天机器人的交互以及如何使用Apache TinkerPop框架持久化它们。 我还将向您展示一些Gremlin查询,以向聊天机器人添加推荐功能。 我的示例“ Recipe Bot”的源代码和设置说明位于GitHub上 。
评论:配方机器人 (Review: Recipe Bot)
The Recipe Bot is a Slack Bot User that lets people request recipes based on specified ingredients or cuisines. Previously I showed you how to add support for users to request their favorite recipes, like so:
Recipe Bot是Slack Bot用户 ,它使人们可以根据指定的食材或美食请求食谱。 之前,我向您展示了如何增加对用户的支持,以请求用户喜欢的食谱,例如:
The graph version of the bot has all of the same features I discussed in my previous article on persisting metadata with JSON, but with the graph version you’ll be adding recommendations.
该机器人的图形版本具有我在上一篇文章中介绍的使用JSON持久化元数据中讨论的所有相同功能,但是使用图形版本时,您将添加建议。
如何与TinkerPop配合使用 (How it works with TinkerPop)
Here is an architecture diagram of how the bot works:
这是机器人如何工作的架构图:
You’ll see that I’m using the Watson Conversation service. Watson Conversation lets me describe the flow of the conversation through the use of dialogs, and it helps me extract information and user intent from chat messages. You can code your own dialog tree and perform your own message parsing, or you can use tools like Watson Conversation or Botkit to help. Here is how the dialog tree for the Recipe Bot is modeled:
您会看到我正在使用Watson Conversation服务。 Watson对话使我可以通过使用对话框来描述对话的流程,它可以帮助我从聊天消息中提取信息和用户意图。 您可以编写自己的对话框树并执行自己的消息解析,也可以使用Watson Conversation或Botkit之类的工具来提供帮助。 这是“配方机器人”对话框树的建模方式:
You can follow a conversation through the dialog tree similar to how you can follow vertices and edges in a graph (after all, trees are graphs too):
您可以通过对话框树进行对话,类似于在图形中遵循顶点和边的方式(毕竟, 树也是图形 ):
In the simplified graph above, the Recipe Bot cares only about the progression between the major entities of the bot:
在上面的简化图中,“食谱机器人”只关心机器人主要实体之间的进度:
- People 人
- Ingredients 配料
- Cuisines 美食
- Recipes 菜谱
数据模型和访问模式 (Data model & access pattern)
As the conversation progresses, you store the following vertices and edges using the TinkerPop API:
随着对话的进行,您可以使用TinkerPop API存储以下顶点和边:
Person vertex: For each person that interacts with the bot, store that person as a vertex in the graph.
人员顶点:对于与机器人进行交互的每个人,请将其作为顶点存储在图中。
{ "label": "person", "type": "vertex", "properties": { "name": "U2JBLUPL2" }}
2. Ingredient or cuisine vertex: When a person requests a specific ingredient or cuisine, you store that ingredient or cuisine — along with the list of recipes retrieved from Spoonacular — as a vertex.
2.配料或料理的顶点:当某人请求特定的配料或料理时,您可以将该配料或料理以及从Spoonacular检索到的食谱列表一起存储为顶点。
{ "label": "cuisine", "type": "vertex", "properties": { "name": "chinese", "detail": "[{\"id\": 573147, \"title\": \"Kale Fried Rice\"..." }}
3. Selects edge, person → (ingredient | cuisine): You create an edge, labelled "selects"
, between the person and the ingredient or cuisine (that is, “person selects cuisine”). In addition, store a "count"
property on the edge and increment its value each time the user requests the same ingredient or cuisine.
3.选择边,人→(成分|菜):在人与配料或菜(即“人选择菜”)之间创建一个标记为"selects"
的边。 另外,在边缘上存储"count"
属性,并在每次用户请求相同的食材或美食时增加其值。
{ "label": "selects", "type": "edge", "inV": 4152, "outV": 4224, "properties": { "count": 3 }}
4. Recipe vertex: When a user requests a recipe, store the recipe as a vertex.
4. 食谱顶点:当用户请求食谱时,请将食谱存储为顶点。
{ "label": "recipe", "type": "vertex", "properties": { "name": "573147", "detail": "Ok, it takes *45* minutes to make...*", "title": "Kale Fried Rice" }}
5. Selects edge, (ingredient | cuisine) → recipe: You create another "selects"
edge between the ingredient or cuisine and the recipe (that is, “cuisine selects recipe”). In addition, store a "count"
property on the edge and increment it each time the ingredient or cuisine selects the same recipe.
5. 选择边缘,(成分|菜肴)→食谱:您在食材或菜肴与食谱之间创建另一个"selects"
边缘(即“美食选择食谱”)。 另外,在边缘上存储一个"count"
属性,并在每次食材或菜肴选择相同食谱时将其递增。
{ "label": "selects", "type": "edge", "inV": 4320, "outV": 4152, "properties": { "count": 22 }}
6. Selects edge, person → recipe: You create yet another "selects"
edge directly between the person and the recipe (that is, “person selects recipe”). Store a "count"
property on the edge and increment it each time a person requests the same recipe.
6.选择边,人→食谱:直接在人和食谱之间创建另一个"selects"
边(即“人选择食谱”)。 在边缘存储一个"count"
属性,并在每个人请求相同食谱时将其递增。
{ "label": "selects", "type": "edge", "inV": 4320, "outV": 4224, "properties": { "count": 4 }}
7. Has edge, recipe → (ingredient | cuisine): Finally, create an edge, labelled "has"
, between the recipe and the ingredient or cuisine (that is, “recipe has cuisine”). This relationship allows you to find all the ingredients and cuisines that a recipe uses. There is no count field on this edge.
7.具有边沿,食谱→(成分|菜肴):最后,在食谱与食材或菜肴(即“食谱有菜肴”)之间创建一个标记为"has"
的边缘。 这种关系使您能够找到食谱使用的所有食材和美食。 此边缘上没有计数字段。
{ "label": "has", "type": "edge", "inV": 4152, "outV": 4320}
The graph for a single user looks something like this:
单个用户的图形如下所示:
So far, by using a graph database, you get the following benefits:
到目前为止,通过使用图形数据库,您将获得以下好处:
- Reduce third-party API calls by caching entities. 通过缓存实体减少第三方API调用。
- Provide a more personal experience for users by harnessing metadata on their interactions. 通过在交互中利用元数据为用户提供更个性化的体验。
A “more personal experience” for Recipe Bot means allowing users to request their favorite recipes. To find a user’s favorite recipes, you use the Gremlin graph traversal language. The following Gremlin query will give you a user’s top-five favorite recipes, sorted by count:
Recipe Bot的“更多个人体验”意味着允许用户请求自己喜欢的食谱。 要查找用户喜欢的食谱,请使用Gremlin 图遍历语言。 以下Gremlin查询将为您提供用户最喜欢的前五种食谱,并按计数排序:
添加建议 (Adding recommendations)
Since you track every user interaction with the bot as a graph, you can find popular ingredients, cuisines, or recipes requested by all users. You can use Gremlin to find popular recipes based on an ingredient or cuisine. Here’s how it works:
由于您以图表的形式跟踪每个用户与机器人的互动,因此您可以找到所有用户要求的流行食材,美食或食谱。 您可以使用Gremlin来根据成分或美食找到受欢迎的食谱。 运作方式如下:
Let’s say, a user is looking for recipes that use onions:
假设用户正在寻找使用洋葱的食谱:
You can find popular recipes that use onions by issuing the following query. (I’ll unpack it further below—don’t worry!):
您可以通过以下查询找到使用洋葱的流行食谱。 (我将在下面对其进行进一步包装-不用担心!):
This query says, “Give me anyone, excluding the calling user, who has requested recipes more than once that have onions.” It breaks down like so:
这个查询说:“给我一个请求,除了调用用户,谁不止一次请求带有洋葱的食谱。” 它像这样分解:
1. Start with "onions"
:
1.以"onions"
开头:
g.V().hasLabel("ingredient").has("name","onions")
2. Get the recipes that have "onions"
. This API call uses the "has"
edge coming from the recipe vertex into the ingredient vertex. Using .in()
skips the edge and only returns the recipe vertex. (You don’t need any properties from the edge object, so there’s no reason to return it here.)
2.获得带有"onions"
的食谱。 此API调用使用从配方顶点到成分顶点的"has"
边缘。 使用.in()
跳过边缘,仅返回配方顶点。 (您不需要边缘对象的任何属性,因此没有理由在此处返回它。)
.in("has")
3. Get the users that have requested these recipes more than once. This call uses the "selects"
edge coming from the person to the recipe:
3.多次获得要求这些食谱的用户。 此调用使用从人到菜谱的"selects"
边缘:
.inE().has("count",gt(1)).order().by("count", decr)
4. Get the users, excluding the current user:
4.获取用户,当前用户除外:
.outV().hasLabel("person").has("name",neq("CURRENT_USER"))
5. Get the full path:
5.获取完整路径:
.path()
This call returns an array of matching paths that looks like this:
该调用返回匹配路径的数组,如下所示:
ingredient ← recipe ← edge ← person
成分←食谱←边缘←人
You can access these recommended recipes at index 1.
您可以从索引1访问这些推荐的食谱。
When you return this recipe list to the user, the app puts the recommended recipes at the top and highlights the number of users who have previously used which recipe:
当您将此食谱列表返回给用户时,应用程序将推荐的食谱放在顶部,并突出显示以前使用过哪种食谱的用户数量:
下一步是什么? (What’s Next?)
Try a deployment for yourself. The project’s README has step-by-step instructions for completing your first deployment on IBM Bluemix. There’s also a Java port of the example app.
自己尝试部署。 该项目的自述文件具有逐步说明,以完成在IBM Bluemix上的首次部署。 示例应用程序还有一个Java端口 。
If you’re already using a dialog tree in your applications and want to use a graph database to persist metadata on interactions, I hope the source code in the repo above gives you some ideas on delivering more personalized experiences to your users.
如果您已经在应用程序中使用对话框树,并且希望使用图形数据库在交互中保留元数据,那么希望以上回购中的源代码能为您提供一些向用户提供更多个性化体验的想法。
And if you’ve enjoyed this article, please hit the ol’ ♥ so other Medium users might find it and dig it too. Happy coding!
如果您喜欢这篇文章,请打ol'♥,以便其他中级用户也可以找到并进行挖掘。 编码愉快!
实时机器人数据库聊天对话数