Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Chat SDK

最終更新 Markdown で表示Agent セットアップ

Agent 内で Chat SDK を動かすときは agents/chat-sdk を使います。最初の統合ヘルパーは、Agents のサブエージェントに状態を保存する Chat SDK の StateAdapter です。

アダプターは、Chat SDK のサブスクリプション、ロック、キュー、重複排除キー、スレッド状態、チャネル状態、コールバックのメタデータ、トランスクリプト一覧、スレッド履歴を Durable Object の SQLite に保存します。各状態シャードは、入口となる Agent 配下の ChatSdkStateAgent サブエージェントです。

インストール

メッセンジャー入口をホストする Worker に、両方のパッケージをインストールします。

npm i agents chat

agents/chat-sdk は Chat SDK 向けの耐久性のある状態を提供します。Telegram、Slack、Discord、Teams、Google Chat など、任意の Chat SDK アダプターと組み合わせて使えます。

基本セットアップ

Chat SDK ランタイムを所有する親 Agent を作成します。Chat SDK の state オプションに createChatSdkState() を渡します。

import { Agent } from "agents";
import { createChatSdkState } from "agents/chat-sdk";
import { Chat } from "chat";
import { createTelegramAdapter } from "@chat-adapter/telegram";

export { ChatSdkStateAgent } from "agents/chat-sdk";

export class MessengerAgent extends Agent {
	chat;

	onStart() {
		const telegram = createTelegramAdapter({
			botToken: this.env.TELEGRAM_BOT_TOKEN,
			mode: "webhook",
			userName: "my_bot",
		});

		this.chat = new Chat({
			adapters: { telegram },
			userName: "my_bot",
			state: createChatSdkState(),
			concurrency: { strategy: "burst", debounceMs: 600 },
		});
	}
}
import { Agent } from "agents";
import { createChatSdkState } from "agents/chat-sdk";
import { Chat } from "chat";
import { createTelegramAdapter } from "@chat-adapter/telegram";

export { ChatSdkStateAgent } from "agents/chat-sdk";

export class MessengerAgent extends Agent<Env> {
	private chat!: Chat;

	onStart() {
		const telegram = createTelegramAdapter({
			botToken: this.env.TELEGRAM_BOT_TOKEN,
			mode: "webhook",
			userName: "my_bot",
		});

		this.chat = new Chat({
			adapters: { telegram },
			userName: "my_bot",
			state: createChatSdkState(),
			concurrency: { strategy: "burst", debounceMs: 600 },
		});
	}
}

Durable Object のマイグレーションに、親 Agent を追加します。

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  // Set this to today's date
  "compatibility_date": "2026-09-20",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "MessengerAgent",
        "name": "MessengerAgent"
      }
    ]
  },
  "migrations": [
    {
      "new_sqlite_classes": [
        "MessengerAgent"
      ],
      "tag": "v1"
    }
  ]
}
# Set this to today's date
compatibility_date = "2026-09-20"
compatibility_flags = ["nodejs_compat"]

[[durable_objects.bindings]]
class_name = "MessengerAgent"
name = "MessengerAgent"

[[migrations]]
new_sqlite_classes = ["MessengerAgent"]
tag = "v1"

サブエージェントのルーティングが解決できるよう、Worker のエントリポイントから ChatSdkStateAgent をエクスポートします。createChatSdkState() を Agent のライフサイクルメソッドまたはリクエストハンドラー内で呼ぶと、現在の Agent を親として使い、this.subAgent() で状態シャードを作成します。

状態のシャーディング

デフォルトでは、Chat SDK の状態は、スレッド風キーのコロン区切り先頭 2 セグメントでシャードされます。

たとえば telegram:-100123:456telegram:-100123:789 は、同じ状態シャード telegram:-100123 を共有します。

デフォルトのキーシャーダーは、次の Chat SDK キー接頭辞を認識します。

  • thread-state:
  • channel-state:
  • msg-history:
  • transcripts:user:

未知のキーは、アダプターのデフォルトシャード名 default を使います。

カスタムシャーディング

スレッド ID を状態サブエージェント名へどう対応させるかは、shardKey で制御します。

