Agent 工程实践 / 09 · 共 12 篇

Agent 工程实践 · 09

异步 Agent:要求变了,旧结果怎么办?

运行时设计 / 异步任务与要求变更

异步查询继续运行时,用户可能已经改变要求。每个请求需要保留身份和发起条件,返回后再按当前任务核对结果。

请求归属与结果适用性,是两次不同的判断。宿主保留发起快照和待处理更新,再把核对后的任务状态交给模型。

查看交互演示 ↓

事件分析

同一个任务,存在两份条件

场景很简单:为一场会议推荐场地,最初是 20人、预算3000元。查询甲受理后,系统可以先整理议程草稿,因为这件事不依赖场地返回;此时仍没有场地推荐,更没有完成预订。

等待期间,用户先把预算降到2000元,又把人数改成30人。这是对两个字段的更新,后一条不能覆盖前一条。接收盘先保存两条事件,调度器再把它们应用到当前条件。查询甲保留原来的20人、3000元快照,用来解释它为什么返回这批候选。

查询甲 · 发起快照20人 / 3000元解释这次查询的输入,保留不改
当前任务 · 已应用条件30人 / 2000元决定候选现在能否成为推荐

这两份条件都正确,只是回答的问题不同。若把新要求直接写进在途请求的旧记录,会抹掉请求真正执行过的条件;若一直沿用旧记录做推荐,又会忽略用户已经提出的变化。

一条完整的事件链

发生的事需要保留或改变的状态
发起查询甲登记待办,保存20人、3000元的发起快照
收到预算与人数更新两条事件分别保留,尚未应用时仍显示待处理
应用两条更新当前条件变为30人、2000元,查询甲快照保持原样
查询甲返回核对请求归属,结束相应待办,再检查候选适用性
按新条件发起查询乙创建新请求,不覆盖查询甲的身份和结果
查询乙返回并复核竹厅32人、1900元进入合格候选,再形成推荐

演示的默认讲解按甲、乙顺序返回。使用“新结果先回,旧结果后回”预设,可以观察另一条合法顺序。到达顺序只能说明谁先返回,不能决定谁有权覆盖当前推荐。

旧结果是否可用,要看它提供了什么证据

查询甲返回松厅和云厅。按当前30人、2000元核对:松厅容量24人,不够;云厅费用2800元,超预算。这批结果不能成为当前推荐。查询乙返回的竹厅容量32人、费用1900元,两项都满足,才能进入候选槽。

但“发起时条件旧了”并不等于“结果必须丢弃”。如果旧查询返回的某个场地仍满足新条件,而且价格、可用性等信息仍然有效,就有复用价值。这里需要判断的是证据适用性,而不是简单比较时间戳。

本例还有一个容易忽略的限制:甲只返回松厅与云厅,它不是完整场地目录。两个候选不合格,只能得出“这批结果不满足要求”,不能推出“没有任何合适场地”。因此需要新查询,也不能从页面列出的固定资料里偷取一个尚未返回的场地给模型。

形成建议前,还应检查接收盘里是否存在尚未应用的要求。本页故意允许“只应用人数”,但只要预算事件仍待处理,推荐就会被阻止。这样,“符合当前条件”才不会变成“符合系统漏读之后的条件”。

工程取舍

异步任务里的四个设计选择

立即重查,还是先复核已有结果?

每次要求变化都取消并重发,实现起来直观,但会浪费仍可能有用的在途工作;始终复用旧结果,则容易漏掉新条件下才出现的候选。查询成本高、返回事实较稳定时,可以先复核再补查;库存、报价或权限变化快时,需要重新获取有效证据。即使复用了某个旧候选,也不代表已经获得新条件下的最优或完整结果。

何时应用更新?

逐条到达、逐条改动的好处是响应快,但后续步骤可能看到中间状态;在明确边界集中应用,比较容易得到一致的任务快照,代价是增加等待。本页把“收到”与“应用”拆开,是为了展示这个差别。真实系统可选择单任务串行处理事件,并在推荐或执行前核对条件版本,避免读到一半新、一半旧的状态。

