等待与延迟的交互设计

10 分钟读完

H13
实战手册 · 智能体体验与人机交互

等待:头九十秒决定一切。

把一次四十秒的智能体运行压掉八秒,几乎买不到任何东西——因为用户放弃的,是那种他估不出长短的等待,而放弃率跟随的是"可读性",不是时长。杠杆在于分母:在开工之前把计划公布出来,用用户能核对的单位向计划汇报进度,同样的四十秒就不再是一片虚空,而变成一条看得见尽头的队列。这一页其余的一切,都是这一步的推论。

STEP 1

智能体运行本就不在交互延迟的量表上,提速救不了它。

那几条经典的响应时间阈值——大约十分之一秒是"瞬时"、约一秒能维持心流、十秒是注意力的上限——是针对"用户在开始之前就能猜出耗时"的操作总结出来的。而一个要做规划、调六次工具、读三个文件、再写一份报告的智能体,活在比那张量表高出一到两个数量级的地方,再怎么优化也搬不回去。

  • 关键变量是"可估性",不是秒数。人们会耐心等一个停在 60% 的进度条,却会不耐烦地盯着一个转了四秒的转圈——差别在于其中一个支撑得起预测。一段用户能标价的等待是他愿意接受的成本;一段标不出价的等待是风险,而人对无法定价的风险的反应就是走开。
  • 在这里,优化模型是最贵、回报也最差的那根杠杆。一次运行的墙钟时间主要被工具调用、重试和限流吃掉时,把生成延迟砍一半,用户感受到的数字只动几个百分点。而公布一份计划只需在提示词里多加一句话,改变的却是量级。
  • 等待不是均匀的,用户能感知到它的质地。一次流式输出了六秒、在工具调用时死寂二十秒、然后又恢复的运行,读起来是坏了,而不是慢。工具调用期间的静默是智能体界面里最常见的非受迫失误,而它是一个渲染缺陷,不是性能缺陷。
  • 不要造假。模拟的进度条、编出来的百分比、与实际工作无关的"正在输入"提示,都是向信任预支的一次性贷款,等到进度条卡在 94% 整整一分钟时连本带息偿还。见为信任而设计
STEP 2

四个时钟,以及真正预测放弃行为的那一个。

"延迟"这个词把四种行为不同、修法也不同的度量压成了一个。分开埋点,否则你会优化错对象。

  • 首 token 时间。每块仪表盘都会显示的那个。它只作为存活信号有意义——证明请求收到了。改进超过一秒左右之后它什么也买不到,而它常常是以牺牲下一个时钟为代价换来的。
  • 首个可核验证据的时间。用户第一次看到自己能独立验证的东西的时刻:一个文件路径、一条搜索结果、一个行数、一个 URL。决定他留不留下的是这个时钟。关于"智能体打算做什么"的散文不是证据;第一条工具结果才是。大多数智能体界面会一边叙述一边把它压后三十秒。
  • 首个可评审产物的时间。输出多到可以开始阅读的时刻——一份草稿、一段 diff、一张不完整的表。早点把粗糙的产物摆到人面前再打磨,胜过晚点交出完美的产物,因为阅读时间和生成时间由此重叠,而不是排队。
  • 完成时间。唯一会出现在满意度问卷里、也最没有设计价值的那一个。它同时是各次运行之间波动最大的一个,所以一个点估计("大约 30 秒")比一个形状("通常不到一分钟;长的要五分钟")更糟。

给它们排序之后最实际的结论是:重排计划,让某件可核验的事先发生,哪怕那不是工作上最合逻辑的顺序。一个先搜索、后推理的智能体,计划更差,等待体验却好得多;而在大多数任务上,结果上的差距小于放弃率上的差距。

STEP 3

给等待一个分母。

不知道还剩几件事,用户就估不出还要等多久。智能体供得起这个数字,因为它会做规划——而大多数界面把计划扔掉了,只渲染它的执行过程。

  • 在第一步开跑之前把计划显示出来。四到六个有名字的步骤,用用户的词汇而不是工具的词汇:"找出这些发票"、"和账簿核对"、"写摘要"。这就把一段无界的等待换成了"四分之三",而那是一个人拿得住的数字。
  • 于是计划就成了承诺,改动必须可见。这是这项技法的代价,也是要把计划写短的理由。智能体如果发现还要多做两步,就说出来——"发现 14 处不匹配,加一轮对账"——因为一份悄悄变长的计划比没有计划更糟,而一个凭空消失的步骤会被读成"跳过了一道检查"。
  • 宁可用计数单位,不要用百分比。"23 个文件中的第 6 个"是诚实的、会自我纠正的,也对"94% 问题"免疫。加在智能体运行上的百分比,是一个用两位有效数字呈现出来的猜测。
  • 步骤名用业务语言,工具调用记在它下面。表层写"正在读取 Q3 账簿";可展开的细节里写 fs.read(/data/q3.csv)。这是两拨不同的读者,而且两拨都真实存在——分层规则见渐进披露
  • 永远不要让界面静默超过几秒。一次漫长的工具调用需要它自己的可见状态("等待搜索 API,已 12 秒"),一次限流后的重试需要被说出来而不是藏起来——用户叫得出名字的停顿可以忍,叫不出名字的停顿就是故障。
