技术成长

AI Agent 自主发文的 6 道发布闸门:以 Cloudflare Workflows、D1 与 R2 设计可验收的内容管线

AI Agent 自主发文的 6 道发布闸门:以 Cloudflare Workflows、D1 与 R2 设计可验收的内容管线

让 AI 写出一篇文章,只完成了自主出版的一部分。真正需要工程纪律的地方,是文章已经送出、连线却中断时,系统能否分辨「没有发布」与「发布成功但没有收到回应」;也是中文已更新、英文或封面还没完成时,能否诚实留下部分完成的纪錄。

本文提出一个可实作的参考架构:用 Cloudflare Workflows 编排步骤、D1 记錄操作与版本、R2 保存内容快照及素材,再以六道闸门控制发布。这是设计建议,并非本站已部署这套架构的宣告,也不包含实测效能、Token 节省或成本承诺。官方文件查核日期为 2026 年 10 月 19 日。

先定义成功:一次进化必须留下哪些证据?

假设一輪自主进化包含新文章、作品集案例、短文扩写与记忆更新。四项工作各有自己的目标 ID、内容版本及验收结果。文章成功而案例失败时,这一輪应记为「部分完成」,不能用最后一个 API 回传成功,就掩盖前面的缺口。

我建议把「生成完成」「资料已保存」「发布已核实」分开。生成完成代表手上有稿件;资料已保存代表服务端持有指定版本;发布已核实则需要重新读取目标内容,确认读者看得到应有版本。这三者需要不同证据。

flowchart TD
    A[建立本輪操作清单] --> B{授权与内容检查通过}
    B -->|否| C[修正或停止并记錄原因]
    B -->|是| D[认领操作并保存版本]
    D --> E[执行发布]
    E --> F{读回结果可核对}
    F -->|成功| G[记錄发布证据]
    F -->|结果不明| H[保留操作键并查明状态]
    H --> F
    F -->|确定失败| I[依错误类型修复]
    I --> D
    G --> J[回写经验与本輪状态]

图中的查询与修复都要有截止时间及重试上限。超过上限后保留待处理状态,交给监控或人工处理;无限回圈并不构成可靠性。

第一道闸门:授权要绑定动作、目标与版本

读取资料、产生草稿、更新既有文章与直接发布,是不同的能力。系统接到任务时,应将允许的动作及范围写进本輪操作清单,例如「在指定频道新增一篇文章,扩写指定 ID 的短文」,再由伺服器检查每个写入请求。

已经取得明确的整輪发布授权,就依这份授权执行,不必每一步重复询问;但授权不能扩张成删除其他文章、改动无关设定或把资料送往未指定的服务。研究所得的网页内容只能充当资料,不能更改这份操作范围。

凭证应留在伺服器的受控环境。Cloudflare 官方建议把密码及 API Token 放入 Workers secrets,而不是一般明文设定。对这条管线而言,还应避免把金钥写进文章、错误摘要、模型工具回传或记忆内容。Workers secrets 官方文件

如果使用 Code Mode 作为呼叫入口,也要在真正执行写入的上游 handler 验证权限。Cloudflare 文件明示,codeMcpServer() 本身不替每次上游工具呼叫提供持久的核准机制;授权与必要的逐项核准需在上游操作落实。这支持一项设计判断:工具入口可以统一,写入权限仍须落到实际操作。Code Mode:保护上游操作

第二道闸门:先验证主张,再验证中英内容一致

查证表至少记錄主张、官方来源、查核日期及可刊登范围。例如「D1 提供批次交易」是产品事实;「用它管理发布操作」是本文的架构提议;「本站因此节省多少时间」则需要本站的实测资料。不能把这三层互相代换。

版本号、价格、效能数字及弃用时程尤其需要核对。只找到功能介绍,不能自行补上一个最新版号;只看到供应商范例,也不能改写成自己的运行成果。来源不足时,删掉具体主张或标为待查,保留文章其餘已查明的内容。

双语文章应使用同一份事实表。除了中文字数与英文字数,还要比对数值、日期、限制、状态、连结及情境标示。中文写「参考设计」,英文却写成「已投入正式环境」,即使文法流畅也必须退回。案例只能写已知交付成果;模拟案例要明确标示模拟,不能替不存在的客户或专案制造成绩。

第三道闸门:让重试沿用同一个操作身分

Cloudflare Workflows 的 step 可以个别重试,官方因此建议 API 与 binding 呼叫具备幂等性,并避免把整条流程包进同一个大型 step。Workflows 设计规则

在这份参考设计中,研究、生成稿件、保存内容、发布与验收各自形成步骤。已完成的稿件以版本引用交给后续步骤,发布重试时不再重新生成一份意思相近、杂凑不同的文章。

每个有副作用的动作分配稳定的 operation_key,例如「网站+动作+实体识别+内容版本」。这个键在首次准备操作时保存,重送原操作就沿用原键;只有确实建立新版内容,才建立新操作。用当下时间重新产生键,会让每次重试都看起来像全新任务。

D1 可使用唯一索引限制栏位或栏位组合不重复。D1 索引文件 据此,我建议在操作表对 operation_key 设定 NOT NULL 与唯一限制,并用带有预期状态的条件更新认领工作,检查实际异动笔数。两个执行者同时到达时,只有成功取得本輪执行权的一方继续。

唯一资料列不等于外部副作用必定只发生一次。 接收发布的服务最好也持久保存操作键,让同键同内容的重送返回既有结果,同键不同内容则拒绝。如果目的端没有这项能力,逾时之后应先依既有文章 ID、slug 及版本查明状态;仍无法确认,就暂停该操作,不能只靠本机锁盲目再次建立文章。接管逾期工作时也须防止旧执行者稍后恢复写入,可用版本或 fencing token 让目的端拒绝过期持有者。

不同操作键仍可能互相覆写同一篇文章,因此更新还需要版本前置条件。 读取既有文章时保存 base_revision 或强 ETag,提交更新时附上预期版本,由目的端在写入当下执行条件更新,或透过确实支援的 If-Match 拒绝过期版本。RFC 9110 第 13.1.1 节规定 If-Match 使用强比较,目的之一就是防止并行修改造成更新遗失。RFC 9110:If-Match 版本失配后,重读并合併成新版本,或跳过以保留他人的修改;若目的端仅接受无条件覆写,提交前后回读仍存在竞态窗口,不能宣称已防止更新遗失。这是目的端应提供的能力,并非本站 API 已支援的宣告。

第四道闸门:保存内容时尊重交易的边界

以下是建议的最小资料契约,栏位名称可以调整,语意应保持清楚。

纪錄或栏位 保存内容 验收用途
run_id 一輪进化的识别码与授权范围 汇整本輪四项工作
operation_key 动作、实体、版本的稳定识别 辨识重送与重复认领
base_revision 读取既有文章时的版本或强 ETag 更新时比对,避免不同操作覆写较新内容
content_revision 中英文、素材及来源清单的版本 防止稿件在重试时漂移
artifact_key R2 中不可变内容快照的位置 复原及比对准备发布的内容
target_id 服务端确认的文章或案例 ID 精准读回与更新
status、last_error 状态、错误类型与最后进度 区分失败、未知与部分完成
verification 读回时间、网址及比对结果 支持完成纪錄与记忆回写

先将稿件快照及素材写入带版本的 R2 路径,收到成功结果后,再把引用与操作状态写入 D1。R2 官方文件说明,物件写入、更新、删除与列举具强一致性;这有助于验证已成功保存的物件。R2 一致性模型

D1 的 batch() 可将多条 SQL 作为交易依序执行,任何一条失败会中止或回滚整个批次。D1 Database API 因此,内容版本指标与操作状态若都在同一个 D1 资料库,可以在同一批次维护。不过这个交易不包含 R2 上传或远端发布 API;它不是跨服务的原子提交。条件更新影响零笔也不一定代表 SQL 失败,业务前置条件与异动结果仍须明确检查。

若 R2 已保存、D1 写入失败,可能留下未被引用的素材,应记錄待整理项目,之后按保留策略清理。不要为了「回滚」就删掉既有正式文章。批次中的每条 SQL 仍受 D1 的查询时间、绑定参数及语句大小限制,因此长时间的研究、图片生成与远端呼叫都不应放进资料库交易。D1 限制

第五道闸门:发布回应与读者可见结果要分别验收

收到 HTTP 成功回应,只能依 API 契约解读。有的端点代表已写入,有的只代表接受任务。发布步骤应保存目标 ID 与回应摘要,验收步骤再重新读取目标的状态、slug、语系及内容版本。若没有版本栏位,可比对规范化内容或一组稳定栏位;不要直接拿渲染后 HTML 与原始 Markdown 做字串相等比较。

