一家中型 SaaS 公司的支持智能体正确处理了一起计费纠纷。它读取了工单,检查了客户账户,发现了重复收费,执行了退款,并发送了一封礼貌的确认邮件。每一步都是正确的。唯一的问题是时间戳:客户所在时区的凌晨 3:14。客户在睡梦中醒来看到退款通知,以为自己的信用卡被盗刷了,在公司有人醒来解释之前,就向银行提交了欺诈申诉。
在那个工作流中,没有任何环节是传统意义上的 Bug。智能体没有产生幻觉,没有选错账户,也没有算错退款金额。它只是完全不知道凌晨 3 点是一个告知别人资金变动的糟糕时间。这个模型读过的人类睡眠习惯相关文本比世界上任何人都多,但它的行为表现仍然像是在对待一个随时待命的服务端点,只要你调用它,它就是清醒的。
这是智能体设计中最隐蔽的失效模式之一。我们花费了巨大的精力关注智能体是否做了“正确的事”,却几乎没有花精力关注它是否在“正确的时间”做这件事。两者并不等同。一个动作可能内容正确但时机错误,而时机上的失败往往才是客户真正会注意到的。
“立即执行”是无人选择的默认设置
当你编写智能体循环时,隐含的契约是:接收输入、决策、执行。执行发生在决策做出的那一刻。中间没有间隔,因为没人设置间隔。“立即执行”并不是你的团队讨论出的政策 —— 它是政策的缺失,是一个没有理由暂停的 while 循环的自然形态。
对于很大一部分智能体操作,即时性是没问题甚至必要的。回答问题、查询订单状态、起草供人工审阅的回复 —— 这些都应该尽可能快地发生。问题在于,同样的循环,带着同样的零延迟默认设置,也管理着那些即时性反而有害的操作:
- 发送面向客户的电子邮件或短信
- 向值班人员升级事件
- 在共享频道发帖,其中的通知会弹窗提醒十几个人
- 触发后续跟进流程(“我们注意到你还没有完成设置”)
- 提交一个会进入某人早间队列的工单
每一项操作都有“好”时间和“坏”时间,而智能体对待它们就像对待数据库读取一样。关于这些操作何时触发的决定是由编写执行层的人隐含做出的,而他们在写下 await sendEmail() 时,几乎肯定没有考虑过时区。
营销界在十年前就吸取了这个教训。发送时间优化(Send-time optimization)现在是任何严肃的电子邮件平台的入门门槛 —— 共识是接收者当地时区的早上 8–10 点效果最好,工具会自动错开全球发送时间,确保没人会在半夜被吵醒。智能体的构建者们正在从头开始重新学习这一点,因为智能体发出的外部邮件不经过营销技术栈。它通过智能体拥有的任何工具进行 HTTP 调用,而该工具对接收者的时钟毫无概念。
两种工作:随时性工作与仅限日间工作
解决方法始于一个智能体自身无法做出的区分。智能体可以采取的每一个动作都属于两个类别之一,你必须明确地标记它们,因为模型不会这么做。
随时性工作(Anytime work)是计算和内部状态变更。读取数据、运行分析、更新内部记录、准备草案、为工单丰富上下文。这些工作在发生时,接收端没有人类。它们可以而且应该 24/7 全速运行。如果你的智能体整晚都在静静地对工单分类、完善 CRM 记录并预先起草回复,那就是系统在按预期运行。
仅限日间工作(Daylight work)是任何涉及人类注意力的操作。界定标准很简单:完成这个动作是否会产生通知、中断或对特定个人的期望? 如果答案是肯定的,那么它就是日间工作,“现在执行”不应该是自动的答案。它应该排队,直到人类清醒、合适的窗口期 —— 除非紧急情况覆盖了这一规则,我们稍后会讨论这一点。
这种拆分的威力在于,它让智能体在保持最大生产力的同时,依然体贴周到。智能体并没有慢下来;它只是将工作中产出成果的部分与交付成果的部分分离开来。晚班完成所有准备工作,早晨交付结果。一个在凌晨 2 点遇到问题的客户,会在早上 8 点看到一份已经完全解决的回复等待着他,这比凌晨 2 点的骚扰通知体验更好,也比业务时间才开始处理的慢节奏人工回复体验更好。
大多数团队从未划清这条界线,因为智能体的工具列表并不鼓励这样做。send_email 和 update_record 在同一个架构中并排存在,看起来同样无害,并由同一个推理步骤调用。你必须在工具级别(而不是提示词中)标注它们是否会触及人类。
Agent 缺失的上下文
Agent 根据你提供的上下文决定要做什么。时间和社交背景通常是几乎没人会包含进去的输入。Agent 知道客户的账户等级、购买历史以及完整的工单记录。但它不知道客户所在地的时间,不知道今天那里是否是公共假期,不知道值班表是否刚刚更替,也不知道接收者是否是更愿意在凌晨 3 点收到消息的夜班人员。
将此视为需要补充的缺失上下文,而非期望它具备的智能。具体来说,Agent 在执行任何面向人类的操作时,其工作上下文应包含:
- 接收者的本地时间和时区。 以 IANA 标识符(
America/Sao_Paulo)存储,绝不要使用原始偏移量,因为偏移量无法应对夏令时的变化。所谓的“凌晨 3 点发送”漏洞,往往是因为将 UTC 值与一个看起来像本地时间但未附加时区的字符串进行比较而导致的。
- 日历上下文。 周末、地区公共假期以及公司特定的静默期(blackout periods)。如果周二在接收者所在国家是国定假日,那么“周二上午 9 点”就是错误的。
- 值班和人员配备状态。 现在谁实际上醒着并负责。升级流程应路由给正在值班的人,而不是路由给服务负责人但此时正在睡觉的人。
- 操作本身的紧急程度。 并不是每条消息都应该得到同样的对待,Agent 需要一个明确的信号来判断哪些可以等待。
这些都不是什么罕见数据。你的公司已经有了假期日历、PagerDuty 值班表以及带有时区字段的客户记录。差距在于,这些数据都没有被接入到 Agent 的决策上下文中。它存在于 Agent 的工具无法读取的系统中。
紧急程度分级:让“等待”变得安全的覆盖机制
幼稚地规定“将所有内容排队到工作时间”是危险的,因为有些事情确实不能等。安全事件、支付系统宕机、数据丢失事件——这些都应该把人叫醒。一个礼貌地将这些事件推迟到上午 9 点的 Agent 比一个完全没有时间逻辑的 Agent 更糟糕。
因此,队列需要一个覆盖机制(override),而且这个机制必须是深思熟虑的,而不是交给模型的心情来决定。定义一组少量且固定的紧急程度级别,并要求 Agent 为每一个日常操作分配一个级别:
- 极高 (Critical) — 不论几点,立即采取行动;叫醒某人是正确的结果。仅限于真正的事故。
- 当天 (Same-day) — 必须在今天送达人类,但如果当前是非工作时间,可以等待下一个工作窗口。
- 常规 (Routine) — 应该在下一个正常的业务窗口送达;完全可以存放到隔夜或周末。
这里的纪律是保持“极高”级别的小规模和定义明确。警报疲劳是事件管理中一个有据可查的失败案例:当所有事情都告警时,人们就会停止查看告警,而真正关键的警报也会随之被忽略。一个因为“不确定”而随意升级的 Agent 会以机器的速度和规模重现这种失败。Agent 的不确定性不是在凌晨 3 点打扰人类的理由;它是将其排队到早上,并将不确定性作为上下文附给处理人员的理由。
让紧急级别成为决策步骤的必填输出,并在 Prompt 中强制要求理由:不是“我要升级这个”,而是“这是‘极高’级别,因为所有用户的生产环境都宕机了”。这种理由是可审计的,它让过度升级变得可见,而不是隐形的。
设计懂得何时等待的 Agent
构建这种机制主要是工程对接,它存在于操作层——而不是模型中。
在 Agent 的决策和执行之间设置一个调度网关(scheduling gate)。当 Agent 决定采取面向人类的操作时,该操作不会直接触发。它会进入一个网关,根据接收者的本地时间、日历和值班状态检查操作的紧急程度,然后立即执行或调度到下一个合适的窗口。耐用执行框架(Durable execution frameworks)使得“调度到上午 8 点”这一路径的实现成本变得非常低——Agent 的运行可以挂起数小时而无需占用进程,并在窗口开启时恢复执行以完成交付。这也意味着延迟的操作可以在部署或崩溃中幸存,而简单的内存定时器则做不到。
三个原则使其在实践中奏效:
- 默认延迟日常工作。 立即执行应该是 Agent 必须用紧急程度来证明其合理性的例外,而不是阻力最小的路径。反转默认设置,凌晨 3 点的邮件就在结构上变得不可能,而不再是你寄希望于通过 Prompt 来防止的事情。
- 保持 Prompt 远离时间逻辑。 不要要求模型去推理时区和假期——它有时会做对,有时会自信地做错,而且你无法对 Prompt 进行单元测试。时区计算、日历查询和值班状态是确定性的代码。模型选择紧急级别;网关负责逻辑计算。
- 让夜间工作可见。 如果你的 Agent 批量处理夜间工作以便早上交付,请将其显现出来:摘要说明它准备了什么、正在保留什么以及原因。一个在上午 8 点到达的人应该看到队列,而不是被它吓一跳。
更深层的一点是,Agent 的能力不仅仅体现在其决策质量上。它还体现在时机感上——这正是体贴的同事与让人疲惫的同事之间的区别。一个好的队友知道哪些问题可以等到早上,哪些不能,并据此行动。我们已经教会了 Agent 变得能干。接下来要教给它们的是体贴。而在操作层面,体贴意味着像清楚该做什么一样,深思熟虑地知道何时该等待。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部