文章指出,把所有模型输出都送入人工队列,会因注意力耗尽和大量正确样本诱发机械批准。文中的合成示例说明,架构中设置审核节点并不等于实际具备有效审查。
在架构图上,human-in-the-loop 看起来很棒。模型做出决策,一个标着“人工审核”的方框放在模型与生产环境之间,所有人在设计文档上签字时,都觉得更安心了。
然后,系统上线了。审核者是一个真实的人,面前有一个真实的待审队列。在一个普通的周二下午,队列里堆着 340 个待审项。大多数一眼看去都没问题。审到第 40 项时,他们已经只看第一行了。审到第 120 项时,他们已经开始按着节奏点击“批准”。
架构图上的方框还在,审核却已经名存实亡。
差距就在这里:我们把人当成了一个注意力无限的组件,但注意力恰恰是整条处理流程里最稀缺的资源。下面是我最常见到的几种失效模式,以及用于说明问题的例子。这些例子综合了多种情况,并不对应某一家具体公司。
最简单的设计,是把模型的每一个输出都送去审核。这让人觉得很谨慎。实际上,它却是最不安全的选择,因为它会逐渐让审核者形成一种习惯:批准才是预期答案。
举个例子:一个发票分类模型的准确率是 97%。审核者每天看 300 张发票,其中大约有 9 张分类错误。这 9 张埋在另外 291 张分类正确的发票中,乍看之下毫无区别。两周后,审核者纠正模型结果的比例降到了接近零。这不是因为模型进步了,而是因为人已经不再认真看了。
解决办法是分流。只有在模型不确定,或者出错代价很高时,才转交人工审核:
def route(decision, confidence, impact):
# High-impact actions always get a human, whatever the confidence
if impact == "high":
return "human_review"
# Low confidence gets a human
if confidence < CONFIDENCE_THRESHOLD:
return "human_review"
# Everything else is auto-approved, but sampled for audit
if random.random() < AUDIT_SAMPLE_RATE:
return "audit_queue"
return "auto_approve"
这里有两个细节很重要。第一,只看置信度是不够的:模型可能信心十足地犯错,而且许多模型的原始分数都没有得到良好校准。在信任某个阈值之前,先用留出数据检查校准情况,并把置信度与影响程度规则结合起来。第二,对自动批准项进行抽样审计,才能知道你的阈值是否仍然合适。
第二种失效模式,是审核界面只显示模型的答案,除此之外什么都没有。审核者只能二选一:从头重做这项任务,或者相信答案。在时间压力下,他们会选择相信答案。
举个例子:一个贷款文档提取工具标出了“年收入:84,000”。为了核实,审核者要打开一份 22 页的 PDF,手动搜索。他们认真查了两次,然后就不再查了。
好的审核界面应该展示模型实际依赖的输入:在源文档中高亮对应文本、展示影响评分的字段,以及触发转交人工审核的规则。这样,核实就从一番调查变成了看一眼。如果你无法展示模型使用了什么信息,那么在增加审核人员之前,值得先解决这个问题。
如果“批准”只需点击一次,而“拒绝”却会打开一张有六个必填字段的表单,那你设计出来的,就是一个让人批准的系统。
纠正结果的操作成本应该和批准一样低:一个操作就能完成修改,简短理由可选,修改后的值自动记录。每次人工纠正都应该留下日志,记录原始输出、修改内容、修改人和修改时间。
这份日志不是文书工作。它是你手里最有价值的数据集,因为它能准确告诉你模型在哪些地方出错,以及阈值是否设在了合适的位置。
如果你不跟踪审核行为,就不会发现人工审核环节何时悄悄失效。以下几个信号值得关注:
这些信号能告诉你,流程中的人是否还在发挥作用。
human-in-the-loop 本质上是一个注意力分配问题,只不过前面放了一个模型。模型的职责,是判断哪些项可以安全地跳过人工审核。界面的职责,是让剩下的决策既能快速完成,又容易做对。日志的职责,是在模型或界面失效时让你看见。
我们在 Cyclopt 经常思考这个问题,因为每一个涉及代码库的 AI 操作,都会带来同一个问题:哪些操作需要人介入,又怎样才能让这个人的审核真正发挥作用?
所以,我想问你:你的人工审核队列里,人工纠正率是多少?你真的知道这个数字吗?
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。