fabro-workflow-factory
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFabro Workflow Factory
Fabro工作流工厂
Skill by ara.so — Daily 2026 Skills collection.
Fabro is an open source AI coding workflow orchestrator written in Rust. It lets you define agent pipelines as Graphviz DOT graphs — with branching, loops, human approval gates, multi-model routing, and cloud sandbox execution — then run them as a persistent service. You define the process; agents execute it; you intervene only where it matters.
由ara.so开发的Skill — 2026每日Skill合集。
Fabro是一款用Rust编写的开源AI编码工作流编排器。它允许你将Agent管道定义为Graphviz DOT图——支持分支、循环、人工审核节点、多模型路由和云沙箱执行——然后作为持久化服务运行。你定义流程,Agent执行,仅在关键环节进行干预。
Installation
安装
bash
undefinedbash
undefinedVia Claude Code (recommended)
通过Claude Code安装(推荐)
curl -fsSL https://fabro.sh/install.md | claude
curl -fsSL https://fabro.sh/install.md | claude
Via Codex
通过Codex安装
codex "$(curl -fsSL https://fabro.sh/install.md)"
codex "$(curl -fsSL https://fabro.sh/install.md)"
Via Bash
通过Bash安装
curl -fsSL https://fabro.sh/install.sh | bash
After installation, run one-time setup and per-project initialization:
```bash
fabro install # global one-time setup
cd my-project
fabro init # per-project setup (creates .fabro/ config)curl -fsSL https://fabro.sh/install.sh | bash
安装完成后,执行一次性全局设置和项目初始化:
```bash
fabro install # 全局一次性设置
cd my-project
fabro init # 项目级设置(创建.fabro/配置目录)Key CLI Commands
核心CLI命令
bash
undefinedbash
undefinedWorkflow management
工作流管理
fabro run <workflow.dot> # execute a workflow
fabro run <workflow.dot> --watch # stream live output
fabro runs # list all runs
fabro runs show <run-id> # inspect a specific run
fabro run <workflow.dot> # 执行工作流
fabro run <workflow.dot> --watch # 流式输出实时日志
fabro runs # 列出所有运行实例
fabro runs show <run-id> # 查看特定运行实例详情
Human-in-the-loop
人工介入操作
fabro approve <run-id> # approve a pending gate
fabro reject <run-id> # reject / revise a pending gate
fabro approve <run-id> # 批准待审核节点
fabro reject <run-id> # 拒绝/修订待审核节点
Sandbox access
沙箱访问
fabro ssh <run-id> # shell into a running sandbox
fabro preview <run-id> <port> # expose a sandbox port locally
fabro ssh <run-id> # 进入运行中沙箱的Shell
fabro preview <run-id> <port> # 将沙箱端口映射到本地
Retrospectives
运行回顾
fabro retro <run-id> # view run retrospective (cost, duration, narrative)
fabro retro <run-id> # 查看运行回顾(成本、时长、执行说明)
Config
配置管理
fabro config # view current configuration
fabro config set <key> <value> # set a config value
---fabro config # 查看当前配置
fabro config set <key> <value> # 设置配置项
---Workflow Definition (Graphviz DOT)
工作流定义(Graphviz DOT)
Workflows are files using the Graphviz DOT language with Fabro-specific attributes.
.dot工作流是使用Graphviz DOT语言编写的.dot文件,包含Fabro专属属性。
Node Types
节点类型
| Shape | Meaning |
|---|---|
| Start node |
| Exit node |
| Agent node (LLM turn) |
| Human gate (pauses for approval) |
| 形状 | 含义 |
|---|---|
| 起始节点 |
| 结束节点 |
| Agent节点(LLM执行步骤) |
| 人工审核节点(暂停等待批准) |
Minimal Hello World
最简Hello World示例
dot
// hello.dot
digraph HelloWorld {
graph [
goal="Say hello and write a greeting file"
model_stylesheet="
* { model: claude-haiku-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
greet [label="Greet", prompt="Write a friendly greeting to hello.txt"]
start -> greet -> exit
}bash
fabro run hello.dotdot
// hello.dot
digraph HelloWorld {
graph [
goal="Say hello and write a greeting file"
model_stylesheet="
* { model: claude-haiku-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
greet [label="Greet", prompt="Write a friendly greeting to hello.txt"]
start -> greet -> exit
}bash
fabro run hello.dotMulti-Model Routing with Stylesheets
基于样式表的多模型路由
Fabro uses CSS-like declarations on the graph to route nodes to models. Use classes to target groups of nodes.
model_stylesheetdot
digraph PlanImplementReview {
graph [
goal="Plan, implement, and review a feature"
model_stylesheet="
* { model: claude-haiku-4-5; reasoning_effort: low; }
.planning { model: claude-opus-4-5; reasoning_effort: high; }
.coding { model: claude-sonnet-4-5; reasoning_effort: high; }
.review { model: gpt-4o; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
plan [label="Plan", class="planning", prompt="Analyze the codebase and write plan.md"]
implement [label="Implement", class="coding", prompt="Read plan.md and implement every step"]
review [label="Review", class="review", prompt="Cross-review the implementation for bugs and clarity"]
start -> plan -> implement -> review -> exit
}Fabro使用类CSS的声明为节点分配模型,支持通过类选择器批量配置节点。
model_stylesheetdot
digraph PlanImplementReview {
graph [
goal="Plan, implement, and review a feature"
model_stylesheet="
* { model: claude-haiku-4-5; reasoning_effort: low; }
.planning { model: claude-opus-4-5; reasoning_effort: high; }
.coding { model: claude-sonnet-4-5; reasoning_effort: high; }
.review { model: gpt-4o; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
plan [label="Plan", class="planning", prompt="Analyze the codebase and write plan.md"]
implement [label="Implement", class="coding", prompt="Read plan.md and implement every step"]
review [label="Review", class="review", prompt="Cross-review the implementation for bugs and clarity"]
start -> plan -> implement -> review -> exit
}Supported Model Stylesheet Properties
支持的模型样式表属性
model: <model-id> # e.g. claude-sonnet-4-5, gpt-4o, gemini-2-flash
reasoning_effort: low|medium|high
provider: anthropic|openai|googlemodel: <model-id> # 例如 claude-sonnet-4-5, gpt-4o, gemini-2-flash
reasoning_effort: low|medium|high
provider: anthropic|openai|googleHuman Gates (Approval Nodes)
人工审核节点
Use to pause execution for human approval. Transitions are labeled with (approve) and (revise/reject).
shape=hexagon[A][R]dot
digraph PlanApproveImplement {
graph [
goal="Plan and implement with human approval"
model_stylesheet="
* { model: claude-sonnet-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
plan [label="Plan", prompt="Write a detailed implementation plan to plan.md"]
approve [shape=hexagon, label="Approve Plan"]
implement [label="Implement", prompt="Read plan.md and implement every step exactly"]
start -> plan -> approve
approve -> implement [label="[A] Approve"]
approve -> plan [label="[R] Revise"]
implement -> exit
}Approve or reject from the CLI:
bash
fabro runs # find the paused run-id
fabro approve <run-id> # continue with implementation
fabro reject <run-id> --note "Add error handling to the plan"使用定义需要暂停等待人工批准的节点,转移边标注(批准)和(修订/拒绝)。
shape=hexagon[A][R]dot
digraph PlanApproveImplement {
graph [
goal="Plan and implement with human approval"
model_stylesheet="
* { model: claude-sonnet-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
plan [label="Plan", prompt="Write a detailed implementation plan to plan.md"]
approve [shape=hexagon, label="Approve Plan"]
implement [label="Implement", prompt="Read plan.md and implement every step exactly"]
start -> plan -> approve
approve -> implement [label="[A] Approve"]
approve -> plan [label="[R] Revise"]
implement -> exit
}通过CLI批准或拒绝:
bash
fabro runs # 找到暂停的运行实例ID
fabro approve <run-id> # 继续执行实现步骤
fabro reject <run-id> --note "Add error handling to the plan"Loops and Fix Cycles
循环与修复流程
Use labeled transitions to build automatic retry/fix loops:
dot
digraph ImplementAndTest {
graph [
goal="Implement a feature and fix failing tests automatically"
model_stylesheet="
* { model: claude-haiku-4-5; }
.coding { model: claude-sonnet-4-5; reasoning_effort: high; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", class="coding",
prompt="Implement the feature described in TASK.md"]
test [label="Run Tests",
prompt="Run the test suite with `cargo test`. Report pass/fail."]
fix [label="Fix", class="coding",
prompt="Read the test failures and fix the code. Do not change tests."]
start -> implement -> test
test -> exit [label="[P] Pass"]
test -> fix [label="[F] Fail"]
fix -> test
}使用标注转移边构建自动重试/修复循环:
dot
digraph ImplementAndTest {
graph [
goal="Implement a feature and fix failing tests automatically"
model_stylesheet="
* { model: claude-haiku-4-5; }
.coding { model: claude-sonnet-4-5; reasoning_effort: high; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", class="coding",
prompt="Implement the feature described in TASK.md"]
test [label="Run Tests",
prompt="Run the test suite with `cargo test`. Report pass/fail."]
fix [label="Fix", class="coding",
prompt="Read the test failures and fix the code. Do not change tests."]
start -> implement -> test
test -> exit [label="[P] Pass"]
test -> fix [label="[F] Fail"]
fix -> test
}Parallel Nodes
并行节点
Run multiple agent nodes concurrently by forking edges from a single source:
dot
digraph ParallelReview {
graph [
goal="Implement then review from multiple perspectives in parallel"
model_stylesheet="
* { model: claude-haiku-4-5; }
.coding { model: claude-sonnet-4-5; }
.critique { model: gpt-4o; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", class="coding",
prompt="Implement the task in TASK.md"]
sec_review [label="Security Review", class="critique",
prompt="Review the implementation for security issues"]
perf_review [label="Perf Review", class="critique",
prompt="Review the implementation for performance issues"]
summarize [label="Summarize",
prompt="Combine the security and performance reviews into REVIEW.md"]
start -> implement
implement -> sec_review
implement -> perf_review
sec_review -> summarize
perf_review -> summarize
summarize -> exit
}通过从单个源节点分叉边实现多个Agent节点并发执行:
dot
digraph ParallelReview {
graph [
goal="Implement then review from multiple perspectives in parallel"
model_stylesheet="
* { model: claude-haiku-4-5; }
.coding { model: claude-sonnet-4-5; }
.critique { model: gpt-4o; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", class="coding",
prompt="Implement the task in TASK.md"]
sec_review [label="Security Review", class="critique",
prompt="Review the implementation for security issues"]
perf_review [label="Perf Review", class="critique",
prompt="Review the implementation for performance issues"]
summarize [label="Summarize",
prompt="Combine the security and performance reviews into REVIEW.md"]
start -> implement
implement -> sec_review
implement -> perf_review
sec_review -> summarize
perf_review -> summarize
summarize -> exit
}Variables and Dynamic Prompts
变量与动态提示词
Use interpolation in prompts. Pass variables at run time:
{variable}dot
digraph FeatureWorkflow {
graph [
goal="Implement {feature_name} from the spec"
model_stylesheet="* { model: claude-sonnet-4-5; }"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement {feature_name}",
prompt="Read specs/{feature_name}.md and implement the feature completely."]
start -> implement -> exit
}bash
fabro run feature.dot --var feature_name=oauth-login在提示词中使用插值,运行时传入变量:
{variable}dot
digraph FeatureWorkflow {
graph [
goal="Implement {feature_name} from the spec"
model_stylesheet="* { model: claude-sonnet-4-5; }"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement {feature_name}",
prompt="Read specs/{feature_name}.md and implement the feature completely."]
start -> implement -> exit
}bash
fabro run feature.dot --var feature_name=oauth-loginCloud Sandboxes (Daytona)
云沙箱(Daytona)
To run agents in isolated cloud VMs instead of locally, configure a Daytona sandbox:
bash
fabro config set sandbox.provider daytona
fabro config set sandbox.api_key $DAYTONA_API_KEY
fabro config set sandbox.region us-east-1Then add sandbox config to your workflow graph:
dot
digraph SandboxedWorkflow {
graph [
goal="Implement and test in an isolated environment"
sandbox="daytona"
model_stylesheet="* { model: claude-sonnet-4-5; }"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", prompt="Implement the feature in TASK.md"]
test [label="Test", prompt="Run the full test suite and report results"]
start -> implement -> test -> exit
}bash
fabro run sandboxed.dot # spins up cloud VM, runs workflow, tears it down
fabro ssh <run-id> # shell into the running sandbox for debugging
fabro preview <run-id> 3000 # forward sandbox port 3000 locally如需在隔离的云VM中运行Agent而非本地,配置Daytona沙箱:
bash
fabro config set sandbox.provider daytona
fabro config set sandbox.api_key $DAYTONA_API_KEY
fabro config set sandbox.region us-east-1然后在工作流图中添加沙箱配置:
dot
digraph SandboxedWorkflow {
graph [
goal="Implement and test in an isolated environment"
sandbox="daytona"
model_stylesheet="* { model: claude-sonnet-4-5; }"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement", prompt="Implement the feature in TASK.md"]
test [label="Test", prompt="Run the full test suite and report results"]
start -> implement -> test -> exit
}bash
fabro run sandboxed.dot # 启动云VM、运行工作流、结束后销毁
fabro ssh <run-id> # 进入运行中的沙箱进行调试
fabro preview <run-id> 3000 # 将沙箱3000端口映射到本地Git Checkpointing
Git checkpointing
Fabro automatically commits code changes and execution metadata to Git branches at each stage. To inspect or resume:
bash
fabro runs show <run-id> # see branch names per stage
git checkout fabro/<run-id>/implement # inspect the code at a specific stage
git diff fabro/<run-id>/plan fabro/<run-id>/implement # diff between stagesFabro会在每个阶段自动提交代码变更和执行元数据到Git分支。如需查看或恢复:
bash
fabro runs show <run-id> # 查看各阶段对应的分支名称
git checkout fabro/<run-id>/implement # 查看特定阶段的代码
git diff fabro/<run-id>/plan fabro/<run-id>/implement # 对比两个阶段的代码差异Retrospectives
运行回顾
After every run, Fabro generates a retrospective with cost, duration, files changed, and an LLM-written narrative:
bash
fabro retro <run-id>Example output:
Run: implement-oauth-2024
Duration: 4m 32s
Cost: $0.043
Files: src/auth.rs (+142), src/lib.rs (+8), tests/auth_test.rs (+67)
Narrative:
The agent successfully implemented OAuth2 PKCE flow. It created the auth
module, integrated with the existing middleware, and added integration tests.
One fix loop was needed after the token refresh test failed.每次运行结束后,Fabro会生成包含成本、时长、变更文件和LLM撰写执行说明的回顾报告:
bash
fabro retro <run-id>示例输出:
Run: implement-oauth-2024
Duration: 4m 32s
Cost: $0.043
Files: src/auth.rs (+142), src/lib.rs (+8), tests/auth_test.rs (+67)
Narrative:
The agent successfully implemented OAuth2 PKCE flow. It created the auth
module, integrated with the existing middleware, and added integration tests.
One fix loop was needed after the token refresh test failed.REST API and SSE Streaming
REST API与SSE流式传输
Fabro runs an API server for programmatic use:
bash
fabro serve --port 8080Fabro运行API服务器支持程序化调用:
bash
fabro serve --port 8080Trigger a run via API
通过API触发运行
bash
curl -X POST http://localhost:8080/api/runs \
-H "Content-Type: application/json" \
-d '{
"workflow": "workflows/plan-implement.dot",
"variables": { "feature_name": "dark-mode" }
}'bash
curl -X POST http://localhost:8080/api/runs \
-H "Content-Type: application/json" \
-d '{
"workflow": "workflows/plan-implement.dot",
"variables": { "feature_name": "dark-mode" }
}'Stream run events via SSE
通过SSE流式接收运行事件
bash
curl -N http://localhost:8080/api/runs/<run-id>/eventsbash
curl -N http://localhost:8080/api/runs/<run-id>/eventsApprove a gate via API
通过API批准节点
bash
curl -X POST http://localhost:8080/api/runs/<run-id>/approve \
-H "Content-Type: application/json" \
-d '{ "decision": "approve" }'bash
curl -X POST http://localhost:8080/api/runs/<run-id>/approve \
-H "Content-Type: application/json" \
-d '{ "decision": "approve" }'Environment Variables
环境变量
bash
undefinedbash
undefinedRequired — at least one LLM provider key
必填 — 至少配置一个LLM提供商密钥
export ANTHROPIC_API_KEY=...
export OPENAI_API_KEY=...
export GOOGLE_API_KEY=...
export ANTHROPIC_API_KEY=...
export OPENAI_API_KEY=...
export GOOGLE_API_KEY=...
Optional — cloud sandboxes
可选 — 云沙箱配置
export DAYTONA_API_KEY=...
export DAYTONA_API_KEY=...
Optional — Fabro API server auth
可选 — Fabro API服务器认证
export FABRO_API_TOKEN=...
---export FABRO_API_TOKEN=...
---Project Structure Convention
项目结构规范
my-project/
├── .fabro/ # Fabro config (created by `fabro init`)
│ └── config.toml
├── workflows/ # Your DOT workflow definitions
│ ├── plan-implement.dot
│ ├── fix-loop.dot
│ └── ensemble-review.dot
├── specs/ # Natural language specs referenced by prompts
│ └── feature-name.md
└── src/ # Your actual source codemy-project/
├── .fabro/ # Fabro配置目录(由`fabro init`创建)
│ └── config.toml
├── workflows/ # DOT工作流定义文件
│ ├── plan-implement.dot
│ ├── fix-loop.dot
│ └── ensemble-review.dot
├── specs/ # 提示词引用的自然语言规格文档
│ └── feature-name.md
└── src/ # 项目源代码Common Patterns
常见模式
Pattern: Spec-driven implementation
模式:规格驱动的实现
dot
digraph SpecDriven {
graph [
goal="Implement from spec with LLM-as-judge verification"
model_stylesheet="
* { model: claude-sonnet-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement",
prompt="Read specs/feature.md and implement it completely"]
judge [label="Judge",
prompt="Compare the implementation against specs/feature.md. Does it conform? Reply PASS or FAIL with reasons."]
fix [label="Fix",
prompt="Read the judge feedback and fix the implementation"]
start -> implement -> judge
judge -> exit [label="[P] PASS"]
judge -> fix [label="[F] FAIL"]
fix -> judge
}dot
digraph SpecDriven {
graph [
goal="Implement from spec with LLM-as-judge verification"
model_stylesheet="
* { model: claude-sonnet-4-5; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
implement [label="Implement",
prompt="Read specs/feature.md and implement it completely"]
judge [label="Judge",
prompt="Compare the implementation against specs/feature.md. Does it conform? Reply PASS or FAIL with reasons."]
fix [label="Fix",
prompt="Read the judge feedback and fix the implementation"]
start -> implement -> judge
judge -> exit [label="[P] PASS"]
judge -> fix [label="[F] FAIL"]
fix -> judge
}Pattern: Cheap draft, expensive refine
模式:低成本草稿+高精度优化
dot
digraph CheapThenExpensive {
graph [
goal="Draft cheaply, refine with a frontier model"
model_stylesheet="
* { model: claude-haiku-4-5; }
.premium { model: claude-opus-4-5; reasoning_effort: high; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
draft [label="Draft", prompt="Write a first draft implementation of the task"]
refine [label="Refine", class="premium",
prompt="Review and substantially improve the draft for correctness and clarity"]
start -> draft -> refine -> exit
}dot
digraph CheapThenExpensive {
graph [
goal="Draft cheaply, refine with a frontier model"
model_stylesheet="
* { model: claude-haiku-4-5; }
.premium { model: claude-opus-4-5; reasoning_effort: high; }
"
]
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
draft [label="Draft", prompt="Write a first draft implementation of the task"]
refine [label="Refine", class="premium",
prompt="Review and substantially improve the draft for correctness and clarity"]
start -> draft -> refine -> exit
}Troubleshooting
故障排除
fabro: command not found- Re-run the install script and ensure (or the install prefix) is on your
~/.local/bin.$PATH - Try or
source ~/.bashrcafter installation.source ~/.zshrc
Agent gets stuck in a loop
- Add a maximum iteration guard: use a counter variable and a conditional transition to force exit after N iterations.
- Check your prompt — ambiguous exit conditions cause looping.
Human gate never pauses
- Confirm the node uses , not just a label containing "approve".
shape=hexagon - Check to confirm the run reached that node.
fabro runs show <run-id>
Sandbox fails to start
- Verify is set and valid.
DAYTONA_API_KEY - Run to confirm
fabro configis set tosandbox.provider.daytona - Check for sandbox error details.
fabro runs show <run-id>
Model not found / API error
- Ensure the correct provider API key is exported (,
ANTHROPIC_API_KEY, etc.).OPENAI_API_KEY - Check the value in your stylesheet matches the provider's exact model ID.
model:
Run exits immediately without doing work
- Verify the DOT file has a valid path from (
start) toshape=Mdiamond(exit).shape=Msquare - Run to visually inspect the graph for disconnected nodes.
dot -Tsvg workflow.dot -o workflow.svg
fabro: command not found- 重新运行安装脚本,确保(或安装前缀)已加入
~/.local/bin。$PATH - 安装后尝试执行或
source ~/.bashrc。source ~/.zshrc
Agent陷入循环
- 添加最大迭代限制:使用计数器变量和条件转移边,达到N次迭代后强制退出。
- 检查提示词——模糊的退出条件会导致循环。
人工审核节点未暂停
- 确认节点使用,而非仅在标签中包含"approve"。
shape=hexagon - 执行确认运行实例已到达该节点。
fabro runs show <run-id>
沙箱启动失败
- 验证已正确设置且有效。
DAYTONA_API_KEY - 执行确认
fabro config已设置为sandbox.provider。daytona - 查看获取沙箱错误详情。
fabro runs show <run-id>
模型未找到/API错误
- 确保已导出对应提供商的API密钥(、
ANTHROPIC_API_KEY等)。OPENAI_API_KEY - 检查样式表中的值与提供商的精确模型ID一致。
model:
运行实例立即退出未执行任务
- 验证DOT文件中存在从(
start)到shape=Mdiamond(exit)的有效路径。shape=Msquare - 执行可视化检查图中是否存在断开的节点。
dot -Tsvg workflow.dot -o workflow.svg