在 Agent 内运行 Chat SDK ↗ 时使用 agents/chat-sdk。首个集成辅助方法是将状态存储在 Agents 子 Agent 中的 Chat SDK StateAdapter。
适配器在 Durable Object SQLite 中存储 Chat SDK 订阅、锁、队列、去重键、线程状态、频道状态、回调元数据、转写列表与线程历史。每个状态分片是入口 Agent 下的 ChatSdkStateAgent 子 Agent。
在托管 messenger ingress 的 Worker 中安装两个包:
npm i agents chatyarn add agents chatpnpm add agents chatbun add agents chatagents/chat-sdk 为 Chat SDK 提供持久状态。可与任意 Chat SDK 适配器配合,如 Telegram、Slack、Discord、Teams 或 Google Chat。
创建拥有 Chat SDK 运行时的父 Agent。将 createChatSdkState() 作为 Chat SDK state 选项传入。
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 },
});
}
}将父 Agent 添加到 Durable Object migration:
{
"$schema": "./node_modules/wrangler/config-schema.json",
// Set this to today's date
"compatibility_date": "2026-08-17",
"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-08-17"
compatibility_flags = ["nodejs_compat"]
[[durable_objects.bindings]]
class_name = "MessengerAgent"
name = "MessengerAgent"
[[migrations]]
new_sqlite_classes = ["MessengerAgent"]
tag = "v1"从 Worker 入口导出 ChatSdkStateAgent,以便子 Agent 路由可解析。在 Agent 生命周期方法或请求 handler 内调用 createChatSdkState() 时,它使用当前 Agent 作为 parent,并通过 this.subAgent() 创建 state shard。
默认情况下,Chat SDK state 按 thread 类 key 的前两个冒号分隔段分片。
例如 telegram:-100123:456 与 telegram:-100123:789 共享同一 state shard telegram:-100123。
默认 key sharder 识别这些 Chat SDK key 前缀:
thread-state:channel-state:msg-history:transcripts:user:
未知 key 使用 adapter 默认 shard 名 default。
使用 shardKey 控制 thread ID 如何映射到 state 子 Agent 名称:
const state = createChatSdkState({
shardKey(threadId) {
return threadId.split(":").slice(0, 2).join(":");
},
});const state = createChatSdkState({
shardKey(threadId) {
return threadId.split(":").slice(0, 2).join(":");
},
});adapter 存储非 thread 形状 key 且仍应路由到 provider 特定 shard 时使用 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 回退到内置 key sharder,再回退到 default shard。
创建由 ChatSdkStateAgent 子 Agent 支撑的 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 |
可选的父 Agent,将调用 subAgent() 创建 state shard。默认为 getCurrentAgent() 的当前 Agent。 |
name |
无法映射 key 的默认 shard 名。默认为 default。 |
shardKey |
将 Chat SDK thread ID 与 lock key 映射到 shard 名。 |
keyShard |
将通用 Chat SDK cache 或 list key 映射到 shard 名。 |
在 SQLite 中存储 state 的子 Agent 类。从 Worker 入口导出以便运行时创建。
export { ChatSdkStateAgent } from "agents/chat-sdk";export { ChatSdkStateAgent } from "agents/chat-sdk";createChatSdkState() 返回的具体 StateAdapter 实现。大多数应用无需直接实例化。
Adapter 实现完整 Chat SDK StateAdapter 接口:
thread.subscribe()与thread.unsubscribe()的订阅。- 用于按线程或按频道并发的锁。
queue、debounce与burst并发策略的待处理消息队列。- 带可选 TTL 的通用键值缓存条目。
- 带最大长度修剪与列表级 TTL 刷新的仅追加列表。
基于这些原语的 Chat SDK 功能包括:
- 消息去重。
- 线程与频道状态。
- 选择
persistThreadHistory的适配器的持久线程历史。 - 回调 URL token 存储。
- 模态上下文存储。
- 跨平台转写。
TTL 读取严格:过期锁、缓存值、队列条目与列表条目在返回前被忽略或删除。
物理清理是惰性的。ChatSdkStateAgent 为最早已知过期时间调度一次清理回调,清理运行后重新调度。这使空闲分片保持安静,同时防止过期行无限累积。