STEP 4

流式输出是"在动",不是"在推进"。

token 流式输出对聊天是正确答案,因为在那里流就是交付物;它被搬进智能体界面时,通常已经不是了。"在动"能安抚人大约十秒,之后就失效,而在长运行上它还会主动误导。

  • 流式吐推理 token,并不告诉用户跑到哪儿了。三段思辨和一行思辨,作为完成度信号看上去完全一样。更糟的是,流畅的文字会暗示一种轨迹本身并不担保的能力——推理文本是生成出来的输出,而不是"决定了答案的那段计算"的日志,这正是思维链忠实性要讲的事。
  • 用户会读流过去的每一句,并拿它要求你。运行期间可见的一切都被当作承诺。一个流式说出"我顺便把 changelog 也更新一下"却没做的智能体,在用户那一侧就是在一件没人指派的任务上失败了。流式输出结论与动作;把猜测挡在可见通道之外。
  • 有产物的时候,流产物,而不是流独白。一段一段出现的 diff、一行一行填上的表格、一节一节拼起来的文档——这些既是"在动"又是"在推进",而且能提前启动评审的时钟。
  • 可打断,才让"可见"变得诚实。如果用户眼看着智能体奔向错误方向却停不下它,那么把过程展示给他就是一种残忍。每一个可见步骤都需要一个能在步骤边界内生效的停止键;见打断、引导与交接
STEP 5

知道什么时候该停止设计等待,转而交接。

在一到三分钟之间的某个地方(取决于用户对这项任务有多在意),正确的设计就不再是更好的进度显示,而是放人走。把注意力按在页面上八分钟,比让人离开、事后再把他叫回来更糟。

  • 把交接阈值明确定下来,并当作产品决策。阈值以下,用户看着、也能引导。阈值以上,运行脱离前台并在完成时通知。失败模式是根本没有阈值,于是界面会乞求注意力十分钟,然后才交货。
  • 提议交接,而不是强制交接。"这看起来是个五分钟的活——要我做完叫你吗?"既尊重了真心打算全程监督的用户,也把其余的人转化掉了。要在估计值发生变化的那一刻提议,而不是在一开始、谁都还没投入任何东西的时候。
  • 交接必须扛得住用户离开。一次脱离前台的运行,如果卡在一个没人在场去点的审批上,那是死锁,不是安全控制。派发之前就决定哪些决策可以由运行独自做出、哪些值得为之阻塞——这正是异步与离场体验的全部主题,而它从你跨过阈值那一刻起就开始了。
  • 把"回来"设计好,因为那才是贵的部分。九分钟后回来的人需要重建"发生了什么",而一大串原始的工具调用记录会让他为此付全款。他需要的是结果在先、决策在次、日志在后。

给任何智能体界面用的一道好检验:如果用户此刻关掉标签页,他会损失什么?如果答案是"整次运行",那你造的系统在索取一份它并没有挣得的注意力。如果答案是"什么也不损失——它会继续跑完并告诉他",那么等待就根本不再是一个设计问题了。

STEP 6

在等待之中失败,以及该盯的那几个数字。

长运行让失败以一种特定方式变贵:用户是在时间已经花掉之后才知道的。由此得出两条规则,然后是埋点。

  • 宁可早而响地失败,不要晚而彻底地失败。一次在第 4 秒就发现缺少凭据的运行,必须在第 4 秒说出来。智能体体验里最糟的模式,是跑了四分钟、以"我无法访问该数据库"收场——等待花光了,什么也没拿回来。见为失败与恢复而设计
  • 永远返回部分成果。二十个文件里处理完了六个、并且六个都点了名,这是一个结果。失败时丢弃部分输出,等于把这段等待唯一买到的东西扔掉。
  • 按已用时长切分的放弃率。头号数字,也是唯一能告诉你交接阈值"实际在哪"而不是"你设在哪"的数字。按十秒一档分桶,那道断崖通常一眼就能看见。
  • 首个可核验证据的时间,p50 与 p90。先优化它,再优化完成时间。放弃行为住在 p90 那一头,而那几乎总是某个慢工具,而不是慢模型。
  • 静默间隔:每次运行中界面最长的一段无更新时间。没人给它埋点,而它与放弃率的相关性比总时长更强。p95 超过几秒就该告警。
  • 估计误差。如果你显示了估计值,就去度量它错得有多离谱,并且宁可给一个你能命中的区间,也不要给一个你会错过的点。系统性乐观是让今后所有估计都被无视的最快途径。

在动延迟本身之前先做这三件事:在第一步之前输出一份简短的编号计划;重排计划,让第一步产出用户能独立核对的东西;给每一次超过两秒的工具调用一个有名字的可见状态。它们的代价是改一段提示词加做一个组件,作用于每一次运行而不只是长尾,而三者加在一起对"感知速度"的推动,超过你手上任何模型或基础设施改动。

相关:异步与离场体验讲交接之后发生什么,流式与部分输出讲底层机制,延迟预算讲语音场景下这些余地统统不存在时怎么办,以及成本、质量与延迟讲底下那个权衡。