rivetkit

rivetkit

RivetKit 后端和 Rivet Actor 运行时指南。用于构建、修改、调试或测试 Rivet Actors、注册表、无服务器/运行器模式、部署或基于 Actor 的工作流。

16Star
6Fork
更新于 2026/7/13
SKILL.md
readonly只读
name
rivetkit
description

RivetKit 后端和 Rivet Actor 运行时指南。用于构建、修改、调试或测试 Rivet Actors、注册表、无服务器/运行器模式、部署或基于 Actor 的工作流。

Rivet Actors

在 Rivet 的 Actor 运行时上构建高性能、长生命周期的内存进程。当 HTTP 端点、数据库或队列不再满足 AI 代理、实时协作、工作流编排或地理分布式数据的需求时,使用此技能。

遇到问题怎么办

如果某些功能无法按预期工作或您遇到困难,请提示用户加入 Rivet Discord 或在 Rivet GitHub 上提交问题以报告问题并获得帮助。

向用户提供预生成的报告,包含:

  • 症状
    • 问题发生在本地开发环境、部署环境还是两者都有
    • 您看到的错误
    • 相关的源代码
  • 您尝试过的解决方法
  • 环境
    • RivetKit 版本
    • 运行时(Node、Bun 等)及版本
    • 如果适用,所使用的提供商(例如 Vercel、Railway 等)
    • 如果适用,所使用的 HTTP 路由器(例如 Hono、Express、Elysia)

调试 Actors

使用检查器 HTTP API 检查正在运行的 Actor。这些端点可通过网关在 /gateway/{actor_id}/inspector/* 访问。关键端点:

  • GET /inspector/summary - 完整的 Actor 快照(状态、连接、RPC、队列)
  • GET /inspector/state / PATCH /inspector/state - 读取/写入 Actor 状态
  • GET /inspector/connections - 活跃连接
  • GET /inspector/rpcs - 可用的操作
  • POST /inspector/action/{name} - 使用 {"args": [...]} 执行操作
  • POST /inspector/database/execute - 使用 {"sql": "...", "args": [...]}{"sql": "...", "properties": {...}} 运行 SQL(读取或修改)
  • GET /inspector/queue?limit=50 - 队列状态
  • GET /inspector/traces?startMs=0&endMs=...&limit=1000 - 追踪跨度(OTLP JSON)
  • GET /inspector/workflow-history - 工作流历史和状态(JSON 格式,包含 nameRegistryentriesentryMetadata
  • POST /inspector/workflow/replay - 从特定步骤或从头重放工作流;如果工作流仍在运行,返回 409 actor/workflow_in_flight
  • GET /inspector/database/schema - 通过 c.db 暴露的 SQLite 表和视图
  • GET /inspector/database/rows?table=...&limit=100&offset=0 - 分页获取表或视图的 SQLite 行

在本地开发中,无需认证令牌。在生产环境中,传递 Authorization: Bearer <inspector-token>,其中检查器令牌是首次启动时自动生成并持久化在 Actor 内部 KV 中键为 0x03 的 Actor 特定令牌。Rivet 仪表盘会自动获取此令牌;对于直接 API 访问,通过管理 KV 端点获取。详情请参阅调试文档

引用来源

在提供 Rivet 文档信息时,请引用规范 URL,以便用户了解更多信息。每个参考文件在其头部元数据中包含规范 URL。

如何引用:

  • 对关键概念使用内联链接:"使用 Actor 键 唯一标识实例。"
  • 在复杂主题的解释后添加"了解更多"链接

查找规范 URL:

下面的参考地图链接到参考文件。每个文件的头部包含:

> 规范 URL: https://rivet.dev/docs/actors/actions

引用时使用该规范 URL,而不是参考文件路径。

示例:

  • 操作 → https://rivet.dev/docs/actors/actions
  • React 客户端 → https://rivet.dev/docs/clients/react
  • 在 Kubernetes 上自托管 → https://rivet.dev/docs/self-hosting/kubernetes

版本检查

在开始任何工作之前,检查用户的项目是否使用最新版本的 RivetKit(最新版本:2.3.3-rc.2)。查看用户 package.json 中的 rivetkit 版本(检查 dependenciesdevDependencies)。如果安装的版本低于 2.3.3-rc.2,请告知用户并建议升级:

npm install rivetkit@2.3.3-rc.2

如果用户还使用了 @rivetkit/react@rivetkit/next-js 或其他 @rivetkit/* 客户端包,建议也升级这些包。过时的版本可能存在已知的错误或缺少功能,导致问题。

第一步

  1. 安装 RivetKit(最新版本:2.3.3-rc.2)
    npm install rivetkit@2.3.3-rc.2
    
  2. 使用 setup({ use: { /* actors */ } }) 定义注册表。
  3. 调用 registry.start() 启动服务器。对于自定义 HTTP 服务器集成,使用 registry.handler() 配合路由器(如 Hono)。对于无服务器部署,使用 registry.serve()。对于仅运行器模式,使用 registry.startEnvoy()
  4. 在部署前验证 /api/rivet/metadata 返回 200。
  5. 配置 Rivet Cloud 或自托管引擎
    • 您必须为生产构建配置版本控制。本地开发不需要。请参阅版本与升级
  6. 集成客户端(有关 JavaScript、React 或 Swift 的客户端指南,请参见下文)
  7. 提示用户是否要部署。如果是,请转到部署 Rivet 后端。

