能把事情做完的 Replicate Webhook。

你的处理程序要保存输出、通知用户,可能还要再串一次运行。AnyHook 在边缘节点应答 Replicate,所以这些都不必在 Replicate 的投递时限内完成。

时限问题

模型运行完成时,Replicate 会发出一个 Webhook。这部分没问题。问题在于你想拿结果做的事:持久化产物、通知用户、扇出到第二个模型、发一条 Slack 消息。

每一步都是一次网络往返,加在一起可能比请求本身还长。Replicate 会重试,最后一次重试大约在预测完成一分钟后到来。你的下游副作用要么执行两次,要么一次都不执行。AnyHook 在边界上解决这个时限问题,让你的处理程序保持线性、直观。

60 秒–5 分钟
Replicate 运行耗时(视频模型)
约 1 分钟
预测完成后,Replicate 发出最后一次重试的时间
重放
一键重新处理历史运行
加密
输出 URL 以 AES-256-GCM 加密保存

通过 AnyHook 接收 Replicate 运行完成回调

创建预测时,把 AnyHook 的接收 URL 作为 `webhook` 参数传入。下游的处理程序有足够的时间去扇出。

import Replicate from "replicate";
import { verifyWebhook } from "anyhook-verify";

const replicate = new Replicate();

// 1. Start the prediction with AnyHook as the callback target.
await replicate.predictions.create({
  version: "...",
  input: { prompt: "..." },
  webhook: `https://in.anyhook.net/${userSlug}/${appSlug}`,
  webhook_events_filter: ["completed"],
});

// 2. Handler, runs after AnyHook has already acked Replicate.
export async function POST(req: Request) {
  if (!(await verifyWebhook(req, process.env.ANYHOOK_SIGNING_SECRET!))) {
    return new Response("invalid", { status: 401 });
  }

  const { id, output } = await req.json();
  await persistOutput(id, output);   //  3s
  await notifyUser(id);              //  2s
  await chainNextModel(output);      // 45s, inside even Free's 60s
  return new Response("ok", { status: 200 });
}

团队常问的问题

适用于所有 Replicate 模型类型吗?
适用,图像、视频、音频、语言模型都可以。Webhook 约定完全相同。AnyHook 把请求体当作不透明的 JSON,原样转发。
Replicate 已经有重试了,为什么还需要 AnyHook?
Replicate 会在传输失败时重试,但它的时间窗口很短,而且只重试 Webhook 投递,不会重试你的下游业务逻辑。AnyHook 按指数退避重试你的处理程序,Scale 套餐最多 10 次;只要你的套餐还保留着某个事件,就可以一键重放它。
不回 Replicate 查,也能看到预测输出吗?
可以。完整的 Webhook 请求体(包括 `output` 里的 URL)都加密保存在你的 AnyHook 事件日志里:在控制台打开,或者用 GET /api/v1/events/{id} 读取。
AnyHook 会验证 Replicate 的签名吗?
会,前提是你完成了设置。Replicate 使用 Standard Webhooks 签名方案(webhook-id、webhook-timestamp、webhook-signature)。把 App 的来源设为 Standard Webhooks,粘贴从 Replicate 的 GET /v1/webhooks/default/secret 拿到的密钥:伪造的请求会在边缘节点被拒收。

只改一个 URL。Replicate 处理程序不用动。

Free 套餐包含每月 10,000 个事件。无需 SDK:把 Replicate 指向你的 AnyHook 接收 URL。