重复的功能请求:怎么合并但不丢失原来的声音
阅读约 1 分钟
三位客户在三个不同的星期,用三种不同的说法,请求了同一种能力,而一套为了拦下重复请求而设计的分诊流程做好了自己的本职工作:把它们分到一组,算作一条带着三票的请求,待办清单也保持干净。这是容易的那部分。哪些标签才真正值得打讲的是,在按措辞分诊之前先按底层能力分组,把这当作应对重复请求的机械式修复;它没讲到的是,一旦三条请求变成了一行,那些话语本身会发生什么,而这份损失通常比它解决掉的那个”重复计数”问题要大得多。
重复请求被合并的时候,到底会真正丢掉什么
丢掉的是每一位提出请求的人各自使用的具体措辞,而这份措辞往往比它最终坍缩进去的那个票数更有信息量。一位客户可能要求”一种导出经过筛选的结果的方法”,另一位要求”尊重我保存过的筛选条件的 CSV 导出”,第三位要求”不包含隐藏列的导出”。这三条其实是同一条底层请求,被正确地分到了一组,但每一种措辞都对那个人真正在意的东西带着一点微妙不同的侧重,而一次只保留第一份提交措辞的合并,会把另外两份彻底扔掉。数字活下来了;而能帮助某人把这个功能的正确版本做出来的那种质感,没有活下来。
如果票数已经说明需求存在,为什么这种质感还重要
因为需求和设计是两个不同的问题,而只有具体的措辞才能回答第二个问题。“导出”上的十票能告诉一个团队这个功能值得去做;但它完全没说”导出”到底是指 CSV、PDF、一封定时邮件,还是一个 API 端点,而一次为了第一份措辞而扔掉十份原始提交中九份的合并,可能会悄悄把这个规格收窄成第一位提出请求的人碰巧问到的那个东西,哪怕另外九个人想要的是某种微妙不同的东西。一条功能请求真正应该记录下来的是什么从接收端讲的正是同一个缺口;而合并重复请求,正是这个缺口在接收之后重新冒出来的地方,恰恰是一个团队最需要了解人们到底真正问过什么的那个范围的那一刻。
一套保留措辞而不是把它扔掉的合并流程,看起来是什么样子
追加,而不是替换。那条规范性的条目在待办清单视图里只保留一个标题,但每一份被合并进来的提交的原始措辞,都会作为一份引文清单,或者作为几个被链接起来的源工单,继续附着在它上面,这样任何一个之后来复查这条条目的人,都能看到人们真正问过什么的那个实际范围,而不是团队里某一个人写的摘要。这样做几乎不花什么成本,只是工单上的一个字段,而不是一套新系统,而这正是压缩信息的合并,和只压缩了信息展示方式的合并之间的区别。
功能:经过筛选的 CSV 导出
票数:12
被合并的请求:
- "一种导出经过筛选的结果的方法" (acct_4421)
- "尊重我保存过的筛选条件的 CSV 导出" (acct_8832)
- "不包含隐藏列的导出" (acct_1097)
...
是不是每一条重复请求都值得合并,还是也存在误判的匹配
有一些确实是误判的匹配,而把”听起来相似”当成”是同一条请求”,本身就是一种独立的失败方式。“让我导出我的数据”和”只让我导出经过筛选的那个视图”,可能会因为一次落在”导出”这个关键词上的匹配而被分到同一组,尽管它们实际描述的是同一种通用能力下两个不同的范围;合并它们,要么会把票数灌到错误的东西上,要么更糟,会因为其中一条碰巧先到达,就把那个范围更窄的版本直接发布出去。一次人工过一遍分组,哪怕是快速的,也能在这种偏差累积起来之前把它拦下来;而单靠自动化的相似度匹配,会在词汇层面过度合并,在意图层面合并不足。
查重到底应该什么时候进行,是在收到请求的那一刻,还是留到以后
两个时机都需要,各有各的道理。在收到请求的那一刻就检查,能抓住那种最明显的情况:一条新请求 只是在重复一件已经开着的事情,在它变成一个独立的、没人追踪的条目之前就把它拦下来;在提交时对 所有开着的请求做一次相似度搜索,不需要任何人插手,就能处理掉这类情况里的大多数。晚一点、以一 个更慢的节奏再做的第二遍检查,抓的是收件时那一遍会漏掉的情况:两条请求当初用的措辞差异足够 大,足以在关键词或者向量匹配那一关侥幸溜过去,但等一个团队看过十几种不同的说法之后,才发现它 们描述的其实是同一种底层能力。跳过这第二遍检查,会让这些近似重复的请求,无限期地散落在各自独 立的标题之下,每一条都只带着自己那一小撮票数,永远也凑不到能真正推动它被开发出来的那个数字。
提出请求的人应不应该知道自己的提交被合并进了一条已有的条目
应该,而这和闭合客户反馈循环遵循的是同一种纪律,只不过应用得比平常更早一步:一个提交了什么、之后再也没听到任何回音的提出请求的人,会认定自己的请求没有走向任何地方,哪怕它其实已经被正确地合并进了一条带着另外十一票、最终确实发布出去的条目里。一句简短的确认,“我们已经把这条和其他人也提过的一条已有请求合并在了一起”,只需要一条消息的成本,就能防止一位客户因为完全看不出这条请求到底有没有被真正追踪过,而每隔几个月就重新提交一次同样的请求。
合并会不会改变功能发布时功劳该记在谁头上
它应该把所有人都包括进去,而不只是最先提交的那个人。闭合反馈循环讲的是在一个请求发布时通知提出请求的人;而对一条被合并的条目来说,这意味着每一个附着在这次合并上的账户,而不只是那个措辞最终变成规范标题的账户,因为从每一位提出请求的人自己的角度看,她确实问过这件事,而它也确实发布了,无论一套分诊流程碰巧保留了谁的措辞。在 Changeloop 中,这意味着 pull request 要点名每一个关联的 issue(Fixes #142, fixes #187);没被点名的 issue 不会收到评论。
FAQ
每条被合并的请求,值得保留多少措辞,是一句引文,还是一条完整的工单链接? 一句简短的引文通常在常见情况下就够了,因为它的目的只是让复查的人能一眼看到措辞的范围;但当原始提交带着重要的额外背景信息时,比如一张截图,或者一段一句引文会把它压平掉的详细工作流描述,也要把完整的工单链接一并保留下来。
保留每一条重复请求的措辞,会不会让待办清单变得更难扫读? 不会,如果它默认是折叠起来的。规范标题是一位快速扫读的复查者会看到的东西;被合并进来的措辞只隔着一次点击或一次展开,为做更深入研究的人而存在,但不会挤占那个只是在数票数的人的视野。
如果两条请求看起来完全一样,但真正做出来之后才发现想要的是不同的东西,该怎么办? 一旦这一点变得清楚,就把它们重新拆开,并且把最初的那次合并当成一个在当时可用信息下做出的合理决定,而不是一个要避免重犯的错误。一套从不拆分任何东西的分组系统,最终总会有几次错误的合并被永久固化下来。
是不是存在一个票数门槛,超过之后被合并的请求就应该获得一次对底层措辞的人工复查? 没有一个固定的数字,但任何一条正在接近开发决策的请求,都值得获得这种复查,无论票数多少,因为那正是”导出”和”带着保存过的筛选条件、以 CSV 形式导出”之间的差别,不再只是一种细微差异、而开始变成规格本身的那个节点。
本文的技术内容未经独立审核。如有错误,请告诉我们,我们会更正。