Claude Code headless: como o claude -p vira um agente de IA orquestrado pelo seu código
Um comando. 11 sites inteiros. Nenhum "time de agentes" com nome bonito conversando entre si.
Claude Code headless é o Claude Code sem interface: claude -p recebe um prompt, executa o loop de agente inteiro e devolve o resultado no stdout, como qualquer processo. Foi isso que rodou na minha máquina enquanto eu não fazia nada: um php artisan que enfileira jobs, e cada job chama esse processo. Terminou com 78% da sessão da assinatura consumida. Se fosse cobrado por token de API, teria custado US$ 528.
O truque não é prompt. É tratar o assistente de IA como um processo: entra instrução, sai resultado, e quem decide a ordem das coisas é o seu código. Neste post eu abro a pipeline do vídeo: como o claude -p vira um agente orquestrado por PHP, onde a conta fecha e como plugar o Higgsfield como etapa de geração de assets sem deixar o modelo decidir quanto gastar.
TL;DR
- O que é: Claude Code rodando sem interface (
claude -p), chamado como subprocesso por uma aplicação Laravel que controla fases, filas e orçamento. - Stack/Modelos: Laravel (artisan + queues), Claude Opus 5.5 via Claude Code CLI, Higgsfield CLI + skills para imagem e vídeo.
- Custo/Acesso: roda dentro da assinatura do Claude (Max, US$ 200) enquanto você usa o login normal; com
--bareou em produto para terceiros, é API key. Higgsfield usa os créditos do seu plano, sem API key. - Link útil: documentação do modo headless e o vídeo completo no YouTube.
O que é Claude Code headless (e por que claude -p é o Agent SDK pela porta do terminal)
Assistente interativo é o que você usa o dia inteiro: abre o terminal, conversa, aprova ferramenta, lê o diff.
Headless é o mesmo binário sem ninguém do outro lado. Você passa o prompt na linha de comando, ele executa o loop inteiro (planeja, chama ferramenta, lê resultado, repete) e devolve a resposta no stdout. Fim do processo.
claude -p "Analise o segmento de mercado da empresa em empresa.json e escreva pesquisa.md" \
--allowedTools "Read,Write,WebSearch" \
--output-format json
A Anthropic descreve isso literalmente como o Agent SDK em formato de CLI: "the same tools, agent loop, and context management that power Claude Code", disponível "as a CLI for scripts and CI/CD" (docs). E a própria visão geral do SDK diz que, para usar o mesmo loop a partir de uma linguagem que não seja Python ou TypeScript, o caminho é rodar o CLI como subprocesso com -p e --output-format json.
Ou seja: PHP, Bash, Go, o que for. Você não precisa do pacote do SDK para ter um agente. Precisa de um exec e de um parser de JSON.
Isso muda o desenho do sistema. Em vez de um agente gigante com 40 ferramentas tentando lembrar de tudo, você escreve uma pipeline determinística no seu código e deixa o modelo resolver só o pedaço probabilístico de cada etapa. É a premissa do loop engineering: iterar em passos pequenos até bater o resultado esperado, com o seu código julgando quando parou.
O mesmo raciocínio vale para a parte visual da pipeline. Eu poderia gastar semanas melhorando meu prompt de imagem no Nano Banana. Em vez disso, pluguei um harness que já é especialista nisso: o Higgsfield, que agrega os modelos de imagem e vídeo e expõe tudo por CLI e skills que o Claude já sabe usar. Volto nele mais abaixo.
A pipeline: Laravel orquestra, Claude executa
A entrada é um cadastro de empresas que já existe no sistema. O comando recebe os IDs e enfileira uma cadeia por empresa:
// app/Console/Commands/BuildSites.php
public function handle(): int
{
$ids = $this->argument('ids');
foreach ($ids as $id) {
Bus::chain([
new ResearchSegment($id),
new ResearchCompany($id),
new WriteCopy($id),
new DesignSystem($id),
new GenerateAssets($id), // etapa nova, ver abaixo
new BuildInPhases($id),
])->onQueue('sites')->dispatch();
}
return self::SUCCESS;
}
Dez empresas, dez cadeias, dez workers. Dentro de cada cadeia as fases são síncronas de propósito: a copy usa a pesquisa, o design usa a copy, o build usa os três. Não tem paralelismo aqui porque não tem independência aqui.
Cada job é um claude -p com prompt próprio, ferramentas próprias e um diretório de trabalho por empresa:
// app/Jobs/RunClaudeStep.php (base dos jobs acima)
protected function runClaude(string $prompt, array $tools, string $workdir): array
{
$result = Process::path($workdir)
->timeout(1800)
->run([
'claude', '-p', $prompt,
'--allowedTools', implode(',', $tools),
'--output-format', 'json',
'--max-turns', '40',
]);
if (! $result->successful()) {
throw new RuntimeException($result->errorOutput());
}
$json = json_decode($result->output(), true, flags: JSON_THROW_ON_ERROR);
$this->logCost($json['total_cost_usd'] ?? null, $json['session_id'] ?? null);
return $json;
}
Com --output-format json o resultado vem com session_id, total_cost_usd e a resposta em result. O session_id permite --resume numa fase seguinte se você quiser manter contexto; eu prefiro não manter. Cada fase começa limpa e recebe os artefatos anteriores por arquivo.
O que cada fase faz:
- Segmento. O que existe no mercado daquele nicho, o que cliente reclama, o que concorrente promete.
- Empresa. Pesquisa intensiva: site atual, avaliações no Google, redes.
- Copy. Prompt específico sobre headline, prova, oferta. Usa os dois arquivos anteriores como insumo.
- Design. Referências de sites premiados via skills (tipo Awesome Design MD e Awwwards) para tirar a cara de página feita por IA.
- Build faseado. Aqui está o ponto que mais economiza sessão.
O build não é um claude -p só. É um loop de implementação: o design vira um plano em fases pequenas, e cada fase roda num processo novo.
foreach ($plan['phases'] as $i => $phase) {
$this->runClaude(
prompt: "Implemente a fase {$i}: {$phase['goal']}. Leia PLAN.md e DESIGN.md. Não avance para a próxima fase.",
tools: ['Read', 'Write', 'Edit', 'Bash(npm *)'],
workdir: $workdir,
);
}
Janela de contexto pequena por fase. O Opus 5.5 trabalha com folga, não alucina componente que não existe, não "aproveita" para refatorar o que ninguém pediu. E se uma fase quebra, você reroda uma fase, não o site inteiro.
Onde a conta fecha: assinatura vs API
Os números do vídeo: 11 sites, 78% da sessão de uma assinatura Max de US$ 200, US$ 528 se fosse API. Um comando pagou a assinatura duas vezes e meia.
Isso funciona porque claude -p, sem flags extras, usa o mesmo login da sua conta. Os tokens saem da cota da assinatura.
Agora os dois asteriscos que o vídeo não teve tempo de abrir:
1. --bare não usa assinatura. A flag recomendada para CI e scripts pula hooks, skills, MCP e CLAUDE.md, e "doesn't use your subscription login": exige ANTHROPIC_API_KEY. A documentação avisa que --bare "will become the default for -p in a future release" (docs). Se isso acontecer, a economia de assinatura passa a depender de você não usar o default.
2. Produto para terceiro é API key. A Anthropic é explícita: "Anthropic does not allow third party developers to offer claude.ai login or rate limits for their products, including agents built on the Claude Agent SDK" (overview). Pipeline interna, na sua máquina, gerando site para o seu cadastro: assinatura. SaaS onde o cliente clica e o seu Claude gera: API.
Se você já leu por aqui que o claude -p ia morrer, a atualização é essa: ele não morreu, virou a porta de entrada oficial do SDK para quem não está em Python ou TypeScript. O que está mudando é o default de autenticação.
Tutorial te mostra o caminho — no Clã você constrói junto. Aula ao vivo toda semana, projetos reais de Engenharia de IA, ao lado de quem já está em produção.
Entrar no ClãO upgrade: Higgsfield como harness pronto de assets
A primeira versão da pipeline gerava imagens chamando o Gemini Nano Banana direto. Não estava ruim. Mas para melhorar eu teria que construir harness: prompt por tipo de asset, referências de estilo, vídeo para o hero, controle de proporção. Semanas.
O mesmo argumento que me fez usar o harness do Claude Code em vez de reimplementar o loop no Agent SDK vale aqui: usar um harness pronto e especialista dá resultado melhor com muito menos código. O Higgsfield agrega modelos de imagem e vídeo (Seedance, Kling, Veo, Nano Banana Pro, Soul) e entrega isso para o agente por CLI, com skills, ou por MCP.
A recomendação oficial deles: MCP para agente de chat, CLI para coding agent (help center). Como a gente vai chamar isso de dentro de um claude -p, é CLI.
npm install -g @higgsfield/cli
higgsfield auth login # OAuth, sem API key; usa os créditos do plano
npx skills add higgsfield-ai/skills
Pronto. A partir daí, o Claude dentro da pipeline tem as skills generate, soul e product-photoshoot e sabe rodar higgsfield generate create seedance_2_5 --prompt ... --wait.
Este clipe abaixo foi gerado exatamente assim, pela mesma sessão que escreveu o post: um higgsfield generate create com Seedance 2.5, descrevendo a pipeline deste texto.
A etapa nova da pipeline entra depois do design:
// app/Jobs/GenerateAssets.php
public function handle(): void
{
$this->runClaude(
prompt: <<<PROMPT
Leia DESIGN.md e liste cada asset visual necessário (hero, produto, seções).
Para cada um, gere com a skill higgsfield-generate usando as fotos em ./fotos como referência.
Salve em ./assets e registre o job_id de cada geração em ASSETS.json.
PROMPT,
tools: ['Read', 'Write', 'Bash(higgsfield *)', 'Skill'],
workdir: $this->workdir(),
);
}
O agente decide o que gerar. Quem decide quanto pode gastar é o Laravel.
Isso é feito com um hook de PreToolUse que consulta o orçamento por site antes de liberar qualquer higgsfield generate:
#!/usr/bin/env bash
# .claude/hooks/budget-gate.sh — recebe o tool call em stdin
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // empty')
case "$cmd" in
higgsfield\ generate*)
php artisan assets:budget-check "$SITE_ID" || {
echo "Orçamento de créditos deste site esgotado." >&2
exit 2 # bloqueia a ferramenta, o Claude recebe o motivo
}
;;
esac
Estourou o orçamento, a ferramenta não roda. Não é "lembre-se de não gastar mais que X créditos" no prompt, que o modelo esquece na terceira iteração. É ferramenta determinística controlando ferramenta probabilística.
Resultado no caso do PimentArt, a empresa de pimentas artesanais do meu pai: três fotos ruins de celular viraram um hero com o produto dentro de cenário e um vídeo curto rodando atrás. A terceira seção, que antes era uma mesa vazia, ganhou uma imagem explicando os três níveis de picância. Tudo saiu da pipeline, sem eu abrir editor.
Limitações e pontos de atenção
-p sem --bare carrega tudo da pasta. Hooks do .claude/settings.json, servidores do .mcp.json, CLAUDE.md. E não mostra diálogo de confiança nem prompt de aprovação de servidor. Rodar claude -p num repositório que você não conhece é executar o que aquele repositório configurou. Em pipeline própria, ok. Em input de terceiro, não.
Sessão acaba. 78% de uma sessão com 11 sites. Se você enfileirar 30, o worker vai bater rate limit no meio e o job vai falhar. Trate 429 como retry com backoff, não como erro fatal, e não conte com a sessão para uso 24/7.
Prompt ruim gera igreja. Eu pedi "mapa de cima, aproxima, entra numa casa, pessoa come coxinha com pimenta" e o primeiro vídeo começou numa igreja. A correção custou bem menos crédito que gerar do zero, mas custou. Descrição vaga em modelo de vídeo vira crédito queimado.
Budget por prompt não segura. Vale repetir: o único controle de gasto que sobreviveu foi o hook. Instrução no system prompt é sugestão.
Dado de cliente no prompt. Cada fase recebe pesquisa sobre a empresa. Se isso incluir dado pessoal de cliente final, mascare antes. O processo headless não tem ninguém olhando o que foi enviado.
FAQ rápido
Preciso do Agent SDK em Python ou TypeScript para fazer isso?
Não. Os pacotes dão callbacks de aprovação, mensagens tipadas e streaming como objetos. Se você só precisa de prompt entra, JSON sai, claude -p --output-format json cobre. A documentação aponta o CLI como subprocesso justamente para outras linguagens.
Funciona com Codex ou outro CLI?
A orquestração sim: é Process::run com outro binário. O que muda é o formato de saída e as flags de permissão. A ideia de fases pequenas, artefatos em arquivo e budget no código é independente do modelo.
Como controlo o gasto de créditos do Higgsfield?
No código, não no prompt. Um hook PreToolUse que bloqueia higgsfield generate quando o orçamento do site estourou. O CLI usa os créditos do plano da conta logada, então o teto real é o seu plano; higgsfield account status mostra o saldo.
Posso vender isso como produto para clientes? Com API key, sim. Com login de assinatura, a Anthropic não permite oferecer isso a terceiros. A pipeline continua igual; troca a autenticação e a linha de custo.
Conclusão
O que rodou aqui não foi "time de IA". Foi um comando artisan, uma fila e um binário chamado em loop com contexto pequeno por fase. O Claude resolve o pedaço probabilístico de cada etapa; o PHP decide a ordem, guarda os artefatos e segura o orçamento.
Quando a geração de assets ficou aquém, a resposta não foi escrever mais prompt: foi plugar um harness pronto e colocar o controle de crédito num hook. É o mesmo princípio dos dois lados.
O próximo passo natural dessa pipeline é fechar o loop com avaliação: um claude -p de revisão que dá nota por seção e devolve a fase que falhou. Se você quer o mapa mental completo do que precisa existir em volta do modelo antes disso, começa pelas 5 peças do agent harness.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.
Entrar no Clã