以下页面介绍了一个示例应用:它将 LangChain 深度代理部署到 Cloudflare Workers 上,提供流式聊天界面、子代理和线程历史记录。这些功能都基于 Agent Streaming Protocol,并通过 Worker 路由(HTTP + SSE)实现。React SPA 通过 Workers Assets 由同一个 Worker 提供服务。无需单独的后端进程:一个 Worker 同时提供 SPA 和协议 API。 源代码位于部署示例中的 js-cloudflare。

部署到 Cloudflare

1

安装并构建

2

配置密钥

3

部署

Wrangler 会在一次部署中同时上传 Vite 构建产物(SPA)和 Worker 脚本。启用 nodejs_compat 和 nodejs_compat_populate_process_env 后,LangChain 就可以从环境中读取 OPENAI_API_KEY。 wrangler.jsonc 通过 new_sqlite_classes 注册 ThreadSession Durable Object,这是 Workers 免费计划所必需的。

必需的 API 端点

应用在 /api/threads/... 下提供 Agent Streaming Protocol。路由在 worker/index.ts 中使用 Hono 实现。

最低配置(流式聊天)

可选配置(侧边栏)

请求流程

  1. 初始化线程状态(GET/POST /state)。
  2. 提交时,SDK 向 /commands 发送 run.start,并接收一个 run_id。
  3. Worker 启动图运行,并将每个协议事件分发到线程对应的 Durable Object。
  4. SDK 订阅 /stream(SSE)。DO 会重放已缓冲的事件,并持续接收实时帧,即使 Worker 隔离实例重启也不会中断。
  5. 子代理(task)运行时会发出带命名空间的事件,这些事件会以 stream.subagents 的形式呈现。

Cloudflare 后端设计

在 Cloudflare 上,Worker(代理 + 检查点保存器)与 Durable Object(SSE 事件日志)之间的拆分是主要设计选择。Worker 隔离实例是临时的,因此重放缓冲区存储在 Durable Objects 中,而不是进程内存中。

生产环境持久化

默认情况下,代理使用内存中的 MemorySaver 检查点保存器(worker/agent/index.ts)。这对本地开发和演示来说已经足够,但在 Cloudflare 上,由于存在多个隔离实例和冷启动,会话状态在部署之间或不同隔离实例之间不会持久化。 在生产环境中:
  1. 换用持久化检查点保存器(例如通过 Hyperdrive 使用 Postgres,或使用基于 DO 的自定义存储)。
  2. 保留每个线程对应的 Durable Object 以实现 SSE 重放(或者将事件日志持久化到 DO 存储 / KV,以支持长期重连)。
如需更多信息,请参阅检查点保存器库和添加记忆 / 持久化。

本地开发

打开 http://localhost:5173。Cloudflare Vite 插件会在开发期间于 Workers 运行时中运行你的 Worker,因此 /api/* 路由的行为与生产环境一致。

项目结构

  • src/components/ — 聊天界面(ChatApp、Chat、MessageThread、Subagents、ThreadHistory、…)。
  • src/lib/chat/threads-client.ts — 浏览器端线程初始化和侧边栏辅助函数。
  • worker/agent/ — 深度代理(createDeepAgent),包含 researcher 和 math-whiz 子代理以及模拟工具。
  • worker/server/ — 协议辅助函数:runs.ts(在 Worker 上启动运行)、threads.ts(基于检查点保存器的状态)、serialize.ts、registry.ts。
  • worker/durable-objects/thread-session.ts — 每个线程的 SSE 事件日志(StreamChannel + matchesSubscription)。
  • worker/index.ts — Hono 应用:协议路由 + Worker 导出。
  • wrangler.jsonc — Worker 配置:nodejs_compat、Durable Object 绑定,以及 SPA 资源路由(run_worker_first: ["/api/*"])。

另请参阅