Por que agentes de programação com IA falham (e como corrigir isso)
Autoria: Prompt Engineering · Assistir no YouTube
Vídeo de autoria do canal indicado, não da IANIA; todos os direitos pertencem ao criador. Transcrição, resumo e tradução gerados automaticamente; o conteúdo no idioma original é preservado na versão em idioma original.
Idioma original: inglês
Vídeo original: Why AI Coding Agents Fail (And How to Fix Them) · Canal: Prompt Engineering · 17:00 · Assistir no YouTube
Tópicos: Agentes de IA, Avaliação e benchmarks de IA, Cibersegurança e segurança de software, Engenharia de software com IA
O vídeo explica a arquitetura de uma software factory que distribui issues entre agentes de programação executados em sandboxes isolados. A demonstração mostra como triagem, workers, verificação independente, revisão de código e integração ajudam a evitar falhas comuns de execução paralela. Em um teste com 10 issues, a factory abriu nove pull requests e pulou uma issue vaga; os nove branches passaram nos testes ocultos, embora um reviewer tenha encontrado um bug que os testes não detectaram. Como várias alterações geraram conflitos de merge, o autor acrescentou uma etapa de integração e manteve a decisão final de merge com uma pessoa.
Pontos-chave
Seção intitulada “Pontos-chave”- Uma software factory é um ciclo em que uma issue é atribuída a um agente, o trabalho é verificado de forma independente e uma pessoa decide se deve fazer o merge.
- Agentes paralelos precisam de sandboxes isolados para evitar que as alterações de um interfiram no trabalho dos outros.
- Um sistema de claim evita que dois agentes trabalhem na mesma issue ao mesmo tempo.
- O worker não deve avaliar o próprio trabalho: um verifier executa os testes em um ambiente limpo, e um reviewer separado inspeciona o diff.
- Documentação atualizada pode ajudar os agentes a lidar com APIs que mudaram desde os dados de treinamento dos modelos.
- Snapshots permitem iniciar sandboxes com dependências já instaladas; isolamento de rede e pausa de execução oferecem controles operacionais e de segurança.
- A factory testada processou 10 issues em paralelo: abriu nove pull requests e rejeitou uma issue deliberadamente vaga.
- Testes aprovados não garantem código correto: a revisão independente encontrou um bug de ordenação que os testes existentes não detectaram.
- Pull requests válidos individualmente ainda podem gerar conflitos entre si; uma etapa de integração pode resolvê-los e executar novamente a suíte de testes.
- O merge permanece uma decisão humana.
Capítulos
Seção intitulada “Capítulos”| Início | Capítulo | Resumo |
|---|---|---|
| 00:00 | O que é uma software factory e por que paralelizar agentes | O vídeo apresenta o ciclo básico da factory e os problemas de isolamento, issues duplicadas, autoavaliação, documentação desatualizada e excesso de pull requests. |
| 03:49 | Sandboxes em nuvem e arquitetura da factory | O autor descreve os recursos dos sandboxes, como snapshots, discos isolados, pausa de execução e controle de tráfego de rede. |
| 07:10 | Pipeline de triagem, execução e verificação | A demonstração apresenta o repositório Tiny Links e as etapas de triagem, worker, verifier e reviewer, além do uso de documentação atualizada. |
| 11:00 | Execução paralela e revisão independente | A factory processa 10 issues, e a revisão encontra um bug de ordenação que passou pelos testes do worker e pela avaliação oculta. |
| 13:10 | Integração, custos e recomendações | Conflitos entre pull requests levam à criação de uma etapa de integração, seguida por uma decisão humana de merge e um resumo das recomendações. |
Citações
Seção intitulada “Citações”No fundo, uma software factory é apenas um ciclo operacional. — 00:00
Passar nos testes não significa que o código está correto. — 12:36
Um sandbox impede que os agentes alterem os arquivos uns dos outros, mas não garante que o código esteja correto. — 15:56
Cada parte da arquitetura existe porque agentes paralelos falham sem ela. — 16:27
Conceitos e entidades
Seção intitulada “Conceitos e entidades”- software factory (conceito): Ciclo que recebe issues, delega correções a agentes, verifica o trabalho e deixa a decisão de merge para uma pessoa.
- sandbox (conceito): Ambiente de execução isolado usado para que agentes trabalhem sem interferir nos arquivos uns dos outros.
- claim system (conceito): Mecanismo que marca uma issue como atribuída para impedir que vários agentes a selecionem simultaneamente.
- verifier (conceito): Etapa independente que executa os testes do trabalho em um ambiente limpo.
- reviewer (conceito): Agente separado do worker que inspeciona o diff em busca de problemas que os testes podem não revelar.
- integrator (conceito): Etapa que reúne pull requests em uma branch de integração, resolve conflitos e executa novamente os testes.
- Upstash (empresa): Empresa que fornece os sandboxes em nuvem usados na demonstração.
- Claude Code (ferramenta): Ferramenta de programação com IA usada nos sandboxes para trabalhar nas issues e resolver conflitos.
- Codex (ferramenta): Uma das opções de agent harness pré-configuradas mencionadas para os sandboxes.
- Context7 (ferramenta): Ferramenta usada para consultar documentação oficial atualizada por meio de uma solicitação web.
- Tiny Links (repo): Pequeno serviço de encurtamento de URLs usado como exemplo na demonstração.
- Sonnet 5 (modelo): Modelo mencionado como usado pela configuração de Claude Code na demonstração.
Tradução completa (pt-BR)
Seção intitulada “Tradução completa (pt-BR)”00:00 Então, todo mundo fala sobre fábricas de software, mas quase ninguém define como isso realmente se parece no código. Hoje vou explicar a arquitetura exata de uma fábrica de software e, depois, vamos construir uma e executá-la em issues reais. Aqui vai um exemplo rápido. Apontei minha fábrica para um repositório com 10 issues reais do GitHub. Cada agent foi iniciado em seu próprio sandbox na nuvem, escreveu código usando Claude Code e, em seguida, teve os resultados avaliados com uma suíte de testes oculta. Em sua essência, uma fábrica de software é apenas um ciclo operacional.
00:35 As issues chegam do seu backlog, e um agent de programação pega uma delas e escreve a correção. Depois, um sistema independente verifica esse trabalho, e uma pessoa decide se vai fazer o merge. A versão mais simples disso é um único prompt. Você entrega uma issue a um agent e pede que ele corrija o bug, escreva testes e abra um pull request. Isso já é uma pequena fábrica de software. E, para um ticket, funciona. O problema é a velocidade. Um agent percorre seu backlog, um ticket de cada vez.
01:08 Então, 10 issues significam esperar por 10 execuções consecutivas. A solução óbvia é executar 10 agents ao mesmo tempo, em paralelo. E é exatamente nesse momento que tudo começa a dar errado. Neste vídeo, vamos analisar uma fábrica de software que vai construir um encurtador de URLs simples. Usando esse exemplo, quero mostrar o que dá errado quando você tenta executar vários agents em paralelo. No momento, nosso encurtador de URLs aceita links sem HTTPS, o que causa redirecionamentos quebrados.
01:40 O primeiro problema é o de uma pasta compartilhada. Se todos os seus agents trabalham no mesmo checkout local, todas as mudanças deles acabam no mesmo lugar. Em um teste que fiz, três agents compartilhando uma pasta produziram um commit que alterava seis arquivos em três issues distintas. A solução é ter um sandbox isolado para cada agent. Assim, cada worker recebe sua própria cópia do código e sua própria máquina. O segundo problema é o de issues reivindicadas por mais de um agent. Dois agents podem pegar exatamente a mesma issue ao mesmo tempo.
02:12 A solução é um sistema de reivindicação. Antes de começar a trabalhar, um agent adiciona um rótulo de reivindicada à issue do GitHub. Assim, todos os outros agents a ignoram. O próximo problema dos agents em paralelo é a armadilha da autoavaliação. Se você deixar um agent avaliar o próprio trabalho, o relatório dele não diz muita coisa. Por exemplo, nos meus testes, os agents workers relataram que os testes passaram todas as vezes, inclusive uma vez em que o verifier constatou que os testes estavam falhando.
02:44 A solução é usar um verifier separado. Você inicia um sandbox novo, que faz checkout do branch do worker e executa os testes; depois, um agent reviewer separado lê o diff real. Outro problema são os limites temporais dos dados de treinamento. Um modelo só conhece as APIs que viu nos dados de treinamento. O problema é que os frameworks mudam constantemente. A solução é dar aos agents uma ferramenta de documentação atualizada para que possam consultar a documentação vigente antes de escrever código.
03:15 O último problema é a enxurrada de PRs. Esses agents adoram abrir pull requests. A solução é permitir que a fábrica abra pull requests, mas deixar o botão de merge estritamente nas mãos de uma pessoa. Agora, se você reunir esses cinco componentes, terá, essencialmente, uma fábrica de software. No restante do vídeo, quero mostrar um exemplo de como tudo isso funciona em conjunto. Vou mostrar isso por meio de um exemplo.
03:49 Para uma fábrica de software funcionar, você precisa de agents de longa duração executados na nuvem. Para os sandboxes, estou usando o Upstash, que tornou este vídeo possível por meio de uma parceria. Então, o que é exatamente uma box? Pense nela como um computador leve na nuvem, sob demanda, construído especificamente para hospedar agents. Quando você inicia uma por meio de uma chamada de API, não recebe apenas um container vazio no qual precisa configurar as ferramentas por conta própria. Cada box
04:24 vem pré-configurada com seu próprio sistema de arquivos isolado, um shell bash, Git, Node e harnesses de agents pré-instalados, como Claude Code ou Codex. Ou você pode simplesmente adicionar seu próprio loop personalizado, se quiser. Veja como isso fica no código. Há quatro primitivas específicas aqui que tornam uma fábrica possível. A primeira é a inicialização extremamente rápida e os snapshots de disco. Quando chamo create, tenho uma máquina Linux ativa em cerca de 2,5 segundos. Agora, em uma
04:57 fábrica de software, você não quer 10 agents em paralelo, cada um executando git clone e npm install do zero. Em vez disso, instalo minhas dependências uma vez em uma box base e, depois, crio snapshots. Um snapshot congela o estado exato do disco da box em uma imagem reutilizável. A partir desse único snapshot, posso iniciar mais cinco boxes em paralelo, e cada uma delas começa com essas dependências já no disco. Assim, você configura tudo uma vez e pode replicar isso
05:31 várias vezes. A segunda primitiva é o isolamento e a pausa do sistema de arquivos. Isso é fundamental. Por exemplo, se eu criar um arquivo dentro da box um e depois procurar por ele dentro da box dois, ele não estará lá. Cada agent tem seu próprio disco privado. O melhor é que, se um agent estiver esperando por uma entrada humana, você pode pausar a box. Isso basicamente congela o estado do disco e interrompe a cobrança pelo uso de computação. Quando você a retoma, o arquivo ainda está exatamente onde o agent
06:04 o deixou, o que é ótimo. Isso permite isolar os agents e pausar a cobrança enquanto você espera por uma entrada humana. A próxima primitiva são os firewalls de tráfego de saída da rede. Se você permite que um agent execute código não confiável ou instale pacotes, não quer que ele se comunique com servidores aleatórios na internet. O Upstash permite restringir o tráfego de saída da rede por box. Por exemplo, nesta box, permiti apenas o registro do npm. Assim, qualquer tentativa de conexão com qualquer outro destino
06:39 será bloqueada. Isso é fundamental do ponto de vista da segurança. Para agents de longa duração, você quer execução remota de verdade, especialmente se eles forem executados em um horário específico enquanto seu laptop estiver desligado. Tudo isso é executado nos servidores em nuvem do Upstash, não no meu laptop. Por exemplo, quando pergunto ao Claude Code, dentro da box, onde está sendo executado, ele informa que é um host Linux remoto com um endereço IP completamente diferente do meu MacBook. Certo. Agora, com todas essas
07:10 primitivas apresentadas, vamos ver o exemplo que vamos executar. Este é o Tiny Links, um pequeno serviço de encurtamento de URLs com 10 issues abertas no GitHub. Quatro são bugs, cinco são novos recursos e uma issue é deliberadamente vaga, só para ver se a fábrica é inteligente o bastante para desistir quando o ticket não faz sentido. Para avaliar o trabalho da fábrica de software, escrevi um teste oculto para cada issue. Esses testes ficam na minha máquina, fora do
07:40 repositório. Portanto, os agents não conseguem vê-los. É assim que verificamos se as correções realmente funcionam, em vez de simplesmente confiar no que os agents dizem. No momento, na main, o aplicativo falha em todas as seis verificações de referência e passa em zero dos nove testes ocultos. Certo. Veja como o pipeline da fábrica está conectado. Primeiro, preparamos uma box base. Clonamos o Tiny Links, instalamos todas as dependências e configuramos o Node, o token do GitHub e o Claude Code, executando Sonnet 5 nela. Depois,
08:16 basicamente, criamos um snapshot dessa box base. A partir daí, a fábrica reivindica cada issue do GitHub, e a issue passa por quatro etapas distintas. Temos agora três boxes novas, cada uma iniciada a partir do snapshot que acabamos de criar. A primeira etapa é a triagem. Uma box nova é iniciada, lê a issue do GitHub e decide se os requisitos estão claros o bastante para serem implementados ou se o ticket deve ser rejeitado. A segunda etapa é o worker. Se a triagem aprovar, uma box nova do
08:50 worker escreve a correção no código, adiciona testes unitários e, então, a fábrica envia o branch. A terceira etapa é o verifier. Nunca confiamos no relatório de testes do worker. Uma box nova do verifier é iniciada a partir do snapshot limpo, faz checkout do branch do worker sem conhecimento prévio dele e executa a suíte de testes por conta própria. Depois, temos a quarta etapa, que é o reviewer. Na mesma box do verifier, o reviewer
09:21 O agent inspeciona o diff real do git linha por linha para detectar bugs de lógica que os testes unitários não identificam. Só se os testes e o revisor aprovarem é que a fábrica abre um pull request. Certo. Para torná-la confiável, temos dois detalhes arquitetônicos sobre os quais quero falar. O primeiro é a transferência de objetos tipados. Então, os estágios não passam históricos de conversa bagunçados uns para os outros. Eles se comunicam estritamente por meio de objetos JSON estruturados. O worker é obrigado a
09:53 retornar um esquema fixo que inclui seu status, um resumo do gráfico, a lista exata de arquivos que alterou e se adicionou testes, além de um valor booleano que indica se os testes passaram. Depois, temos documentação atualizada por meio da injeção de chave via proxy, para resolver o problema dos dados de treinamento desatualizados. Integrei o Context7, que pesquisa a documentação oficial atualizada com uma única solicitação web. Agora, coloquei um pequeno comando CLI de documentação dentro de cada caixa e instruí o worker a chamá-lo sempre que não tiver
10:26 100% de certeza sobre uma API. E repare como a segurança funciona. A chave da API do Context7 é anexada pelo Upstash fora da caixa, na solicitação de saída. Assim, o agent dentro da caixa pode ler a documentação, mas nunca chega a ver a chave da API. Certo. Agora, vamos executar a fábrica em 10 issues. Aqui teremos cinco pipelines paralelos de cada vez. À esquerda da tela, vocês veem os registros de eventos em tempo real de cada estágio. À direita, podem acompanhar o sandbox sendo iniciado
11:00 e encerrado no console do Upstash. No GitHub, cada issue recebe o rótulo de reivindicação, uma por uma. Agora, vamos entrar em uma das caixas de workers em execução enquanto ela está trabalhando. Aqui, o agent não tem certeza sobre uma API do Node. Então, vocês podem ver que ele executa nosso comando de documentação para verificar como os parâmetros de pesquisa de URL se comportam na versão atual do Node antes de editar o arquivo. E aqui está o worker lidando com nosso bug de HTTPS. Ele lê o código existente de validação de URL e reescreve a verificação
11:34 para receber o objeto URL e impor estritamente os protocolos HTTP ou HTTPS; depois, escreve novos testes unitários, executa-os e o branch é commitado e enviado. Certo, a execução completa das 10 issues terminou em 4 minutos e meio. A fábrica abriu nove pull requests e pulou deliberadamente a issue fraca, exatamente como queríamos. E, quando executei minha suíte de testes externa nesses
12:04 nove branches, todos passaram no teste oculto. Agora, lembrem-se de que eu disse antes que vocês precisam tanto de um verificador quanto de um revisor. Vou mostrar um dos rastros em que dá para ver por que eles são necessários. Nessa execução, o worker disse que os testes dele passaram. O verificador independente executou a suíte de testes, e ela passou. Até meu teste de avaliação oculto passou. Mas o agent revisor ainda rejeitou o pull request. Quando o revisor leu o diff, percebeu
12:36 que, se dois links fossem criados no mesmo milissegundo, a lista de links apareceria na ordem errada, e o revisor reproduziu o bug. O teste unitário do worker não detectou esse bug específico porque os dados de teste usavam slugs pré-ordenados. Portanto, passar nos testes não significa que o código está correto. Um agent dedicado à revisão de código, separado do worker, detectou um bug de ordenação que todos os outros testes deixaram passar. E é por isso que vocês querem ter esse verificador e revisor
13:10 independentes. Agora, aqui está a parte mais interessante. Todos os nove pull requests verificados funcionam perfeitamente por conta própria. Mas, quando tentei mesclá-los no branch principal, sete dos nove tiveram conflitos de merge imediatamente. Por quê? Porque todos os nove agents começaram exatamente do mesmo snapshot base, e a maioria deles adicionou seus próprios testes unitários ao mesmo arquivo de teste. O problema é que nenhum dos agents sabia da existência dos outros oito. Então, tive que adicionar um
13:42 quinto estágio à fábrica: o integrador. O integrador é mais uma caixa do Upstash que traz os PRs aprovados, um de cada vez, para um branch de integração unificado. Sempre que o git merge encontra um conflito, um agent do Claude Code dentro da caixa do integrador abre os marcadores de conflito e combina os dois lados, para que nenhum código ou teste se perca; depois, executa novamente a suíte completa de testes após cada merge, para garantir que o código combinado continue funcionando. No nosso caso, todos os
14:17 nove PRs passaram pelo integrador e foram mesclados sem conflitos; o agent resolveu os outros sete conflitos. E a etapa final é uma decisão humana na hora do merge. Aqui está o pull request do nosso bug de HTTPS. Vejo que o verificador foi aprovado e o revisor também deu sua aprovação. Então, posso simplesmente clicar em merge. Logo depois desse único merge, o branch principal passa a rejeitar corretamente os links sem HTTPS.
14:47 Certo. Vamos falar sobre quanto isso realmente nos custou. A execução da fábrica com 10 issues distribuídas por quatro estágios custou, no total, cerca de 3,67 em uso de tokens do Claude Code. O estágio do integrador, que resolveu sete conflitos e executou a suíte, custou US$ 6,37 em uso de tokens. Já a caixa do Upstash custa cerca de US$ 0,01 pelo dia inteiro, incluindo todas as minhas execuções de teste. Agora, como um agent de programação
15:24 passa quase todo o tempo esperando a API do LLM transmitir tokens, e o Upstash cobra apenas pelo tempo de CPU ativo, o custo do computador do sandbox acaba sendo praticamente um erro de arredondamento. Um aviso: o Upstash inclui uso de modelos integrado até um limite mensal. Portanto, para execuções pesadas da fábrica, vocês vão querer fornecer sua própria chave de API ou aumentar esse limite mensal. Agora, se quiserem construir sua própria fábrica de software, há algumas coisas para ter em mente. Um
15:56 sandbox impede que os agents alterem os arquivos uns dos outros, mas não garante que o código esteja correto. A qualidade do código ainda depende dos testes, do verificador e do revisor. Segundo: agents paralelos podem criar conflitos de git quando mexem em arquivos compartilhados, como suítes de testes ou roteadores. Planejem uma etapa de integração. Em resumo, uma fábrica de software é apenas um ciclo em que chegam issues. Um agent cria a correção, uma caixa separada a verifica e uma pessoa faz o merge. E cada
16:27 parte da arquitetura existe porque agents paralelos falham sem ela. Vocês vão querer manter uma caixa com um snapshot para cada agent, um bloqueio para reivindicar uma issue, um verificador independente, consulta à documentação atualizada e um integrador para resolver conflitos de merge, além de uma pessoa no final. Deixei o código completo da fábrica e a documentação do Upstash Box na descrição, para que vocês possam experimentar isso nos próprios repos. Contem nos comentários como estão executando agents de programação
17:00 em paralelo e o que acaba dando errado. Enfim, espero que tenham achado este vídeo útil. Obrigado por assistir e, como sempre, até o próximo.
Transcrição original
[00:00] So everyone talks about software factories but almost nobody’s defines what that actually looks like in code. Today I am going to break down the exact architecture of a software factory and then we’re going to build one and run it on real issues. Here’s a quick example. I pointed my factory at a repository with 10 real GitHub issues. Every agent spun up inside its own cloud sandbox, wrote code using cloud code, and then created the results against a hidden test suite. At its core, a software factory is just an operating loop.
[00:35] Issues come in from your backlog and a coding agent picks up one and writes the fix. Then an independent system checks the word that work and a human decides whether to merge it. The simplest version of this is a single prompt. You hand one agent one issue and tell it to fix the bug, write tests, and open a pull request. That’s already a tiny software factory. And for one ticket, it works. The problem is speed. One agent works through your backlog one ticket at
[01:08] a time. So 10 issues mean waiting for 10 runs back to back. The obvious move is to run 10 agents at once in parallel. And that’s the exact moment everything kind of starts to break. Now, in this video, we’re going to look at a software factory that is going to build a tiny URL shortener. Now, using this example, I want to show you what breaks if you try to run multiple agents in parallel. So, right now, our URL shortener accepts links missing HTTPS, which causes broken
[01:40] redirects. The first one is shared folder problem. If all your agents work inside the same local checkout, now all their changes piled up in the same place. In a test I ran uh three agents sharing one folder produced, one commit touching six files across three separate issues. So the fix is one isolated sandbox per agent. So every worker gets its own copy of the code and its own machine. Now second is double booking issues. So two agents will grab the
[02:12] exact same issue at the same time. The fix is a claim system. Before an agent starts working, it puts a claimed label on the GitHub issue. So every other agent skips it. The next problem with parallel agents is self-grading trap. If you let an agent grade its own work, its report doesn’t tell you much. Uh, for example, in my test runs, the worker agents reported that the tests pass every single time, including once when the verifier saw the test were actually
[02:44] failing. So, the fix is to use a separate verifier. Uh, you spin up a fresh sandbox that checks out the workers branch and runs test itself followed by a separate reviewer agent that reads the actual diff. Now, another problem is with the training cutoffs. A model only knows the APIs that it has seen in its training data. And the problem is that frameworks change constantly. So the fix is give the agents a live documentation tool so it
[03:15] can look up current documents before writing code. The last problem is PR flood. These agents love to open pull requests. Now the fix is that the factory is only allowed to open pull requests but the merge button stays strictly with the human decision. Now if you have five of these components together you essentially have a software factory and in the rest of the video I actually want to show you an example of how all of this comes together. Now I’m
[03:49] going to show you through an example. For software factory to work, you need to have longunning agents which are running in the cloud. Now, for the sandboxes, I’m using Upstash for making this video possible through their partnership. So, what actually is a box? Think of this as on demand lightweight computer in the cloud built specifically to host agents. When you spin up one via the API call, you’re not just getting a bare container where you have to wire up tools yourself. Each box
[04:24] comes preconfigured with its own isolated file system, a bash shell, get node, and pre-installed agent harnesses like clot code or codeex. Or you can just drop in your own custom loop if you want. Now, here’s what it looks like in code. And there are four specific primitives here that makes a factory possible. The first one is extremely fast boot and disk snapshots. So when I call create in about 2 and 1/2 seconds I have a live Linux machine. Now in a
[04:57] software factory you don’t want 10 parallel agents each running git clone and npm installed from scratch. So instead I install my dependencies once on a base box and then take snapshots. A snapshot freezes the exact state of the box disk into reusable image. From that single snapshot, uh I can boot five more boxes in parallel and every single one wakes up with those dependencies already sitting on disk. So you configure it once and then you can replicate it
[05:31] multiple times. Now the second primitive is file system and pause isolation. And this is critical. For example, if I write a file inside box one and then check for it inside box two, it is not there. Each agent has its own private disk. Now the beauty is that if an agent is waiting on human input, you can actually pause the box. So it basically freezes the disk state and it stops billing compute and when you resume it, the file is still right where the agent
[06:04] left it, which is great. So, it gives you the ability to isolate and pause billing when you’re waiting for human input. The next one is network egress firewalls. So, if you’re letting an agent run untrusted code or install packages, you don’t want it talking to random servers on the internet. Upstach lets you lock down network egress per box. So for example on this box I allowed listed only the npm registry. So any connection attempt to anywhere else
[06:39] is going to get blocked. And this is critical from a security standpoint. For longunning agents you want true remote execution especially if they’re going to be running at a specific internal while your laptop is off. So all of this runs on upstach’s cloud servers not on my laptop. So for example, when I ask the client code inside the box where it’s running, it reports a remote Linux host with a completely different IP from my MacBook. Okay. Now with all those
[07:10] primitives out, let’s look at the example that we’re going to be running. So this is Tiny Links, a small URL shortener service uh with 10 open GitHub issues. Four are bugs, five are new features, and one issue is deliberately vague. uh just to see if the factory is smart enough to walk away when the ticket doesn’t make any sense. Now to grade the software factories work, I wrote one hidden test per issue. These tests live on my machine outside the
[07:40] repository. So the agents are not able to see them at all. That’s how we verify if the fixes actually work rather than uh taking agents work for it. So right now on main the app fails all six of my baseline checks and passes zero out of nine hidden tests. Okay. So here’s how the factory pipeline is wired together. First we prepare one base box. We clone tiny links install all dependencies then wire up node the GitHub token and cloud code running sonnet 5 on this and we
[08:16] basically take a snapshot of this base box. So from there the factory claims each GitHub issue and the issue moves through our four distinct stages. Now we have three brand new boxes each booted from the snapshot that we just created. So stage one is triage. A fresh box wakes up reads the GitHub issue and decides whether the requirements are clear enough to build or if it should reject the ticket. Stage two is the worker. If triage approves, a fresh
[08:50] worker box writes the code fix and then adds unit tests and the factory pushes its branch. Then stage three is the verifier. So we never trust the workers test report. A fresh verifier box boots from the clean snapshot, then checks out the workers branch cold and runs the test suite itself. And then we have stage four which is the reviewer. So inside the same verifier box reviewer
[09:21] agent inspects the actual git diff line by line to catch logic bugs that unit tests miss. Only if both the tests and the reviewer sign off then the factory opens a pull request. Okay. In order to make it reliable we have two architectural details that I want to talk about. The first one is typed object handoff. So uh stages don’t pass messy chat histories to each other. They communicate strictly through structured JSON objects. The worker is forced to
[09:53] return a fixed schema which includes its status, a chart summary, the exact list of files it’s changed and whether it added tests and a boolean for whether the test pass. Then we have live docs via proxy key injection to solve the stale training data problem. I integrated context 7 which searches live official documentation via a single web request. Now I put a tiny doc cli command inside every box and instructed the worker to call it whenever it is not
[10:26] 100% sure about an API. And notice how the security works. The context 7 API key is attached by upstach outside the box on the outbound request. So the agent inside the box can read the docs but never actually sees the API key. Okay. So now let’s run the factory across 10 issues. Here we’ll have five parallel pipelines at a time. So on the left side of the screen you see the live events logs from each stage. On the right you can watch the sandbox spinning
[11:00] up and tearing down inside the upstaches console. on GitHub. The issue picks up the claim label one by one. Now, let’s jump inside one of the live workers boxes while it’s working. So, here the agent isn’t sure about a node API. So, you can see it runs our docs command to check how URL search parameters behave in the current node before editing the file. And here’s the worker handling our HTTPS bug. Um so it reads the existing URL validation code, rewrites the check
[11:34] to passse the URL object and strictly enforces HTTP or HTTPS protocols, then writes new unit tests, runs them and the branch gets committed and pushed. Okay, so the entire 10 issue run finished in 4 and 1/2 minutes. The factory opened ninepull requests and deliberately skipped the one wake issue which is the exact behavior we wanted. And when I ran my external test suite against those
[12:04] nine branches, all nine pass the hidden test. Now remember earlier uh when I said you need both a verifier and a reviewer. So let me show you one of the traces where you actually see why you need them. So on that run the worker said it its tests passed. The independent verifier ran the test suite and it passed. Even my hidden evaluation test passed. But the reviewer agent still rejected the pull request. So when the reviewer read the diff, it realized
[12:36] that if two links were created inside the exact same millisecond, the link list came back in the wrong order and the reviewer reproduced the bug. The workers unit test never caught that specific bug because the test data used pre-sorted slugs. So passing tests does not mean the code is right. having a dedicated code review agent separated from the worker caught an ordering bug that every other test missed. And that’s why you want to have this independent
[13:10] verifier and reviewer. Now, here’s the most interesting part. So, all the nine verified pull requests work perfectly on its own. But when I tried to merge them into the main, seven out of the nine immediately through merge conflicts. Why? because all nine agents started from the exact same base snapshot and most of them added their own unit tests to the exact test file. Now the problem is that none of the agents knew the other eight existed. So I had to add a
[13:42] fifth stage to the factory, the integrator. So the integrator is one more upstatch box that pulls the approved PRs one at a time into a unified integration branch. Whenever get merge hits a conflict, a clot code agent inside the integrator box opens the conflict marker combines both sides so no code or test gets lost and then reruns the full test suite after every single merge to make sure the combined code still works. Now in our case all uh
[14:17] nine PRs went in through the integrator to merge cleanly and the agent resolve the other seven ones and the final step is a human decision maker at the merge step. So here’s the pull request for our HTTPS bug. I can see the verifier passed and the uh reviewer also signed off. So I can simply click merge. So right after that single merge main properly rejects links missing HTTPS.
[14:47] Okay. So let’s talk about what this actually cost us. So factory run where we had 10 issues across four stages. The total cost was about 3.67 in cloud code token usage. the integrator stage which resolved seven conflicts and was running the suite. It was $6.37 in token usage. Now, upstute box, it’s about $.01 for the entire day, including all my test runs. Now, because uh coding
[15:24] agent spends almost all of their time waiting for the LLM API to stream tokens back, and Upstash only builds for active CPU time, the sandbox computer is basically a rounding error at this point. Now, one heads up. Upstach includes built-in model usage up to a monthly cap. So for heavy factory runs, you will want to pass in your own API key or increase that monthly cap. Now, if you want to build your own software factory, a few things to keep in mind. A
[15:56] sandbox keeps agents from stepping on each other’s files, but it doesn’t make the code right. Code quality still comes from your tests, your verifier, and your reviewer. Second, parallel agents can create git conflicts when they touch shared files like test suites or routers. Plan for an integrated step. So to recap, a software factory is just a loop where issues comes in. An agent builds the fix, a separate box verifies it, and a human merges it. And every
[16:27] piece of the architecture is there because parallel agents break without it. You want to keep one snapshot box per agent. uh an issue claim lock an independent verifier live documentation lookup and integrator to merge conflicts and then a human at the end. I have linked the full um factory code and the stash box documents down in the description if you can so you can try this on your own repos. Let me know in the comments how you are running codeing
[17:00] agents in parallel and what actually breaks. Anyways, I hope you found this video useful. Thanks for watching and as always, see you in the next one.