OpenRig 世界包(World Pack)编写指南:用八区域为 Agent 构建持久运行环境
OpenRig 世界包(World Pack)编写指南:用八区域为 Agent 构建持久运行环境
世界包(World Pack)是 OpenRig 中"定位 Agent"的载体:它用一组简短文件描述 Agent 身处何处、那里存在什么、以及应当如何行动。本文以仓库内置的
world-example模板为主线,结合world-public公共世界包与rig context命令族的源码实现,完整讲解世界包的安装、检索、解剖、八区域编写方法、Book World 实战练习与可验证性原则。读完本文,你将掌握如何为一个项目(书籍写作或软件开发)亲手写出第一个可安装、可验证、可被 Agent 正确检索的世界包。
什么是世界包
在 OpenRig 中,一个世界包(world pack)的核心职责是把 Agent 安放进一个具体的运行环境。用模板原文(your-world.md)的话说:
A world pack situates an agent: it describes where the agent is, what exists there, and how to act.
也就是说,世界包回答三组问题:Agent 现在在哪里;那里有什么实体、关系和规则;以及 Agent 应该如何在这个环境里行动。它不是零散的任务提示词,而是一份持久化的运行现实(durable operating reality),让 Agent 在 fresh(全新入场)、handover(交接)与 post-compaction(压缩后恢复)等不同情境下都能快速找回自己与世界的关系。
世界与其他上下文类型的边界
世界包不是 OpenRig 中唯一的上下文种类。公共世界包 build-your-world.md 明确给出了四类上下文的一级划分:
- WORLD(世界):Agent 身处何处——实体、关系、规则、历史、状态来源与能力(affordances)。
- LORE(传闻):某个席位(seat)在环境中生活后习得的经验。
- SKILLS(技能):可重复执行的程序化能力。
- MISSION(任务):当前正在做的工作及其意义。
这一划分在源码层面被固化:context-pack-types.ts 中的 ATOM_TAXONOMIES = <a href="https://link.gitcode.com/i/a1c9e35b2899623ee7e7d81ef7dbef92" target="_blank">"world", "lore", "skills", "mission"] 是唯一的 taxonomy 定义源(见 [context-pack-types.ts,并由 context-pack-taxonomy-surface.ts 导出给 CLI 安装校验器共用)。也就是说,"世界"在 OpenRig 中是一个一等公民的分类(taxonomy),不是随意的目录名。
世界包与仓库 AGENTS.md 的关系
如果你的仓库使用 AGENTS.md,start-here.md 明确了两者的分工:仓库指令解释"如何在该代码树内工作",世界包解释"更大的运行现实"——围绕它的实体、关系、规则、历史、状态来源与能力。两者互补,互不替代,也不应互相吞并。判断标准是:属于"这棵树里怎么干活"的内容放 AGENTS.md;属于"这个世界里有什么、按什么规则运转"的内容放世界包。
安装与检索一个世界包
安装:rig context add <pack-directory>
world-example 模板给出的标准安装流程(your-world.md):
rig context add <pack-directory> # 从目录安装一个世界包
rig context list # 确认安装后暴露的 ref
rig config get context.root # 仅在确实需要路径时,取回配置的上下文存储根目录
在源码层面,rig context add 由 context.ts 实现,它会把包目录安装到 $OPENRIG_HOME/context/<name>/,并且只接受普通文件(拒绝符号链接),与 rig specs add 的形态一致。安装前会执行一系列安全校验:assertSafeInstallRef(ref 名称安全)、assertTreeHasNoSymlinks(目录树无符号链接)、assertDestinationNamespaceContained(目标命名空间受控),以及 validateContextPackManifestForInstall(manifest 可安装性校验),详见 context-install.ts 的调用(context.ts)。
检索:rig context get 与 rig context show
rig context get world-example:取回装配好的世界包字节内容,用于阅读;world-public包的校验脚本会确认输出中包含# Enter the world、# Build your world、# Boundaries等章节(见 verify-world.sh 中retrieve-public-pack检查)。rig context show world-example --json:当需要操作安装目录本身(例如运行包内的校验脚本)时,用该命令派生真实的包目录路径,而不要在文章或指令中写死机器相关路径。rig context list:确认当前安装暴露了哪些 ref,以及每个 ref 的relativePath、sourceType(builtin/user_file/workspace)等信息。rig context profile <pack> --situation fresh:按情境(situation)组合出该包的 atom 图谱,并实时派生阅读成本(totalEstimatedTokens),供 Agent 决定该请求多少内容。
CLI 的 context 子命令族(list / show / preview / compose / add / rm / sync)全部经由 daemon 的 /api/context-packs/library/* 路由执行,且支持 claude-code / claude / codex 运行时枚举(contextRuntimeArg,见 context.ts)。
世界包的解剖:manifest.yaml 是入口
一个世界包的最小形态是一个目录 + 一个 manifest。world-example 的清单(manifest.yaml)只有两个文件:manifest.yaml 与 your-world.md,但 manifest 中的每个字段都是理解整个体系的关键:
name: world-example
version: "0"
taxonomy: world
purpose: "A fill-in template showing the anatomy of an OpenRig world pack."
files:
- path: your-world.md
role: world
summary: "A minimal fill-in template for describing an agent's world."
atoms:
- id: your-world
address: your-world.md
taxonomy: world
regions: [identity, ontology, terrain, actors, laws, history, state, affordances]
situations: [fresh, handover, post-compaction]
purpose: depth
runtime: any
order: 10
priority: core
probe:
prompt: "Describe the operating world for a book-writing project."
expect: "The agent fills one coherent world file and derives volatile state instead of creating a folder per region."
字段语义拆解:
taxonomy: world:声明这个包属于世界类。合法值由ATOM_TAXONOMIES枚举约束,安装与解析共用同一份定义,避免 CLI 与 daemon 判定不一致。files:manifest 命名了包内的每个文件,并给出role(本例为world)与summary。公共包则进一步使用orientation、convention、boundaries、claims、verifier等角色,见 world-public/manifest.yaml。atoms:当同一份字节需要附加"情境、运行时、顺序、区域"等元数据时,以 atom 形式声明。world-example只有一个 atom,其regions恰好覆盖全部八个区域;situations声明它适用于 fresh / handover / post-compaction 三种情境;priority: core表示核心内容。probe:定义了一个可验证的"探针"——prompt 与期望输出。world-example 的探针要求 Agent 在书籍写作项目中"填充一份连贯的世界文件并从命令派生易变状态,而不是为每个区域各建一个文件夹"(对应模板中"区域名是 atom 元数据,不是强制目录结构"的声明)。
公共世界包 world-public/manifest.yaml 展示了更完整的设计:三个核心 atom(enter-the-world / author-a-world / know-the-edges)按 order 10/20/30 排序,author-a-world 与 know-the-edges 通过 requires: [enter-the-world] 建立依赖;另有 codex-bootstrap 与 coverage-map 两个仅用于 profile 的 atom,以及 codex-coverage、guided 两个 profile,后者把三个 atom 按 phase(guided-world → project-mission-role-task)编排成一套引导式入场流程。这展示了从"单一文件模板"到"多 atom + profile 组合"的完整演进路径。
编写你自己的世界:八区域详解
world-example 模板把世界的内容组织为八个区域(region)。模板原文强调:区域名是 atom 元数据,不是强制的目录布局——一个连贯的文件可以覆盖多个区域,切忌把同一件事拆成八份副本。
下面结合模板原文逐区说明,并给出书籍世界的填充示例。
Identity(身份)
Name the world and the agent's place in it.
先给世界命名,并说明 Agent 在世界中的位置与角色。书籍世界中可以写:"这是《星港编年史》三部曲的写作世界,你是主编助理,负责维护手稿完整性、追踪编辑决策并提醒作者下一步动作。"
Ontology(本体论)
Define the important kinds of things and what each is for.
定义这个世界里重要的"事物种类"及其用途。书籍世界中可定义:手稿(分卷、章节、修订稿)、来源材料(访谈记录、参考书目、设定文档)、编辑批注(批注与裁决)、决策记录(采纳/否决某段剧情的原因)等。
Actors(行动者)
Name who else is present, what they own, and how to reach them.
列出还有谁在场、他们拥有什么、如何联系他们。书籍世界中:作者(拥有终稿决定权,通过邮件/工作目录联系)、责任编辑(拥有风格与文法裁决权)、插画师(拥有视觉设定)、以及 Agent 自己(拥有什么、向谁汇报)。
Terrain(地形)
Map where code, records, documentation, and operational surfaces live.
绘制代码、记录、文档与运维面所在位置。书籍世界:手稿存放于 manuscript/,来源材料存放于 sources/,决策记录存放于 decisions/,发布物存放于 build/。注意:此处给出的是稳定路径映射;易变的计数、清单与状态应交给命令去派生(见下文 State 区域)。
Laws(法则)
State the durable rules and precedence that govern action here.
陈述持久规则及其优先级。书籍世界可写:"第一卷剧情不可改动,除非作者在决策记录中明确授权;风格裁决优先级:作者 > 责任编辑 > 语法工具;涉及发布日期的决策必须记录在 decisions/ 并引用证据。"软件世界的同类物是工程规范、约定与权限边界(映射关系见下文"Book World 练习")。
History(历史)
Record prior decisions and events that explain the world's current shape.
记录解释世界当前形态的既往决策与事件。书籍世界:为什么采用双时间线叙事、第三卷为何删去某支线、出版节奏如何从季更改为月更……这些"为什么"是库存与目录无法发现的,必须由作者亲手书写。
State(状态)
Point to commands or sources that derive what is true right now.
指向能够派生当前真相的命令或来源。书籍世界:当前章节完成度、字数统计、待编辑批注数——这些都应通过命令(如 manuscript/status.sh 或仓库脚本)实时派生,而不是在文件中抄一份会过期的答案。这一原则贯穿 OpenRig:rig whoami --json 派生身份、rig ps --nodes --json 派生拓扑、rig context list 派生可用包、rig --help 派生命令面(见 start-here.md)。
Affordances(能力)
List what the agent can do and the trigger for reaching each capability.
列出 Agent 能做什么,以及触发每种能力的条件。书籍世界:当收到"生成下一章大纲"指令时,读取设定文档并产出大纲草稿;当手稿通过校验脚本时,更新发布预览;当决策记录出现冲突时,向作者请求裁决。
区域是标签,不是目录
再次强调模板的告诫:The region names below are atom metadata, not a required directory layout. 在 manifest 的 regions 字段中给 atom 打上 identity, ontology, terrain, actors, laws, history, state, affordances 标签即可(这正是 world-example/manifest.yaml 的写法),消费方可以按元数据过滤,但不存在按区域子集组合的操作——公共世界包明确声明不承诺 region selector(见 build-your-world.md 与 claims.yaml 中的 no-region-selector),并把该能力留给未来的 profile-composer 工作。
实战练习:Book World
模板给出了一个可立即执行的练习(your-world.md):
Run
rig context get world-example, copy this pack, and make the project a book world by describing the writer, manuscript, sources, editorial rules, decisions, current draft state, and next useful actions in a few coherent files.
练习步骤:
rig context get world-example取回模板字节;- 复制包目录(
manifest.yaml+your-world.md); - 把八个区域逐个替换为书籍世界的事实:作者、手稿与来源、存放位置、编辑规则、塑造了当前稿态的决策、如何派生当前稿态、Agent 接下来有用的动作;
- 保持文件数量少而连贯("a few coherent files"),读起来像一个地方而不是一套档案系统——如果排布感觉像文件柜而非居所,就简化它。
为什么用"书"作为练习对象?公共世界包解释了这个设计选择(build-your-world.md):模型的世界构建流畅度在书籍语境下需要最少的翻译成本,而"毫无软件背景的读者"恰恰是最难的陌生访客情形。更重要的是,书籍世界与软件世界之间存在直接的映射:
| 书籍世界 | 软件世界 |
|---|---|
| 手稿 | 代码库 |
| 编辑规则 | 工程规范与约定 |
| 稿态(派生) | 构建与部署状态(派生) |
| 作者/编辑 | 团队 |
也就是说,书籍练习学到的方法可以平移回软件世界:把命名文件与 manifest 当作规格形态、把逐条可失败的检查与校验器当作测试套件、把"从源头派生"的命令当作反馈回路——世界构建提供信息架构,软件形态提供可建造性。
让世界可验证:Claims 与 Checks
world-example 模板的 Checks 区域承载了整个体系最重要的原则(原文):
For every checkable authored claim, add a named check that can fail; flag taste or genuinely unverifiable claims instead of dressing judgment up as a test; and derive paths, counts, inventories, and live state from commands rather than copying current answers into this file.
拆解为三条可执行规则:
- 每个可检查的声明都要有一个能失败的命名检查。公共世界包的 claims.yaml 把每一条声明映射到
check: <name>或flagged: "<理由>",前者由 verify-world.sh 中的同名检查背书。 - 品味或真正无法验证的声明,用 flag 标注,而不是把判断伪装成测试。例如
world-purpose声明被标记为flagged: "Authored purpose and taste; no live scan can prove it."——没有任何实时扫描能证明"世界是持久运行现实"这个判断,诚实标注比强行造测试更符合体系精神。 - 路径、计数、清单与实时状态一律从命令派生,而不是把当前答案抄进文件。这正是
author-derive-rule的全部含义:"书写库存无法发现的作者关系,指向命令来回答会变化的事实;当实时系统能回答时,不要背记花名册、路径、计数、状态或命令列表"(claims.yaml)。
verify-world.sh 是这套原则的活样板:它以 [ok] / [FAIL] / [skip] 三种输出逐项检查包内声明,末尾输出 N passed · N failed · N skipped 并以退出码表示结果。值得注意的检查包括:rig context get world-public 的装配内容必须包含三章标题、rig context profile world-public --situation fresh 必须返回正向 token 总数且包含三个核心 atom、rig whoami --json 必须返回完整席位身份、rig ps --nodes --json 必须包含当前 canonical session、甚至会用临时 ref 实测 rig context add 的安装与 rig context rm 的清理闭环(见 verify-world.sh)。这套"声明清单 ↔ 命名检查 ↔ 可失败校验器"的对应关系,就是世界包防止"声明漂移成有后果的谎言"的防线。
边界与最佳实践
公共世界包不做什么
boundaries.md 明确划出了公共世界包的边界——它只覆盖共享的世界结构与发现面(四类上下文分离、八区域元数据、作者/派生规则、最小编写约定、发现命令),不提供特定 rig 的现实、当前任务、本地传闻、仓库指令或不可逆的产品/运营判断。这些缺口不是"用像样的散文填上"的:应读取本地世界、任务、传闻、仓库指令与实时命令面,仍无来源时向决策所有者提问。
命名空间边界
公共世界包以 world-public 为 ref;本地安装的私有世界保持 rig-local,使用自己的 ref,永远不会被这个内置包遮蔽。校验脚本会验证 world-public 出现在列表而本地 world/install 仍保持本地命名空间(private-ref-boundary 检查)。这意味着你可以放心安装示例包做练习,不会污染你自己的世界。
最小起步建议
公共世界包给出一个克制到极致的起步形态(build-your-world.md):
book-world/
manifest.yaml
world.md
boundaries.md
随后按需演进:manifest 命名文件,散文陈述持久目的与信任关系,同一份字节需要情境/运行时/顺序/区域元数据时再加 atom,作者声明可能漂移成有后果的谎言时再加 claim 台账与校验器——不为还没有读者的仪式增加复杂度。十个维度的诚实覆盖图(product / topology / context / skill / queue-custody / source-worktree / proof-review / lifecycle-release / continuity-recovery / host-boundary)则帮助 Agent 知道"何时该读哪一份精确地址"(详见 build-your-world.md 的覆盖图表),阅读成本由 profile 组合时实时派生,而非抄写进包内。
总结
从 world-example 的最小模板到 world-public 的完整公共世界包,OpenRig 的世界包体系可以浓缩为一句话:用命名文件陈述持久关系,用八区域元数据标注内容维度,用可失败的命名检查约束声明,用命令派生一切易变事实。 安装用 rig context add <pack-directory>,确认用 rig context list,阅读用 rig context get <ref>,取路径用 rig context show <ref> --json,组合阅读图谱用 rig context profile <ref> --situation fresh。先用 Book World 练习打通"信息架构 + 可建造性"的心智模型,再把它平移回你的软件项目,你就能让 Agent 在 fresh、handover、post-compaction 三种情境下都清楚地知道:自己在哪里、那里有什么、该如何行动。