你将做出一个可重放事件的工作流应用,处理草稿、人工批准、执行、临时失败和重试。最终网页能接收事件列表,给出发布记录、实际尝试次数与被阻止次数。本课中的发布只写返回结果,不会向任何外部平台发送信息。建议分三次学习,约180分钟。
1. 把模型建议与执行状态分开
需要 Python 3.10+(Windows 若找不到 python,可用 py -3 代替),运行 python verify.py 看起始代码失败。每项失败只显示期望与实际的字段差异;卡住时先在项目页逐层展开分层提示,仍无法定位再运行 python verify.py --explain 查看诊断。模型未来可以提出操作建议,真正是否允许执行必须由程序状态决定。输入为JSON对象,events最多100条,允许的type只有draft、approve、publish。
初始state为empty,可能的state为empty、draft、approved、published。draft要求非空text(字符串,不能只含空白,最多10000字符),保存为当前草稿并进入draft状态,使之前批准失效——即使新正文与旧正文完全相同。approve仅能将draft变为approved;其他状态(empty、approved、published)收到approve,blocked加1。publish要求非空key(字符串,不能只含空白,最多64字符),可选fail必须为布尔值,缺省为false。
以下属于整份输入非法,抛ValueError,不返回部分结果:输入不是对象、events不是列表或超过100条、某个事件不是对象或type不在允许列表、draft的text不合格、publish的key不合格、fail不是布尔值(字符串 "false" 也不行)。
输出为 {"state": 最终状态, "published": 成功记录列表, "attempts": 真正执行次数, "blocked": 被拦截次数},published 每项为 {"key": 请求标识, "text": 发布时的正文},按首次成功的先后排列。
{"events":[{"type":"draft","text":"下周体验课开放报名。"},{"type":"publish","key":"notice-001"}]}
这个输入的结果应为draft,published为空,attempts为0,blocked为1。拒绝执行必须发生在尝试调用工具之前。
2. 实现批准与执行
先实现draft和approve分支,再实现publish。只有approved状态能真正尝试发布;此时attempts加1。fail=true模拟临时失败,保留approved以便重试,不写成功记录。成功时写入key与当前text,进入published。
给编程助手的完整首轮任务:
实现solution.py中的solve(payload),将events作为状态机逐个处理。使用明确的工具允许列表,不调用eval、exec或shell。先校验每种事件字段,再按README定义更新状态。将被拒绝次数blocked与真正执行次数attempts分开。只修改solution.py,保持project.json与verify.py不变。实现后解释每一种事件为什么允许或拒绝。
本地教学程序是单用户模拟,approve事件代表已完成的人工确认;生产系统必须从已鉴权的管理员会话生成此事件,不能相信模型输出或任意客户端自己填写“已批准”。
3. 让重试不会产生重复操作
使用成功记录字典保存key与text。publish校验字段后,先检查key是否已有成功记录,再检查批准状态:相同key和相同正文(与当前草稿比较)再次到来时,视为重复请求,不增加attempts也不增加blocked,不新增发布,即使此时state已是published;相同key但正文不同则blocked加1(只计一次),旧记录保持不变。只有key没有成功记录时才检查state是否为approved。
修改草稿之后,即使以前已批准,仍应要求新的approve。检查changed和key_conflict两项:前者防止旧审批被新正文借用,后者防止旧请求标识被新任务借用。这两个条件不能互相替代。
4. 做一次完整故障演练
运行 python run.py 并打开终端地址,依次选择未经批准、修改正文、临时失败、重复请求四种用例。观察实际attempts和blocked的变化,下载结果。