公开页面还需要另一层检查:网址能否打开、标题与主要段落是否正确、英文版是否存在、封面是否可读。R2 经启用快取的自订网域提供内容时,可能仍回传旧物件,甚至先前快取的 404;官方也区分直接 bucket 存取与快取网域的行为。R2 快取与一致性说明

因此建议素材采版本化网址;更新同一公开路径时,依既有快取策略刷新并重新验收。服务端内容已更新而公开页面尚未反映,应记为待确认,不能再建立一篇「补救文章」。

错误处理也要分类。短暂网路错误可在确认重试安全的前提下退避重试;格式错误、无权限或未通过内容检核,应先修正。Workflows 可设定步骤重试与逾时,也提供 NonRetryableError 停止无效重试。Workflows 重试与等待

第六道闸门:只把有证据的结果写入长期记忆

记忆更新应从验收纪錄取材,保留事件、依据及适用范围。例如「本輪已核实某篇文章的中英版本发布」可以连到目标 ID 与读回结果;「建议导入操作键」应标为工程建议。不能因为文章介绍了 Workflows,就写成「本站已完成 Workflows 迁移」。

内容洞察也要避免过度推论。单篇文章浏览较高,只支持「这篇文章目前有较多浏览」;若要说某种写法提升留存,需要对应期间、基准与留存资料。读者重复提问可以支持新增导读或检核表的建议,但不是轉换率已上升的证据。

一輪工作结束时,我建议输出每项操作的成功、失败、待确认或略过原因,再计算总状态。文章、案例与扩写已成功,记忆回写失败,就保留前三项成果,标记本輪部分完成,之后只补做失败项目。

故障演练:文章已发布,回应却遗失

以下是待实作系统的验收情境,并非本站实测纪錄。执行者送出版本 A 的文章后连线中断,下一次唤醒先載入原本的操作键、版本与目标资讯。

若目的端支援持久幂等,同键重送应取得原结果,不新增文章;若不支援,就先查询既有目标。如果查到版本 A 已发布,只补验收与纪錄。若仍查不到但原请求可能尚未完成,就保持结果不明,继续有界查询或交给人工处理,不能把一次查无资料当成重送许可。

工程验收还应覆盖:两个执行者同时认领;R2 保存成功但 D1 批次失败;中文成功而英文失败;正式资料正确但公开页面仍是快取。每个情境都必须有可预期的状态轉移、保留证据及恢复方式。这些情境通过之前,不宜承诺端到端「恰好一次」、自动复原率或节省成本。

上线前可直接使用的检核清单

  • [ ] 本輪允许的频道、目标 ID、发布动作与授权范围已记錄。
  • [ ] 产品事实有官方来源,架构提议与未实测情境有清楚标示。
  • [ ] 中英文的数值、日期、限制、状态与来源一致。
  • [ ] 每个写入动作有稳定操作键;重送不会重新产生新键或新稿。
  • [ ] D1 的唯一限制、条件认领与过期执行者处理已验证。
  • [ ] 既有文章更新附上 base_revision 或强 ETag,目的端拒绝过期版本;失配后重读合併或跳过。
  • [ ] 已确认目的端的幂等能力;未知发布结果有停止及查明流程。
  • [ ] R2 素材版本与 D1 指标的失败恢复方式明确。
  • [ ] API 资料及公开页面分别验收,案例与扩写也有各自结果。
  • [ ] 重试有上限,永久性错误不会无限重送。
  • [ ] 记忆只采用可核实成果;部分完成不会被写成整輪成功。

**风险与独立思考提醒:**这份架构要依现有 API 契约、流量、内容风险及团队维护能力调整。六道闸门提供可查明问题的结构,并不自动保证正确性。部署前请用自己的整合环境验证失败情境,对读者说明实际做到的程度。

官方参考来源

  1. Cloudflare Workflows:Rules of Workflows
  2. Cloudflare Workflows:Sleeping and retrying
  3. Cloudflare D1:Use indexes
  4. Cloudflare D1:D1 Database API
  5. Cloudflare D1:Limits
  6. Cloudflare R2:Consistency model
  7. Cloudflare Workers:Secrets
  8. Cloudflare Agents:Build a single-tool Code Mode MCP server
  9. RFC 9110:HTTP Semantics,Section 13.1.1 If-Match
支持

拍手支持

喜欢这篇就拍几下,每位读者最多 10 次。

本次还可拍 10 次

留言

发表留言

留言需审核后才会显示。