这里的预算与人数更新属于不同字段,可以合并;若同一字段连续修改,应定义权威顺序,例如服务端确认的任务修订号。网络到达时间不一定代表用户意图的先后,不能不加区分地采用“最后到达覆盖一切”。

请求取消之后,还要等待什么?

发送取消请求,只说明系统表达了停止意图。本页将查询从“运行中”切到“取消请求中”,收到执行器确认后才标为“已取消”。如果结果在确认之前已经完成,取消确认不能追溯抹掉这次完成;确认后的晚到回执也不能重新激活请求。

对于查询,停止采用结果通常足以隔离影响;对于发邮件、预订或扣款,必须另外核对外部动作究竟有没有发生。停止等待、停止工作和撤销已发生的副作用需要分别处理。这个演示只推荐场地,不涉及真实预订。

重复投递与失败重试,需要两种身份

重复回执不应再次完成同一待办,也不应重复触发外部动作。重试则是同一逻辑请求下的一次新尝试:除了请求身份,还需要尝试身份,才能判断晚到回执来自旧执行还是新执行。本页查询乙失败后会保留失败记录,并生成新的句柄再重试。

如果操作可能产生副作用,还需要服务端认可的幂等约定:同一业务意图的网络重试应复用相应幂等键,不能因为换了尝试句柄就再订一次。同样,参数已经变化的新意图也不能随意复用旧幂等键。请求归属、尝试归属和副作用去重各自解决不同问题。

落到实现

让运行时持有事实,再把事实交给模型

这套机制可以归纳为三个值得在实现中持续检查的约束:

  • 已发出的请求可追溯。身份、发起条件和终态有记录,新要求不改写旧请求的事实。
  • 收到的事件有去处。要求更新明确为待处理或已应用,回执对应具体请求;无法归属的记录先隔离。
  • 推荐绑定已核对的条件。模型获得最新任务快照和适用证据,条件再次变化时,旧建议需要复核。

本页的状态转移、容量与预算核对在浏览器内实际执行;场地资料、回执和模型建议使用固定样例。生产实现仍需补上持久化、故障恢复、并发更新控制和副作用约束。演示也没有开放任意旧重试句柄的回执注入,不能据此认为已经覆盖全部重试竞态。

异步的关键,是让仍在运行的工作、已经发生的事实和当前有效的要求保持可区分。这样,结果晚到时,系统仍知道它是谁的、能用来做什么,以及还缺什么才能继续。

交互演示 · 异步任务调度台

先看默认事件链,也可手动比较乱序、遗漏更新与取消
00:00 / 00:00
异步任务调度台当前已应用:20人 / 3000元
模型人数20预算3000甲待机乙待机更新
旁白字幕

事件实验与查询记录

亲手比较事件的到达顺序

选择预设会暂停旁白、重建比较起点。再用按钮决定哪个查询先返回;不会连接真实服务。

用户要求与处理边界

查询返回与核对

待处理事件

取消、重复回执与失败实验

请求取消后先等待执行器确认;若结果先完成,取消确认不能抹除真实结果。

核对任务、条件与当前推荐

不依赖场地结果的准备工作

当前建议

收到新要求后,旧建议需要复核;无合格证据时不生成有效推荐。核对由本例明确规则执行,不表示真实模型一定遵守。

事件记录与固定场地资料

按实际发生顺序记录

    教学数据(不等于模型已经收到)

    场地容量总费用
    松厅24人1800元
    云厅40人2800元
    竹厅32人1900元

    查询甲按20人/3000元,只返回松厅与云厅,不是完整目录;查询乙按30人/2000元,才返回竹厅。所有价格、场地与结果均为固定教学样例。

    异步任务调度台 · 虚构会议场地 / 只查询推荐,不预订 · 教学模拟,动作与状态由同一时间轴驱动。自动讲解使用默认条件;改变下方条件可独立实验。

    登录后收藏评论 0

    登录后发表评论

    暂无评论。