一键安装
新用户只需运行安装器;它会安装 CLI、生成配置并进入交互式 setup:curl | bash 时可先下载、检查,再执行:
git、gh 和调度器 user session(Linux 为 systemd,macOS
为 launchd);uv 会在需要时提供 Python 3.14。安装器还会替你安装
Pi CLI(通过
npm install -g --ignore-scripts @earendil-works/pi-coding-agent)——
Node ≥ 22.19(npm 随附其中)是它唯一不替你安装的前提:请从
官方下载页自行安装 Node,安装器会校验版本。
手动安装时,orbi setup 找不到 orbi.toml 会生成一个:相邻存在
.orbi.example.toml 就用它,否则用 CLI 包内自带的示例——且不会覆盖已有配置。
PyPI 安装
CLI 已发布到 PyPI:orbi-cli——
同时提供 sdist 和 wheel,要求 Python ≥ 3.14。发布包名为
orbi-cli;安装后的命令仍是 orbi。
uv tool install orbi-cli 把它装进隔离的 tool 环境(系统解释器过旧时,
uv 会自动供应兼容的 Python 3.14);在已激活的 Python ≥ 3.14 环境里,
pip install orbi-cli 是普通 pip 路径:
uv tool install 显式加
--python 3.13,会以 uv resolver 消息
orbi-cli==<version> depends on Python>=3.14 失败;在已激活的旧版本环境里
运行 pip install orbi-cli,则报
No matching distribution found for orbi-cli。两种情况的修复方式相同:
选择兼容的解释器——给 uv tool install 指定 --python 3.14(uv 自动
供应),或在 Python ≥ 3.14 构建的环境里运行 pip。
卸载 tool 安装用 uv tool uninstall orbi-cli(完整卸载步骤见
Operations);这些安装只给你 orbi 命令本身。要运行
Orbi 本体,用上方的一键安装或下面第 2 步的 editable checkout
安装——Orbi 部署驱动的是 editable 安装,CLI 跟随同步后的 checkout。
前提
这些前提由你自己安装——orbi setup 只检查它们(校验
git、gh、uv 和调度器 user session——Linux 为 systemd,macOS
为 launchd);它从不自动安装
系统包、从不安装 gh、也不执行 gh auth login(你先登录,setup 只
验证登录状态)。orbi check 是覆盖同一清单的只读前置条件门禁,另外校验
Python 版本、pi CLI、配置文件、各仓库访问权限、git transport 和模型
provider——失败即快速退出,并给出原因、修复动作和官方文档链接。
用官方安装器安装
uv(已对照
uv 官方文档):
gh——最低已验证版本为 2.94.0:Runner 的
队列扫描用到 gh api --paginate --slurp(gh 2.48.0 引入)和原生的
blockedBy 依赖字段(gh 2.94.0 引入)。过旧的包会让 orbi setup 通过,
但每个 tick 都以 unknown flag: --slurp /
Unknown JSON field: "blockedBy" 失败,永远领不到 Issue——Ubuntu 24.04
的发行版包(2.45.0)正是这种情况;Fedora(2.97.0)与 Arch(2.100.0)
当前原生满足最低版本。在 Ubuntu/Debian 上,用官方 apt 仓库安装或修复
(官方 Linux 安装说明):
gh --version 验证。
Pi 的 npm 包在 engines 里声明了 Node ≥ 22.19.0 的下限,但 npm 并不
强制执行:在更旧的 Node 上,上面的 npm install 仍然报告成功,随后每一次
pi 调用都会因 bundle 里的 SyntaxError 崩溃——这是安装路径上最难诊断的
故障。Debian trixie 和 Ubuntu 24.04 的发行版默认 Node 都低于该下限。修复
方法:安装 Node ≥ 22.19,再用上面的命令重装 Pi。orbi check 会真实执行
pi --version(只在 PATH 上找到并不算通过),探针失败时会在 fix= 里
给出这个下限。
Pi 必须配置一个能稳定服务 coding agent 的 provider(system prompt +
tool schemas + 长 session)。派活之前先用一次真实调用验证 endpoint——
不要假设 key 或模型服务可用:
local-llm-kv-cache proxy 是可选增强(本地 llama.cpp 模型更快的
prefix 复用),不是核心前提——见可选组件。1. Clone 仓库
2. 安装 CLI
正式使用方式是安装后的orbi console script(pyproject.toml
的 PEP 621 打包把 orbi = orbi:main 映射为可执行文件),
以 editable uv tool 安装——这是官方本地部署方式(Issue #152)。
在 clone 目录里安装,--python 传一个兼容的解释器(Issue #861):
系统 Python 是 3.14 或更新(Fedora 43、当前 Arch 自带)时直接用
python3,否则传 3.14 让 uv 自动供应或选择——Ubuntu 24.04 系统自带
Python 3.12,用精确路径把安装钉死到该系统解释器会因依赖解析失败而退出
1;而 python3、3.14 这类宽泛写法会让 uv 选取或供应一个满足要求的
解释器(在这类宿主机上即托管安装的 CPython 3.14):
uv tool 把 CLI 装进隔离的 tool 环境,可执行文件落在 ~/.local/bin
(调度器 unit 的 PATH 已包含该目录)。
两种部署模式(Issue #330,PR #334):安装命令两者完全相同——orbi
永远从 orbi clone 安装一次——区别在配置。自举模式(本页默认):
repo_dir 就是 orbi checkout 自身,部署 home 和交付 checkout 是同一
个目录。外部单仓库模式:deploy_home 指向 orbi checkout,
repo_dir 指向外部用户仓库 X——orbi 安装一次后指向 X,X 里开
ai-ready issue 即被开发,且绝不会从 X 重装 CLI。配置差异见第 3 步
和下面的「外部单仓库模式(deploy_home)」一节。
为什么必须 --editable:非 editable 安装会把源码复制进 tool
环境的 site-packages;service 的 ExecStartPre 每次启动前把 checkout
快进到最新 main——源码被复制后 CLI 仍在执行旧副本(启动死锁:
Issue #152)。editable 安装下 tool 环境直接从 clone 目录导入
orbi,下一个 CLI 进程(下一个 timer 启动的 Runner)自动取到
merge 后的代码:普通 Python 源码与 systemd 模板/迁移代码变更不需要
任何重装或升级命令。
自 src layout(Issue #168)起,editable finder 映射整个
src/orbi/ package 目录——新增 package 模块不需要重装
(#158 的 stale 模块清单问题已在根上修复)。当其余打包输入变化
(pyproject.toml 的依赖、入口点、包名、构建后端或 Python 版本)时,
Runner 每次启动(在任何 slot/claim 之前)自动刷新安装——刷新失败会
fail fast(结构化 cli_install_failed 行:原因 + 精确修复命令)。这个
Runner 内刷新在 console script 连 import orbi 都失败时不可达
(#248 现场:#168 的 src 布局迁移让已安装的 editable finder 过期,Runner
在 import 阶段就死了,刷新根本没机会运行)——这类损坏由 service 的第一个
ExecStartPre 步骤在 Python 进程外自愈:它探测 orbi --version,
探测失败时执行同一条 editable 强制重装——排在第二步(orbi sync-engine-source,Issue #535)之前,因为第二步需要可用的 CLI
(完整机制见运维)。
orbi doctor 报告一致性
(cli_source: clean 或 cli_source: DRIFT + 结构化 cli_source_drift
行),orbi setup 幂等地校验或重装。发布包不携带第三方运行时
依赖、token 或用户目录——配置文件和用户 systemd 目录保持机器本地。
checkout 根目录没有 orbi.py(与 package 同名的 flat 文件
会遮蔽 checkout 根目录在 sys.path 上的一切进程的已安装 package);
直接执行入口 python3 -m orbi.cli 运行与 console script 完全
相同的代码,保留为开发/兼容路径。
3. 创建配置
仓库带一份提交的 example;真实配置是本地状态(gitignored)。orbi setup 会在配置缺失时从仓库提供的 example 创建 orbi.toml。
配置保存在 orbi.toml(相对路径相对配置文件目录解析)。ORBI_CONFIG
可选择其他文件,orbi check 会校验它。完整参考见配置参考。
第一次运行所需的最小配置:
deploy_home 设为 Orbi checkout,并参阅配置参考。
外部单仓库模式(deploy_home)
Issue #330(PR #334)把 orbi 的部署 home 与交付 checkout 解耦:orbi 从 orbi 仓库安装一次后,可以指向任意用户仓库 X——在 X 里开ai-ready Issue,会被领取、在 X 的 worktree 里实现、对 X 开 PR。
- 自举模式(默认):
repo_dir就是 orbi checkout 自身——部署 home 和交付 checkout 是同一个目录(deploy_home缺省,取repo_dir)。 本页第 1–8 步描述的就是这个模式。 - 外部单仓库模式:
repo_dir是用户仓库 X,deploy_home是 orbi checkout。两个 checkout 各司其职:deploy_home(orbi checkout)——CLI 自更新来源(editableuv tool安装、ExecStartPrefast-forward 与 CLI 自愈)、systemd/unit 模板({{ORBI_REPO_DIR}}占位符渲染的是这个路径)、labels.toml、prompt 默认;repo_dir(用户仓库 X)——交付 checkout:Issue 从 X 领取,任务 worktree 从 X 冻结的origin/<base_branch>创建,PR 对 X 打开, slot 锁在<repo_dir>/.orbi/slots/。
<deploy_home>/orbi.toml 读配置
({{ORBI_REPO_DIR}} 占位符渲染的是 deploy home 路径),所以
orbi.toml 和可选的 .orbi/env 放在 orbi checkout,而不是 X:
<repo_dir>/.worktrees/;
workspace_root 是告诉实现者 agent「可修改仓库所在目录」的路径
({{WORKSPACE_ROOT}} prompt 占位符);未设置的 prompt /
prompt_review 相对 deploy_home 解析。)
其余一切——第 4–8 步(模型 provider、orbi setup、手工 tick、smoke
walkthrough、timers)——不变:orbi setup 从 deploy_home 读标签、
CLI 安装和 unit 模板,检查交付 checkout repo_dir(见一次性
setup)。
一台机器跑多个部署(Issue #747)
一台机器可以承载多个相互独立的 Orbi 部署——各自的 checkout、各自的orbi.toml、各自的 timer 组。每个部署的 config 必须声明一个互不相同的
unit_name:
orbi setup / orbi install-units 管理的正是这个部署的单元
(orbi-core@1/2.service 和 orbi-core@1/2.timer);第二个部署配
unit_name = "website",在同一台机器上管理 orbi-website@1/2.*。
一台机器上只允许一个部署不设 unit_name——它独占共享的 orbi@1/2
命名。
不要手工编写 systemd unit 文件。每个 tick 的漂移自愈只比对当前
unit_name 对应的已装模板单元,手工写的 orbi-core.service 对
所有部署都不可见:模板更新永远到不了它,也没有任何地方报这个缺口。
orbi doctor 让这种绕过可见——它把这些文件列在 unmanaged_units
下,并带出各自指向的 ORBI_CONFIG:
unit_name,运行 orbi install-units
让受管理的 @ 单元接管,然后移除手写的单元文件。
每个任务池一个部署
多个独立部署只有在任务池互不相交时才能共存:每个source_repos
任务池只能由一个部署服务,无论这些部署在同一台机器还是不同机器
上。不同的 checkout、不同的 unit_name 或不同的 active_milestone
都不能隔离共享的任务池——这些部署仍然扫描并领取同一批 Issue,而各自
部署目录下的本地 slot 和领取锁无法互相协调。source_repos 互不相交
的部署——例如每个仓库一个部署——完全受支持(Issue #1518)。
要在同一个仓库上并发交付,请只用一个部署并调高它的
max_concurrency(第 8 步与 Operations):多出来
的 Runner 实例共享该部署的 slot 与领取/恢复状态,slot 因此仍能正确
串行化领取。调高 max_concurrency 只增加并发——它不会扩大 fresh-claim
范围,也不会改变 active_milestone 边界(第 6 步)。
失败场景是具体的:一个独立部署看不到另一个部署正在进行的交付,可能
把那次运行误判为丢失并重启它——两个部署随后争抢同一个 Issue。让每个
部署使用互不相交的 source_repos;当同一个仓库需要更高并发时,保持
单个部署并调高 max_concurrency。
4. 配置模型 provider
Runner 从不启动或管理模型进程——它启动 Pi,而 Pi 需要一个能真正 使用的 provider。有两条路径,只需要其中一条:路径 A:Pi 自己的 provider(不配置 Orbi)
pi_providers 不设,Runner 就和你手工运行 Pi 完全一样地启动它——
Pi 用自己的 agent 目录和你在那里配置的 provider。派活之前先用 Pi
自己的检查确认 provider 就绪:
路径 B:pi_providers 文件(由 Orbi 管理选择)
把 pi_providers 指向一个 Pi 自己的 models.json 形状的 JSON 文件。
每个 run 开始时 Runner 会物化一个 per-run agent 目录
(<worktree>/.orbi/pi-agent/,gitignored),其 models.json
把你的用户 provider 与文件的 provider 合并(id 冲突时文件胜)——你
已有的 provider 继续可用,文件只做添加或覆盖——并为该 run 选中配置
的 provider/model。这份副本按原样写入——apiKey 中的
$VAR / ${VAR} 保持引用本身,由 Pi 1.0 在请求时从 Runner 传给
Pi 进程的环境中插值(Pi 自己的 docs/models.md),所以明文 key 绝不
写进工作目录(Issue #1554)。你的文件本身绝不被修改;选中 provider
的引用无法解析时,配置加载仍然 fail fast。
一个 OpenAI-compatible 远程 endpoint(key 不进文件——引用环境变量):
llama.cpp server(OpenAI-compatible 路由在 /v1,默认
127.0.0.1:8080;--alias 设置 API 报告的模型名,所以下面 id
必须与它一致):
orbi.toml 里选择 provider 和 model(Runner 会以
--provider groq --model groq/compound 传给 Pi;设置
pi_thinking 时再传 --thinking <level>):
为什么选 groq/compound 而不是 qwen/qwen3.8-27b
两个模型都在 Groq 免费档上,qwen/qwen3.8-27b 的请求数配额甚至更高
(1K RPD 对 250 RPD)——但对交付量级的工作,起决定作用的是 token
配额,不是请求数。按 Groq 账号页面的限流数据(用户于 2026-09-12
提供,不是 Orbi 实测——依赖前请重新核对
官方限流表),
groq/compound 是 70K TPM、无日 token 上限,qwen/qwen3.8-27b
是 8K TPM / 200K TPD。
在本仓库的交付量级下,这是性质之别,不是程度之别:本仓库自身交付的
中位数约为每次交付 220 万 token(implement 与 review
合计;来源是一个带 CI、有 Issue 规范的 Python 仓库——对其他仓库
未验证),所以 200K TPD 连一天一次的中位交付都覆盖不了,8K TPM
本身就意味着数小时的限流等待。token 墙先于请求墙到来,这正是更高
的 RPD 在这里不起作用的原因。因此模板、
provider 指南与本指南统一钉在 groq/compound
上——它的 TPM 同样偏低,仍然只适合短小、边界清晰的 coding Issue,
不适合长上下文仓库分析。这些是账号限额,不是 Orbi 承诺;真实的
Groq 请求、usage 计量与 429 响应在本文中仍未实测。
让 API key 不进仓库、不进文档
文件里 key 以环境变量引用("$GROQ_API_KEY");真实值放在
gitignored 状态目录的 env 文件里,由 systemd unit 在 service 启动时
加载:
EnvironmentFile=-{{ORBI_REPO_DIR}}/.orbi/env(Issue #172);
{{ORBI_REPO_DIR}} 占位符在安装时被替换为你的 checkout 路径
(Issue #262),所以已安装 unit 的 EnvironmentFile 自动指向
你的 .orbi/env——无需手工编辑。无 key 的本地 server 完全
不需要 env 文件(上面的 "local" 字面量占位即可通过形状检查)。
Runner 校验什么(fail fast,在任何 slot/claim 之前)
- 文件存在且是合法 JSON,
providers对象非空; - 每个列出 models 的 provider 都有非空
baseUrl和api(provider 级或 model 级); - 选中的
pi_provider和pi_model在文件里有定义; - 选中 provider 的
apiKey环境变量引用能解析出非空值——变量缺失 或为空会让启动失败,错误里只报变量名(绝不报 key 值)。
provider 边界
文档化且经过测试的路径是 OpenAI-compatible endpoint (api: "openai-completions")——本地 llama.cpp server 或任意
兼容 API。文件原样传给 Pi,所以 Pi 目录里的其他 catalog 条目继续
可用;Orbi 不测试、也不保证该边界之外的逐 provider 集成。
5. 运行一次性 setup
setup 入口用一条命令完成全部初始化:校验你安装好的前提(git、gh、 python3、uv、systemd user session——缺失会 fail fast 并给出可执行的 安装指引)、校验或重装 editable CLI 安装(Issue #152——运行中的 CLI 必须从部署 checkout 导入)、验证gh auth status 和仓库权限、从仓库
管理的 labels.toml(标签名/颜色/描述的唯一事实源——commit 从不创建
标签,缺标签会让扫描静默漏掉对应状态)声明式对齐平台标签、安装
systemd user units 并 enable timer、检查 checkout、报告可选模型 proxy:
orbi suggest。只有在
终端上——并且模型 provider 为 ok、仓库没有任何带交付标签的 Issue
(ai-ready、ai-in-progress、ai-pr-opened、ai-merged 或仓库
自己的 dispatch_label)时——它才会问一次:
Scan OWNER/REPO and suggest three Issues to deliver? [Y/n]
Y(或回车)运行交互式 orbi suggest 流程:读取仓库、提出最多三个
Issue、每个建议问一次,把你确认的 Issue 创建或打标签,最后打印它创建
或标记的每个 Issue 的 URL。没有终端的调用者永远不会看到提示:setup 打印
Run 'orbi suggest --repo OWNER/REPO' to get three suggested Issues.,
而 --json 既不打印问题也不打印该提示。之后任何时候
orbi suggest --json 都会把 Suggestions 文档(repo、base_sha、
session_dir 与 suggestions)打印到 stdout 且不写任何东西。
6. 手工运行一个 tick
手工命令只用于首次验证和排查——正常运行由 timer 调度(第 8 步):PYTHONPATH=src 把 checkout 的 src/ layout 放进 import 路径;
-m 运行 Runner package 模块——已安装的 orbi console script
运行的是同一个 tick。)
一个 tick 最多做一件事:恢复一个已打开的 PR(review/fix/merge),或
领取一个 ai-ready Issue(带 p0 标签的 Issue 最先被领取,然后是
bug 标签的,最后是普通 feature;设置 active_milestone 后只领取该
Milestone 的 Issue——Issue #139),然后退出。ready 队列为空时干净
退出,不领取任何东西。
7. Smoke walkthrough(从零)
验证环境可用的最小端到端证明。在第 1 步的 clone 目录里运行;每条命令 都相对该目录。验证完整链路
交付不止于 PR——同一个 run(同一 run id、分支、worktree、PR)在后续 tick(手工或 timer)里继续走独立审查和 merge。每个阶段都有具体、可 检查的成功标准:ai-ready → ai-in-progress → ai-pr-opened → ai-merged,PR 已合并且 body 带 Fixes #<n>(GitHub 在 merge 时原生
关闭 Issue),journal 显示 run_end ... result=pr_opened、
review ... verdict=pass 和 merged pr=...。任何一步失败,Issue 会
被单独标记 ai-blocked 并留下现场(run id、分支、worktree、
session、phase、last activity、具体错误),journal 显示
run_failed ... reason=...——恢复方法见运维。
故障排查
真实失败现场、证据在哪里、怎么修。它们全部 fail fast——没有静默重试。
标签生命周期、journal 字段和恢复规则见运维;
review/merge 契约见工作流。
8. 验证 timers
setup 已经安装 unit 模板,并按max_concurrency enable timer 实例:
N 时启用 @1 到 @N(上限 MAX_RUNNER_INSTANCES = 5;各自触发自己的 service
实例——见运维);验证一下:
ExecStartPre
fast-forward 和每实例启动语义定义在运维(Timers)。
容量为 N 时 N 个实例可以同时运行;容量和启用的 timer 数都由
max_concurrency 决定,flock slot 仍是最终安全边界。
提交的 unit 模板与机器无关:它们携带
{{ORBI_REPO_DIR}} 占位符
而不是硬编码的 checkout 路径(Issue #262)。orbi install-units
(以及 orbi setup)在安装时用部署 home(deploy_home,缺省
repo_dir)的解析后路径替换它,因此任何位置的 clone 都能干净部署
——无需手工编辑已安装的 units。外部单仓库模式(Issue #330)下,unit
的 WorkingDirectory、ORBI_CONFIG、EnvironmentFile、ExecStartPre
fast-forward、base-sync.lock 和 CLI 自愈全部作用于 orbi 源码
checkout,绝不作用于交付 checkout X。ExecStart 是已安装的 orbi
CLI,保持 home 相对(%h/.local/bin/orbi)。仓库模板仍是其余一切的
唯一事实源——漂移检测见运维。