Plataforma multiagente de entrega de software: orquestração LangGraph, execução paralela, judge com veto objetivo (pytest/ruff/mypy), gate humano em decisões críticas, circuit breakers de custo e tempo, execução durável e observabilidade OTel.
- 530 funções de teste entre cenários unitários e de integração.
- CI com PostgreSQL 16 e Neo4j 5, incluindo restart, lease e heartbeat.
pytest,ruffemypypodem vetar uma entrega mesmo quando o judge LLM aprova.- Tokens, custo, latência, falhas e tentativas são rastreados por workflow.
- O sistema roda localmente com provider simulado; integrações reais são opt-in.
| Capacidade | Implementação verificável |
|---|---|
| Paralelismo | Fan-out de tarefas independentes e merge determinístico por ID |
| Quality gate | Judge incremental combinado com pytest, ruff e mypy |
| Controle humano | Aprovação, retry, aceite parcial e abort em decisões críticas |
| Limites operacionais | Circuit breakers de tokens, custo, tempo e tentativas |
| Execução durável | Checkpoints em PostgreSQL e retomada após interrupção |
| Observabilidade | Spans OTel/Langfuse por job e chamada de LLM |
| Hooks de ferramentas | Políticas pre/post/error, bloqueio e auditoria configuráveis |
| Acesso à web | URLs do pedido viram evidências citáveis [W1] e a ferramenta fetch_url deixa planner e executor buscarem páginas durante a tarefa; tudo pelo controlador, com guarda anti-SSRF, allowlist e hooks (opt-in) |
| Avaliação contínua | evals/ com LLM real, orçamento fechado e gates; relatório versionado em evals/baseline/ (como rodar) |
| Interoperabilidade | servidores MCP como ferramentas dos agentes, CLI forgehand, SSE no dashboard e forgehand.toml (quickstart) |
Piloto técnico de 20/07/2026: 9 workflows reais, em 3 cenários e 3 rodadas, executados com LLM via OpenRouter após as correções de regressão.
| KPI | Resultado | Gate |
|---|---|---|
| Conclusão | 88,9% (8/9) | >= 80% |
| First pass | 88,9% | >= 60% |
| Falha técnica | 0% | 0% |
| Custo médio | US$ 0,00291 | <= US$ 0,05 |
| Latência p95 | 41,59 s | <= 120 s |
Gate final: aprovado. Consulte a metodologia, diagnóstico das falhas e matriz completa. Os números são um piloto interno reproduzível, não um benchmark público independente.
O dashboard e o comando forgehand deliver enviam uma mudança ou issue à
fábrica, com critérios, orçamento, build e entrega por PR. A CLI oferece prévia
sem execução (--dry-run) e acompanhamento retomável (forgehand wait ID).
Veja o fluxo pelo terminal e seus pré-requisitos.
Para operação persistente em um host Linux, use a instalação para uma equipe:
API, PostgreSQL e dois workers com dados compartilhados. forgehand doctor --json
verifica a instalação e a compatibilidade dos workers sem chamar modelos. O
procedimento de backup e restauração preserva histórico,
idempotência e aprovações pendentes em um destino isolado.
O novo /studio transforma uma ideia em escopo editável e backlog. Após aprovação,
gera uma aplicação de cadastros no navegador, com criação, edição, exclusão, busca
e pacote ZIP com código. Histórico persistido em SQLite, acesso por cliente/projeto
e reserva estimada de custo. É uma primeira versão frontend, não um sistema de
produção com backend ou banco compartilhado. Desativado por padrão; veja
como habilitar e usar.
Também é possível baixar uma base full-stack independente com login, dados persistentes privados por usuário, PostgreSQL, migração e Docker. Ela foi verificada em execução local, mas ainda exige regras de negócio e preparação operacional antes de produção.
A interface acima é servida pela própria aplicação e consulta /readyz e
/metrics para exibir a saúde real do runtime. Para reproduzir o estado local
sem bancos externos:
make demo
# ou, sem make (ex.: Windows):
uv sync --extra dev --locked
uv run uvicorn app.main:app --env-file .env.demoO mission control e o executor operacional rodam em qualquer plataforma. O
factory mode (checkout isolado, sandbox Docker, lock POSIX por workflow)
exige Linux ou WSL e falha fechado com PosixRequired em outros hosts.
O perfil .env.demo força todos os backends para memória e
funciona mesmo com um .env de produção presente. Abra
http://localhost:8000/dashboard e use a chave local dev-key. Executar
um workflow exige também configurar um provider de LLM (comentado no fim do
.env.demo); apenas abrir e validar o mission control não consome tokens.
cp .env.example .env
# preencha OPENROUTER_API_KEY e confirme LLM_PROVIDER_BACKEND=openrouter
docker compose up --buildMission control em http://localhost:8000/dashboard: autentica com a API key,
inicia workflows, acompanha etapas, tarefas, tokens e custo, responde ao gate
humano e copia a entrega final sem depender de curl. O histórico recente por
projeto permite retomar uma execução anterior sem guardar IDs manualmente.
curl localhost:8000/health
curl localhost:8000/readyz
curl localhost:8000/metrics/prometheus
curl localhost:8000/audit/events -H 'X-API-Key: dev-key'O corpo do POST /workflows deve ir em UTF-8. Em terminais Windows (Git Bash,
PowerShell) o texto com acentos digitado inline chega corrompido e a API
responde There was an error parsing the body; salve o JSON em arquivo e envie
com curl --data-binary @req.json -H 'content-type: application/json; charset=utf-8'.
Provedor de LLM (OpenAI direto, OpenRouter ou Anthropic), execução sem Docker, worker dedicado com Postgres, memória persistente em Neo4j, tracing OTel/Langfuse, tuning de fila e o executor operacional (aplicação de arquivos e validação objetiva por capability): docs/configuration.md.
Para usar a chave OpenAI em .env.local, consulte OpenAI direto.
Integrações e produto:
docs/integrations.md— GitHub/PR, sandbox, webhooks, benchmark e RBAC;docs/private-repositories.md— checkout privado, credenciais e retomada;docs/security-model.md— fronteiras, controles e riscos residuais;docs/go-to-market.md— design partner, piloto, demo e métricas de ROI.docs/production-runbook.md— deploy, alertas, incidente e rollback.CHANGELOG.md— histórico versionado e próximas mudanças.
curl -X POST localhost:8000/workflows \
-H 'X-API-Key: dev-key' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "forgehand-demo",
"request": "Analise este projeto e entregue um resumo curto com 3 próximos passos técnicos prioritários."
}'
curl localhost:8000/workflows/{workflow_id} \
-H 'X-API-Key: dev-key'
# quando status = awaiting_decision:
curl -X POST localhost:8000/workflows/{workflow_id}/decision \
-H 'X-API-Key: dev-key' \
-H 'Content-Type: application/json' \
-d '{"decision": "accept_partial"}' # ou "retry" | "abort"
# cancela um workflow na fila ou em execução:
curl -X POST localhost:8000/workflows/{workflow_id}/cancel \
-H 'X-API-Key: dev-key'POST /workflows
│
enqueue em fila compartilhada (queued)
│
worker dedicado → load_context → create_plan → [route_to_execution]
│ Send × N (paralelo, só ready_tasks)
execute_task (timeout + budget por tarefa,
│ judge incremental no branch)
│ join
evaluate_results (consolidação + judge_router)
┌─────────┼──────────┐
replan synthesize human_gate (interrupt)
│ │ accept_partial | retry | abort
└────►────┴──────────┘
persist_memory → END
Camadas:
app/graph/— estado (fonte única de verdade emplan, reducers para fan-out seguro), nós e montagem do grafo. Ondas normais de dependências não consomem iterações de replan;app/agents/— planner, executores por capability, judge e advisor. Falam apenas com oProviderRouter;app/providers/— porta única para LLMs: retry, circuit breaker, custo por tabela injetada, saída estruturada validada. Anthropic + qualquer endpoint OpenAI-compatible (locais inclusos);app/api/— FastAPI sobre o checkpointer; workflows e interrupts sobrevivem a restart comCHECKPOINTER_BACKEND=postgres. Em produção a API só enfileira jobs; o processamento roda emapp.workerou no serviçoworkerdo Compose.
Perfis Python da fábrica podem declarar políticas de arquitetura executáveis: limites de imports com diagnóstico por arquivo/linha, correção orientada por evidências e veto de publicação. A política é aprovada pelo operador, não pelo agente gerador.
| Regra | Mecanismo |
|---|---|
| Agente não chama fornecedor | ProviderRouter é a única porta; agente pede tier, não modelo |
| Saída estruturada | response_schema + validação Pydantic no provider |
| Critério de aceitação obrigatório | min_length=1 no schema do planner + validator do AgentTask |
| Timeout | asyncio.wait_for(task.timeout_seconds) no worker |
| Paralelismo | AgentProfile.max_parallel_tasks limita o fan-out por agente |
| Idempotência | idempotency_key() determinística por (projeto, tarefa, tentativa) |
| Judge não é só LLM | validator do EvaluationResult rejeita aprovação com sinal objetivo falhando; critérios tipados (arquivo criado, só criações, conteúdo, testes/lint/tipos, citations) são decididos por código e o LLM só vê os subjetivos |
| Judge não se auto-aprova | papel judge com bindings próprios no router; a avaliação registra judge_models e independent_judge; em escalate o router troca de modelo, e tarefas críticas exigem quórum unânime |
| Modelo caro só por escalonamento | tiers no registry; escalate() sobe um degrau, fallback degrada para baixo |
| Rastreabilidade | TaskAttempt por tentativa + checkpoints consultáveis via SQL |
| Exploração limitada | agentes leem o workspace só por ferramentas confinadas ao root; teto de chamadas e de tokens no ToolLoop, run_check só por nome do allowlist |
| CI é veto | com delivery, o workflow só termina verde: CI vermelho reabre as tarefas que publicaram, com as falhas como required_changes, dentro de max_iterations |
uv run pytest tests/unit tests/integrationOs testes de restart com PostgreSQL e de memória com Neo4j são opt-in para que a suíte padrão seja portável. Com os bancos locais disponíveis:
RUN_POSTGRES_TESTS=1 uv run pytest tests/integration/test_postgres_restart.py
RUN_NEO4J_TESTS=1 NEO4J_PASSWORD=<senha> uv run pytest tests/integration/test_neo4j_memory.pyEsse módulo também valida renovação de lease e ownership da entrega. Enquanto
um workflow está em execução, o worker atualiza locked_at periodicamente;
confirmações e falhas só são aceitas quando locked_by ainda pertence ao
worker que recebeu o job. Workers externos também registram heartbeat no
PostgreSQL; /readyz deixa de responder 200 quando nenhum worker registrado
está ativo. A CI sobe PostgreSQL 16 e Neo4j 5 e executa esses cenários.
O consumo agregado inclui planner, executores, judge e advisor. Antes de cada
tentativa de chamada, o provider reserva uma estimativa conservadora da entrada
completa e do máximo de saída; a chamada só começa se couber no saldo do
workflow e da tarefa. Branches paralelos dividem esse saldo. A estimativa pode
interromper o trabalho antes do teto de tokens medidos; não é garantia de
faturamento do fornecedor. Uso sem confirmação após erro ou timeout fica em
unconfirmed_tokens / unconfirmed_cost_usd, separado do consumo medido e
descontado do saldo. Uma decisão humana retry concede headroom e fica
registrada no checkpoint. Veja limites e recuperação.
Os testes de integração exercitam o grafo completo com providers reais sobre transporte HTTP mockado — o request de verdade é montado e o response de verdade é parseado.
O Studio também oferece entregas incrementais de produto: plano persistente ligado a um repositório existente, contexto imutável por tentativa e avanço condicionado a merge verificado, sempre com execução explicitamente aprovada.
Novas tentativas contam com admissão atômica e recuperação aprovada: o mesmo envio não cria outro job de início; ordens, contexto e limites são preservados. Recuperação após reinício exige PostgreSQL; não é garantia de efeitos externos exactly-once.
Perfis também podem exigir aceitação independente de comportamento: casos CLI aprovados pelo operador, comparados no host e executados sem escrita no repositório. Testes verdes ou aprovação do modelo não substituem os casos exigidos.
- Fase 1 — núcleo funcional vertical (com paralelismo e gate humano antecipados)
- Fase 2 — execução paralela (Send + reducers), timeouts, retries, budgets
- Fase 3 — advisor: consultado no replan quando os sinais objetivos do
AdvisorTriggerdisparam; injeta diagnóstico/orientação na próxima tentativa e é o único fluxo que escala tier (tier_escalated) - Fase 4 — memória de projeto persistente em Neo4j
(
(Project)-[:HAS_WORKFLOW]->(Workflow)-[:EXECUTED]->(Task)); backend viaMEMORY_BACKEND=memory|neo4j, histórico recente entra no contexto do planner - Fase 5 — ferramentas reais no judge (pipeline objetiva com
pytest/ruff/mypy— ver "Executor operacional" acima) - Fase 6 — filas/workers (Postgres com lease/heartbeat), auth com RBAC, auditoria, métricas Prometheus
- Fase 7 — tracing OTel/Langfuse via OTLP: span
gen_aipor chamada na porta única doProviderRouter, span raiz por job no worker etrace_idgravado em cadaTaskAttempt
