
Sechzig Container auf einem Server
Eine Bare-Metal-Box führt Dutzende bis Hunderte von Hoody-Containern aus. KSM und BTRFS-Dedup machen die Marginalkosten nahezu null.
Ein Recherche-Agent bekommt einen komplexen Prompt. Statt alles selbst zu machen, POSTet er an die Containers-API und kriegt drei Sub-Agent-URLs zurück. Jeder Sub-Agent kann seine eigenen Sub-Agenten starten. Keiner weiß von einem Orchestrator. Sie rufen sich einfach gegenseitig über HTTP auf.
Jeder Knoten im Baum ist ein Hoody-Container mit einem hoody-agent-Service. Eltern und Kinder kennen sich nur über URL. Es gibt keinen zentralen Planer, der von oben zuschaut.
Bekommt den Prompt. Entscheidet, welche Sub-Tasks er fan-outten will. POSTet an die Containers-API, um pro Sub-Agent einen neuen Container zu spawnen, und ruft dann jeden /api/v1/agent/tasks-Endpoint mit dem Slice an Arbeit auf, der ihm gehört.
Jeder läuft in seinem eigenen Container mit eigenem Filesystem, eigenem Terminal und eigener SQLite. Keiner kann die anderen korrumpieren. Jeder kann entscheiden, dass er Hilfe braucht, und seine eigenen Kinder genauso starten wie der Parent. Das Protokoll ist symmetrisch.
Der Fact-Checker sieht fünf Claims, startet fünf Container parallel, feuert fünf HTTP-Requests, wartet auf fünf Responses. Dasselbe Pattern, eine Ebene tiefer. Idle Container kosten nichts, also sind tiefe Bäume wirtschaftlich gratis.
Es gibt keine Agent-Runtime zu installieren, keinen Message-Bus zu konfigurieren, keinen Shared State zu synchronisieren. Der Eltern-Agent nutzt dieselbe Containers-API wie ein Mensch: POST zum Erstellen, dann die Child-URL aufrufen.
// Parent agent (running in its own Hoody container).
// Spawn three sub-agents, hand each one a slice of work,
// await their results in parallel.
const HOODY = 'https://api.hoody.com';
async function spawnChild(name) [
// 1. Create a fresh container with the agent service running.
const res = await fetch(HOODY + '/api/v1/projects/' + PROJECT + '/containers', [
method: 'POST',
headers: [ authorization: 'Bearer ' + TOKEN ],
body: JSON.stringify([
name,
server_id: SERVER,
container_image: 'debian-12',
hoody_kit: true,
ai: true,
]),
]);
const child = (await res.json()).data;
// 2. Hit the child's agent URL like any other HTTP service.
const agentUrl = 'https://' + PROJECT + '-' + child.id + '-agent-1.' + SERVER + '.containers.hoody.com';
return [ id: child.id, agentUrl ];
]
const [scrape, summarize, factCheck] = await Promise.all([
spawnChild('scrape'),
spawnChild('summarize'),
spawnChild('fact-check'),
]);
// 3. Dispatch tasks. Each child runs autonomously,
// can spawn its own children the same way.
const results = await Promise.all([
fetch(scrape.agentUrl + '/api/v1/agent/tasks', [ method: 'POST', body: JSON.stringify([ description: scrapeBrief ]) ]),
fetch(summarize.agentUrl + '/api/v1/agent/tasks', [ method: 'POST', body: JSON.stringify([ description: summarizeBrief ]) ]),
fetch(factCheck.agentUrl + '/api/v1/agent/tasks', [ method: 'POST', body: JSON.stringify([ description: factCheckBrief ]) ]),
]);Beide Endpoints sind dokumentierte Hoody-APIs: POST /api/v1/projects/$PID/containers spawnt einen neuen Container mit vorinstalliertem Agent-Service; POST $CHILD_URL/api/v1/agent/tasks dispatcht eine Aufgabe an ihn. Der Fact-Checker kann denselben Code laufen lassen, um seine eigenen Per-Claim-Verifier zu spawnen — die Rekursion ist einfach HTTP.
Jedes Agent-Framework ist eine dünne Schicht über In-Process-Function-Calls. Sie alle nehmen an, dass Agenten Memory teilen, Python teilen, eine einzelne Runtime teilen. Hoody nimmt das Gegenteil an: Agenten sind separate Computer, und HTTP ist bereits das Protokoll, das sie sprechen.
POST /api/v1/projects/$PID/containers
fetch(child.url + '/api/v1/agent/tasks')
Zwei HTTP-Calls pro Kind. Der Eltern-Agent importiert kein Framework, registriert kein Tool, teilt keinen State. Jeder Sub-Agent ist ein Peer mit URL — gleiche Form wie der Parent, gleiche Form wie jeder andere HTTP-Service, den du aufrufen würdest.
Jeder Agent ist ein Peer mit URL. Sie rufen sich gegenseitig auf, wie jeder HTTP-Service jeden anderen HTTP-Service aufruft.
Es gibt keinen Orchestrator. Es gibt keinen Message-Bus. Es gibt keinen Shared State zu synchronisieren. Das Einzige, was begrenzt, wie viele Agenten du parallel laufen lässt, ist, wie viel du ausgeben willst — und Idle Container kosten nichts.
Die Orchestrierungs-Frameworks und Ephemeral-Runtime-Services, zu denen Leute greifen, wenn ein Agent nicht reicht. Jedes löst einen Slice des Problems. Das HTTP-native Primitiv ersetzt den Slice und das Framework drumherum.
Hör auf, Agent-Graphen zu verkabeln. Starte einen. Lass ihn den Rest starten.