Rivet Actors 文档工程规范:docs Bundle 布局、CodeSnippet 类型安全嵌入与术语体系解析
【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actors
本文档从 Rivet Actors 仓库的 docs/CLAUDE.md 出发,系统解析这套文档包(docs bundle)的工程规范:页面如何组织、Frontmatter 如何声明、导航如何配置、代码示例如何以类型安全的方式嵌入,以及全站术语如何保持一致。无论你是要为本仓库贡献新的文档页面,还是想理解 docs 目录与官网站点的发布链路,都能从中获得一套可直接照做的完整流程。
文档包(Docs Bundle)的定位与发布机制
在深入具体规则之前,先要理解一个关键前提:本仓库docs/下的页面并不在本仓库内渲染。docs/CLAUDE.md开头即声明,这些页面由独立的官网仓库发布,官网仓库通过 symlink 把本目录链接进其内容集合。这意味着:
- 这里编写的每一页最终都会成为公开文档的一部分,因此只有真正的页面(real pages)才能出现在
content/下; - 任何脚本、测试夹具、临时笔记如果被放进
content/,都会被当作文档页面发布出去; - 页面在本仓库与官网站点之间通过同一套相对路径解析,规范由此而来。
这种"仓库写文档、网站发文档"的多仓库协作模式,是所有后续规则(布局、Frontmatter、路径、术语)的出发点。docs 目录既是内容源,也是被外部系统消费的"产物目录",规范必须保证两者对齐。
目录布局:content 之下只有真实页面
docs/CLAUDE.md给出了标准的目录骨架:
docs/ sidebar.json navigation for the two tabs content/ docs/**.mdx -> /{product}/docs/... tutorials/**.mdx -> /{product}/tutorials/...对照本仓库的实际结构(docs/content),布局比骨架示例更丰富:
docs/content/docs/:产品文档主体,约 50 个.mdx页面,覆盖 Quickstart(backend、react、next-js、rust、effect、cloudflare、supabase)、Features(state、actions、events、queues、schedule、sqlite)与 Concepts(crash-course、keys、input、lifecycle 等);docs/content/learn/:教程类内容,如 a-radically-simpler-architecture.mdx、chat-room.mdx;docs/content/integrations/:集成页面(durable-streams、flue、vercel-eve、workflow-sdk);docs/content/use-cases/:使用场景页;docs/sidebar.json:导航配置(本仓库内唯一,位于 docs/sidebar.json)。
核心原则只有一条:content 目录与发布产出一一对应。规范的表述是 "The website linksdocs/contentinto its content collection, so only real pages belong undercontent/"。所以在贡献新内容时,先判断它是不是一个真正面向读者的页面;如果是脚本、夹具或内部笔记,请放到 docs 之外的目录,否则会被无声地发布出去。
Frontmatter 规范:title 与 description 双必填
每一页都必须声明title和description两个 Frontmatter 字段,它们承担双重职责:
- 两者都用于SEO(搜索引擎与页面摘要);
- 当 sidebar 条目省略标题时,侧边栏回退使用页面的
title。
docs/CLAUDE.md给出的标准示例:
--- title: "In-Memory State" description: "Actors store state in memory for instant reads and writes." ---仓库中的真实页面完全遵循此格式。以 docs/content/docs/state.mdx 为例,其 Frontmatter 为:
--- title: "In-Memory State" description: "Actors store state in memory for instant reads and writes. State can be persisted automatically or kept ephemeral." skill: true ---这里还出现了一个可选的skill字段(true/false),在 crash-course.mdx 中同样出现。这类附加字段表明:Frontmatter 不限于 title/description,还可以承载站点级元数据,但 title/description 是硬性要求。实际编写时请始终以这两个字段起步,description 应写成一句完整、可独立检索的句子,说明页面要解决什么问题。
sidebar.json:导航即配置
导航完全由 docs/sidebar.json 驱动。docs/CLAUDE.md给出的最小示例:
{ "docs": [ { "title": "General", "pages": [ { "title": "Introduction", "href": "/actors/docs", "icon": "faSquareInfo" } ]} ], "tutorials": [] }关键规则有三条:
href必须是完整的站点路径,包含产品段(product segment)。例如/actors/docs/quickstart/backend、/actors/docs/state,而不是相对路径或文件名;- 往
content/添加页面并不会自动加入导航,必须同时在这里登记。只写页面、不同步 sidebar,页面就会"存在但不可达"; - Self-Host 标签页不在此文件中,由网站侧生成,因此不需要(也不应该)在这里维护。
仓库中的实际 sidebar.json 比示例大得多,结构上包含三个顶层区段:docs(按 General / Quickstart / Features / Concepts / Clients / Reference 分组)、learn、integrations。每个条目支持icon(Font Awesomeexport 名称,如faSquareInfo、faNodeJs、faRust)、collapsible(可折叠分组)、pages(子页面)、badge(如 Rust、Effect.ts 的 "Beta" 徽标)等字段。这印证了docs/CLAUDE.md中"图标以 Font Awesome export names 传输,而非对象"的说法——导航数据是纯 JSON,仓库侧无需依赖网站的图标包。
实操要点:新增一页文档时,遵循"页面 + 导航"双提交;调整分组或排序时,直接编辑 sidebar.json 中对应条目的顺序即可。
CodeSnippet 代码嵌入:让示例永不腐烂
这是整套规范中最具工程价值的机制,docs/CLAUDE.md用了一整节(Code)来约束它。核心思想一句话概括:文档中的 TypeScript 示例必须来自真实源码文件,并且必须通过编译,否则网站构建失败。
为什么禁止内联 TypeScript
规范原文是 "Never inline a fenced TypeScript block"。原因是类型检查:真实示例放在examples/下,通过<CodeSnippet>嵌入,它们会参与tsc --noEmit编译,一个无法编译的 snippet 就会让网站构建失败。这从根本上杜绝了文档代码"腐烂"(rot)——代码一旦变更,构建即报警,而不是等到读者踩坑。
仓库证据充分:文档页中大量使用<CodeSnippet>,例如 crash-course.mdx 单页出现 26 处,state.mdx、actions.mdx 也各有十余处。而示例源码集中存放在 examples/docs 下,按主题分目录:actors-state/、actors-actions/、actors-crash-course/、actors-request-handler/、actors-sqlite/等,与文档页面一一对应。
示例工程本身是可编译的独立包:examples/docs/package.json 名为docs-snippets,提供check-types脚本(tsc --noEmit),依赖rivetkit(workspace:*)、@rivetkit/react、@rivetkit/engine-api-full、effect、hono、pg、drizzle-orm等——它涵盖了文档示例可能用到的全部 SDK 与第三方库,从依赖层面保证类型检查真实有效。
路径规则:相对仓库根
<CodeSnippet file="examples/docs/actors-state/durable-basic.ts" />Snippet 路径相对本仓库根目录,这样同一个路径在本仓库和官网站点(通过 symlink 消费)解析结果一致。这也是为什么示例统一放在仓库根下的examples/docs/,而不是散落在docs/content内部。
region:嵌入文件的局部片段
当文件过长、只想嵌入其中一段时,用region="name",并在源码中用注释界定:
<CodeSnippet file="examples/docs/actors-request-handler/http-api-fetch.ts" region="fetch" />对应源码 examples/docs/actors-request-handler/http-api-fetch.ts 中的界定符:
// docs:start fetch // Replace with your actor ID and token const actorId = "your-actor-id"; // ... // docs:end fetch export {};另一个实例是 examples/docs/actors-inspector-tabs/inspector-tab-types.ts,用// docs:start types/// docs:end types围住一组类型导入,再被 inspector-tabs.mdx 以<CodeSnippet file="examples/docs/actors-inspector-tabs/inspector-tab-types.ts" region="types" />引用。注意源码文件在片段之外通常还需要export {}(或类型导出)保持自身模块完整——snippet 是"从可编译文件中截取",而不是"为文档临时拼一段"。
@nocheck 的适用边界
规范允许@nocheck,但仅限当前分支尚不存在的 API。例如 state.mdx 中的外部数据库示例:
import { actor } from "rivetkit"; import { Pool } from "pg"; // One shared pool for the whole process, created once and reused by every actor const pool = new Pool({ connectionString: process.env.DATABASE_URL }); // ...这表示:示例引用了真实 API,但因环境(如未安装pg的 CI 或 API 尚未落地)跳过类型校验。反过来说,能编译的代码就不该加@nocheck,加了反而掩盖真实类型错误。
CodeGroup 与多文件 workspace
<CodeGroup>用于并列展示同一主题的多个变体,如 state.mdx 中 Durable 类型的三个文件:
<CodeGroup> <CodeSnippet file="examples/docs/actors-state/durable-basic.ts" title="Basic" /> <CodeSnippet file="examples/docs/actors-state/durable-dynamic-init.ts" title="Dynamic init" /> <CodeSnippet file="examples/docs/actors-state/durable-with-input.ts" title="With input" /> </CodeGroup>跨多个文件的完整示例则用<CodeGroup workspace>,每个文件一个<CodeSnippet>。仓库中的实际用例见 websocket-handler.mdx(两处)、sqlite-drizzle.mdx 与 clients/swiftui.mdx。
可内联的代码类型
禁止内联的规则只针对 TypeScript。Shell 命令、YAML、Dockerfile 和终端输出可以放心使用普通 fenced block。例如 request-handler.mdx 中配合 region 示例展示的 curl 命令:
curl -X POST "https://api.rivet.dev/gateway/{actorId}/request/increment" \ -H "x-rivet-token: {token}"以及<Tabs>/<Tab>切换组件(见 crash-course.mdx 的 State、Vars、Connections 示例)都属于允许内联的展示结构。此外,每个 TypeScript snippet必须包含其 imports 并定义所有引用到的符号,保证片段脱离文档上下文也能独立编译。
内容边界:什么不该写进这里
docs/CLAUDE.md用 "What does not belong here" 一节明确划定了三类禁区,避免文档包与网站仓库职责混淆:
- 营销页面(Marketing pages):归网站仓库,本仓库只承载技术文档;
- 部署与自托管指南(Deploy and self-hosting guides):在网站仓库写一次,跨产品模板化复用,不写每产品的副本。这与 sidebar.json 中"Self-Host 标签由网站生成"的机制互相印证;
- 网站组件(Website components):不允许通过相对路径或别名从网站仓库 import,页面必须只依赖站点已提供的组件(如
<CodeSnippet>、<CodeGroup>、<Tabs>、<Accordion>这类声明式组件)。
这条边界保证了 docs 目录的纯净:它是内容源,不是渲染环境。编写页面时只使用网站约定的声明式组件与规范允许的内联代码类型,页面才能在官网正确渲染。
术语体系:一份贯穿全站的词典
docs/CLAUDE.md的 Terminology 一节定义了强制性的术语使用规则,适用于所有对外发布内容。它们不是"建议"而是"硬约束",直接影响检索与 Agent 理解的一致性:
| 场景 | 必须使用 | 禁止使用 |
|---|---|---|
| 负责路由、调度、持久化的服务 | control plane | engine、server、orchestrator |
| 运行用户代码(带 Rivet SDK)的进程 | worker | envoy、runner、node、compute、data plane |
| 部署级名词 | 不使用 "agent"(agentOS 与 Actors 存在不可恢复的语义冲突) | agent |
| 代理基础设施 | 不出现 "envoy"(Envoy Proxy 是 CNCF 顶级项目,内部代码另有命名) | envoy |
| 托管服务名称 | Rivet Cloud("Rivet Compute" 已退役) | Rivet Compute |
| 产品拼写 | agentOS | AgentOS |
| 专有名词 | Rivet Actor大写(通用 "actor" 小写) | 大小写混用 |
| 域名 | rivet.dev | rivet.gg |
这套术语的工程价值在于:文档、SDK、官网与 Agent 消费方共享同一套命名,避免了"一个概念多个名字"造成的歧义。例如把运行用户代码的进程统一定义为 worker,配合examples/docs与docs/content中一致的页面命名(actions、events、queues、sqlite 等),让文档体系在机器可读层面也保持稳定。
写作规范:句子、标点与"不记录增量"
写作层面的两条硬规则:
- 注释与正文一律使用完整句子,绝不使用破折号(em dash),需要分隔时用句号。这既保证了可读性,也避免了部分渲染管线对破折号的解析问题;
- 不记录增量变化(Do not document deltas)。一个从未见过旧版本的读者,从"这个功能曾经叫 X,后来改名为 Y"这类表述中得不到任何价值。文档应只描述当前状态的最终形态。
这两条与"术语不回溯历史"(如 Rivet Compute 已退役,直接写 Rivet Cloud)共同构成了面向当前版本的写作观。
本地预览与发布链路
docs/CLAUDE.md提供了完整的本地预览流程:将网站仓库克隆到本仓库旁边,网站会自动检测兄弟目录并实时提供本目录的页面:
git clone <网站仓库地址> cd rivet-website && pnpm install && pnpm dev需要排查或切换产品文档来源时,有两个实用操作:
pnpm assemble会打印每个产品解析到的 checkout,用于确认本仓库的 docs 是否被正确链接;- 指向其他 checkout 时,重新指向 symlink 即可。该 symlink 是 gitignored 的,
assemble会保留已存在的 symlink:
ln -sfn /path/to/this/repo/docs/content src/content/docs/<product>整体发布链路可以归纳为:本仓库编写(docs/content页面 +examples/docs示例 +sidebar.json导航)→ 网站仓库 symlink 消费 → assemble 校验与链接 → 类型检查 → 站点构建发布。任何一环(如 snippet 编译失败)都会在构建期暴露问题,这正是该工程规范追求"早失败、可追溯"的体现。
总结
Rivet Actors 的 docs bundle 规范用一套清晰的工程手段解决了文档工程的两个根本问题:示例永不腐烂(通过examples/docs源码 + 类型检查 +<CodeSnippet>强制嵌入)与内容永不漂移(通过术语词典、内容边界、Frontmatter 与 sidebar 双登记机制)。对于想要为本仓库贡献文档的开发者,最低限度的入门清单是:把页面放进docs/content/的正确子目录、写全 title 与 description、用<CodeSnippet>引用 examples/docs 中的真实示例、同步更新 docs/sidebar.json,并严格遵循术语与写作规范。
【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actors
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考