Tutorial 3: Composing Multi-Agent Workflows
This tutorial walks you through using Rnix Compose to orchestrate multiple agents collaborating on a complex task, and monitoring execution in real-time with rnix top.
Prerequisites
- Completed Tutorial 1: Writing Your First Skill (familiar with Skill and Agent creation)
- Rnix installed and working
- Basic understanding of Rnix process and VFS concepts (see Core Concepts)
What You Will Learn
- How to design multi-agent DAG workflows
- How to write
compose.yamlto define agent dependencies - How to launch workflows with
rnix compose up - How to monitor execution in real-time with
rnix top - How to use pipe syntax and AgentShell scripts for more flexible orchestration
Step 1: Design the Multi-Agent Workflow
Scenario
We will build a code review workflow with three stages:
- Analyzer — reads code files and outputs a code quality analysis
- Doc Generator (doc-gen) — generates improvement documentation based on the analysis
- Checker — verifies the quality of the analysis and documentation
DAG Dependencies
analyzer ──→ doc-gen ──→ checkerdoc-gen depends on analyzer completing first, and checker depends on doc-gen completing first. This is a simple linear DAG.
The Rnix Compose DAG scheduling engine automatically resolves dependencies and determines execution order through topological sorting. If the dependency graph allows parallelism (e.g., both A and B depend on C, then A and B can execute in parallel), the engine schedules them concurrently.
Preparing Agents
You can reuse the Agent from Tutorial 1 or use the existing code-analyst. This tutorial uses the built-in code-analyst Agent and the default Agent (no additional setup needed).
Step 2: Write compose.yaml
Create compose.yaml in the project root:
version: "1.0"
intent: "Code review workflow"
model: "haiku"
agents:
analyzer:
intent: "Analyze code quality of kernel/kernel.go"
agent: "code-analyst"
doc-gen:
intent: "Generate improvement documentation based on analysis results"
depends_on:
analyzer: completed
checker:
intent: "Verify the quality and completeness of analysis and recommendations"
depends_on:
doc-gen: completedField Reference
| Field | Description |
|---|---|
version | Compose spec version (currently "1.0") |
intent | Overall workflow description |
model | Global default model (individual agents can override) |
agents | Agent definition map |
agents.<name>.intent | Task description for this agent |
agents.<name>.agent | Named agent definition to use (optional, defaults to generic agent) |
agents.<name>.depends_on | Dependencies: <upstream_agent>: completed |
How the DAG Scheduling Engine Works
After reading compose.yaml, the Compose engine:
- Parses the dependency graph — builds a directed acyclic graph (DAG) from all agents and
depends_onrelationships - Topological sort — determines execution layers (agents with no dependencies go in layer 1, those depending on them in layer 2, etc.)
- Layer-level parallelism — agents in the same layer execute concurrently
- Result passing — upstream agent output is injected into downstream agent context
Step 3: Run rnix compose up
rnix compose upThe Compose engine launches the workflow:
compose | Code review workflow | starting
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[layer 1/3] analyzer
PID 5 | code-analyst | running...
PID 5 | completed | 0 | 3.8s | 1,450 tokens ✓
[layer 2/3] doc-gen
PID 6 | default | running...
PID 6 | completed | 0 | 4.2s | 1,180 tokens ✓
[layer 3/3] checker
PID 7 | default | running...
PID 7 | completed | 0 | 2.5s | 890 tokens ✓
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
compose | completed | 3/3 agents | 10.5s | 3,520 tokensEach agent executes in DAG order, with downstream agents automatically receiving upstream agent output as context.
Step 4: Real-Time Monitoring with rnix top
While the workflow is running, open another terminal and run:
rnix topYou will see a TUI (Terminal User Interface) displaying real-time status of all processes:
rnix top — Real-time Monitor Refresh: 1s
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PID STATE AGENT TOKENS ELAPSED INTENT
5 running code-analyst 1,200 2.3s Analyze kernel/kernel.go…
6 created default 0 - Generate improvement docs…
7 created default 0 - Verify analysis quality…
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Processes: 3 | Running: 1 | Waiting: 2 | Completed: 0
Total tokens: 1,200 | Elapsed: 2.3srnix top refreshes continuously. You can observe in real-time:
- Which agents are running (
running) - Which are waiting for dependencies (
created) - Token consumption and execution time
Press q to exit rnix top.
Step 5: View Results
View Compose Output
After rnix compose up completes, it outputs an execution summary for each agent. For more detailed results, use JSON output:
rnix compose up --jsonThe JSON output contains complete results for each agent:
{
"ok": true,
"data": {
"intent": "Code review workflow",
"agents": [
{"name": "analyzer", "pid": 5, "exit_code": 0, "elapsed_ms": 3800, "tokens": 1450},
{"name": "doc-gen", "pid": 6, "exit_code": 0, "elapsed_ms": 4200, "tokens": 1180},
{"name": "checker", "pid": 7, "exit_code": 0, "elapsed_ms": 2500, "tokens": 890}
],
"total_elapsed_ms": 10500,
"total_tokens": 3520
}
}View Reasoning Logs
Use rnix log to view each agent's reasoning process:
rnix logLogs are grouped by time and process, showing each agent's reasoning steps and decisions.
Step 6: Cleanup
If the workflow fails midway or needs to be stopped, use:
rnix compose downThis terminates all compose-spawned processes and cleans up resources.
Advanced Scenarios
Pipe Syntax Alternative
For simple linear workflows, you can use pipe syntax instead of a compose file:
rnix -i 'spawn "Analyze kernel/kernel.go" --agent=code-analyst | spawn "Generate improvement docs" | spawn "Quality check"'The pipe operator | automatically injects the previous agent's output as the next agent's [PIPE_INPUT] context.
Using Variables and Environment Passing
Combine with AgentShell environment variables for more flexible workflows:
rnix -i '
export TARGET=./kernel/kernel.go
spawn "Analyze $TARGET code quality" --agent=code-analyst | spawn "Generate improvement docs"
'Or use environment in compose.yaml:
agents:
analyzer:
intent: "Analyze code quality"
agent: "code-analyst"Using if/else Conditional Branching
Generate a fix plan when issues are found, otherwise output a passing report:
result = spawn "Analyze kernel/kernel.go" --agent=code-analyst
if $result.exitcode == 0
spawn "Generate passing report"
else
spawn "Generate fix plan" on-error spawn "Log analysis failure"
endAgentShell supports full control structures:
if/else/end— conditional branching based on upstream resultson-error— inline error handling (automatically executes fallback on failure)- Variable assignment —
result = spawn "..."captures execution results - Property access —
$result.exitcodeaccesses the exit code
rnix compose down
If a workflow has lingering processes (e.g., a hung agent), use compose down to force cleanup:
rnix compose downNext Steps
Congratulations! You have mastered the three core skills of Rnix:
- Writing Skills and Agents — creating reusable agent capabilities
- Debugging — tracing and locating errors with strace
- Workflow orchestration — composing multi-agent collaboration with Compose and pipes
Further Learning
- Core Concepts — deep understanding of Rnix's OS design philosophy
- Reference Manual — complete definitions for all Syscalls, VFS paths, and CLI commands
- Tutorial 1: Writing Your First Skill — review Skill writing details
- Tutorial 2: Debugging Your First Bug — review debugging techniques
Related Documentation
- Core Concepts — mental model for processes, VFS, and Skills
- Reference Manual: CLI Commands — complete parameters for compose up/down, top, and log
- Reference Manual: IPC Architecture — Compose engine's internal communication mechanism