PromptHub
Developer Tools Artificial Intelligence

Fractals: The Recursive AI Agent Swarm That's Replacing Linear Workflows

B

Bright Coding

Author

15 min read
118 views
Fractals: The Recursive AI Agent Swarm That's Replacing Linear Workflows

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.

Comments (0)

Comments are moderated before appearing.

No comments yet. Be the first to share your thoughts!

Support us! ☕