🔄
Актуальность: документация и тарифы заново сверены 3 октября 2026 года. Текущая опубликованная версия npm-пакета agents — 0.26.0. SDK работает поверх Durable Objects; McpAgent устарел и сохраняется для миграции существующих серверов. Для новых MCP-маршрутов без протокольной сессии применяется createMcpHandler. Хранение и операции SQLite учитываются по текущим тарифам Durable Objects.

Cloudflare Agents SDK — набор библиотек на TypeScript для агентов с постоянной идентичностью и состоянием. Каждый экземпляр работает как отдельный Durable Object, то есть адресуемый объект внутри сети Cloudflare. Он хранит данные во встроенной SQLite, обрабатывает HTTP-запросы, WebSocket-соединения и события e-mail и может запускать задачи по расписанию.

📌
Главная идея: создайте отдельный экземпляр агента для пользователя, сессии или комнаты. Состояние переживает перезапуски, деплои и hibernation (гибернацию), а изменения можно синхронизировать с браузером через WebSocket.

Материал рассчитан на разработчика, который знаком с TypeScript и HTTP. SDK (набор библиотек для разработки) помогает построить серверную часть агента; сам по себе он не выбирает модель и не выдаёт доступ пользователю. Для запуска примера нужен проект starter с React, bindings и типами Cloudflare.

Какую задачу решает Agents SDK

Простой обработчик вызова языковой модели (LLM) сам по себе не обеспечивает сохранение состояния между запросами. Приложению приходится отдельно загружать историю, управлять блокировками, сохранять результат и восстанавливать прерванные операции.

Agents SDK переносит эту работу в модель акторов на Durable Objects. Она подходит для сценариев, где нужны:

  • отдельная память для каждого пользователя или процесса;
  • двусторонняя связь с интерфейсом;
  • задачи по расписанию;
  • ожидание подтверждения человека;
  • длинные операции с восстановлением после сбоя;
  • координация нескольких специализированных агентов.

Как устроен экземпляр агента

Durable Object можно представить как адресуемый микросервер внутри сети Cloudflare. Один идентификатор всегда ведёт к одному экземпляру. Например, user-42 и user-43 получают независимые состояния и SQLite-базы.

У экземпляра есть:

  • this.state для состояния, которое нужно сохранять и синхронизировать с клиентами;
  • this.sql для собственных таблиц и SQL-запросов;
  • обработчики HTTP, WebSocket и e-mail событий;
  • расписание и устойчивое выполнение задач (durable execution);
  • доступ к Workers bindings через this.env.

Каждый агент может иметь миллионы независимо адресуемых экземпляров. Масштабирование достигается разделением нагрузки по именам пользователей, сессий, комнат или других сущностей.

Минимальный агент с постоянным состоянием

Сохраните серверный код в src/server.ts. Тип Env создаётся по конфигурации командой wrangler types, как показано ниже.

Актуальный клиентский API вызывает разрешённые методы через типизированный stub. Методы, доступные браузеру, отмечаются декоратором @callable().

import { Agent, callable, routeAgentRequest } from "agents"

export type CounterState = {
  count: number
}

export class CounterAgent extends Agent<Env, CounterState> {
  initialState: CounterState = { count: 0 }

  @callable()
  increment() {
    this.setState({ count: this.state.count + 1 })
    return this.state.count
  }

  @callable()
  reset() {
    this.setState({ count: 0 })
  }
}

export default {
  async fetch(request: Request, env: Env) {
    return (
      (await routeAgentRequest(request, env)) ??
      new Response("Not found", { status: 404 })
    )
  },
} satisfies ExportedHandler<Env>

setState() сохраняет новое состояние в SQLite и рассылает обновление подключённым клиентам. Прямое изменение this.state вместо setState() не следует использовать. Класс агента должен быть зарегистрирован в миграции с new_sqlite_classes.

Для произвольных таблиц используйте SQL API:

this.sql`CREATE TABLE IF NOT EXISTS notes (
  id TEXT PRIMARY KEY,
  body TEXT NOT NULL
)`

Подключение React-клиента

Поместите компонент в src/client.tsx и отрисуйте <Counter /> в React-приложении starter. Хук useAgent вызывается внутри компонента, а RPC через stub — в обработчике кнопки. RPC означает вызов разрешённого серверного метода из клиента.

import { useState } from "react";
import { useAgent } from "agents/react";
import type { CounterAgent, CounterState } from "./server";

export function Counter() {
  const [count, setCount] = useState(0);
  const [error, setError] = useState("");
  const agent = useAgent<CounterAgent, CounterState>({
    agent: "CounterAgent",
    name: "user-42",
    onStateUpdate: (state) => setCount(state.count),
  });

  return <section>
    <p>Счётчик: {count}</p>
    <button onClick={async () => {
      try { await agent.stub.increment(); setError(""); }
      catch { setError("Не удалось изменить счётчик"); }
    }}>Прибавить один</button>
    {error && <p role="alert">{error}</p>}
  </section>;
}

