一个开源版的 Cloudflare Durable Objects 替代方案……没有供应商锁定、没有内存限制,并内置可观测性。

Durable Actors 帮助你构建实时应用例如聊天系统(如 ChatGPT、Codex)、协作工具(如 Notion)以及智能体集群(如 Devin)。

它们提供有状态的无服务器函数,这是一个基础构建块,抽象掉了分布式系统中的持久化、协调和基础设施难题。

在线演示·TypeScript 文档·Python 文档

工作原理

  1. 定义一个actor,一个带有持久状态(即数据在中断、错误和重启后依然存活)和串行执行(即并发调用者可以安全地更新它)的类。 例如:
  • 如果你在构建 ChatGPT……一个聊天 actor 可以存储对话,使其在 LLM 不稳定和服务器崩溃时依然存活(持久状态)
  • 如果你在构建 Notion……一个文档 actor 可以协调来自多人和多个智能体的并发编辑(串行执行)
  1. 使用 Durable Actors SDK 自动生成类型安全的客户端。目前,它支持 Python 和 TypeScript。
  2. 用一条命令在本地开发,之后在 GCP 上自托管 Durable Actors 运行时。

快速开始:多人 AI 聊天

Teammates share one TeamAgent chat across regions; prompts queue, replies stream to everyone, and conversation state is durably persisted.

1. 创建你的项目

安装 Node.js 22.19+ 和 Bun 1.3.9+。

npx durable-actors init my-actors
cd my-actors
npm install
npx durable-actors dev #在你的机器上本地运行服务器

2. 定义一个actor

在你的 actor 项目的src/actors.ts中定义并导出 actor,这是由durable-actors dev加载的默认入口点。运行时按需加载 actor,并持久化标记为@Persisted的字段。

例如,一个聊天历史 actor:

import { openai } from "@ai-sdk/openai"
import { streamText } from "ai"
import { Actor, type ActorSocket, Interleave, Persisted } from "durable-actors"

type Message = { role: "user" | "assistant"; content: string }

export class ChatHistory extends Actor<null, string, Message[]> {
    @Persisted messages: Message[] = []

    async onConnect(socket: ActorSocket<null, Message[]>) {
        socket。send(this。messages)
    }

    @Interleave // 让其他调用在 await 期间运行,例如在回复流式传输时的新连接。
    async onMessage(_socket: ActorSocket<null, Message[]>, text: string) {
        this。messages。push({ role: "user", content: text })
        const result = streamText({ model: openai("gpt-5-mini"), messages: [...this。messages] })
        const reply: Message = { role: "assistant", content: "" }
        this。messages。push(reply)
        this。broadcast(this。messages)
        for await (const chunk of result.textStream) {
            reply.content += chunk
            this.broadcast(this.messages)
        }
    }
}

3. 连接你的后端

我们让将 actor 集成到你现有的技术栈变得非常简单。只需生成客户端,你就能获得一个完全类型安全的契约来进行交互。

npx durable-actors generate

创建一个到单个共享聊天的 WebSocket 连接:

import express from "express"

import { actors } from "../generated/index.js"

export const app = express()

app.post("/api/chat/socket", async (_req, res) => {
    const grant = await actors.ChatHistory.prepareWebsocket({
        actorId: "lobby",
        metadata: null
    })
    res.set("Cache-Control", "no-store").json(grant)
})

4. 连接前端

import { useEffect, useRef, useState } from "react"
import { createRoot } from "react-dom/client"

import type { actors } from "../generated/index.js"

function Chat() {
    const socket = useRef<WebSocket>(null)
    const [messages, setMessages] = useState<actors.ChatHistory.Outgoing>([])

    useEffect(() => {
        let active = true
        async function connect() {
            const response = await fetch("/api/chat/socket", { method: "POST" })
            const { websocketUrl } = await response.json()
            if (!active) return
            socket.current = new WebSocket(websocketUrl)
            socket.current.onmessage = event => setMessages(JSON.parse(event.data))
        }
        void connect()
        return () => {
            active = false
            socket.current?.close()
        }
    }, [])

    function send(form: FormData) {
        const text = String(form.get("message")).trim()
        if (!text || socket.current?.readyState !== WebSocket.OPEN) return
        socket.current.send(JSON.stringify(text))
    }

    return (
        <main>
            <div role="log" aria-label="Messages">
                {messages.map((message, index) => (
                    <p key={index}><strong>{message.role}:</strong> {message.content}</p>
                ))}
            </div>
            <form action={send}>
                <input name="message" aria-label="Message" required />
                <button>Send</button>
            </form>
        </main>
    )
}

createRoot(document.getElementById("root")!).render(<Chat />)

如需一个包含错误处理和重试的完整应用,请参阅AI Chat 示例。

5. 监控与调试

Durable Agents 提供内置的可观测性功能:

o11y-screenshot

示例

如需完整的示例应用,请参阅AI Chat、Collaborative Documents和Chatroom。

社区

欢迎提交 bug 报告、功能请求、文档修正和代码贡献。有关仓库设置和检查,请参阅贡献指南,并遵守我们的行为准则。

使用GitHub Issues用于报告 bug、想法和问题。请通过我们的安全政策私下报告漏洞。

在GitHub Releases上关注开发和发布说明。

许可证

MIT© 2026 Terse