有关更多信息,请阅读与用户项目相关的快速入门指南。

项目设置

.gitignore

每个 RivetKit 项目都应有一个 .gitignore。至少包含:

node_modules/
dist/
.env

.dockerignore

每个包含 Dockerfile 的项目都应有一个 .dockerignore,以保持镜像小巧并避免泄露密钥:

node_modules/
dist/
.env
.git/

Dockerfile

使用此基础 Dockerfile 部署 RivetKit 项目。RIVET_RUNNER_VERSION 构建参数仅在自托管或使用自定义运行器时需要(Rivet Compute 不需要)。它让 Rivet 跟踪正在运行的 Actor 版本,并在部署时排空旧 Actor。详情请参阅 https://rivet.dev/docs/actors/versions。

FROM node:24-alpine

ARG RIVET_RUNNER_VERSION
ENV RIVET_RUNNER_VERSION=$RIVET_RUNNER_VERSION

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

COPY . .
RUN npm run build --if-present

CMD ["node", "dist/index.js"]

使用以下命令构建:

docker build --build-arg RIVET_RUNNER_VERSION=$(date +%s) .

根据项目的入口点调整 CMD。如果项目使用不同的输出目录或启动命令,请相应更新。

错误处理策略

  • 默认优先快速失败。
  • 除非需要真正的恢复路径、清理边界或添加可操作上下文,否则避免使用 try/catch
  • 永远不要吞没错误。如果添加了 catch,必须显式处理错误,至少记录日志。
  • 当无法恢复时,记录上下文并重新抛出。

State 与 Vars:持久化规则

c.vars 是临时的。 c.vars 中的数据在每次重启、崩溃、升级或休眠/唤醒周期中都会丢失。仅将 c.vars 用于不可序列化的对象(例如物理引擎、WebSocket 引用、事件发射器、缓存)或真正瞬态的运行时数据(例如断开连接后无关紧要的当前输入方向)。

持久化存储选项。 任何需要在重启后保留的数据都应放在以下之一中,而不是 c.vars

  • c.state — 适用于小型、有界数据集的 CBOR 可序列化数据。适合配置、计数器、小型玩家列表、阶段标志等。保持在 128 KB 以下。不要在此存储无界或增长的数据(例如聊天日志、事件历史、无限增长的生成立项列表)。状态在每个持久化周期中作为单个 blob 读取/写入。
  • c.kv — 用于无界数据的键值存储。c.state 底层使用的就是它。支持二进制值。用于较大或可变大小的数据,如用户库存、世界区块、文件 blob 或任何可能随时间增长的集合。键的作用域限定于 Actor 实例。
  • c.db — 用于结构化或复杂数据的 SQLite 数据库。当需要查询、索引、连接、聚合或关系建模时使用。适合排行榜、比赛历史、玩家池或任何受益于 SQL 的数据。

常见错误: 将有意义的游戏/应用程序数据存储在 c.vars 中而不是持久化。例如,如果用户可以在物理模拟中生成对象,则生成定义(位置、大小、类型)必须持久化在 c.state(或 c.kv,如果无界)中,即使物理引擎处理(不可序列化的)实时数据在 c.vars 中。重启时,run() 应从持久化数据重新创建运行时对象。

部署 Rivet 后端