useAgent подключается по WebSocket. Все клиенты одного экземпляра получают обновления после setState(). Для приложения без React используйте AgentClient из agents/client.

user-42 здесь — общее учебное имя, а не проверка личности. Любой клиент, допущенный к этому маршруту, разделяет его счётчик. Для личной истории проверяйте авторизацию и связь пользователя с экземпляром на сервере до маршрутизации и вызова методов; одного имени и @callable() недостаточно.

Основные возможности

Состояние и собственная SQLite

State API удобен для данных, которые должны автоматически попадать в интерфейс. this.sql подходит для истории, индексов и прикладных таблиц, которыми приложение управляет самостоятельно.

WebSocket и hibernation

WebSocket Hibernation позволяет сохранить соединения, пока JavaScript экземпляра не выполняется. Объект, который простаивает и соответствует условиям hibernation, не тарифицируется за compute duration. При обычном WebSocket.accept() Cloudflare начисляет duration за всё время соединения; активные исходящие соединения также могут удерживать объект в памяти.

Расписание и фоновые задачи

API агента включает schedule(), scheduleEvery() и методы чтения расписания. Его можно использовать для напоминаний, периодических проверок и отложенных действий без отдельного cron-сервиса.

Для устойчивого выполнения внутри агента доступны волокна исполнения (fibers), очереди и повторные попытки (retries). Выбор зависит от длительности задачи и требуемой модели восстановления.

Workflows для длинных операций

Cloudflare Workflows разбивает процесс на сохраняемые шаги. Вызов модели или инструмента можно оформить отдельным step.do(), который создаёт контрольную точку (checkpoint). После сбоя Workflow возобновится с последнего успешного шага, а уже сохранённые успешные шаги не будут выполнены заново. Внешние операции с побочными эффектами всё равно должны быть идемпотентными или защищёнными собственными ключами выполнения.

Workflows также поддерживает:

  • автоматические повторы отдельных шагов;
  • step.sleep() без расхода compute во время ожидания;
  • waitForEvent() для подтверждения человеком;
  • передачу прогресса агенту и WebSocket-клиентам.

E-mail, суб-агенты и наблюдаемость

Жизненный цикл Agent включает onEmail(). Письмо можно направить в нужный экземпляр через Cloudflare Email Routing.

В SDK доступны фоновые суб-агенты с прогрессом и сохраняемыми контрольными точками (durable milestones). Для диагностики доступен tracing: он показывает ходы агента, вызовы моделей и инструментов, подтверждения и использование токенов. Запись содержимого сообщений и инструментов отключена по умолчанию; включайте её только для данных, которые допустимо хранить.

MCP: клиент и сервер теперь разделены

В части Model Context Protocol (MCP) агент может подключаться к MCP-серверам через addMcpServer().

Для публикации обычного remote MCP-сервера с июля 2026 года рекомендуется фабрика без состояния createMcpHandler() из agents/mcp/server. Она создаёт изолированный сервер на каждый запрос и не требует Durable Object. Старый McpAgent объявлен устаревшим и заморожен по возможностям.

Состояние-вариант всё ещё может понадобиться серверу с protocol sessions, RPC, pushed server-to-client requests или replay. Такие реализации следует мигрировать постепенно, сохраняя старый маршрут только на переходный период.

Как сочетать с LLM SDK

Cloudflare Agents SDK отвечает за идентичность, состояние, соединения и исполнение. Вызов модели можно делать через Workers AI либо внешний SDK OpenAI, Anthropic, Google AI и других провайдеров.

Для чат-приложений в актуальной архитектуре предусмотрен AIChatAgent из @cloudflare/ai-chat: он добавляет сохранение сообщений, возобновляемый стриминг и React-хук useAgentChat. Пакет @cloudflare/think добавляет восстановление после сбоев, инструменты и работу с суб-агентами.

Полезные сценарии

Чат поддержки с памятью

Задача: хранить историю обращения и отвечать одному клиенту в реальном времени.

Создайте один экземпляр на клиента и храните состояние обращения в state или SQLite. Подключите виджет через useAgent.

Проверяемый результат: повторно подключитесь к тому же имени экземпляра. Состояние должно восстановиться, а последующие обновления должны прийти всем открытым клиентам.

Ограничение: данные одного активно нагруженного клиента остаются сосредоточены в одном экземпляре. Ключ экземпляра нужно выбирать так, чтобы нагрузка распределялась по пользователям или сессиям.

Исследовательская задача с восстановлением

Задача: выполнить длинное исследование с вызовами модели и инструментов.

