让一个LLM智能体自己注册账号、收验证码、读邮件,邮箱就不再是基础设施里的一个小细节了。它变成了执行状态的一部分。问题在于,两个智能体可能几乎同时启动同一套流程,如果它们都去查"最新收到的那封邮件",其中一个就会把另一个的证据吃掉。表面看像是自动化随机抽风,真正的原因是从一开始就没有人拥有这个收件箱。
搜"temp mail"这类词,出来的结果往往把好几种完全不同的用法混在一起。但对智能体来说,技术问题要具体得多:谁能读这个邮箱、在哪个时间区间内读、凭什么证明这封邮件属于它这次执行?
两个智能体不该共用同一份证据
设想一个很简单的流程:智能体A申请了一个临时地址,智能体B也申请了一个;两边都完成了注册,都在等确认邮件;然后两个都去查同一个共享收件箱。就算邮件主题长得像,最先出现的那封也未必属于正在发问的那个智能体。重试会让情况更糟——它可能读到上一次执行留下的有效邮件,然后把这一步标记成已完成。
解决办法不是让模型"再小心一点"。LLM在工具能给出可验证约束的时候表现更好。所有权应该写在契约和服务器里,而不是写在一条软绵绵的指令里。
这里有个办法是把三种标识符分开:
- runId:智能体的一次完整执行
- leaseId:临时使用这个邮箱的许可
- messageId:实际被消费掉的那份证据
有了这些数据,一份自动化日志就能解释清楚发生了什么,不用再从自由文本里把故事拼回来。
给每个邮箱设计一个租约
租约是一份带所有者、带过期时间、带版本号的预留。说白了就是:智能体拿到了使用某个地址的许可,但这个许可既不永久,也不能转让。
一条最小记录大概长这样:
{"leaseId": "lease_8f2", "runId": "run_42", "mailbox": "agent-42@example.test", "status": "active", "expiresAt": "2026-10-16T12:00:00Z", "fence": 7}
其中的fence是一个每次租约换主就递增的数字。如果一次旧执行在超时之后又回来了,它手里那个旧值已经不能用来读邮件或确认邮件了。这个细节能防止一个慢任务复活,然后覆盖掉当前状态。
过期时间要短,但得够走完流程。租约太短会导致不停续期,太长又会让邮箱被锁住。实际操作中,最好根据智能体的延迟预算来定这个时间,而不是图省事用一个全局值。
做注册流程时,还可以把租约和唯一别名结合起来用。
给邮件工具定一份最小契约
智能体用的工具应该提供小而明确的操作,结果也要显式返回:
- reserveMailbox(runId, ttl) 返回 leaseId、address、fence、expiresAt
- waitForMessage(leaseId, fence, after, selector) 返回 messageId、receivedAt、body
- ackMessage(leaseId, fence, messageId) 返回 acknowledged: true
- releaseMailbox(leaseId, fence) 返回 released: true
waitForMessage不该只接受一个地址。它必须校验leaseId、fence、after时间点,以及一个用来限定预期邮件的selector。这样,一封旧邮件就不会被当成新证据蒙混过关。
错误也是契约的一部分。lease_expired、fence_mismatch、message_not_found、provider_unavailable,这些能让智能体自己决定是续期、等待、重试一个安全动作,还是干脆停下。一个笼统的错误只会带来盲目重试,让自动化变得更贵。
如果流程里包含升级或通知,那就值得把事件和邮件之间的关系记下来。有用的信号不只是"来了点什么",而是"来的是那封能证明状态正确转换的邮件"。
围栏令牌与执行状态
智能体应该沿着可检查的状态往前走:planned、reserved、action_sent、message_seen、acknowledged、released。每一次状态转换都要确认这次执行仍然是租约的所有者。如果message_seen发生在released之后,工具必须拒绝它,哪怕那个地址还存在。
退出原因也值得存下来。released_success、expired_timeout、released_error,这些比一个简单的布尔值有用得多。当运维在CI里看到一个失败时,他能分清这是投递慢,还是真的撞车了。
"tem email"这个词可能出现在搜索或测试数据里,但不该变成一条过于宽泛的匹配规则。"temp mailid"也一样:部分匹配可能把另一个场景的证据吃掉。selector必须严格,最好把收件人、预期主题和一个执行标识符组合起来用。
什么时候预留,什么时候释放
需要为每一次工具调用都预留一个邮箱吗?不一定。按业务流程或按一次隔离的执行来预留就行。为每一步都建一个预留会增加延迟,也让历史记录难以追踪。正确的边界,是需要独占性的那个单位。
邮件来得太慢怎么办?不要无限制地加大超时。返回观察到的状态,如果messageId存在就保留它,然后决定是续租还是结束这次执行。一个清晰的界限,既保护服务方,也保护自动化的预算。
模型能决定什么时候释放吗?它可以提议,但系统也应该在finally之类的路径里释放。智能体可能因为一个意外响应就停住了,服务器不该指望模型记得清理资源。
怎么验证隔离真的生效?并行跑两个流程,故意延迟其中一次读取,再让其中一个租约过期。只有当每个流程消费掉自己的邮件、旧智能体收到fence_mismatch时,测试才算通过。这种场景能抓到顺序测试永远看不到的竞态。
这个模式很小:预留、验证所有权、消费证据、释放。但它把一套脆弱的集成,变成了智能体可以放心使用、边界清晰的组件。在邮件自动化里,可靠性从读第一封邮件之前就开始了——从某次执行拿到一个所有者的时候开始。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.