项目介绍
Agent 开发框架 · 2026-11-09 更新 · 本站尚未实测
rote 是一个开源命令行工具,用来把已经验证可用的 Claude 技能或 Agent 技能(一个 SKILL.md 加 references/ 目录)编译成带类型、确定性的流水线。按照 README 的定位,它把固定逻辑和工具编排搬进可审阅的代码里,只在真正需要判断的步骤上调用模型;原来的 10 到 20 分钟 Agent 循环可以变成后台工作流,并用更少的 token 反复运行、做回归测试。
README 明确说明该项目处于 pre-1.0 阶段:BDR 示例上的端到端流程可用,但涉及外部厂商 API 的提取模块目前是 NotImplementedError 桩代码,需要自行补全;Restate 适配器尚在计划中。
核心能力
点击能力名称查看输入、输出和原文依据。
- 技能编译:
rote compile读取技能文本,确定流水线结构(节点种类、连接方式、必选节点、人工审批点),并产出与运行时无关的中间表示pipeline.yaml和各节点的类型签名、提取出的 Python 模块与测试。 - 五类节点:
pure_function、external_call、llm_judge、agent_loop、hitl_gate,把确定性部分与模糊判断部分分开。 - 多运行时适配:同一份 IR 可输出到编译后技能、DBOS、Temporal、纯 Python、Cloudflare Workflows、DBOS TypeScript、Inngest。
- 人工审批闸门:
hitl_gate可在持久化运行时上挂起并在收到信号后恢复。 - 测试与评估:编译时对生成的确定性代码运行测试(可用 OS 沙箱),
rote eval可输出前后对比记分卡,--run会真实执行两侧进行测量。 - 按节点换模型:生成的 judge 运行时读取
ROTE_MODEL_<ID>与ROTE_BASE_URL_<ID>,可指向 OpenAI 兼容端点(README 举例 Ollama、vLLM、网关)。
实际应用场景
适用场景
适合已经反复运行、准备长期无人值守执行的技能,例如费用审计、运营报表、文档摘要在内的批处理流程;README 明确把探索性、一次性任务列为不适合编译的对象,这类任务应继续保留 Agent 循环。
安装与接入
README 给出以下方式(均为原文命令):
- 安装 CLI:
uv tool install rote-cli或pip install rote-cli;零安装可用uvx --from rote-cli rote ...。 - 在 Claude Code 中作为插件安装:
/plugin marketplace add trevhud/rote与/plugin install rote@rote。 rote compile需要驱动:已安装并登录的 Claude Code(claude)、Codex(codex),或设置ANTHROPIC_API_KEY使用进程内api驱动,后者需pip install 'rote-cli[api]'。rote emit不需要 LLM。- MCP 触发:项目附带
server.json,以uvx --from rote-cli[serve] serve通过 stdio 启动,用于把已编译流水线作为 MCP 工具触发。README 提到/rote:serve与docs/mcp-trigger.md。
具体命令与参数请以仓库 README 为准,本文不补充未在资料中出现的配置。
使用条件与限制
- 是否需要部署
- 需自行准备运行环境,具体要求见正文
- 是否需要注册
- 账号和认证要求见正文;未明确说明的项目仍待核验
- 是否需要 API Key
- 待核验
- 费用与额度
- 费用边界见正文,项目许可不代表模型或托管服务免费
- 所需权限
- 待核验
- 许可证与服务条款
- 待核验
权限费用与限制
- 编译阶段会消耗模型 token:README 示例称 BDR 技能约 13 分钟、约 0.70 美元(Claude Code 上的 Sonnet),属于作者给出的示例数据,实际费用随技能与模型变化,需自行评估。
rote本身不收取编译费用,但 API 驱动按你的 API 凭据计费;使用 Claude/Codex 订阅登录时依赖各自服务条款。- 编译生成的测试代码由 LLM 写出,README 说明默认在 OS 沙箱中运行;若机器上无可用沙箱则跳过测试并标注为未验证,
--trust-skill会去掉沙箱、--no-verify-tests不运行测试,两种情况下都建议先人工审阅生成代码。 rote login用于连接托管服务 Rote Cloud(app.roteskills.com),托管服务的收费标准、数据存放地域与条款资料未说明,待核验。- 各运行时(DBOS、Temporal、Cloudflare、Inngest)的托管与部署成本由对应厂商决定,资料未列出价格。
国内使用情况
网友核验 用户经验分享
与站长实测独立,不代表官方认证或本站已实测。
最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。
分项统计、有效期与样本量
| 核验项目 | 有效人数 | 成功 / 部分 / 失败 / 无法判断 | 成功率 | 最近核验 / 有效期 |
|---|---|---|---|---|
| 官方网站访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| GitHub 仓库访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 安装与运行 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 官方服务国内连接 / MCP 连接 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 国内网络情况 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 国内模型兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 自定义 API | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外服务依赖 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外账号要求 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 中文界面 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 客户端兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 账号及费用信息 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。
最近有效核验
暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。
查看全部有效核验 →国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。
- 官方网站访问
- 尚未实测 待核验
- GitHub 仓库访问
- 尚未实测 待核验
- 官方服务国内连接
- 尚未实测 待核验
- 国内网络情况
- 尚未实测 待核验
- 国内模型兼容性
- 尚未实测 待核验
- 自定义 API
- 尚未实测 待核验
- 海外服务依赖
- 尚未实测 待核验
- 海外账号要求
- 尚未实测 待核验
- 中文界面
- 尚未实测 待核验
- 国内最后核验时间
- 尚未实测
许可与国内使用
仓库 LICENSE 为 Apache License 2.0(Copyright 2026 Trevor Hudson),覆盖仓库代码;托管服务 Rote Cloud、第三方运行时与第三方模型服务各有自己的条款,公开仓库不代表这些服务免费或可任意使用。资料未说明国内网络环境下的可用性、镜像源或合规情况,待核验。README 也提示 PyPI 上另有同名 rote 备忘录库,与本项目的 rote-cli 不能装在同一个环境。
项目资料与来源
字段依据与待核验事项
access:来源确认 · uv tool install rote-cli # or: python3 -m venv .venv && . .venv/bin/activate && pip install rote-cli
project_type:来源确认 · `rote` is an open source CLI that compiles a proven Claude skill or agent skill (a `SKILL.md` plus `references/`) into a typed, deterministic pipeline.
原始 README(折叠技术参考)
# rote
**Compile AI agent skills into cheap, fast, deterministic pipelines that
run without an LLM in the loop.**
[](https://github.com/trevhud/rote/actions/workflows/ci.yml)
[](https://pypi.org/project/rote-cli/)
[](https://pypi.org/project/rote-cli/)
[](https://pypi.org/project/rote-cli/)
[](LICENSE)
<!-- mcp-name: io.github.trevhud/rote -->
**Your Claude skill works. Running it a thousand times does not.**
`rote` is an open source CLI that compiles a proven Claude skill or
agent skill (a `SKILL.md` plus `references/`) into a typed,
deterministic pipeline. It moves the fixed logic and tool orchestration
into reviewable code, and calls a model only for the steps that
genuinely need judgment. A 10 to 20 minute agent loop becomes a
background workflow that costs a fraction of the tokens and can be
regression tested.
### Try it free in 60 seconds
No API key, no subscription, no tokens, no clone. The
[`expense-audit`](examples/expense-audit/) example is a month-end expense
audit skill whose compiled pipeline ships with working code, and it comes
inside the package, so you can emit it and run it before you compile
anything of your own:
```sh
uv tool install rote-cli # or: python3 -m venv .venv && . .venv/bin/activate && pip install rote-cli
# (the first dbos run offers to add the dbos extra; you confirm it)
rote example expense-audit # copies the skill, IR, code and sample input to ./expense-audit
# (zero-install: uvx --from rote-cli rote example expense-audit)
# IR -> a plain Python script, then run it on the sample batch
rote emit expense-audit/expected/pipeline-draft.yaml --runtime python --out expense-audit/app-python
rote run expense-audit/app-python --input expense-audit/input.json
```
`rote example` prints these commands (and the dbos and eval ones) for
the copy it made. `rote example` alone lists what is bundled. Prefer the
repo? `git clone https://github.com/trevhud/rote.git && cd rote`, then
use `examples/expense-audit/` in place of `expense-audit/`.
```
rote run (python): succeeded
0.1s
{
"file_report": {
"report_path": "/home/you/expense-audit/app-python/reports/2026-09-expense-audit.md",
"status": "draft",
"reviewer": null,
"reimbursable_usd": 2395.59,
"pending_usd": 18.75,
"returned_usd": 889.81,
"batch_total_usd": 3304.15,
"auto_approved": ["Dev Patel", "Emi Tanaka"],
"review_items": 1,
"blocked_items": 5
}
}
```
Sixteen expense lines in five currencies went through a parallel wave of
three mandatory checks, a per-employee audit fanned out five ways, and a
report written to disk, with no model anywhere in the loop. The full
skill also parks for the controller's approval, which needs a durable
runtime:
```sh
rote emit expense-audit/expected/pipeline.yaml --runtime dbos --out expense-audit/app-dbos
rote run expense-audit/app-dbos --input expense-audit/input.json \
--signal controller_review='{"reviewer": "Priya Shah", "approved_ids": ["EXP-2403", "EXP-2413", "EXP-2420"], "rejected_ids": ["EXP-2410"]}'
# ... "status": "final", "reimbursable_usd": 2414.34, "returned_usd": 889.81
```
What compiling it bought, measured: we ran the same batch twice each way
with `rote eval --run` (the skill as an agent via `claude -p` on Sonnet,
against the dbos app above):
| | Skill run as an agent | Compiled pipeline |
| --- | --- | --- |
| Wall clock per run | 42.9 s | 9.8 s, mostly DBOS startup |
| Cost per run | $0.22 | $0 |
| Identical output across runs | 1 of 2 | 2 of 2 |
So it's roughly 4x faster in practice, it drops from $0.22 a run to
nothing, and it gives the same answer every time. The agent's two runs
disagreed on where they filed the report. Full results are in
[`examples/expense-audit/scorecard.md`](examples/expense-audit/scorecard.md).
To get a scorecard for any pipeline without running anything, use
`rote eval`. It fetches the live price list once and runs no inference.
Its numbers are an estimate from turn counts, not a measurement:
```sh
rote eval examples/expense-audit/expected/pipeline.yaml
```
`pip` installs don't include `examples/`, hence the clone. The other
examples' extracted modules are `NotImplementedError` stubs waiting for
real vendor API clients, so `expense-audit` is the one that runs end to
end. Details in [its README](examples/expense-audit/README.md).
### Compile your own skill
```sh
pip install rote-cli # or zero-install: uvx --from rote-cli rote ...
# `rote compile` runs an LLM agent, so it needs a driver: Claude Code
# (`claude`) or Codex (`codex`) installed and authed, or ANTHROPIC_API_KEY
# for the in-process `api` driver. (`rote emit` needs no LLM; see below.)
# Default target is a compiled skill: the same skill name and trigger,
# with its fixed steps in code, run by the agent you already use:
rote compile ./examples/docs-digest/skill --out ./compiled/
# rote compile: ✓ docs-digest v...
# next: rote skill install .../compiled/runtime/skill/docs-digest
# then swap it in for the original docs-digest skill (Claude Code:
# ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest)
# or see it give the original's answer first: rote try ./examples/docs-digest/skill
```
rote checks `~/.claude/skills/<name>` before it prints the link. When your
original skill is already there, `ln -s` would nest the link inside it
(and exit 0), so rote prints the swap with the original moved aside
instead, plus the undo. Nothing is deleted, and rote runs none of it:
```
then, for Claude Code: your original docs-digest skill is at ~/.claude/skills/docs-digest.
To use the compiled one instead, move the original out of the skills folder (nothing is
deleted): mv ~/.claude/skills/docs-digest ~/docs-digest.original && ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest
undo: rm ~/.claude/skills/docs-digest && mv ~/docs-digest.original ~/.claude/skills/docs-digest
```
```sh
# Or emit a background workflow instead (see the table below):
rote compile ./examples/bdr-outreach/skill --runtime dbos --out ./compiled/
rote compile ./examples/bdr-outreach/skill --runtime cloudflare --out ./compiled/
```
Measured on claude-sonnet-4-6, original skill against its compiled skill,
with every compared field matching within the original's own run-to-run
noise:
| Skill | Original | Compiled skill |
| --- | --- | --- |
| expense-audit | 154 s, $0.34 | 43 s, $0.13 |
| ops-report | 55 s, $0.13 | 42 s, $0.12 |
| docs-digest | 17.9 s, $0.093 | 16.3 s, $0.049 |
`rote try <skill>` runs that comparison on a skill of yours: it compiles,
installs, and runs both sides on the same input, after showing the cost.
The name comes from *rote learning*: doing something so many times, so
reliably, that it becomes mechanical. That's what compilation does to a
skill.
---
## Why
Agent skills work, but repeating them in production is expensive, slow,
and non-deterministic. Token cost is what bites first: every run
re-reads the skill text, the tool schemas, and a growing transcript to
re-derive a procedure the author already wrote down. The two production
skills adapted into `examples/` averaged ~0.9M and ~1.6M cache-read
tokens *per run* before compilation, for work that is mostly arithmetic
and fixed API calls. Latency is next (a 10 to 20 minute agent loop is
unacceptable as a background job), then determinism: a "MANDATORY"
check enforced only by prose can be silently skipped, and there's no
way to regression-test a behavior the LLM has to remember.
The fix is to separate the parts of a skill that are *actually* fuzzy
from the deterministic procedures wearing fuzzy clothing. Move the
deterministic parts into code, keep the LLM only where the input is
genuinely unbounded (parsing, classifying, drafting), and wrap the whole
thing in a durable execution engine with explicit human-in-the-loop
gates. That compilation step is what `rote` automates.
| | Run the skill as an agent, every time | Compile it with `rote` |
| --- | --- | --- |
| Tokens per run | Full agent loop | Only the judgment steps |
| Latency | 10 to 20 minutes | Background, seconds to minutes |
| Reproducibility | Prose `MANDATORY` can be silently skipped | Deterministic nodes always run |
| Testing | No per-step regression tests | Typed nodes, per-step tests, eval seeds |
| Failure recovery | Restart the loop | Durable retries and resume |
| Human approval | Ad hoc | Explicit HITL gates that suspend and resume |
There's third-party data for what this buys. ["Compiled AI: Deterministic
Code Generation for LLM-Based Workflow Automation"](https://arxiv.org/abs/2604.05150)
(Trooskens et al., Apr 2026) measured compiling LLM workflows into
deterministic code: **57× fewer tokens** at 1,000 transactions, **450×
lower** median latency, **100% reproducibility** (vs. 95% for direct
inference at temperature 0), and ~**40× lower TCO** at a million
transactions a month. The multiples grow with volume. Once a workflow
is proven, every run through an agent loop pays LLM prices for work code
does for free.
A distinction worth being precise about: durable-execution vendors make
fuzzy agents *durable* (wrap the loop in retries and state so it survives
crashes, still fuzzy inside). `rote` *removes* the fuzzy loop. The two
compose: Temporal, Cloudflare Workflows, and the rest are `rote`'s
compile targets, not its rivals.
**When not to use `rote`:** exploratory and one-off work should stay an
agent loop. Flexibility is the whole point there, and there's nothing
proven to compile yet. `rote` is for the skill you've run twenty times
and want to run a thousand more, unattended.
---
## How it works
One `rote compile` run does the whole thing. First rote decides the
pipeline's structure: which nodes exist and of which kind, how they are
wired, which run once per item, which are mandatory, where a person must
approve, and which constants they carry (System-1, see
[`docs/design/system1-compile.md`](docs/design/system1-compile.md)). One
Claude Haiku call reads the whole skill and proposes that structure, and
rote checks every node against the skill's text, its tools' schemas and
the sample input before accepting it. `--structure rules` decides it with
rules over the skill's text instead, with no model call.
Then an LLM agent (itself defined as a skill) writes only the text those
decisions need: the extracted Python modules for the deterministic
parts, their tests, and the typed signatures and prompts for the
LLM-judge parts. rote holds the agent to its decisions, and emits a
runtime-agnostic intermediate representation (`pipeline.yaml`) plus
runnable code for the durable execution engine of your choice.
`--no-system1` runs the original path instead, where the agent applies
the full compilation rubric and decides the structure too. `--update`
always uses that path, because System-1 does not support incremental
re-compilation yet.
The agent implements the deterministic `pure_function` steps the skill
spells out and writes tests for them. Before the compile reports
success, rote checks what the agent wrote and runs those tests, and any
failure goes back to the agent to fix. The tests are code an LLM wrote
from a skill you may not have written, so rote runs them in an OS
sandbox (`sandbox-exec` on macOS, bubblewrap on Linux): no network, no
reads outside the compile's work dir and the Python install, no programs
other than Python, no API keys in the environment, an empty `HOME`. If
no sandbox works on your machine, the tests are skipped and the compile
says the deliverable is unverified. `--trust-skill` runs them without a
sandbox, and `--no-verify-tests` never runs them; either way, review
`<out>/compiled/tests/` before running them yourself.
`rote` is a three-layer system; each layer has one job and contracts on
a small interface.
```
SKILL.md + references/ Source skill bundle (untouched)
│ rote compile
▼
compiler agent An LLM agent (Claude / Codex /
(pluggable driver) Anthropic SDK) runs the rote-compile
│ skill against the source bundle.
│ filesystem contract: work_dir/pipeline.yaml
▼ + extracted/ + signatures/
Pipeline IR (pipeline.yaml) Pydantic-validated DAG of typed
│ nodes. Five node kinds. Runtime-agnostic.
│ rote.adapters.<runtime>
▼
emitted runtime code Native code for the target durable
execution engine.
```
1. **The compiler agent** (`skills/rote-compile/`): a regular
Anthropic Skill (`SKILL.md` + six reference files). This is the
*brain*; it runs inside any Skills-compatible surface, and you don't
need `rote` to use it.
2. **The IR** (`src/rote/ir.py`): Pydantic models for the five node
kinds plus edges, retries, HITL gates, and metadata. The IR is the
source of truth; everything downstream is template substitution.
3. **Runtime adapters** (`src/rote/adapters/`): pluggable modules that
consume an IR and emit runnable code for one engine.
The compiler's job ends when it has produced a valid `pipeline.yaml`.
Code emission is *deterministic Python*, never agent-driven, so the
same IR always produces byte-identical output.
---
## Quickstart
### From Claude Code (recommended)
`rote` ships as a Claude Code plugin, so you can compile a skill without
touching Python tooling:
```
/plugin marketplace add trevhud/rote
/plugin install rote@rote
```
New here? Run `/rote:setup`, or `uvx --from rote-cli rote setup` in a
terminal. It imports the MCP servers you already use, compiles one of your
skills, and shows that the compiled skill gives the same answer, with time
and cost on each side. It asks before every step and shows the cost before
anything is spent.
Then say "compile this skill" (or run `/rote:compile`). It confirms the
source directory, asks which runtime you want, runs the CLI via
[uv](https://docs.astral.sh/uv/) in the background, and reports the
emitted pipeline. `/rote:implement` then fills in the emitted stub
modules against each node's IR contract and verifies the result with
`rote run`. A third skill, `/rote:serve`, wires compiled
pipelines up as MCP tools so Claude can trigger the deployed workflows
(see [docs/mcp-trigger.md](docs/mcp-trigger.md)).
Prefer a terminal? The same thing is one `uvx` command:
```sh
uvx --from rote-cli rote compile ./my-skill --out ./compiled
```
**Hosted platform:** [roteskills.com](https://roteskills.com) is the
project site (concepts, benchmarks methodology, worked examples).
[app.roteskills.com](https://app.roteskills.com) is Rote Cloud, a
managed path for teams that would rather not operate a runtime: run
`rote login`, then `rote compile --cloud` (or set `deploy: rote-cloud`
with `rote init`) runs server-side, streams progress back, auto-deploys,
and downloads the artifacts locally. Everything in this README still
works logged out.
> **Naming note:** the `rote` package on PyPI is an unrelated
> memoization library that also installs `import rote`, so the two can't
> share an environment. This project's distribution is `rote-cli` and the
> import name stays `rote`. The package installs the same CLI under two
> commands, `rote` and `rote-cli`, so both `uvx rote-cli ...` and
> `uvx --from rote-cli rote ...` work. See [docs/releasing.md](docs/releasing.md).
### Run on the bundled example
The repo includes a real BDR outreach skill (lead generation, contact
vetting, CRM upload, mandatory exclusion checks, email personalization,
manual enrollment handoff) in `examples/bdr-outreach/skill/`:
```sh
rote compile examples/bdr-outreach/skill --out /tmp/bdr-compiled
```
On that skill the compiler produces a 22-node IR that's **78.9%
codifiable** (15 of 19 non-gate nodes), extracts 5 Python modules and 2
typed judge signatures, and flags 3 mandatory nodes and 3 HITL gates,
all in ~13 minutes for ~$0.70 (Sonnet via Claude Code). Along the way it
independently lifts the three MANDATORY exclusion checks out of prose,
pulls four batch-size constants out of prompt text, and models a
parallel entry path the hand-written baseline missed.
`rote` auto-detects a driver in the order `claude` → `codex` → `api`;
override with `--agent`. The output directory splits into `compiled/`
(the agent's `pipeline.yaml`, `extracted/`, `signatures/`, eval seeds,
and a `compile-report.md`) and `runtime/<runtime>/` (the adapter's
emitted code + a README on how to run, signal gates, and deploy).
`compiled/compile-metrics.json` preserves final token counts, session ID,
and the driver's cost estimate before emission starts, so an adapter
failure does not lose the paid run's metrics. Missing final output stays
null with `usage_complete: false`; unchanged updates retain prior metrics.
Its `usage` block says, for each stage that called a model, whether its
tokens were measured, so a driver that reports none reads as `unavailable`,
not as a free run.
Local `api` and `openai-api` compilation automatically discovers your
registered, authenticated MCP servers and exposes their read-only tools.
Pass `--no-mcp` to skip that discovery and compile without live MCP calls:
```sh
rote compile examples/bdr-outreach/skill --local --agent api --no-mcp --out /tmp/bdr-compiled
```
This leaves the emitted pipeline's MCP bindings intact. The flag also works
with `rote analyze` and with an API driver selected through config or
auto-detection. It rejects cloud compilation, subprocess drivers, and
`--baseline`, whose raw skill run uses its own MCP tools. API drivers bill
through your API credentials.
### Other commands
- **`rote emit <pipeline.yaml> --out <dir>`**: run just the adapter step
on an existing IR. LLM-free, so no cost and no driver needed, which
makes it the cheap inner loop while iterating on adapters or IR
shapes. Re-emitting is safe: a `.rote-manifest.json`
tracks what `rote` wrote, and files you've edited are left untouched
(the fresh version lands as `<name>.new`).
- **`rote compile --update`**: re-compile incrementally when the skill
changes. `rote` diffs the skill against the previous run's
`provenance.json` and re-derives only the nodes whose source sections
changed; unchanged nodes keep their ids (so in-flight durable workflows
aren't orphaned) and implemented stubs are kept. No change → no agent run.
- **`rote run <path>`**: one-off local execution of either side. A
skill directory runs as an agent via `claude -p` (your registered MCP
servers injected, read-only tool gate unless `--allow-writes`); an
emitted runtime directory, or a `compile --out` directory, runs
the pipeline itself on any of the six runtimes (`python`/`dbos`/`temporal`
in-process or on a managed local dev server, `cloudflare` under
`wrangler dev`, `inngest` against a managed `inngest-cli dev`,
`dbos-ts` against your Postgres or a throwaway Docker one). HITL
gate payloads via `--signal name='{...}'` or an interactive prompt.
Runtimes that bundle a dev UI surface it: temporal runs print a live
Temporal Web UI URL and inngest runs print the dev-server dashboard,
both live for the duration of the run. Output JSON on stdout, status
on stderr, so it pipes.
- **`rote deploy <path>`**: push an emitted pipeline where it runs:
`cloudflare` wraps `npx wrangler deploy` (with `--dry-run`), `dbos` /
`dbos-ts` wrap `npx dbos-cloud app deploy`, and the vendor CLI owns auth
and output; rote adds detection and preflights (including surfacing
*which* account your wrangler session belongs to before uploading).
Runtimes with no push model (temporal, inngest, python) print honest
hosting guidance with doc links instead of a fake action.
`--target rote-cloud` bundles a cloudflare-emitted app (esbuild via
npx) and uploads it to a hosted rote-cloud instance. With a stored
`rote login`, no flags or env vars are needed (`--url`/`--token` and
`$ROTE_CLOUD_URL`/`$ROTE_CLOUD_TOKEN` still override).
- **`rote login`**: connect the CLI to a rote-cloud account via the
OAuth device flow: your browser opens with a one-time code pre-filled
(over SSH, `--device` prints the code + URL instead), you click
Approve, and the CLI stores a tenant API key at
`~/.local/share/rote/cloud.json` (mode 0600). Once logged in,
`rote compile --cloud` runs **on rote cloud**, and so does a compile
whose runtime is `cloudflare` or whose `deploy` is `rote-cloud`
(flag, env or config). A flagless compile stays local and emits a
compiled skill, logged in or not. On rote cloud the skill bundle
syncs up (sha-diffed, so unchanged files don't re-upload), the
platform runs the compilation server-side, live progress streams back
through the same renderer as a local run, the result auto-deploys,
and the artifacts download into your `--out` directory in the exact
local layout. `--local` keeps the compilation on your machine (a
cloudflare compile then emits locally and auto-deploys), `--no-deploy`
or `deploy: none` keeps everything local; `--cloud` forces the server
even where config says otherwise. `rote whoami` shows the account (verified
live); `rote logout` revokes the key server-side and clears the store.
- **`rote init`**: one-time onboarding: pick where compiled pipelines
run (locally, with `skill` first and recommended, or rote cloud, with
login offered), which
compiler driver and model do the work, and who decides a local
compile's structure. It shows what it will write and asks before
writing. Answers are saved to `~/.config/rote/config.yaml`
(`--project` writes a `./rote.yaml` that overrides it per-repo) and
every later command reads them. Every question has a flag, so CI and
agents run it with flags and `--yes`; it never prompts without a
person at a terminal.
- **`rote config`**: print every configurable default with its
effective value *and the layer that set it*. Resolution everywhere is
`flag > ROTE_* env (ROTE_RUNTIME, ROTE_DEPLOY, ROTE_AGENT,
ROTE_MODEL, ROTE_EFFORT) > project rote.yaml > user config > built-in`. Config
files are strict: a typo'd key or value is a loud error, never a
silent fallback. `--json` for automation.
- **`rote eval <compiled>`**: render the before/after scorecard (wall
clock, cost across the current model lineup at live prices, and how
much of the run is still LLM-decided). `rote compile` writes this to
`compiled/scorecard.md` automatically. Add `--run` to *measure*
instead of estimate: it executes both sides for real and appends
measured cost, turns, and output agreement across trials. With
`--run --runtime skill` the after side is the compiled skill, run by
an agent through `rote skill run`, so both sides are agents and the
table compares context, tokens, time, cost and field fidelity
(`--budget` is required).
- **Per-node inference**: emitted judges read `ROTE_MODEL_<ID>` and
`ROTE_BASE_URL_<ID>` at runtime, so you can swap the model or point at
any OpenAI-compatible endpoint (Ollama, vLLM, a gateway) without
re-emitting.
---
## The five node kinds
Every step in a compiled pipeline is exactly one of five kinds. Full
guidance:
[`references/node-kinds.md`](skills/rote-compile/references/node-kinds.md).
| Kind | What it is | Where the LLM lives |
| --- | --- | --- |
| `pure_function` | Fixed logic, deterministic I/O | Not involved |
| `external_call` | Vendor API call with fixed semantics + retries | Not involved |
| `llm_judge` | Fuzzy classification against a rubric, typed I/O | Typed signature (DSPy/BAML in Python; Zod + vendor SDK in TS), from the IR's runtime-agnostic `signature_spec` |
| `agent_loop` | Genuinely exploratory tool use | Bounded agent loop |
| `hitl_gate` | Explicit human approval, suspend until signal | Durable suspend/resume |
The guiding rule: **keep the LLM at points where the input is unbounded
or ambiguous, and codify everything else.** When a step could go either
way, prefer the more deterministic kind.
---
## Runtimes
Pick with `--runtime`; the same IR drives all of them. Under
`--backend api`, none of the emitted code references MCP: the
crystallization step replaces tool calls with direct vendor API calls.
The compiler agent gets web search and fetch tools for that, writes each
call from the vendor's current reference page, and cites the page as
`# docs: <url>`; `compile-report.md` lists every cited page beside
whether the agent fetched it during the compile. The api backend's calls
are Python, so it needs a Python runtime (`dbos`, `python`, `temporal`).
Under the default `--backend mcp`, tool-using nodes emit a working MCP
client call (with durable park-on-auth on every MCP-capable runtime);
see [`docs/mcp-client.md`](docs/mcp-client.md).
| Runtime | `--runtime` | Language | Shape | Notes |
| --- | --- | --- | --- | --- |
| **Compiled skill** (default) | `skill` | Python driver + SKILL.md | a skill dir: the original's name and description, `scripts/` runs the fixed steps, the agent answers only judges and gates | Install with `rote skill install`; runs in Claude Code, Codex and other skill clients through `rote skill run` |
| DBOS | `dbos` | Python | `main.py` with `@DBOS.workflow` + `@DBOS.step` per node | No orchestrator to deploy; SQLite (dev) / Postgres (prod) |
| Temporal | `temporal` | Python | `workflow.py` + `activities.py` | Signal handlers for HITL gates |
| Plain Python | `python` | Python | single `main.py` script | Max legibility, stdlib only; refuses HITL-gate pipelines |
| Cloudflare Workflows | `cloudflare` | TypeScript | `WorkflowEntrypoint` + `wrangler.jsonc` | `wrangler deploy`-ready |
| DBOS (TypeScript) | `dbos-ts` | TypeScript | `src/main.ts` (DBOS Transact) | Zero-orchestrator; Postgres-only |
| Inngest | `inngest` | TypeScript | one `inngest.createFunction` | Mounts into an existing Node/Next.js app; retries are function-level |
---
## Drivers
`rote` ships three interchangeable compiler drivers. Pick whichever
matches your auth. The same `pipeline.yaml` comes out either way.
| Driver | Backend | Auth | Install |
| --- | --- | --- | --- |
| `claude` (default) | `claude -p` subprocess | Claude Max/Pro OAuth or `CLAUDE_CODE_OAUTH_TOKEN` | Install Claude Code separately |
| `codex` | `codex exec` subprocess | ChatGPT Plus/Pro OAuth | Install Codex CLI separately |
| `api` | `anthropic` Python SDK | `ANTHROPIC_API_KEY` | `pip install 'rote-cli[api]'` |
The `claude` driver scrubs `ANTHROPIC_API_KEY` from the subprocess so a
subscription login wins, and limits the agent to read/write/glob/grep
tools. The default model is **Sonnet** rather than Opus, because the
task is structured-rubric-following, not deep reasoning; Sonnet brings
per-run cost from ~$3.50 to ~$0.70. Override with `--model` for skills
where Opus earns its cost. Full design record, including the auth gotcha:
[docs/agent-runtime.md](docs/agent-runtime.md).
`rote` explicitly **does not** depend on `claude-agent-sdk`: Anthropic's
ToS forbids third-party agents built on the Agent SDK from using
claude.ai login credentials without approval, which would defeat the
subscription path.
---
## How it differs from other tools
For a side-by-side with calcifier, skill-to-workflow, Claude Code dynamic workflows, and hand-written workflows, see [docs/comparison.md](docs/comparison.md).
- **vs. raw durable engines (Temporal / Cloudflare / Inngest / Restate):**
they give you the workflow *runtime*; they don't help you decide *what
should be a workflow*. `rote` is the missing step that turns a working
skill into something worth running on one.
- **vs. LangGraph:** LangGraph is an excellent state machine, but its
graph is hand-built. `rote` produces a graph *from prose*, classifies
nodes by determinism, and pushes work out of the agent loop wherever
the data supports it.
- **vs. using Skills directly:** Skills run great interactively. `rote`
is what you reach for when a skill becomes business-critical and needs
to run unattended with hard reliability guarantees and per-step
regression tests.
---
## Status
`rote` is **pre-1.0**. The end-to-end flow works on the BDR example. The
fast suite (`pytest tests/`) makes no real API calls, spends no tokens,
and runs on every push. CI also runs every `slow`-marked e2e suite on
every push: DBOS over SQLite, the MCP server over real stdio, the
TypeScript targets via `tsc --noEmit` and live dev servers (Cloudflare
`wrangler dev`, the Inngest dev server), and DBOS TypeScript against a
Docker Postgres. Locally, `pytest tests/ -m slow` runs them; they need a
Node toolchain and Docker.
Known gaps: extracted modules that need a vendor API client (HubSpot,
ZoomInfo, and so on) come out as `NotImplementedError` stubs you fill in,
and a Restate adapter is planned.
Published on
PyPI as [`rote-cli`](https://pypi.org/project/rote-cli/) via tag-driven
Trusted Publishing ([docs/releasing.md](docs/releasing.md)).
On the numbers: static scorecard estimates, observed production-agent
baselines, and independent research are three different kinds of
evidence, and mixing them produces marketing rather than benchmarks.
They're kept separate, with the assumptions written out, at
[roteskills.com/benchmarks](https://roteskills.com/benchmarks). To
measure your own workflow instead of reading someone else's, use
`rote eval --run`.
---
## Repository layout
```
rote/
├── docs/ agent-runtime · mcp-client · mcp-trigger · releasing
├── skills/rote-compile/ the compiler agent (SKILL.md + 6 reference files)
├── src/rote/
│ ├── cli.py rote compile / emit / eval / serve
│ ├── ir.py Pydantic IR models + load_pipeline
│ ├── compiler/ orchestrator + drivers/ (claude · codex · anthropic_api)
│ └── adapters/ dbos · temporal · python · cloudflare · dbos_ts · inngest
│ (+ _common / _py_common / _ts_common emit helpers)
├── examples/
│ ├── expense-audit/ free first run: working extracted code · fan-out · HITL gate
│ ├── bdr-outreach/ canonical: all 5 node kinds · IR baseline · run snapshots
│ ├── ops-report/ 100% roteness: zero LLM nodes + a HITL gate
│ ├── deal-monitor/ data-heavy: parallel waves · fan-out judges · template render
│ └── invoice-push/ agent-loop archetype: bounded browser loop · turn-dominated cost
└── tests/ fast + slow suites (pytest -m slow)
```
---
## Documentation
- [`AGENTS.md`](AGENTS.md): operating manual for a coding agent *driving*
`rote` as an installed tool (invocation contract, the slow/costs-money
`compile` flow, auth, failure recovery, the stub-filling job, `--json`)
- [`docs/agent-runtime.md`](docs/agent-runtime.md): design record for the
driver abstraction (the `claude -p` env gotcha; the non-use of
`claude-agent-sdk`)
- [`docs/mcp-client.md`](docs/mcp-client.md): the OAuth MCP client
emitted code uses under `--backend mcp`: endpoint/credential
resolution and durable park-on-auth across every MCP-capable runtime
- [`docs/mcp-trigger.md`](docs/mcp-trigger.md): `rote register` +
`rote serve`: compiled pipelines as MCP tools (FastMCP 4.x)
- [`docs/releasing.md`](docs/releasing.md): tag-driven PyPI Trusted
Publishing
- [`skills/rote-compile/`](skills/rote-compile/): the compiler's
`SKILL.md` and its six rubric files (node kinds, crystallization
heuristics, IR schema, LLM-judge extraction, implementation, eval
estimates)
- [`examples/expense-audit/`](examples/expense-audit/): the free first
run: a hand-compiled pipeline with working extracted code that
`rote run` completes on python, dbos, and temporal with no credentials
- [`examples/bdr-outreach/`](examples/bdr-outreach/): the canonical
skill, its ground-truth IR, and snapshotted real compiler runs
- [`examples/ops-report/`](examples/ops-report/): the 100%-roteness
archetype: every step deterministic, one durable HITL gate, zero LLM
nodes after compilation
- [`examples/deal-monitor/`](examples/deal-monitor/): the data-heavy
archetype: parallel entry waves, fan-out judges, and a template render
replacing per-run LLM-generated HTML
- [`examples/invoice-push/`](examples/invoice-push/): the `agent_loop`
archetype: a bounded browser-automation loop stays one agent node
while the date math, filtering, and reporting around it compile to
code, plus the measured runs that forced the loop-aware cost model
- [`examples/rote-compile/`](examples/rote-compile/): the compiler compiling
its own core skill, with preserved artifacts and an offline audit of
the generated workflow's runtime and data-flow failures
---
## Roadmap
In rough priority order:
1. **Pre-filter as a `pure_function` node**: today hard thresholds are
lifted into a judge's `forward()`, which works for the Python
runtimes but not the TypeScript ones; a separate node makes the
short-circuit uniform across all six.
2. **Make self-compilation executable**: the
[preserved core-skill run](examples/rote-compile/) produced valid IR,
and runtime emission now succeeds. Its offline audit still has
data-flow and agent-result contract failures. Close those gaps before
treating it as a working replacement compiler.
3. **More example skills**: four archetypes are covered today (BDR
outreach, 100%-roteness, data-heavy, agent-loop). Research-heavy,
retrieval-heavy, and code-review skills each stress the IR in ways
none of those four do.
---
## FAQ
### What is rote?
`rote` is an open source CLI, Apache-2.0 licensed and published as
[`rote-cli`](https://pypi.org/project/rote-cli/) on PyPI, that compiles
a proven AI agent skill into a typed, deterministic pipeline. It reads
an Anthropic-style `SKILL.md`, classifies each step, moves fixed logic
and tool orchestration into reviewable code, and calls a model only for
the steps that genuinely require judgment.
### How does rote reduce AI agent token costs?
It removes model calls rather than making them cheaper. A repeating
agent spends tokens re-reading instructions, tool schemas, and history
to re-derive a procedure it already established. `rote` compiles that
procedure into code, so a repeated run pays only for the steps still
classified as needing judgment.
### When should I compile a skill instead of leaving it as an agent?
Keep one-off exploration in an agent, which is what agents are good at.
Compile a skill once the procedure is proven, repeats often, and needs
lower cost, faster execution, regression tests, explicit approvals, or
reliable retries.
### Does rote replace my agent framework or MCP?
No. A compiled workflow can still call authenticated MCP servers and
retain bounded agent loops. `rote` decides which parts of a process
should stop being inference; your runtime and your integrations stay
where they are.
### Where does the compiled workflow run?
Anywhere you already run durable work. `rote` emits DBOS, Temporal,
Cloudflare Workflows, plain Python, DBOS TypeScript, and Inngest.
[Rote Cloud](https://app.roteskills.com) is an optional managed path for
teams that would rather not operate the runtime themselves.
---
## Contributing
The most useful contribution right now is to **run `rote compile` on a
real skill of your own and report what happens**. The rubric was
designed against one skill and needs more. Adding a runtime adapter or a
compiler driver, or improving the rubric, are all good next steps. See
[CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, the test layout, and
the adapter/driver how-tos.
## License
Apache-2.0. See [LICENSE](LICENSE).
历史前置条件说明(补充参考)
Python 环境;uv 或 pip 安装 rote-cli;编译需 Claude Code 或 Codex 已登录,或 ANTHROPIC_API_KEY;部分运行时需 Node 工具链、Docker、Postgres;托管云服务费用与条款待核验;国内可用性待核验
项目来源与清单版权许可
https://github.com/trevhud/rote
整理来源:https://github.com/slavakurilyak/awesome-ai-agents
清单版权与许可:
MIT License
Copyright (c) 2024 Slava Kurilyak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.