← 全部文章
工程发布于 2026年8月20日4 分钟阅读

助手无从知晓

Ulyssify Engineering在公开中打造约束装置

Ulyssify 会屏蔽让你分心的应用和网站。它有一个助手 Anka,能用自然语言帮你把屏蔽规则设置好。上周,它以一种很有启发的方式出了错:

下面这段对话为英文原文:

UserAdd this site to my Night dev block list.
AssistantDone! It's now in the Night dev list. 🔒
UserI'm looking at Night dev. It's not there.

那个网站其实进了另一个列表,行为也并不相同。助手确认了一件从未发生的事,被质疑时又开始猜测。

一个很诱人的诊断是「模型还不够聪明」。但我们没有止步于此,而是回溯了整段对话,发现了更值得说的结论:再大的模型也不可能答对。 那些事实从来就没有进入它的上下文,它们在两个环节丢失了。

漏洞一:助手看到的数据视图会过时

我们的设置界面永远不会落后,因为它们直接渲染后端返回的内容。助手看到的却是另一回事:那是某个人在功能上线当天手写的一个摘要函数,只列出了寥寥几个字段。后来产品长出了带有真实时段的日程安排,却没有人更新那个摘要,也没有任何机制强制谁去更新。

你的数据 设置界面 自动更新 助手的视图 手工录入,就此定格 ✓ 能看到新字段 ✗ 永远学不到
界面直接读取数据源,助手读的却是一份手工誊抄的副本。

所以助手根本看不到用户已经设置了一个午夜时段的日程,于是它提议去重建那些用户其实早已拥有的东西。这不是愚蠢,而是失明。

修复:一致性是一项测试,而不是一句承诺

我们不再指望任何人去记住这件事。现在有一个 CI 测试会读取界面真正渲染的那些字段,并要求其中每一个要么呈现给助手,要么带着一条写明的理由被排除。只要你往界面里加了一个字段,却没有替助手做出决定,构建就会变红,并给出一条消息告诉你该怎么做。

界面新字段 任何人都能添加 CI 关卡 呈现给助手 → ✓ 通过 排除并写明理由 → ✓ 通过 被遗漏 → 构建失败
遗漏不再悄无声息,遗漏会变红。

漏洞二:助手叙述的是它的计划,而不是结果

进错列表这个 bug 更糟。服务器已经执行了操作,并如实存下了发生的一切,包括那个网站真正进了哪个列表。可是助手的后续回复,是用它自己先前的计划,再加上一句笼统的「执行成功」拼出来的。那份存好的事实,在模型看到它之前一步就被丢掉了。

现在,后续回复是基于存好的结果生成的:真实的列表,真实的状态,真实的 id。如果某样东西进了意料之外的地方,助手会如实说出来,因为它被告知的就是这个。而且请求里的任何内容都无法注入到那条消息里,每一个事实都由服务器生成。

之前 助手的计划 "Done! It's blocked 🔒" 确认的是它自己的意图 之后 操作执行 存好的服务器结果 真正发生的事 诚实的确认
现在的确认来自真正发生的事,而不是原本的意图。

从未出问题的那部分:两扇门,一道关卡

有一个特性,让这件事只是尴尬,而没有变成危险,它也是我们设计中最会全力捍卫的一环。助手没有属于自己的 API。它的操作在 HTTP 之下的一层进入后端,运行的正是人类点击时所运行的那一批带关卡的函数。

人类点击 在设置里 助手操作 在你批准之后 同一个带关卡的内核 两者共用一套规则 收紧屏蔽:立即生效 放松屏蔽:需要等过 你自己设定的冷却期
没有单独的助手 API。两扇门通向同一道关卡,规则因此无法各行其是。

这一点之所以重要,是因为对手是谁。在一个约束装置里,最有动机去破解屏蔽的人,正是用户自己,在凌晨一点,和自己过去的决定讨价还价。如果助手有属于自己的写入路径,那么每一句提示词都可能成为一个漏洞。正因为它走的是人类那条路径,任何会放松强制的操作,无论请求措辞如何,都得排在用户自己设定的冷却期后面。助手可能会出错,但它不可能成为一条绕行的捷径。

要说清这不是什么:它不是「行动前先问一下人」,那一点别处已经讲得很充分。它是一个关于底层管道的更强的主张。「助手能做人类能做的一切」,应当指的是能力上的对等,而不是一套平行的 API 界面,因为人类同样无法跳过冷却期。

这里面关于审批的那一半,业界已经讲得不少:12-Factor Agents 论证了要把人留在环路之中,Anthropic 的智能体工具编写指南则讲了如何把有意义、高信噪比的结果返回给模型。而关于底层管道的那些主张,也就是助手的写入路径就是人类那条带关卡的路径,以及它的确认是由存好的服务器事实重新拼装而来,是我们还没见到有人写下来的部分,所以我们把它写了下来。

我们把这次事故变成了一个永久的测试,从而闭合了这个环路:那次对话里的确切配置如今成了一个测试夹具,CI 会断言助手的上下文包含了答对所需的每一个事实。

如果你正在构建一个应用内的助手
  1. 一份手写的数据摘要,早就已经过时了。把界面与助手之间的一致性做成一个会失败的测试,而不是一句要靠人去信守的承诺。
  2. 喂给模型的应当是来自服务器的结果,而绝不是它自己的计划。一个只会叙述意图的助手,迟早会确认一件虚构的事。
  3. 让助手的写入走和人类点击相同的、带关卡的代码路径。这样一来,一个糊涂的助手只会令人尴尬,而绝不会带来危险。
  4. 在争论模型有多聪明之前,先修好它能看到什么。一个更大的模型,若在缺失事实的基础上推理,也只是用更漂亮的文字去编造。