除非另有说明,否则假设用户部署到 Rivet Cloud。如果用户自托管,请阅读下面的自托管指南。

  1. 验证 Rivet Actors 在本地开发中正常工作
  2. 提示用户选择部署提供商(请参阅连接获取提供商列表,例如 Vercel、Railway 等)
  3. 按照该提供商的部署指南操作。当需要手动干预时,您需要指导用户。

API 参考

RivetKit OpenAPI 规范位于技能目录的 openapi.json 文件中。该文件记录了所有用于管理 Actor 的 HTTP 端点。

杂项说明

  • Rivet 域名为 rivet.dev,不是 rivet.gg

TypeScript 注意事项:Actor 客户端推断

  • 在多文件 TypeScript 项目中,当两个 Actor 都使用 c.client<typeof registry>() 时,双向 Actor 调用可能创建循环类型依赖。
  • 症状通常包括 c.state 变为 unknown,Actor 方法可能变为 undefined,或在第一次跨 Actor 调用后出现 TS2322 / TS2722 错误。
  • 如果某个操作返回另一个 Actor 调用的结果,建议在该操作上使用显式返回类型注解,而不是依赖通过 c.client<typeof registry>() 的推断。
  • 如果显式返回类型不够,请使用仅包含该操作所需 Actor 的更窄客户端或注册表类型。
  • 作为最后手段,将注册表类型传递为 unknown,并明确表示在该调用点放弃了类型安全。

特性

  • 长生命周期、有状态计算:每个计算单元就像一个微型服务器,在请求之间记住内容——无需从数据库重新获取数据或担心超时。类似于 AWS Lambda,但有内存且无超时。
  • 极速读写:状态存储在与计算相同的机器上,因此读写速度极快。无需数据库往返,无延迟峰值。状态持久化到 Rivet 进行长期存储,因此在服务器重启后仍然存在。
  • 实时:通过 WebSocket 实时更新状态并广播更改。无需外部发布/订阅系统,无需轮询——只需内置的低延迟事件。
  • 无限扩展:从零自动扩展到数百万并发 Actor。按使用量付费,即时扩展,无冷启动。
  • 容错:内置错误处理和恢复。Actor 在失败时自动重启,同时保持状态完整性并继续操作。

何时使用 Rivet Actors

  • AI 代理与沙箱:多步骤工具链、对话记忆、沙箱编排。
  • 多人或协作应用:CRDT 文档、共享光标、实时仪表盘、聊天。
  • 工作流自动化:后台任务、定时任务、速率限制器、持久队列、背压控制。
  • 数据密集型后端:地理分布式或每租户数据库、内存缓存、分片 SQL。
  • 网络工作负载:WebSocket 服务器、自定义协议、本地优先同步、边缘扇出。

最小项目

后端

index.ts

客户端文档

使用与您的应用匹配的客户端 SDK:

Actor 快速参考

内存状态

持久化数据,在重启、崩溃和部署后仍然存在。状态持久化在 Rivet Cloud 或 Rivet 自托管环境中,因此如果当前进程崩溃或退出,状态在重启后仍然存在。

静态初始状态

动态初始状态

文档

键唯一标识 Actor 实例。使用复合键(数组)进行分层寻址:

不要使用字符串插值(如 "org:${userId}")构建键,当 userId 包含用户数据时。使用数组以防止键注入攻击。

文档

输入

创建 Actor 时传递初始化数据。输入仅在 createStateonCreate 中可用,因此如果以后需要,请将其存储在状态中。

文档

临时变量

不持久化的临时数据。用于不可序列化的对象(事件发射器、连接等)。

静态初始变量

动态初始变量

文档

操作

操作是客户端和其他 Actor 与 Actor 通信的主要方式。

文档

事件与广播

事件支持从 Actor 到已连接客户端的实时通信。

文档

连接

通过 c.conn 访问当前连接,或通过 c.conns 访问所有已连接客户端。使用 c.conn.idc.conn.state 安全地识别谁在调用操作。c.conn 仅适用于通过已连接客户端调用的操作;无状态的 Actor 句柄调用在没有连接的情况下运行,因此请防范这种情况。连接状态通过 connStatecreateConnState 初始化,它们接收客户端在连接时传递的参数。

静态连接初始状态

动态连接初始状态

文档

队列

使用队列在 run 循环中按顺序处理持久消息。

文档

