# まさかのリトライ内蔵！Cloudflare の Agents SDK がすごいことになってる！

おつかれさま、しぃちゃんだよ！今日は Cloudflare の Agents SDK に新しいバージョンが届いてて、中身をのぞいたらリトライ処理がまるっと内蔵されてて驚いちゃった。地味だけど「これ欲しかった」って機能がぎゅっと詰まってるので紹介するね。

## なにが発表されたの？

Cloudflare Changelog にて、Agents SDK v0.5.0 のリリースが発表されたよ。目玉は次の 3 つ。

- 組み込みのリトライユーティリティ(`this.retry()`)
- 接続ごとにプロトコルメッセージの送受信を制御できる機能
- `@cloudflare/ai-chat` の内部を書き直した v0.1.0(data parts、ツール承認の永続化など追加)

Agents SDK は Cloudflare Workers 上でステートフルな AI エージェントを組み立てるためのフレームワークで、今回のアップデートは「エージェントの信頼性」と「チャット UI の使い勝手」を底上げする内容になってるよ。

## 今までどうだったの？

これまでは、外部 API 呼び出しなどが一時的に失敗したときのリトライ処理は自分で書く必要があったの。指数バックオフやジッターを実装するのは地味に面倒だし、キューやスケジュール済みタスクにリトライ設定を持たせたいときも、独自のロジックを組むしかなかったんだよね。

WebSocket 接続まわりも、これまでは全ての接続に対して ID・状態・MCP サーバー一覧などの JSON プロトコルメッセージが自動で送られる仕様だった。バイナリだけをやり取りしたい組み込み機器や MQTT クライアントを繋ぐときには、この余計なメッセージが邪魔になるケースもあったみたい。

`@cloudflare/ai-chat` も、ページ再読み込みや Durable Object の休止をまたぐとツールの承認状態が消えてしまったり、ストリーム再開のタイミングで競合が起きたりと、細かい不具合が積み重なっていたよ。

## これで何が変わるの？

まず、不安定な外部サービスを呼ぶ処理に `this.retry()` を挟むだけで、指数バックオフとジッター付きの再試行が使えるようになったよ。エージェント開発者が自前で書いていたリトライロジックを、SDK 標準の仕組みに置き換えられるのが嬉しいポイント。

WebSocket を使う組み込み機器・IoT系のクライアントを繋ぐ人にとっては、余計なプロトコルメッセージをオフにできるので通信がすっきりするはず。

チャット UI を作っている人には、`@cloudflare/ai-chat` v0.1.0 の恩恵が大きいよ。ツールの承認待ち状態がページ更新後も残るようになったから、ユーザーが操作をやり直す手間が減るし、data parts のおかげでメッセージに型付きの構造化データを乗せられるようになったの。

うれしいのは、破壊的変更が無いこと。既存の `AIChatAgent` や `useAgentChat` はコード変更なしでそのまま動くよ。

## 深く潜ってみよう

`this.retry()` は非同期関数と、`maxAttempts`(最大試行回数)や `shouldRetry`(リトライするかどうかを判定する述語関数)を持つオプションを渡して使うよ。

```js
const data = await this.retry(() => callUnreliableService(), {
  maxAttempts: 4,
  shouldRetry: (err) => !(err instanceof PermanentError),
});
```

リトライ設定はタスク単位でも渡せて、`queue()` / `schedule()` / `scheduleEvery()` / `addMcpServer()` にオプションとして指定すると、その設定が SQLite に永続化される。

```js
await this.schedule(
  Date.now() + 60_000,
  "sendReport",
  { userId: "abc" },
  { retry: { maxAttempts: 5 } },
);
```

クラス単位でデフォルトのリトライ挙動を決めておくこともできるよ。

```js
class MyAgent extends Agent {
  static options = {
    retry: { maxAttempts: 3 },
  };
}
```

リトライオプションはキューやスケジュールに登録した時点でバリデーションされる仕組みなので、設定ミスに早めに気づけるのもポイント。ワークフロー系の内部処理にもリトライが追加されたよ。

プロトコルメッセージの制御は、`shouldSendProtocolMessages()` を実装することで接続ごとに ON/OFF できる。

```js
class MyAgent extends Agent {
  shouldSendProtocolMessages(connection, ctx) {
    const subprotocol = ctx.request.headers.get("Sec-WebSocket-Protocol");
    return subprotocol !== "mqtt";
  }
}
```

現在の状態は `isConnectionProtocolEnabled()` で確認でき、この設定は Durable Object が休止しても保持される。

`@cloudflare/ai-chat` 側では、`ResumableStream` クラスと WebSocket 用の `ChatTransport` を新設し、SSE のパース処理も整理し直したとのこと。追加された機能はこんな感じだよ。

- data parts: `data-*` という型付き JSON データをメッセージに付加できる。型と ID を合わせてインプレース更新したり、追記したり、一時的なパーツとして扱うこともできる
- ツール承認の永続化: 承認待ち状態のツールがページ更新や DO 休止をまたいでも保持される
- `maxPersistedMessages`: SQLite に保存するメッセージ数の上限を設定し、超えた分は自動削除
- `useAgentChat` の `body` オプション: すべてのリクエストに共通データを添えて送れる
- 段階的な永続化: ハッシュベースのキャッシュで、変化のない SQL 書き込みをスキップ
- 行サイズ保護: SQLite の 1 行 2 MB 上限に対して 2 段階の圧縮処理を用意
- `autoContinueAfterToolResult` のデフォルトが `true` に変更され、クライアント側のツール結果や承認が自動でサーバー処理の続行をトリガーするようになった

バグ修正としては、ストリーム再開時の競合状態、DO 休止後にクライアント側ツールのスキーマが失われる不具合、ツール承認後に発生していた `InvalidPromptError` などが解消されたよ。ほかにも、`getQueue()` や `getSchedule()` のような同期 SQL 操作だけのメソッドから不要な `async` が外され、長時間実行ツール中に接続が切られないよう POST の SSE に 30 秒おきの `event: ping` キープアライブも入ったの。

アップグレードはいつも通りパッケージを更新するだけ。

```sh
npm i agents@latest @cloudflare/ai-chat@latest
```

## まとめ

- `this.retry()` で指数バックオフ + ジッター付きのリトライが標準機能に
- `queue()` / `schedule()` / `scheduleEvery()` / `addMcpServer()` にリトライ設定を渡せて SQLite に永続化される
- クラスの `static options` でデフォルトのリトライ方針をまとめて指定できる
- `shouldSendProtocolMessages()` で接続ごとにプロトコルメッセージの送信を制御可能
- `@cloudflare/ai-chat` v0.1.0 は内部を書き直しつつ破壊的変更なし。data parts やツール承認の永続化、`maxPersistedMessages` などが新規追加

Cloudflare Workers 上でエージェントやチャット UI を組んでいる人には、地味だけど確実に開発体験が良くなるアップデートだと思う。次のデプロイのついでに `npm i agents@latest` 、試してみてね。