const state = createChatSdkState({
	shardKey(threadId) {
		return threadId.split(":").slice(0, 2).join(":");
	},
});
const state = createChatSdkState({
	shardKey(threadId) {
		return threadId.split(":").slice(0, 2).join(":");
	},
});

アダプターがスレッド形ではないキーを保存していても、プロバイダー固有のシャードへ振り分けたいときは keyShard を使います。

const state = createChatSdkState({
	keyShard(key) {
		if (!key.startsWith("dedupe:telegram:")) {
			return undefined;
		}

		const chatId = key.slice("dedupe:telegram:".length).split(":")[0];
		return chatId ? `telegram:${chatId}` : undefined;
	},
});
const state = createChatSdkState({
	keyShard(key) {
		if (!key.startsWith("dedupe:telegram:")) {
			return undefined;
		}

		const chatId = key.slice("dedupe:telegram:".length).split(":")[0];
		return chatId ? `telegram:${chatId}` : undefined;
	},
});

undefined を返すと、組み込みのキーシャーダーへ戻り、その後デフォルトシャードへフォールバックします。

API

createChatSdkState(options)

ChatSdkStateAgent サブエージェントをバックエンドにした、Chat SDK の StateAdapter を作成します。

import { createChatSdkState } from "agents/chat-sdk";

export { ChatSdkStateAgent } from "agents/chat-sdk";

const state = createChatSdkState({
	// parent: this // Optional. Defaults to the current Agent from getCurrentAgent().
});
import { createChatSdkState } from "agents/chat-sdk";

export { ChatSdkStateAgent } from "agents/chat-sdk";

const state = createChatSdkState({
	// parent: this // Optional. Defaults to the current Agent from getCurrentAgent().
});

オプション:

オプション 説明
agent 任意。ChatSdkStateAgent のカスタムサブクラス。デフォルトは ChatSdkStateAgent です。
parent 任意。subAgent() を呼んで状態シャードを作る親 Agent。デフォルトは getCurrentAgent() が返す現在の Agent です。
name 対応付けできないキー向けのデフォルトシャード名。デフォルトは default です。
shardKey Chat SDK のスレッド ID とロックキーをシャード名へ対応付けます。
keyShard 汎用の Chat SDK キャッシュキーまたはリストキーをシャード名へ対応付けます。

ChatSdkStateAgent

SQLite に状態を保存するサブエージェントクラスです。ランタイムが作成できるよう、Worker のエントリポイントからエクスポートします。

export { ChatSdkStateAgent } from "agents/chat-sdk";
export { ChatSdkStateAgent } from "agents/chat-sdk";

ChatSdkStateAdapter

createChatSdkState() が返す具体的な StateAdapter 実装です。ほとんどのアプリケーションでは、直接インスタンス化する必要はありません。

保存される内容

アダプターは Chat SDK の StateAdapter インターフェース全体を実装します。

  • thread.subscribe()thread.unsubscribe() のサブスクリプション。
  • スレッド単位またはチャネル単位の同時実行用ロック。
  • queuedebounceburst の同時実行戦略向けの保留メッセージキュー。
  • 任意の TTL 付き汎用キー値キャッシュ。
  • 最大長トリミングとリスト単位 TTL 更新を備えた追記専用リスト。

これらのプリミティブの上に構築される Chat SDK 機能には、次があります。

  • メッセージの重複排除。
  • スレッドとチャネルの状態。
  • persistThreadHistory をオプトインしたアダプター向けの永続スレッド履歴。
  • コールバック URL トークンの保存。
  • モーダルコンテキストの保存。
  • クロスプラットフォームのトランスクリプト。

クリーンアップの動作

TTL の読み取りは厳密です。期限切れのロック、キャッシュ値、キュー項目、リスト項目は、返す前に無視または削除されます。

物理的なクリーンアップは遅延実行です。ChatSdkStateAgent は既知の最短有効期限に対してクリーンアップコールバックを 1 つスケジュールし、実行後に再スケジュールします。アイドルなシャードは静かにしたまま、期限切れ行が無限に溜まるのを防ぎます。

Chat SDK メッセンジャーの例

サブエージェント内の Chat SDK 状態、burst/debounce 同時実行、managed fiber 上で動く Think ベースの AI 返信を使って、Telegram メッセンジャーボットを構築します。

役に立ちましたか?