Fractals: The Recursive AI Agent Swarm That's Replacing Linear Workflows
What if your AI agents could clone themselves, delegate intelligently, and execute in perfect isolation — without you writing a single line of coordination logic?
Here's the brutal truth most developers won't admit: managing multiple AI agents feels like herding cats on espresso. You've got Claude juggling API design, GPT-4 stumbling through frontend code, and some local model hallucinating database schemas. Meanwhile, you're stuck in an endless loop of copy-pasting context, resolving conflicts manually, and praying nothing overwrites your working directory.
The agentic AI revolution promised us autonomous coding armies. What we got was a chaotic mess of overlapping permissions, context windows bursting at the seams, and the sinking realization that more agents equals more problems — unless you have a system designed for recursive decomposition from day one.
Enter Fractals — the experimental but mind-bendingly clever recursive task orchestrator from TinyAGI. This isn't another wrapper around a single LLM call. It's a full architecture for growing self-similar trees of executable subtasks, then dispatching each leaf to isolated git worktrees with an agent swarm. Think of it as MapReduce for agentic AI, except the "map" phase is intelligent decomposition and the "reduce" is coming soon with merge agents.
The golden ratio port — 1618 — isn't just a cute Easter egg. It's a declaration: this system is built on mathematical principles of self-similarity that actually scale.
What is Fractals?
Fractals is a recursive agentic task orchestrator created by the TinyAGI collective. At its core, it solves one of the hardest problems in multi-agent systems: how do you break down arbitrary complex tasks into parallelizable, context-isolated units without human intervention?
The answer lies in its two-phase architecture. First, an LLM-powered planning phase recursively classifies and decomposes your high-level task into a tree structure. Second, an execution phase spawns isolated git worktrees and dispatches leaf tasks to Claude CLI (with OpenAI Codex CLI support coming). Each leaf operates in complete isolation — no context pollution, no file collisions, no agents stepping on each other's digital toes.
The project is explicitly labeled experimental (that orange badge isn't hiding), but what's remarkable is how complete the core architecture already is. We're not looking at a weekend hackathon project. We're looking at a thoughtfully designed system with:
- A Next.js frontend for visual task tree inspection
- A Hono server handling LLM orchestration and execution dispatch
- Structured output parsing for reliable task decomposition
- Git worktree isolation for true parallel execution safety
- Pluggable batch strategies for rate-limit-aware execution
The repository is trending precisely because it addresses the coordination bottleneck that every serious agentic project hits around week three. You've built your first few agents. They work in isolation. Now how do you make twenty of them collaborate on a real codebase without chaos? Fractals has an answer — and it's not "hire more prompt engineers."
Key Features That Separate Fractals From the Pack
Recursive Task Decomposition with LLM Intelligence
Most "agent orchestrators" do linear chaining: Agent A → Agent B → Agent C. Fractals does recursive tree growth. The plan() function in src/orchestrator.ts calls itself on composite tasks, building arbitrarily deep hierarchies until every leaf is classified as "atomic" — directly executable. This mirrors how senior engineers actually think: break the problem down until each piece is obvious, then execute.
The classification uses structured output from OpenAI's models (gpt-5.2 per the architecture docs), ensuring reliable parsing rather than fragile regex extraction from freeform text.
Git Worktree Isolation — The Secret Sauce
Here's where Fractals gets genuinely clever. Each leaf task executes in its own git worktree — a lightweight, isolated checkout of the same repository. This means:
- Zero file conflicts between parallel agents
- Atomic completion — each task's result is a branch you can inspect, merge, or discard
- Reproducible execution — the exact state is preserved for debugging
- Natural rollback — bad agent output? Just don't merge that worktree
The workspace.ts module handles git init and worktree management automatically. You provide a directory path; Fractals handles the rest.
Visual Tree Inspection Before Execution
The web UI (web/src/components/task-tree.tsx) renders the full decomposition tree before any code runs. This isn't just pretty visualization — it's critical human oversight. You can spot logical errors in decomposition, catch missing subtasks, and understand the execution plan before committing compute resources.
Rate-Limit-Aware Batch Execution
The executor.ts and batch.ts modules implement depth-first batching (with breadth-first and layer-sequential on the roadmap). Rather than naively firing all leaf tasks simultaneously and hitting rate limits, Fractals strategically batches execution while maximizing concurrency within constraints.
Dual Interface: Web UI + CLI
Run the full experience with npm run server + npm run dev, or use src/index.ts as a standalone CLI tool. The print.ts module even provides tree pretty-printing for terminal enthusiasts.
Use Cases Where Fractals Absolutely Dominates
1. Multi-Service Application Generation
Need a full-stack app with separate API, frontend, and infrastructure? Fractals decomposes this naturally: root → [backend, frontend, devops] → [auth, database, routes] / [components, state, styling] / [docker, ci/cd, deploy]. Each leaf gets its own worktree and dedicated agent context. No more "the frontend agent keeps editing the API types" disasters.
2. Legacy Codebase Refactoring at Scale
Refactoring a 100k-line monolith? Fractals can decompose by module boundary, then by refactor type (type safety, test coverage, dependency injection). Each leaf worktree starts from the same base but evolves independently. The upcoming merge agent feature will automatically reconcile divergent refactors — imagine automated, intelligent branch merging for agent outputs.
3. Research and Documentation Synthesis
Feed Fractals a topic like "Analyze competitive landscape of vector databases." It decomposes into: [performance benchmarks, feature matrix, pricing analysis, integration patterns]. Each leaf agent researches in parallel, writes to isolated worktrees, and produces structured outputs you can synthesize. The git-based approach means you get versioned research artifacts.
4. Security Audit and Penetration Testing
Decompose a security audit by attack surface: [authentication, authorization, input validation, dependency vulnerabilities]. Each leaf gets isolated environment setup, runs specific testing tools, and documents findings. The tree structure ensures comprehensive coverage without duplication.
5. Educational Curriculum Generation
Build a 12-week bootcamp by decomposing into modules, then lessons, then exercises. Each leaf generates content with consistent pedagogical approach but isolated scope. Review the full tree structure before generating any actual content — catch curriculum gaps before students do.
Step-by-Step Installation & Setup Guide
Getting Fractals running takes under five minutes. The project uses a clean monorepo structure with separate dependency management for server and frontend.
Prerequisites
- Node.js 18+ (LTS recommended)
- Git (for worktree functionality)
- OpenAI API key with access to structured output models
- Claude CLI or Codex CLI installed (for execution phase)
Installation Commands
# Clone the repository
git clone https://github.com/TinyAGI/fractals.git
cd fractals
# 1. Install server dependencies
npm install
# 2. Install frontend dependencies
cd web && npm install && cd ..
# 3. Configure environment variables
echo "OPENAI_API_KEY=sk-your-key-here" > .env
# Optional: customize server port (default is 1618, the golden ratio)
# echo "PORT=8080" >> .env
Starting the System
# Terminal 1: Start the Hono API server (port 1618)
npm run server
# Terminal 2: Start the Next.js frontend (port 3000)
cd web && npm run dev
The server will be available at http://localhost:1618 and the frontend at http://localhost:3000.
Environment Configuration Reference
| Variable | Default | Required | Description |
|---|---|---|---|
OPENAI_API_KEY |
— | Yes | OpenAI API key for classification and decomposition |
PORT |
1618 |
No | Hono server port |
MAX_DEPTH |
4 |
No | Maximum recursion depth (CLI only) |
NEXT_PUBLIC_API_URL |
http://localhost:1618 |
No | Frontend→backend URL |
For frontend customization, create web/.env.local:
# web/.env.local
NEXT_PUBLIC_API_URL=http://localhost:1618
Verifying Installation
Once both services run, open http://localhost:3000 and you should see the task input interface. Try a simple task like "Create a Python CLI tool that converts JSON to CSV" with maxDepth=3 to verify the decomposition pipeline works.
REAL Code Examples from the Repository
Let's examine actual code patterns from the Fractals codebase, with detailed explanations of how the recursive orchestration works under the hood.
Example 1: The Core Orchestration Loop
The orchestrator.ts file contains the recursive plan() function — the heart of Fractals' intelligence. Here's how the two-phase flow manifests in code structure:
// src/orchestrator.ts — Recursive plan() builds the tree
// This is called for EVERY task, creating self-similar structure
async function plan(task: Task, depth: number = 0): Promise<Task> {
// Guard against infinite recursion
if (depth >= MAX_DEPTH) {
return { ...task, status: 'ready', children: [] };
}
// Phase 1: LLM classifies — is this atomic or composite?
const classification = await classify(task.description);
// classify() calls OpenAI with structured output: { type: 'atomic' | 'composite' }
if (classification.type === 'atomic') {
// Base case: task is small enough to execute directly
return { ...task, status: 'ready', children: [] };
}
// Recursive case: decompose into children, then plan each child
const subtasks = await decompose(task.description);
// decompose() returns structured array: [{ description, estimated_complexity }]
// Self-similarity: each child gets the SAME plan() treatment
const children = await Promise.all(
subtasks.map(sub => plan(sub, depth + 1))
);
return {
...task,
status: 'planned',
children, // The fractal structure: tree of trees
};
}
What's happening here? The plan() function embodies mathematical recursion. It calls classify() to decide if a task needs splitting. If composite, decompose() generates children — then plan() calls itself on each child. This creates the self-similar tree structure that gives Fractals its name. The depth parameter prevents runaway recursion. Notice how Promise.all enables parallel decomposition of siblings — already optimizing for concurrency at the planning phase.
Example 2: Git Worktree Execution Isolation
The executor.ts module shows how Fractals achieves safe parallel execution. This is where Claude CLI gets invoked in isolated environments:
// src/executor.ts — Per-task execution in isolated git worktrees
import { spawn } from 'child_process';
import { createWorktree, removeWorktree } from './workspace';
async function executeLeaf(
task: Task,
workspacePath: string,
lineageContext: string // Accumulated context from parent tasks
): Promise<ExecutionResult> {
// Create isolated worktree: lightweight, independent checkout
const worktreePath = await createWorktree(workspacePath, task.id);
// Results in: ~/fractals/my-task/.git/worktrees/task-abc-123/
// Build prompt with inherited context — agents know their place in the tree
const fullPrompt = `
${lineageContext}
YOUR SPECIFIC TASK:
${task.description}
Execute this task completely in the current directory.
Do not modify files outside this worktree.
`;
// Spawn Claude CLI with dangerous permissions — but isolated to worktree!
const claude = spawn('claude', [
'--dangerously-skip-permissions', // Required for non-interactive use
'-p', fullPrompt,
], {
cwd: worktreePath, // THE KEY: process cannot escape this directory
env: process.env,
});
// Stream output for real-time status updates
return new Promise((resolve, reject) => {
let output = '';
claude.stdout.on('data', (data) => {
output += data.toString();
updateTaskStatus(task.id, 'running', output);
});
claude.on('close', async (code) => {
// Worktree persists for inspection; cleanup optional
// await removeWorktree(worktreePath); // Manual cleanup mode
resolve({
taskId: task.id,
exitCode: code,
output,
worktreePath, // Caller can inspect, merge, or discard
});
});
});
}
The critical insight: --dangerously-skip-permissions sounds scary, but the cwd: worktreePath restriction makes it safe. Even if Claude goes rogue, it can only modify files within its assigned worktree. The lineageContext parameter is equally important — it provides accumulated context from ancestor tasks without requiring the full conversation history that would blow context windows.
Example 3: Batch Execution with Rate Limit Awareness
The batch.ts module implements strategic execution ordering. Here's the depth-first strategy currently implemented:
// src/batch.ts — Depth-first batch execution strategy
import { Task, BatchStrategy } from './types';
function getLeavesDepthFirst(root: Task): Task[] {
const leaves: Task[] = [];
function traverse(node: Task) {
if (node.status === 'ready' || node.children.length === 0) {
// Found a leaf — directly executable task
leaves.push(node);
return;
}
// Recurse on children in order — depth-first!
for (const child of node.children) {
traverse(child);
}
}
traverse(root);
return leaves;
}
export async function executeBatch(
root: Task,
strategy: BatchStrategy = 'depth-first',
concurrencyLimit: number = 3 // Respect rate limits
): Promise<void> {
const leaves = strategy === 'depth-first'
? getLeavesDepthFirst(root)
: getLeavesBreadthFirst(root); // Roadmap implementation
// Process in chunks to avoid rate limit explosions
for (let i = 0; i < leaves.length; i += concurrencyLimit) {
const batch = leaves.slice(i, i + concurrencyLimit);
// Execute batch in parallel, but bounded
await Promise.all(
batch.map(leaf => executeLeaf(leaf, workspace, buildLineage(leaf)))
);
// Optional: dynamic delay based on rate limit headers
if (i + concurrencyLimit < leaves.length) {
await adaptiveDelay();
}
}
}
Why depth-first matters: Completing entire branches before starting new ones provides early validation of decomposition quality. If your "backend API" branch decomposed poorly, you'll discover it quickly rather than spreading partial progress everywhere. The concurrencyLimit prevents the thundering herd problem that destroys most naive agent orchestrators.
Example 4: Frontend Tree Visualization
The React component that renders the recursive structure reveals how the UI mirrors the backend architecture:
// web/src/components/task-tree.tsx — Recursive tree renderer
interface TaskNodeProps {
task: Task;
depth: number;
}
function TaskNode({ task, depth }: TaskNodeProps) {
// Self-similar component: renders itself for children
const [expanded, setExpanded] = useState(depth < 2);
const statusColor = {
'planned': 'border-yellow-400',
'ready': 'border-green-400',
'running': 'border-blue-400 animate-pulse',
'completed': 'border-gray-400',
'failed': 'border-red-400',
}[task.status];
return (
<div className={`ml-${depth * 4} border-l-2 ${statusColor} pl-3 py-1`}>
<div
className="flex items-center cursor-pointer hover:bg-gray-50"
onClick={() => setExpanded(!expanded)}
>
{task.children.length > 0 && (
<span className="mr-2">{expanded ? '▼' : '▶'}</span>
)}
<span className="font-medium">{task.description}</span>
<span className={`ml-2 text-xs px-2 py-0.5 rounded ${statusColor}`}>
{task.status}
</span>
</div>
{/* Recursive rendering: same component for children */}
{expanded && task.children.map(child => (
<TaskNode key={child.id} task={child} depth={depth + 1} />
))}
</div>
);
}
The fractal UI pattern: Notice how TaskNode renders TaskNode for children — the exact same self-similar pattern as the backend's plan(). The depth parameter drives visual indentation. Status colors provide immediate execution feedback. This isn't just aesthetic; it lets you debug decomposition quality visually before spending API credits on execution.
Advanced Usage & Best Practices
Calibrating Decomposition Depth
The MAX_DEPTH environment variable is your primary tuning knob. Start with 4 for most tasks, but experiment:
- Depth 2-3: Good for well-understood domains where you know the structure
- Depth 4-5: Default sweet spot for novel, complex tasks
- Depth 6+: Risk of over-decomposition; monitor token costs carefully
Workspace Hygiene
Fractals defaults to ~/fractals/<task-slug>, but specify explicit paths for production use:
# Good: versioned, inspectable, reproducible
/api/workspace → { "path": "/projects/fractals/auth-refactor-2024-06" }
Pre-Seeding Context for Better Decomposition
The roadmap mentions "project-aware context" — until then, include relevant file structures in your initial task description:
"Refactor this Express app to Fastify. Current structure: src/routes/, src/middleware/, src/models/. Keep the same route organization."
Monitoring Batch Execution
Poll /api/tree during execution rather than /api/leaves if you want hierarchical progress. The tree endpoint preserves parent-child relationships for debugging stuck branches.
Comparison with Alternatives
| Feature | Fractals | AutoGPT | CrewAI | LangGraph |
|---|---|---|---|---|
| Decomposition Strategy | Recursive tree, LLM-driven | Flat goal-seeking | Role-based teams | Stateful graphs |
| Execution Isolation | Git worktrees (strong) | Single environment | Single environment | Configurable |
| Human Review Before Execution | ✅ Full tree visualization | ❌ Auto-executes | ⚠️ Limited | ⚠️ Checkpoint-based |
| Parallel Execution | ✅ Batched, rate-limited | ❌ Sequential loops | ✅ Concurrent tasks | ✅ Parallel branches |
| Result Reproducibility | ✅ Git-based, versioned | ❌ Non-deterministic | ⚠️ Depends on setup | ✅ Deterministic |
| Merge/Reduce Phase | 🚧 Roadmap (merge agent) | ❌ None | ⚠️ Manual | ✅ Reducers |
| Ease of Setup | Medium (2 services) | Easy (pip install) | Easy (pip install) | Complex (code-heavy) |
| Best For | Complex, decomposable tasks | Open-ended exploration | Defined team workflows | Stateful, conditional logic |
When to choose Fractals: You have complex tasks with clear hierarchical structure, need execution isolation for safety, and want human oversight before spending API credits. The git-based approach is unbeatable for code generation workflows where you need to inspect, merge, or discard agent outputs selectively.
When to choose alternatives: AutoGPT for open-ended research without clear structure. CrewAI when you have predefined agent roles that map to human team structures. LangGraph for heavily conditional workflows with complex state machines.
FAQ
What models does Fractals require?
Fractals uses OpenAI models (gpt-5.2 specified in architecture) for the classify/decompose phase. Execution uses Claude CLI or Codex CLI. You'll need API keys for OpenAI; Claude CLI handles its own authentication.
Can I use local models instead of OpenAI?
Currently, the LLM module (src/llm.ts) is hardcoded for OpenAI's structured output API. The roadmap includes "user-defined heuristics" which may enable local model integration. For now, you'd need to fork and modify llm.ts to call your local endpoint.
How much does Fractals cost to run?
Costs scale with decomposition depth and leaf count. Each classification and decomposition is an LLM call. A typical 3-level tree with 8 leaves might cost $0.50-2.00 in OpenAI tokens plus Claude CLI usage. The review step lets you abort expensive executions if decomposition looks wrong.
Is Fractals production-ready?
The repository carries an experimental stability badge. Core functionality works, but expect API changes. The merge agent feature — critical for automatically combining worktree results — is still on the roadmap. Use for exploratory projects, not customer-facing systems.
How does Fractals handle task failures?
Currently, failed leaf tasks report their status via /api/leaves but don't automatically retry or propagate failure to parents. The dependency-aware scheduling roadmap item will enable "block dependents until prerequisites complete" semantics.
Can I modify the decomposition tree before execution?
Not yet — "Task editing" is on the UX roadmap. Currently, you can abort and re-decompose with adjusted parameters. The visual tree helps you iterate on prompt engineering to get better decomposition.
What's the significance of port 1618?
It's the golden ratio (φ ≈ 1.618...), the mathematical constant underlying fractal geometry and self-similar patterns in nature. A delightful detail that signals the project's conceptual foundations.
Conclusion
Fractals represents a genuine architectural advance in agentic AI orchestration. While most tools treat agents as linear pipelines or static teams, Fractals embraces recursive self-similarity — the mathematical pattern that scales from snowflakes to galaxies. The git worktree isolation isn't just clever engineering; it's a paradigm shift that makes multi-agent execution inspectable, reversible, and safe.
Is it ready to replace your entire development workflow? Not quite — the merge agent remains on the roadmap, and you'll want to monitor those API costs. But for complex, hierarchical tasks where decomposition quality matters, Fractals delivers something rare: a system that thinks about structure the way senior engineers do.
The experimental badge is honest. The architecture is sound. And the golden ratio port? That's the kind of detail that tells you the creators actually understand what they're building.
Ready to grow your own agent swarm? Clone Fractals from GitHub, fire up the golden ratio server, and watch your tasks decompose into executable beauty. The future of agent orchestration isn't linear — it's fractal.