a↗Agent 工程实战中文课程 / v1.0.0⌕ 搜索课程/
本页目录

L05 参考解:将对话原型服务化:任务、审批、事件流

这是可讨论的参考设计,不是唯一架构。先完成实验题面,再对照本解。

关键推导

创建Run与“以后记得发消息”必须原子绑定。Outbox并不把网络投递变成exactly-once;它把“可能丢掉要做的事”转换为“允许重复传递同一件事”。重复消费再由请求/运行幂等性控制。

审批必须被表示为一个持久对象,不是循环内input()。提案内容改变后需要重新批准;过期边界是now>=expires_at无效。审批已消费后的重复确认不应产生新操作。

参考RunLedger刻意只实现创建、抢占、受fence保护的worker状态更新、事件读取和Outbox记录。完整API、等待恢复、取消与reconciler是本实验需要补齐的项目层;不能把这个内核伪装成完整工作流引擎。

参考算法与实现位置

BEGIN
  INSERT run UNIQUE(tenant,user,request_key)
  INSERT event(run,seq=1,type=created)
  INSERT outbox(run,kind=dispatch)
COMMIT

publisher: read pending → publish same message_id → mark sent
consumer: deduplicate message/run → acquire execution ownership → run

SSE每个事件使用稳定id;页面刷新后先读取快照,再衔接游标事件,处理快照与流之间的版本边界。

应当得到的可检查结果

故障/动作 期望
同key同请求POST两次 同run_id,仅一条初始Outbox
同key不同请求 409语义冲突
事务提交后未投递进程退出 Outbox仍可恢复投递
投递成功但未mark_sent 允许重复投递,消费者必须去重
after_seq=1重连 只回seq>1;客户端仍处理重复网络帧
等待审批时claim NOT_RUNNABLE
其他租户读run/events NOT_FOUND

怎样判断替代实现是否等价

替代实现必须保留题面中的身份来源、状态归属和失败语义。数据库/框架可以更换,但应把相同故障窗口重新跑一遍。只在正常路径输出一致,不足以证明恢复与授权等价。异步或并发实现还必须解释取消传播、竞争窗口和资源回收。

常见错误与修正

第一类错误是把协议或框架提供的局部保证放大成业务保证:格式正确不等于授权,执行结束不等于业务成功,持久化不等于外部副作用恰好一次。修正方式是找到事实源并把不变量放在拥有该事实的层。

第二类错误是用演示数据替代证据。已有fixture可以检查确定性公式与状态机,但真实模型、网络或容器的结论需要实际运行。报告同时写出“已验证”“仅模拟”“未验证”,比宣称全部完成更有工程价值。

实现范围与限制

没有交付FastAPI服务、认证系统、消息Broker或浏览器SSE实现;它们的字段、错误语义与验收条件已完整规定,需在个人项目/网页开发中实现。教学网站本身不必部署这些危险服务,可用纯状态机展示。

开放题评分要点

事务/幂等25;审批25;事件与重连20;权限15;服务边界与测试15。 正确的反例、失败分析和替代方案论证应获得分数;框架堆叠、只报最终成功截图、删除失败成本不应获得同等评价。