Запустите Workflow из агента, вынесите вызовы модели и инструментов в отдельные step.do() и передавайте прогресс в интерфейс.

Проверяемый результат: после прерывания Workflow продолжается после последнего сохранённого шага, а не начинает работу заново.

Ограничение: внешние операции с побочными эффектами всё равно должны быть идемпотентными или защищёнными собственными ключами выполнения.

Комната совместной работы

Задача: синхронизировать состояние комнаты между несколькими участниками.

Используйте имя комнаты как идентификатор агента. Все участники подключаются к одному WebSocket-маршруту и получают обновления состояния.

Проверяемый результат: изменение, отправленное одним клиентом через setState(), появляется у остальных подключённых клиентов.

Ограничение: одна горячая комната остаётся сосредоточенной в одном экземпляре, поэтому нагрузку и размер состояния нужно оценить заранее.

Когда инструмент подходит

Agents SDK полезен для чатов с памятью, совместных интерфейсов, расписаний, длительных процессов и агентов, которым нужен устойчивый адресуемый runtime.

Для одноразового LLM-вызова без памяти обычный Worker проще. Также заранее оцените зависимость от Cloudflare: Durable Objects, hibernation, alarms и встроенная SQLite являются особенностями платформы.

Создание проекта

Установите поддерживаемый Node.js ≥22. C3 и Wrangler на дату проверки требуют эту версию. Команда ниже создаёт локальный проект; если мастер предложит публикацию, выберите No до проверки конфигурации.

npm create cloudflare@latest -- --template cloudflare/agents-starter

Для существующего проекта:

npm install agents@0.26.0

Минимальная серверная конфигурация wrangler.jsonc для агента. Если добавляете её в React/Vite-starter, сохраните его настройки статических файлов и сборки: этот фрагмент не заменяет всю конфигурацию интерфейса.

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "my-agent",
  "main": "src/server.ts",
  "compatibility_date": "2026-10-03",
  "compatibility_flags": ["nodejs_compat"],
  "durable_objects": {
    "bindings": [
      {
        "name": "CounterAgent",
        "class_name": "CounterAgent"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["CounterAgent"]
    }
  ]
}

После изменения конфигурации выполните npx wrangler types, чтобы создать тип Env с привязкой CounterAgent. Не создавайте второй binding и не меняйте уже применённую миграцию рабочего проекта: для нового класса нужна новая миграция.

Имя class_name должно точно совпадать с экспортированным классом. new_sqlite_classes включает SQLite-хранилище для состояния агента, а флаг nodejs_compat требуется пакету agents. Для проекта с Vite актуальный starter также подключает agents/vite, а tsconfig.json расширяет agents/tsconfig для корректной обработки TC39-декораторов.

Проверка результата

  1. Запустите проект командой npm run dev.
  2. Откройте React-клиент и вызовите agent.stub.increment().
  3. Убедитесь, что onStateUpdate получил новое значение.
  4. Обновите страницу и подключитесь к тому же имени экземпляра.
  5. Проверьте, что значение сохранилось.
  6. Откройте второй клиент с тем же именем и убедитесь, что оба клиента получают последующие обновления.

Если состояние пропадает, проверьте new_sqlite_classes, вызов setState() и совпадение имени экземпляра. Если WebSocket не подключается, возвращайте ответ routeAgentRequest() без создания новой оболочки Response.

⚖️
Серверный CounterAgent и компонент Counter проверены локально TypeScript 5.9.3 с agents 0.26.0 и React 19.2.4. Это проверка типов; реальное выполнение Worker, WebSocket, сохранение SQLite и браузерный сценарий не запускались.

Цена и лимиты

Данные заново сверены 3 октября 2026 года по официальной странице тарифов Durable Objects.

  • Free: 100 000 запросов и 13 000 GB-s duration в день.
  • Paid: 1 млн запросов и 400 000 GB-s в месяц включены; сверх лимита — $0.15 за млн запросов и $12.50 за млн GB-s.
  • SQLite на Free: 5 млн прочитанных строк, 100 000 записанных строк в день и 5 GB суммарного хранения.
  • SQLite на Paid: 25 млрд прочитанных и 50 млн записанных строк в месяц включены; далее $0.001 за млн чтений и $1.00 за млн записей.
  • Хранение на Paid: 5 GB-month включены, далее $0.20 за GB-month.
  • Вызовы Workers AI или внешнего LLM-провайдера оплачиваются отдельно от этих лимитов Durable Objects.

На бесплатном плане превышение конкретного суточного лимита приводит к ошибкам дальнейших операций этого типа до сброса лимита в 00:00 UTC.

Официальные ссылки


Следующий шаг

Для работающего агента переходите к трассировке и подтверждению действий.

Выбор экземпляра и проверка его владельца определяют, чья память хранится и кто может вызвать методы.

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov