让 AI 自动化脚本可重试、可验证、可回滚
把 LLM API 接进脚本并不难:发送请求、读取文本、写入文件即可。真正困难的是让它可以重复运行。网络会超时,服务会限流,模型可能返回语法正确但业务错误的数据,脚本也可能在完成一半时退出。如果每次失败都靠人工检查现场,这只是一次性演示,不是可靠自动化。
先给一次任务稳定身份
每次执行生成 run_id,每个业务输入再计算稳定的 item_key。请求日志、输出文件、检查点和写入记录都携带这两个标识。重启后脚本先读取检查点,已完成且校验通过的项目直接跳过,正在处理的项目重新判断,而不是盲目从头发送所有请求。
对外部写操作使用幂等键。若目标 API 不支持幂等,则先查询目标状态,再通过本地事务日志记录“准备写入—已写入—已验证”三阶段。这样网络在响应返回前断开时,程序不会因为不知道结果而重复创建资源。
重试要区分错误
并非所有失败都应该重试。连接超时、临时网关错误和限流通常可以退避重试;身份验证失败、输入超限和 schema 不兼容应立即停止。退避加入随机抖动,避免多个任务同时再次冲击服务,并尊重服务返回的等待提示。
RETRYABLE = {408, 429, 500, 502, 503, 504}
for attempt in range(max_attempts):
try:
return call_api(payload, idempotency_key=item_key)
except ApiError as exc:
if exc.status not in RETRYABLE:
raise
sleep(backoff(attempt, retry_after=exc.retry_after))
raise RetryBudgetExceeded(item_key)
重试预算同时限制次数和总时长。日志记录每次失败类别与等待时间,但不输出令牌、完整请求头或敏感输入。
结构化输出必须再次校验
即使 API 支持 JSON Schema,也要在本地重新验证。语法通过后继续检查业务约束,例如文件路径是否位于允许目录、标识符是否唯一、日期范围是否合理、引用对象是否存在。模型给出的解释文本与执行参数分开保存,只有参数通过全部检查才进入写入阶段。
解析失败可以把最小错误摘要反馈给模型做一次修复,但修复同样消耗重试预算。连续失败的原始响应保存为脱敏样本,进入人工处理队列,不能用空值默默替代。
写入前建立可逆边界
修改文件时先保存原始哈希和副本,在同一目录生成临时文件,完成语法和内容检查后再原子替换。修改数据库时优先使用事务;跨系统操作则使用补偿动作,并明确哪些步骤不可自动撤销。
读取与校验 -> 生成候选结果 -> 本地验证
-> 保存原状态 -> 应用修改 -> 验证目标状态
└─ 失败:执行补偿并验证恢复
回滚脚本不能只存在文档里。它要在另一份测试副本上运行,确认旧哈希、旧字段和旧行为均恢复,再允许生产任务启用写入模式。
观测与验收
每次任务输出输入数量、成功数量、跳过数量、重试次数、失败分类、产物路径和最终退出码。成功条件是目标状态通过独立读取验证,而不是请求返回 200。失败时保留未完成队列,下一次运行能从检查点继续。
- [x] 相同输入重复运行不会生成重复资源
- [x] 429、超时和临时 5xx 按预算退避重试
- [x] 401、schema 错误和越界路径立即停止
- [x] JSON 通过语法与业务规则双重校验
- [x] 中途强制退出后可以从检查点继续
- [x] 修改前保存原状态,回滚在副本上实际验证
- [x] 日志能定位任务,同时不泄露凭据
可靠的 AI 自动化不是相信每一次输出,而是把不确定结果包在确定流程里:输入有身份,错误有分类,输出有 schema,写入有边界,结果有独立验证,失败有恢复路径。模型负责生成候选内容,程序负责决定它是否能够进入真实系统。
评论区