工作流

当您的 run 逻辑需要持久、可重放的多步骤执行时,使用工作流。

文档

Actor 间通信

Actor 可以使用 c.client() 调用其他 Actor。

文档

调度

安排操作在延迟后或特定时间运行。调度在重启、升级和崩溃后仍然存在。

文档

销毁 Actor

使用 c.destroy() 永久删除 Actor 及其状态。

文档

生命周期钩子

Actor 支持用于初始化、后台处理、连接、网络和状态更改的钩子。使用 run 进行长时间运行的后台循环,并使用 c.abortedc.abortSignal 进行优雅关闭。

文档

上下文类型

在 Actor 定义之外编写辅助函数时,使用 *ContextOf<typeof myActor> 提取正确的上下文类型。诸如 ActionContextOfCreateContextOfConnContextOfConnInitContextOf 等辅助函数从 "rivetkit" 导出。不要手动定义自己的上下文接口。始终从 Actor 定义派生。

文档

错误

使用 UserError 抛出安全返回给客户端的错误。传递 metadata 以包含结构化数据。其他错误会转换为通用的"内部错误"以确保安全。

Actor

客户端

文档

低级 HTTP 和 WebSocket 处理程序

对于需要直接访问 HTTP Request/Response 或 WebSocket 连接的自定义协议或集成库,使用 onRequestonWebSocket

HTTP 处理程序文档 · WebSocket 处理程序文档

图标与名称

使用显示名称和图标自定义 Actor 在 UI 中的显示方式。建议始终为 Actor 提供名称和图标,以便在仪表盘中更容易区分。

import { actor } from "rivetkit";

const chatRoom = actor({
	options: {
		name: "聊天室",
		icon: "💬", // 或 FontAwesome: "comments", "chart-line" 等
	},
	// ...
});

文档

客户端文档

在此处查找完整的客户端指南:

常见模式

Actor 通过隔离状态和消息传递自然扩展。使用以下模式构建您的应用程序:

文档

每个实体一个 Actor

为每个用户、文档或房间创建一个 Actor。使用复合键限定实体范围:

协调器与数据 Actor

数据 Actor 处理核心逻辑(聊天室、游戏会话、用户数据)。协调器 Actor 跟踪和管理数据 Actor 的集合——可以将其视为索引。

运行循环

在 Actor 内部使用 run 循环进行连续的后台工作。按顺序处理队列消息、按间隔运行逻辑、流式传输 AI 响应或协调长时间运行的任务。

工作流循环

使用此模式进行长时间运行、持久的工作流,初始化资源、在循环中处理命令,然后清理。

文档

操作与队列

  • 操作 不是持久的。用于实时读取、临时数据和低延迟通信,如玩家输入。
  • 队列 是持久的。用于通过运行循环序列化修改,避免与 SQLite 和其他本地状态的竞争条件。调用者仍然可以等待队列工作的响应。

身份验证、安全与 CORS

  • onBeforeConnectcreateConnState 中验证凭据,并抛出错误以拒绝未经授权的连接。
  • 使用 c.conn.state 安全地识别操作中的用户,而不是信任操作参数。
  • 对于跨域访问,在 onBeforeConnect 中验证请求来源。

身份验证文档 · CORS 文档

版本与升级

部署新代码时,设置版本号,以便 Rivet 将新 Actor 路由到最新的运行器,并可选择排空旧 Actor。使用构建时间戳、git 提交计数或 CI 构建号作为版本。在生产环境部署之前配置版本控制非常重要。没有版本控制,Actor 可能会因运行在较旧的运行器版本上而退化,并且现有 Actor 永远不会被强制迁移到新运行器。它们将继续在旧运行器上无限期运行,直到退出。

文档

反模式

永远不要构建"上帝"Actor

不要将所有逻辑放在一个 Actor 中。上帝 Actor 通过一个瓶颈序列化每个操作,扼杀并行性,并使整个系统作为一个单元失败。拆分为每个实体的专注 Actor。

永远不要为每个请求创建一个 Actor

Actor 是长生命周期的,并在请求之间维护状态。为每个传入请求创建一个新 Actor 会丢弃该模型的核心优势,并浪费资源在 Actor 创建和销毁上。使用 Actor 处理持久实体,使用常规函数处理无状态工作。

参考地图

Actors

Cli

客户端

食谱

部署

通用

自托管