匮乏即是富足,自律产生喜悦
This is Part 1 of the CookieBot Case Studies, a series on reducing user confusion in conversational systems.
这是 CookieBot案例研究的 第1部分, CookieBot案例研究 是关于减少对话系统中的用户混乱的系列文章。
Authors: Gwen Christian and Christy Doran
作者: Gwen Christian 和 Christy Doran
At last, your backordered sourdough starter has arrived in the mail, and you’re ready to start baking. You’re just a few hours (… you think?) away from your very first loaf of sourdough! Since you’re feeling pretty late to the game, instead of asking a friend, you turn to your trusty voice assistant, and download BakingBot.
最后,您的缺货酵母发酵剂已经到达邮件中,您就可以开始烘烤了。 您距离第一个面包面团仅几小时(...您认为吗?)! 由于您感觉游戏迟到了,因此您无需求助朋友,而转向可信赖的语音助手,然后下载BakingBot。
![A conversation between BakingBot and the user, in which BakingBot doesn’t know how to make bread, and the user is frustrated](https://i-blog.csdnimg.cn/blog_migrate/4bcad89fa59fcfbab6fc614aa87a3c2c.png)
You’re all ready to leave a bad review — what kind of baking bot doesn’t know about bread? And then you see in the description “We have thousands of cookie recipes for every occasion.” It turns out BakingBot is a cookie specialist! So how did we get into this mess?
大家都准备好发表不好的评论-哪种烘焙机器人不了解面包? 然后,您会在描述中看到“我们每种情况都有数千种Cookie食谱”。 事实证明,BakingBot是Cookie专家! 那么,我们如何陷入困境呢?
这幅画怎么了? (What’s wrong with this picture?)
One of the keys to creating satisfying conversational user experiences is making sure that your users have an accurate model of what your system can do. The sort of inconsistency illustrated above confuses users, who will reasonably assume that the opening “I can teach you how to bake” means the bot will be able to answer questions about all manner of baked goods, because ‘baked goods’ are a clearly defined, coherent category. Similarly for other natural domains — if the system knows about Thomas Jefferson, it should know about all presidents; if it can do conversions between weights, it should also do conversions for lengths and volumes.
创建令人满意的会话用户体验的关键之一是确保您的用户具有系统可以做什么的准确模型。 上面说明的这种不一致会使用户感到困惑,他们会合理地假设开头的“我可以教你如何烘焙”一词意味着该机器人将能够回答有关各种烘焙产品的问题,因为“烘焙产品”的定义很明确,连贯的类别。 同样,对于其他自然领域,如果系统了解托马斯·杰斐逊,则应该了解所有总统。 如果它可以在重量之间进行转换,则还应该进行长度和体积的转换。
This consistency is particularly critical in task-based systems: if my banking system can tell me the balance of my checking account, but not the balance of my bank credit card, I won’t just be confused — I’ll be less inclined to use it in the future, because my experience was frustrating, and its limits aren’t clear. It can also be downright embarrassing, like the customer care agent we built that handled complaints but not compliments and responded to a compliment with “I’m sorry you had a bad experience…”
这种一致性在基于任务的系统中尤为重要:如果我的银行系统可以告诉我支票帐户的余额,但不能告诉我银行信用卡的余额,那么我不仅会感到困惑-我会更不会将来使用它,因为我的经历令人沮丧,并且它的局限性尚不清楚。 这也可能是完全令人尴尬的事情,例如我们建立的客户服务代理处理投诉但没有恭维,并以“对不起,您的经历很糟糕……”来回应赞扬。
Understanding system scope cuts both ways:
了解系统范围有两种方法:
- If users have a mental model that is too restricted, they’ll miss out on some of your great functionality. 如果用户的思维模式过于受限,他们将错过您的某些出色功能。
- If users have a mental model that is too broad, they’ll get frustrated when they try things that don’t work. 如果用户的思维模式过于广泛,那么他们在尝试无法解决的问题时会感到沮丧。
Our end goal is to make sure your users have a clear idea of what to expect from your bot. Think of it like this: when you overpromise, it feels like running into invisible walls. There are a lot of ways to keep from doing that, from putting stickers on your windows to deter birds, to using frosted glass, to actually building opaque walls. At the end of the day, the easier it is for your users not to run into them, the better.
我们的最终目标是确保您的用户对机器人的期望有清晰的认识。 这样想:当您过度承诺时,感觉就像碰到了看不见的墙。 有很多方法可以阻止这种情况发生,从在窗户上贴贴纸以阻止鸟类进入,到使用磨砂玻璃,再到实际建造不透明的墙壁。 归根结底,您的用户越容易遇到他们,就越好。
![A GIF, where a person jogging past a mime appears to run into the mime’s invisible wall and falls down.](https://i-blog.csdnimg.cn/blog_migrate/f4a5d0c226598df8f630fd7aa03d4899.png)
建立共享域模型 (Building a shared domain model)
Let’s start by looking at several tools we can use to define our domain model, and locate coverage gaps.
让我们先来看几个可用来定义领域模型并定位覆盖范围差距的工具。
定义机器人的范围 (Defining the scope of your bot)
From the start of the design process, think carefully about the (usually limited) number of things you are designing the bot to do and what other things the average user will think of as “the same”. Once you have identified the key features of your system, consider the interaction from the user’s perspective:
从设计过程开始,请仔细考虑正在设计机器人的事情(通常是有限的)以及普通用户认为“相同”的其他事情。 确定系统的关键功能后,请从用户角度考虑交互:
![BakingBot & CookieBot defined by their places in different natural domains, “Recipes,” “How to Cook,” and “Baked Goods”.](https://i-blog.csdnimg.cn/blog_migrate/1bff526c9cd26c2360ca6517ba4bf55c.png)
- Imagine you were talking to a person that does whatever your bot does. What other things might you ask them? 想象一下,您正在与一个执行您的机器人行为的人交谈。 您还能问他们什么?
- What motivated you to talk to them (e.g. if it’s a weather bot, why might you want to know what the weather is)? 是什么促使您与他们交谈(例如,如果它是一个天气机器人,那么为什么您想知道天气是什么)?
Brainstorming is necessary but not sufficient. Look for other resources that do the same job perhaps in a different modality, like a website, or FAQs related to your task. What are the opposites of things you cover? If you take complaints, you need to also deal with compliments; if you can turn lights on, you need to be able to turn them off — or at least know that turning them off is a thing that is possible in the world. User studies with mock-ups or early prototypes are one of the most reliable ways to spot gaps in your system’s coverage — we’ll go into user studies in more depth in a future article.
头脑风暴是必要的,但还不够。 寻找其他可能以不同方式完成相同工作的资源,例如网站或与您的任务相关的FAQ。 您涵盖的事物有哪些对立面? 如果您提出投诉,您还需要处理表扬。 如果您可以打开灯,则需要能够将它们关闭-或至少知道关闭它们在世界上是可能的。 使用模型或早期原型进行用户研究是找出系统覆盖范围中最不可靠的方法之一-我们将在以后的文章中更深入地进行用户研究。
培训用户 (Training the user)
品牌推广 (Branding)
A critical, and often overlooked way to establish clear expectations from your user is with consistent branding — if you call your bot the CookieBot, users will understand that its specialty is cookies. There are other more subtle ways to convey capabilities if you system has a visual component — what background images do you use, what are your icons? Are they all cookies, or are they all sorts of baked goods?
始终如一的商标是建立用户明确期望的一种关键且经常被忽视的方法-如果您将您的机器人称为CookieBot,则用户将了解其专长是cookie。 如果您的系统具有视觉组件,则还有其他更细微的方式来传递功能-您使用什么背景图像,什么是图标? 它们都是饼干还是各种烘焙食品?
![Branding images. Similar handwritten logos on yellow background. BakingBot shows baked good variety, CookieBot shows cookies.](https://i-blog.csdnimg.cn/blog_migrate/44fddfc92c5216f54110bed4c40aba52.png)
Remember, as you’re creating branding materials, you are trying to provide an accurate model of your bot can do. If we called our bot BakingBot, and used the branding above, it might see more engagement — but the users would be frustrated and the ratings could be much lower.
请记住,在创建品牌资料时,您正在尝试提供机器人可以执行的准确模型。 如果我们调用机器人BakingBot并使用上面的品牌,它可能会吸引更多用户-但是用户会感到沮丧,并且评分可能会低得多。
入职 (Onboarding)
Users’ initial interactions are also a key place to establish clear boundaries about what is and is not handled.
用户的初始交互也是建立明确界限的关键位置。
In your very first interaction with the user, be direct about what you can do.
在与用户的第一次互动中,请直接说明您可以做什么。
Too broad: I can teach you how to bake! (Implies: wide coverage of baked recipes, instructions for how to do things, e.g. cream butter, etc)
太宽泛:我可以教你如何烘烤! (示例:广泛的烘焙食谱,操作说明,例如奶油黄油等)
Just right: I have just the right cookie recipe for every occasion! (Implies: recipes for cookies, recipes sorted by occasion)
恰到好处:我每次都有合适的Cookie食谱! (示例:Cookie的食谱,按场合排序的食谱)
以身作则 (Leading by example)
In this case study, our focus is how to define and communicate your bot’s domain — not necessarily digging into specific wording choices in your design. However, wording is a significant component, because everything the bot says gives the user data about what it understands. Even if you aren’t building the kind of bot that requires explicit user training in the form of dedicated onboarding, you’ll always be doing implicit onboarding, as each system turn is subtly training your users. That includes everything from your domain coverage to the kinds of responses the bot is expecting.
在本案例研究中,我们的重点是如何定义和传达您的机器人域-不必在设计中深入研究特定的措词选择。 但是,措辞是一个重要的组成部分,因为机器人说的一切都会向用户提供有关其理解的数据。 即使您不是在构建那种需要专门的入职培训形式的显式用户培训的机器人,也总是会隐式进行入职培训,因为每个系统回合都在巧妙地培训用户。 这包括从您的域范围到机器人期望的响应的所有内容。
Here are some places to pay close attention:
这里是一些需要密切注意的地方:
When your bot talks about what it can do.
当您的机器人谈论它可以做什么时 。
- Just like in our onboarding example, the bot says “I can teach you how to bake”, when a better example for its domain is “I have just the right cookie recipe for every occasion!” 就像在我们的入门示例中一样,机器人会说“我可以教你如何烘烤”,而其域名的一个更好的例子是“我在每种情况下都有正确的Cookie配方!”
Whenever your bot asks a question.
每当您的机器人问一个问题时。
- The type of question should suggest the type of answer you’re expecting. For example, sometimes you might want to soften a question, like “Can you tell me what cookie you want to make?”, but you’re potentially inviting a yes/no response, in addition to the open-ended ‘what cookie do you want to make?’. 问题类型应建议您期望的答案类型。 例如,有时您可能想简化一个问题,例如“您能告诉我您要制作什么cookie吗?”,但除了开放式“ cookie的作用是什么”之外,您还可能会邀请是/否回答。你想做吗?
- Some questions can mislead the user: If you ask “What kinds of cookies do you want to make?” but then you only have 2 cookie recipes available, the user will get frustrated. If you ask if the user needs vegan recipes, but your backend doesn’t support that filtering yet, then they’ll lose trust when ‘butter’ is on the ingredients list. 有些问题可能会误导用户:如果您问“您想制作哪种Cookie?” 但是您只有2个cookie食谱可用,用户会感到沮丧。 如果您询问用户是否需要纯素食食谱,但您的后端尚不支持该筛选,那么当“黄油”在成分列表中时,他们将失去信任。
测试中 (Testing)
Now you’ve built the best system you can — test, test, test. Find expert users, naive users, kids, and see what they try to do. Once you’re live, keep a close eye on your logs, and don’t just assess your conversational strategies — you also need to assess and reassess the other elements discussed above. You might even do A/B testing of onboarding variations, or of doing additional training steps for new users. Testing is so important, we’ll explore it further in its own article.
现在,您已经构建了可以使用的最佳系统-测试,测试,测试。 查找专家用户,天真的用户,孩子,然后看看他们想做什么。 生活之后,请密切注意日志,而不仅仅是评估您的对话策略-您还需要评估和重新评估上面讨论的其他元素。 您甚至可以对入门版本进行A / B测试,或者为新用户执行其他培训步骤。 测试是如此重要,我们将在自己的文章中进一步进行测试。
如何处理覆盖率差距 (How to handle coverage gaps)
Ideally, your bot covers a complete natural domain — all presidents, all consumer banking transactions, all recipes. That’s not always an option. Maybe you’re integrating with a backend that only supports certain transaction types, or only has certain kinds of recipes, and you have no ability to improve or extend them. It may also be the case that you have resource limitations and can only build a subset of the “full” experience.
理想情况下,您的机器人可以覆盖一个完整的自然领域-所有总裁,所有消费者银行交易,所有食谱。 这并不总是一种选择。 也许您正在与仅支持某些交易类型或仅具有某些种类的配方的后端集成,而您却无法改进或扩展它们。 也可能是您有资源限制,只能建立“完整”体验的一部分。
Once you’ve identified a coverage gap, there are strategies for when you can tell that the user has fallen into that gap, and ones for when you can’t tell.
一旦确定了覆盖范围的差距,便有一些策略可以确定何时可以确定用户已落入该差距,以及可以确定何时不能确定用户的策略。
可以告诉 (Can Tell)
Let’s start with an example that the bot fully handles.
让我们从机器人完全处理的示例开始。
![A chat between user and bot. The bot can tell the user Abe Lincoln’s height, but not Grover Cleveland’s.](https://i-blog.csdnimg.cn/blog_migrate/70cf8d53c9f93fa5643c74e34595bfeb.png)
Here, our bot is using the backend Interesting Presidential Facts Database, but it looks like the things that were “interesting” varied pretty wildly between presidents.
在这里,我们的漫游器正在使用后端有趣的总统事实数据库,但看起来“有趣”的事情在总统之间变化很大。
Abraham Lincoln = [height: 6'4"” , preferred_hat_type:stovepipe, nickname: “Honest Abe”, initial-career: “lawyer”, most-famous-speech: “The Gettysburg Address”, cause-of-death: “assassination”, children: “4: Robert, Edward, Willie and Tad”]
亚伯拉罕·林肯= [身高:6'4“”,preferred_hat_type:stovepipe,昵称:“诚实安倍”,职业初期:“律师”,最著名的演讲:“葛底斯堡演说”,死因:“暗杀”,儿童:“ 4:罗伯特,爱德华,威利和塔德”]
Grover Cleveland: [initial-career: “teacher”, nickname: “Grover was his middle name, and his first name was Stephen”, children: “6 or 7: There was also a child born out of wedlock that he admitted could possibly be his during his first presidential campaign”]
格罗弗·克利夫兰(Grover Cleveland):[最初的职业:“老师”,绰号:“格罗弗(Grover)是他的中间名,他的名字是斯蒂芬(Stephen)”,孩子们:“ 6或7:还有一个非婚生子女,他承认可能在他的第一次总统竞选中成为他的人”
Let’s break down the bot’s response:
让我们分解一下机器人的响应:
Tell users what’s out of scope. It’s often not ideal to surface backend limitations directly to the user, for example “I’m sorry, that’s not in my database.” A better option is to use this opportunity to train the user in what the bot can and can’t handle. In this case, we don’t have an easy way to summarize what’s in or out of scope (saying “I have a selection of random presidential facts” isn’t great), so we open with “I’m not sure [question],” i.e. “I’m not sure how tall Grover Cleveland was.”
告诉用户哪些超出范围。 直接向用户显示后端限制通常不是理想的选择,例如“很抱歉,这不在我的数据库中。” 更好的选择是利用这个机会来培训用户机器人可以处理和不能处理的内容。 在这种情况下,我们没有一种简单的方法来总结范围之内或范围之外的内容(说“我有一个随机的总统事实选择”不是很好),因此我们以“我不确定[问题] ],即“我不确定格罗弗·克利夫兰有多高。”
Try to get the users what they need, even if you can’t do it on your own. The straightforward option here is to augment our bot with another backend, but let’s say this isn’t an alternative. Here, we offer to fallback to a web search for Wikipedia, because we think that will have the information. This is the strategy employed by most of the mainstream smart assistants.
尝试获取用户所需的资源,即使您自己不能做到。 这里最直接的选择是用另一个后端扩展我们的机器人,但是我们说这不是替代方案。 在这里,我们提供回退到Wikipedia的网络搜索的方法,因为我们认为这将提供信息。 这是大多数主流智能助手所采用的策略。
Next, let’s try an example the bot can identify as being in the coverage gap, but can’t fully handle.
接下来,让我们尝试一个示例,该机器人可以识别出处于覆盖范围内,但不能完全处理。
![A chat between bot and user. The bot coaches the user when it can’t handle a request to do 2 tasks at once.](https://miro.medium.com/max/9999/1*nTI1Ti3Ga8lTgP3Plp3tkw.png)
![A continuation of the same chat where the user accomplishes their second task as well as the first.](https://i-blog.csdnimg.cn/blog_migrate/b6a2f1db0e9d8d8508246e9ea7ce4886.png)
In this case, we have a bot for a local grocery store chain, it can make lists and tell you the weekly specials. However, in testing the team noticed that users often tried to make multiple requests in the same utterance, but their classifier couldn’t reliably handle it. They trained it to reliably recognize when a user tries to ask for multiple things at a time.
在这种情况下,我们为本地杂货店连锁店提供了一个漫游器,它可以列出并告诉您每周的特价商品。 但是,在测试小组中,他们注意到用户经常尝试以相同的发音提出多个请求,但是他们的分类器无法可靠地处理它。 他们对其进行了培训,以可靠地识别用户何时一次尝试询问多个问题。
Let’s break down the bot’s response:
让我们分解一下机器人的响应:
Tell the users what’s out of scope: In this case, we were indirect. Instead of saying “I’m sorry, I can’t understand multiple things at the same time”, we say “Sorry, that was a lot all at once.”
告诉用户超出范围的情况:在这种情况下,我们是间接的。 我们没有说“对不起,我无法同时理解多件事”,而是说“对不起,一次过很多。”
It tells users how to be successful. Here we are very clear: please only give the bot one task at a time.
它告诉用户如何成功。 在这里,我们非常清楚:请一次只给机器人一个任务。
The bot’s response is much more human-like than saying “I can only understand things if you tell me one at a time”. The negative example (focusing on what the bot can’t do) is a less natural restriction from a user’s point of view, and it can make them feel unsure about their interactions with the bot. Just like conversations between humans, it’s most productive to focus on the behavior you need.
该机器人的回应更像是人类,而不是说“如果您一次告诉我,我只会理解事情”。 从用户的角度来看,否定示例(关注于机器人不能做什么)是一种不太自然的限制,它会使他们不确定与机器人的交互。 就像人与人之间的对话一样,专注于您需要的行为最有成效。
This example, in particular, illustrates something important about finding ways to train the user: it doesn’t all need to be up-front, in a dedicated onboarding conversation. Finding ways to gracefully handle issues, and guide users to engage with the bot more successfully are just as valuable.
特别是,该示例说明了有关寻找培训用户方法的重要事项:在专用的入职对话中,并不需要全部都预先准备好。 寻找合适的方式来妥善处理问题,并指导用户更成功地与bot互动同样有价值。
无法分辨 (Can’t Tell)
What if your bot gets an input it can’t make sense of at all? Here, it’s all about the fallback. Let’s look at two ways we can use fallback messages to address a coverage gap in a banking app:
如果您的机器人得到了输入却完全没有意义的怎么办? 在这里,所有关于后备。 让我们看一下两种使用后备消息来解决银行应用程序中的覆盖范围缺口的方法:
Tailor the fallback message to address known coverage gaps.
量身定制后备消息以解决已知的覆盖差距。
![A chat between a bot and a user, where the user requests a feature and the bot has a fallback message addressing that feature](https://i-blog.csdnimg.cn/blog_migrate/2ff72c99f5c0b1b1b205a7e28336ed06.png)
Let’s break down the bot’s response:
让我们分解一下机器人的响应:
Clearly communicate what’s in scope: The bot explains here exactly what it can do. It doesn’t have to cover every edge case, but it’s a lot more satisfying for the user than a generic error + reprompt strategy. Communicating the edges of the bot’s understanding lets the user know that it’s not worth trying again.
清楚地传达范围内的内容:机器人在这里确切地解释了它可以做什么。 它不必覆盖所有的极端情况,但是比一般的错误+重新提示策略对用户来说要令人满意的多。 交流机器人的理解的边缘,使用户知道不值得再次尝试。
Tell the users what’s coming next: This is a great example for our fictional banking client, because they know that transfers and payments are the most common user requests that the bot can’t handle. Since we know they’re very common, and on the roadmap, there’s a good chance that the users who hear this particular fallback message were asking about one of these features. If something is common, but not on your roadmap, this might not be the best strategy.
告诉用户接下来会发生什么:对于我们的虚构银行客户来说,这是一个很好的例子,因为他们知道转账和付款是机器人无法处理的最常见的用户请求。 既然我们知道它们非常普遍,并且在路线图中,很可能听到此特定后备消息的用户会问这些功能之一。 如果某些事情很常见,但并不在您的路线图上,那么这可能不是最佳策略。
Create a fallback flow
创建后备流程
![A flow diagram showing how to transition from the fallback message through offering users the option of giving feedback.](https://i-blog.csdnimg.cn/blog_migrate/cd821b99a2b6c83854072b79d38a8ebe.png)
With the fallback flow we’ve defined, here’s what the resulting conversation might look like:
通过我们定义的后备流程,以下是可能产生的对话:
![A chat between a bot and a user. The bot doesn’t understand and it clarifies if the user needs something out of scope.](https://i-blog.csdnimg.cn/blog_migrate/0f114f4680069afbc10c541cb187c8a4.png)
![The continuation of the chat. The bot gives the option of leaving feedback, and the user takes it.](https://i-blog.csdnimg.cn/blog_migrate/6afad8bbdeff8556549f49e9621435f9.png)
Let’s break down the bot’s response:
让我们分解一下机器人的响应:
Clearly communicate what’s in scope: Just like the example above, we clearly communicate what the bot can do.
清楚地传达范围内的内容:就像上面的示例一样,我们清楚地传达了机器人可以做什么。
Elicit Feedback: This strategy can really help mitigate user frustration. Your goal is that the user feels listened to, and like they are stakeholders in the process. Here, we have no conditions on the user response: we treat all input like a good faith response, and allow them continue onwards. (If you want to see a successful study, where the bot teamed up with users to collect feedback against the developers, check out Cliff Nass’ How I Made Clippy Lovable.)
明确的反馈:此策略确实可以帮助减轻用户的挫败感。 您的目标是让用户感到被倾听,就像他们是流程中的涉众一样。 在这里,我们对用户响应没有任何条件:我们将所有输入都视为真诚响应,并允许其继续进行。 (如果您希望看到一个成功的研究,该机器人与用户合作收集开发人员的反馈,请参阅Cliff Nass的《 我如何使Clippy Lovable成为现实》 。)
TL; DR (TL;DR)
In this article, we talked about the value of establishing a shared model of the bot’s domain with the user. When the user perceives the domain to be much broader than the bot can handle, using it feels like running into invisible walls. What can you do?
在本文中,我们讨论了与用户建立bot域共享模型的价值。 当用户感觉到该域的范围超出了机器人可以处理的范围时,使用它就像进入了不可见的墙。 你能做什么?
It all starts when you’re defining the scope of your bot. As much as possible, aim for coverage of a complete natural domain.
这一切都始于您定义机器人的范围。 尽可能争取覆盖整个自然域 。
Use branding and onboarding to set user expectations clearly, starting even before their first interaction.
使用品牌和入职培训可以清楚地设置用户期望 ,甚至在他们第一次互动之前就开始。
Lead by example: make sure that your wording and language choices throughout the bot don’t communicate abilities you don’t have (and use them to subtly advertise the abilities you do!)
以身作则:确保您在整个漫游器中的措辞和语言选择不会传达您不具备的能力(并巧妙地宣传您所具备的能力!)
Running into walls always sucks, but if you’ve identified gaps in your coverage, you can add markers and strategic cushioning. User training doesn’t stop at onboarding — your errors and fallbacks are opportunities to guide the user.
碰到墙总是很烂,但是如果您发现覆盖范围内的空白,则可以添加标记和战略缓冲。 用户培训不仅仅局限在入门阶段 -您的错误和后备是指导用户的机会 。
展望未来 (Looking Ahead)
Here, we’ve talked about some of the situations where users are misled or allowed to become confused about what a system can do. In the rest of the CookieBot Case Studies, we are going to address other ways user confusion can be minimized through better bot design.
在这里,我们讨论了在某些情况下,用户被误导或被允许对系统的功能感到困惑。 在CookieBot案例研究的其余部分中,我们将探讨通过更好的机器人设计来最大程度地减少用户混乱的其他方式。
We’d love to learn how you stay on the same page with your end-users! We’re continuing the CookieBot Case Studies — next, we want to talk about testing.
我们很想学习您如何与最终用户保持同一页面! 我们将继续进行CookieBot案例研究-接下来,我们想谈谈测试。
致谢 (Acknowledgments)
Thanks so much to Andreea Danielsecu and Jennie Stenhouse for editing! Your feedback was so helpful, and any remaining errors are our own.
非常感谢Andreea Danielsecu和Jennie Stenhouse进行编辑! 您的反馈意见非常有帮助,所有其他错误都是我们自己的。
All illustrations are © 2020, Gwen Christian.
所有插图均为©2020, Gwen Christian 。
CookieBot started out as an example, but the more we sketched it out for this article, the more motivated we are to start building it. Or perhaps we’re just hungry.
CookieBot最初是作为示例,但是我们在本文中草拟的内容越多,我们就越有动力开始构建它。 也许我们只是饿了。
翻译自: https://medium.com/@gwen.christian/when-surprise-and-delight-diverge-2886d78519bb
匮乏即是富足,自律产生喜悦