
Sessenta contêineres em um servidor
Uma caixa bare-metal executa dezenas a centenas de contêineres Hoody. KSM e BTRFS dedup fazem o custo marginal próximo a zero.
Você quer um painel de modelos revisando a mesma entrada. Cinco contêineres, cinco provedores diferentes, cinco opiniões. O framework de orquestração geralmente inventa cem linhas pra coordenar isso. Você não escreve nenhuma — cada agente ganha seu próprio caminho de pipe, e o juiz faz curl nos cinco em paralelo.
Cada agente roda em seu próprio contêiner com seu próprio handle de modelo. Cada um faz streaming do veredito para seu próprio caminho de pipe. O processo juiz faz curl nos cinco caminhos em paralelo — o pipe segura cada veredito até o juiz conectar, então transmite os bytes. Sem barramento de mensagens, sem framework de orquestração, sem grafo de callbacks.
Cinco contêineres sobem em paralelo, cada um com um handle de modelo diferente. O juiz faz POST do prompt para o endpoint de agente de cada contêiner ao mesmo tempo.
Enquanto o modelo pensa, o agente envia seu veredito para pipe/agent-N com PUT. O pipe segura os bytes — sem disco, sem broker — até alguém fazer curl pra puxar.
GET em pipe/agent-1 até pipe/agent-5 com um curl em cada. O pipe roteia os bytes de cada agente para o juiz assim que as duas pontas conectam.
O juiz lê o JSON de cada caminho, conta os votos, retorna a maioria. Cinco contêineres, um caminho HTTP cada, sem SDK entre eles.
#!/usr/bin/env bash
set -euo pipefail
PROMPT='review this PR for security issues'
AGENTS=(claude-sonnet gpt-4o gemini llama mixtral)
BASE=https://pipe.hoody.com/api/v1/pipe
# Each container streams its verdict into its own path.
# Five paths fan-in to one judge — no broker, no SDK.
for i in "$[!AGENTS[@]]"; do
N=$((i + 1))
curl -s -X POST "https://agent-$N.hoody.com/v1/run" \
-d "[\"prompt\": \"$PROMPT\", \"sink\": \"$BASE/agent-$N\"]" &
done
# Read all five verdicts in parallel.
VERDICTS=()
for i in 1 2 3 4 5; do
VERDICTS+=("$(curl -s "$BASE/agent-$i")")
done
wait
# Tally — majority wins.
printf '%s\n' "$[VERDICTS[@]]" \
| jq -r .verdict \
| sort | uniq -c | sort -rn | head -1PUT empurra cada veredito pra cima. GET puxa cada um pra baixo. O pipe é o fio — os bytes vão do agente ao juiz assim que as duas pontas conectam, com backpressure por caminho. Para adicionar um sexto agente, você sobe um sexto contêiner e adiciona uma sexta linha ao loop.
O mecanismo é uma forma só — cinco contêineres, cinco caminhos, um juiz — mas o valor se lê diferente dependendo do que você está tentando vencer.
Você não precisa de um framework de orquestração pra mandar um prompt pra cinco APIs e tirar a média das respostas. Um loop bash com cinco curls já faz isso. O ensemble de agentes sempre foi cinco chamadas HTTP disfarçadas.
Adicionar um agente: outro contêiner, outro caminho de pipe, mais uma linha no fetch paralelo do juiz. Tirar um: matar o contêiner, remover a linha. Não há nada pra reconfigurar — sem barramento de mensagens, sem grafo de callbacks, sem migração de schema.
Modelos baratos transmitem primeiro; os caros só terminam quando o consenso é incerto. Como cada agente é um contêiner separado com seu próprio pipe, você pode encerrar o painel assim que três concordam — sem estado compartilhado, sem RPC de abort, é só fechar os pipes.
Cada agente ganha um caminho. O caminho é o fio.
Cinco provedores de modelo, cinco contêineres, cinco caminhos HTTP — e um juiz que cabe em vinte linhas de bash. O framework de orquestração sempre fingiu que HTTP não existia.
O juiz lê cada caminho, conta os votos, retorna a maioria. Para adicionar um agente, sobe um contêiner e adiciona um caminho. Não há barramento de mensagens pra reconfigurar.
Todo framework aqui traz seu próprio conceito de "agente" mais um jeito específico do fornecedor de um agente conversar com outro. O pipe colapsa essa superfície em HTTP — um caminho por agente, curl nas duas direções.
Você não precisa de um orquestrador. Você precisa de cinco contêineres e cinco caminhos de pipe. O juiz são vinte linhas de bash.