设计经得起重试的异步记忆写入

设计经得起重试的异步记忆写入
2026年8月5日指南阅读约 12 分钟

当模型工作超过 HTTP 生命周期时,用回执、幂等、终态、重试与计费组成可运营的写入协议。

记忆提取不是普通数据库插入。客户端超时后,模型供应商仍可能已经接受任务;队列可能重复投递;worker 也可能在提交记录后、确认消息前崩溃。如果 API 把这一切伪装成一次同步请求,客户端就无法判断应该重试、等待还是报警。

可靠的写入协议必须把“已接受”和“已完成”分开。HTTP 请求创建唯一命令身份并返回回执;持久任务拥有执行过程;终态事件拥有最终结果。

先说结论

  • 接受推断写入前要求幂等键。
  • 模型工作开始前,先持久化命令并预留托管用量。
  • 返回 HTTP 202 和持久事件身份,不伪造一条已经完成的记忆。
  • 把队列投递视为唤醒;数据库中的任务和租约才是权威。
  • 规范记录只提交一次,并公开明确的成功或失败终态。
  • 计费从同一个持久结果结算:成功只扣一次,终态失败只退一次。

最危险的是结果不明确的时间窗

假设客户端提交推断记忆并等待五秒,供应商调用用了六秒。第五秒客户端看到超时,第六秒 worker 提交了两条记忆。如果客户端没有稳定命令身份就重试,系统可能再次推理并产生重复;如果完全不重试,用户又会以为写入丢失。

协议必须让这些状态可区分:

状态它能证明什么客户端的安全动作
Accepted命令已经持久记录保存回执并观察事件
Pending目前没有 worker 持有有效租约等待;修复任务或分发器可以重新认领
Running一个 worker 持有未过期租约不要创建第二条命令
Succeeded规范记录及必要状态已经提交读取结果
Failed自动执行到达不可继续的错误检查错误;必要时显式授权重试

调用模型之前,先提交命令

FishMem Cloud 会验证请求、绑定已认证工作区、计算规范化命令哈希、声明幂等键、预留额度,并创建一条 memory_infer 操作任务。只有完成这些步骤后才分发工作。HTTP 返回 202,是因为系统已经接受对命令的责任,而不是因为工作已经结束。

任务负载携带结构化作用域、推理输入、幂等身份和托管用量授权,即使原始 HTTP 请求早已消失也能执行。成功完成后,持久任务里的敏感原始输入会被命令指纹和审计、重放所需的最小结果证据替代。

幂等性是一份命令契约

幂等键不是“以后帮我去重”的提示,而是规定一个调用意图只有一个身份。

  • 相同键、相同规范化命令:返回或继续原操作。
  • 相同键、不同命令:明确冲突。
  • 不同键、相同文本:除非产品另有规定,否则视为不同意图。

哈希应覆盖语义命令字段,而不是传输噪音。作用域、推理模式、消息内容和记忆选项会改变命令;请求编号、连接时间和重试计数通常不会。

队列不是任务存储

Cloudflare Queue、定时任务或其他分发器可以唤醒 worker,但投递消息不能是任务存在的唯一证据。消息会重复、延迟或耗尽。持久任务需要记录尝试次数、状态、租约所有者、租约过期时间、下次尝试、终态错误和最终结果。

worker 通过比较并交换的语义认领任务。worker 崩溃后,另一个 worker 可以接管过期租约;队列消息没到时,定时修复会找到 pending 任务重新分发。两条路径最终都汇聚到同一个操作身份。

冻结准备好的写入计划

重新调用模型可能得到不同事实。在任何规范写入发生前,这种变化也许可以接受;发生部分提交后就不安全。FishMem 核心日志会先冻结稳定记录 ID 与待执行变更计划,再完成各类投影。重试时重放相同计划,而不是产生第二种解释。

操作日志分别跟踪规范状态和投影状态。如果记录已经提交但向量写入失败,重试会为现有记录修复向量,不会再添加一次记忆。

终态必须携带足够的结果证据

客户端不应依赖读取 worker 日志来判断结果。Event API 提供持久任务的隐私安全投影,包含状态、尝试次数、时间、错误与结果引用。SDK 可以提供等待完成的便利方法,但任何保留事件 ID 的客户端都能直接观察底层资源。

错误类型要稳定到足以驱动决策:

  • 输入无效:修正请求,不自动重试;
  • 幂等冲突:排查调用方为何复用了命令身份;
  • 供应商或临时基础设施错误:执行有上限的重试;
  • 授权或计费失败:要求新的有效授权;
  • 终态提取拒绝:明确展示没有记忆被提交。

计费必须属于同一套协议

托管推理不能让任务状态和资金状态各说各话。FishMem 在入队前预留所需额度;终态成功时只结算一次;终态失败时释放预留并在请求账本记录退款。人工重试必须在执行前重新授权,旧失败任务不是对未来额度的无限领取权。

这样可以避免三种结果:没有运行却收费、成功提交后又退款,以及模糊重试造成重复收费。

按失败类别设计重试策略

失败自动重试?原因
供应商在返回结果前超时有上限,且命令仍安全时可能是暂时错误;幂等任务控制重复
结构化输出无效仅按明确提取策略重复提示未必能修复语义不匹配
额度不足需要新的授权或套餐变更
投影写入失败修复已有规范记录
幂等冲突调用方用一个身份提交了两条命令

发布前需要主动制造的故障

  1. 在完成前、执行中和完成后重复同一请求。
  2. 修改负载后复用同一键,确认得到冲突。
  3. 分别在推理前、推理后、规范提交后终止 worker。
  4. 丢弃队列投递,确认修复任务能找到持久操作。
  5. 让租约过期,确认只有一个新 worker 成功接管。
  6. 强制投影失败,确认重试不会复制规范记录。
  7. 确认成功只扣一次、终态失败只退一次。
  8. 成功后移除原始任务输入,同时确保事件仍可解释。

API 边界

infer=false 是同步确定性写入,因为调用方已经提供要保存的记录;infer=true 默认异步,因为模型工作可能超出 HTTP 生命周期并独立失败。混合两条路径,要么会让确定性写入承担不必要复杂度,要么会让推断写入假装同步完成。

延伸阅读

继续阅读