O que podemos aprender com o experimento da Cursor com Rust e SQLite

MMaximilian Schwarzmüller
Computing/SoftwareInternet Technology

Transcript

00:00:00O SQLite foi reescrito em Rust.
00:00:02E eu sei que acabamos de ter a reescrita do Bun em Rust
00:00:04e você pode se perguntar por que todo mundo está reescrevendo
00:00:06tudo em Rust, mas isso não é sobre o Rust.
00:00:09Isso nem sequer é sobre o SQLite.
00:00:11Eu sei que existe o banco de dados Turso,
00:00:15que já é uma reimplementação modernizada
00:00:18do SQLite em Rust.
00:00:19Esse é o que você quer usar
00:00:21se quiser usar um banco de dados baseado em Rust e SQLite
00:00:23pronto para produção.
00:00:26Em vez disso, este experimento, o mini SQLite,
00:00:29cujo link está abaixo e que você pode conferir,
00:00:32não é sobre o SQLite ou o Rust.
00:00:34Na verdade, é um experimento da equipe do Cursor,
00:00:37focado em enxames de agentes e na engenharia
00:00:40de um sistema de agentes de IA, descobrindo o que funciona
00:00:44e o que não funciona para construir algo
00:00:47como o SQLite apenas a partir de sua documentação,
00:00:51porque é sobre isso que trata esse experimento.
00:00:53Há um post no blog super detalhado e muito interessante
00:00:56e nós vamos mergulhar nele.
00:00:57Há muitos aprendizados interessantes ali sobre os quais
00:00:59precisamos falar, e que você também encontra no link abaixo,
00:01:02onde eles explicam como executaram esse experimento, além do ponto de partida
00:01:07e da ideia por trás dele, que era pegar a documentação do SQLite,
00:01:12que no final soma 835 páginas, se você colocar tudo em um único documento,
00:01:18que é, obviamente, escrita principalmente para humanos.
00:01:23Quero dizer, não é a documentação mais acessível que já vi,
00:01:27mas é claro que foi feita para humanos, pois é muito mais antiga do que toda essa onda de agentes de IA.
00:01:32Ainda assim, ela também funciona como uma especificação super detalhada,
00:01:37uma especificação super detalhada porque descreve minuciosamente como usar o SQLite
00:01:43e qual é o comportamento ou os recursos previstos.
00:01:48E a equipe do Cursor pegou essa documentação
00:01:52e usou um conjunto de testes público, o SQLogic test,
00:01:57que é um grupo de testes que avalia o comportamento do SQLite
00:02:02ou que testa consultas especificamente.
00:02:05E eles usaram isso para verificar se a implementação
00:02:09que os agentes construíram com base nessa documentação
00:02:13realmente funciona com essa suíte de testes oficial e enorme.
00:02:19Agora, alguns avisos importantes logo de início.
00:02:23Esta suíte de testes é voltada para testar consultas e o comportamento delas.
00:02:29Ela não testa todos os recursos e capacidades que o SQLite possui.
00:02:35Ela não testa o desempenho de maneira geral.
00:02:38Ela não testa concorrência.
00:02:40Há muita coisa no SQLite que isso não testa.
00:02:44E este resultado do mini SQLite desse experimento, um dos resultados,
00:02:49já que eles realmente reconstruíram o SQLite várias vezes com diferentes combinações de agentes,
00:02:53e nós vamos detalhar isso, está lá apenas como algo a ser explorado.
00:02:57Não está pronto para produção.
00:02:59Não é o que você quer usar.
00:03:01É apenas o resultado de um experimento onde o objetivo era usar a documentação
00:03:06para reconstruir o SQLite e fazer com que essa versão reconstruída passasse em todos esses testes.
00:03:13E a equipe do Cursor usou várias combinações de modelos aqui.
00:03:17Por que combinações?
00:03:18Porque, como veremos, eles usaram uma abordagem
00:03:21em que múltiplos agentes trabalhavam juntos: agentes planejadores, executores e revisores.
00:03:28E eles reconstruíram esse banco de dados SQLite com diferentes combinações e depois mediram para obter uma qualidade semelhante.
00:03:37Assim, todas essas combinações alcançaram o mesmo nível de qualidade e a mesma quantidade de testes aprovados, mas mediram quanto custava cada combinação.
00:03:45Por exemplo, usar o GPT 5.5 para tudo, tanto para agentes planejadores quanto para executores, levou a um custo de implementação do SQLite em Rust, baseado na documentação, de cerca de US$ 10.000.
00:03:59Por outro lado, combinar o Opus 4.8 com o Composer 2.5 — e o Composer 2.5 é aquele modelo super rápido, muito barato, muito eficiente, mas não super inteligente do Cursor —, combinar esses dois levou ao mesmo nível de qualidade e à mesma quantidade de testes aprovados que as outras combinações por apenas uma fração do custo, por apenas US$ 1.300.
00:04:24E a ideia aqui era usar o Opus 4.8, que é o modelo mais capaz, é claro, para o planejamento e para o design das tarefas, que são então repassadas para os agentes executores que usam o Composer 2.5.
00:04:39E esse já é um aprendizado importante deste artigo, o que não é uma novidade absoluta, é claro.
00:04:44Você mesmo pode fazer isso se estiver desenvolvendo software.
00:04:47É uma boa ideia dividir seu trabalho, dependendo da complexidade do projeto, é claro, em tarefas diferentes executadas por agentes diferentes, usando subagentes, por assim dizer, onde alguns focam no planejamento,
00:05:03definindo uma tarefa focada a partir da tarefa geral, como um trabalho individual, digamos, e depois ter vários agentes que implementam essa tarefa.
00:05:14Porque acontece que, para apenas gerar um bom código, você não precisa necessariamente de uma inteligência de ponta se o contexto for bom.
00:05:24Portanto, se a tarefa estiver claramente definida, se todas as informações úteis estiverem na descrição da tarefa, e então, é claro, outros fatores também podem importar.
00:05:33Por exemplo, pode importar como é a base de código ao redor ou como são os exemplos que você fornece a um agente.
00:05:39Tudo isso influencia o resultado, mas os agentes executores que apenas escrevem código podem ser muitos se a tarefa for bem especificada e o contexto for bom.
00:05:49E era sobre isso que tratava a maior parte do experimento.
00:05:52Como projetar um sistema capaz de lidar com uma tarefa dessa escala.
00:05:57Porque, claro, como mencionei, para os seus projetos também vale a pena considerar ter agentes planejadores e executores.
00:06:07Claro que não para todas as tarefas.
00:06:10Se você tem uma correção rápida de bug ou uma tarefa bem simples, não há problema nenhum em dizer diretamente ao seu agente de código, seja qual for:
00:06:19“Ei, estou com este problema.
00:06:20Quero que você faça isto.”
00:06:21Dê a ele um contexto extra e deixe-o fazer o trabalho dele.
00:06:24Ele pode, dependendo da estrutura do agente de código, acionar subagentes.
00:06:28Mesmo assim, o Claude Code pode fazer isso.
00:06:31Outras estruturas como o PI podem não fazer isso se você não der as extensões certas.
00:06:36Mas mesmo sem subagentes, muitas tarefas podem ser resolvidas por apenas um agente e você ficará bem.
00:06:43Mas para projetos e tarefas mais complexos, ter essa divisão pode ser útil, incluindo agentes revisores.
00:06:51Isso é algo que eu pessoalmente também gosto de fazer.
00:06:54Mais uma vez, dependendo da complexidade da tarefa.
00:06:56Mas ter essa divisão é algo que funciona muito bem.
00:06:59E isso, é claro, não é nada revolucionariamente novo.
00:07:02O que é novo é que, para algo como essa reescrita do SQLite, você tem múltiplos processos paralelos de agentes planejadores, executores e revisores; múltiplos executores, mas também múltiplos planejadores e revisores.
00:07:18E eles entram em conflito o tempo todo.
00:07:19Foi isso que a equipe do Cursor acabou descobrindo aqui.
00:07:22Agora, neste post do blog, que é muito, muito interessante,
00:07:26eles mencionam que, no início deste ano, já haviam feito um experimento com uma estrutura de agentes onde construíram um navegador web do zero.
00:07:33E agora eles usaram essa mesma estrutura ou esse mesmo sistema de agentes para fazer a reescrita do SQLite.
00:07:40Mas eles também construíram um novo sistema simplesmente baseado nos aprendizados que têm agora como experimento.
00:07:47E então, neste experimento e neste post, eles comparam essas diferentes abordagens e se aprofundam em todos os desafios que encontraram ao tentar configurar e executar esse sistema que reconstrói o SQLite.
00:07:59E um dos primeiros desafios enfrentados ao trabalhar com um sistema no qual centenas ou milhares de executores trabalham simultaneamente é que o controle de versão tradicional, o Git, não dá conta mais.
00:08:13Como eles escreveram em um post anterior sobre o enxame, sabemos que ferramentas como Git e Cargo dependem de bloqueios grosseiros para controle de concorrência, o que significa que o mesmo dado é bloqueado para não ter múltiplos gravadores simultâneos.
00:08:30Isso é bom para um único desenvolvedor, mas inviável para o volume de trabalho produzido por centenas de agentes concorrentes.
00:08:36O enxame do navegador do início deste ano atingiu um pico de cerca de 1.000 commits por hora.
00:08:41Esse é o enxame que reconstruiu aquele navegador.
00:08:45O novo sistema, projetado para este experimento, atinge um pico de cerca de 1.000 commits por segundo.
00:08:52Então, o enxame antigo tinha 1.000 commits por hora, o que é um pouco mais do que a maioria dos humanos faz, obviamente.
00:09:02O novo sistema, no entanto, teve cerca de 1.000 commits por segundo, o que é uma quantidade impressionante e claramente não é para o que o Git foi feito.
00:09:14Obviamente.
00:09:15Para facilitar esse ritmo de atividade, construímos um novo sistema de controle de versão do zero.
00:09:21O rendimento não foi o único motivo para dominar essa camada.
00:09:25Toda alteração no sistema passa pelo sistema de controle de versão.
00:09:29Portanto, é onde os conflitos se tornam visíveis primeiro.
00:09:31E vários dos mecanismos de coordenação da próxima seção são implementados diretamente dentro dele.
00:09:37E isso é realmente interessante.
00:09:39Eles criaram um novo sistema de controle de versão para a era dos agentes de IA.
00:09:43Porque o antigo, o Git, que todos nós usamos, não tem nada de errado.
00:09:48Só para deixar bem claro.
00:09:49Estamos falando de um experimento em uma escala e em uma tarefa que muitos de nós nunca enfrentaremos, pelo menos não tão cedo.
00:09:57Mas ainda assim, o sistema antigo, o Git, não foi feito para ter centenas de agentes, centenas de entidades trabalhando no mesmo código simultaneamente.
00:10:07Então eles construíram um novo sistema de controle de versão que consegue lidar com uma concorrência insanamente alta, mas que também ajuda a resolver conflitos por meio de agentes.
00:10:19Porque, obviamente, é no sistema de controle de versão que os conflitos ficam visíveis se duas alterações afetarem o mesmo trecho de código em um arquivo.
00:10:28Então essa é a primeira coisa importante aqui.
00:10:30Eles criaram um sistema de controle de versão totalmente novo para este experimento para conseguir executá-lo de forma eficiente.
00:10:37Agora, naturalmente, como mencionaram aqui, eles encontraram muitos problemas nessa escala e com esse ritmo de mudanças a 1.000 commits por segundo.
00:10:48Por exemplo — e isso é muito interessante —, todos esses problemas que encontraram e como os resolveram nos dão uma visão de como a engenharia de software pode ser no futuro, pelo menos em certos cenários.
00:11:01O problema de design de “cérebro dividido”.
00:11:03Dois planejadores, sem saberem um do outro, implementam o mesmo conceito de maneiras diferentes em partes diferentes da base de código.
00:11:10Ou seja, duplicação: o mesmo conceito de formas distintas em partes diferentes do código.
00:11:16Normalmente, você gostaria de extrair e reutilizar essa lógica, certo?
00:11:21Corrigimos isso por meio de engenharia de prompts.
00:11:24Portanto, nenhum sistema novo e sofisticado foi construído aqui, apenas ajustes nos prompts.
00:11:28Os planejadores tomam as decisões arquiteturais, os próprios agentes planejadores, em vez de delegá-las.
00:11:34E exigimos que eles garantam que duas subárvores delegadas não decidam sobre a mesma questão.
00:11:39Portanto, é uma questão de configuração aqui.
00:11:40Tudo se resume a garantir que, ao dividir esse sistema em planejadores, executores e assim por diante, você garanta que seus diferentes planejadores — porque não há apenas executores paralelos, mas também planejadores paralelos — tenham tarefas claramente definidas com raríssima chance de conflito ou sobreposição.
00:12:02Então isso, é claro, começa no design feito por humanos.
00:12:08Em como você configura a tarefa, em como você instrui os prompts, certo?
00:12:11Corrigimos isso através de prompts.
00:12:13Isso desce por aquela árvore de agentes com todos aqueles nós e folhas paralelas, onde você quer garantir que, à medida que os agentes dividem as tarefas em subtarefas, eles sejam instruídos a cortar tarefas com baixa chance de sobreposição.
00:12:34Portanto, este é, em última análise, um desafio de planejamento humano, que consiste em configurar o sistema da maneira correta do lado humano.
00:12:43Foi assim que eles resolveram ou enfrentaram esse problema.
00:12:47Outro problema enfrentado foi a disputa entre planejadores.
00:12:51Uma forma mais severa de disputa ocorre quando dois planejadores sabem da existência um do outro e disputam através de alterações constantes nos mesmos arquivos.
00:12:59O problema são duas visões distintas da realidade, e ferramentas de mesclagem não conseguem resolver uma divergência.
00:13:04Em vez disso, fazemos com que os agentes registrem as decisões em documentos de design compartilhados.
00:13:08O código que depende de uma decisão carrega uma referência de verificação compilada de volta ao seu documento.
00:13:13Quando os planejadores se contradizem sem saber, um reconciliador mescla os documentos e as referências propagam a resolução para o restante do fluxo.
00:13:21No final, relacionado ao ponto anterior, ao dividir o trabalho entre planejadores, ainda assim, no desenvolvimento de software, você não pode evitar completamente sobreposições ou domínios, lógicas e áreas compartilhadas que precisam ser tocadas por planejadores e executores na base de código.
00:13:43Foi aí que os agentes planejadores começaram a disputar uma implementação, e eles resolveram isso introduzindo um agente reconciliador, presumo eu, que mescla os documentos criados por esses planejadores.
00:13:59Documentos estes elaborados para depois serem entregues aos executores.
00:14:02Eles inseriram uma etapa de reconciliação que une os documentos dos agentes planejadores em conflito, para que falassem uma linguagem consistente e concordassem em uma implementação, ajudando a evitar que a mesma coisa fosse reimplementada de formas diferentes no código.
00:14:21Pelo que entendi, esses dois trabalham juntos.
00:14:24Naturalmente, eles também encontraram conflitos de mesclagem.
00:14:29Planejar e garantir que não haja sobreposição ou que haja o mínimo possível, e que os planejadores falem a mesma língua, é o primeiro passo importante.
00:14:38Mas ainda assim, múltiplos executores, mesmo trabalhando no mesmo plano, têm grandes chances de alterar os mesmos arquivos e entrar em contradição.
00:14:50Há muitos outros executores que não vão simplesmente garantir que não trabalharão nos mesmos arquivos.
00:14:55Por isso eles acabam mexendo nos mesmos arquivos.
00:14:57Por isso eles acabam mexendo nos mesmos arquivos.
00:14:58Para resolver uma colisão, eles teriam que parar, absorver o contexto do outro agente e fazer a mesclagem a partir disso.
00:15:03Naturalmente, se dois agentes — ou dois humanos — trabalham no mesmo arquivo, para resolver esse conflito ambos precisam parar para encontrar uma decisão,
00:15:19uma implementação que resolva o conflito.
00:15:23Os agentes executores, no entanto, são ruins nisso e, na prática, ou sobrescrevem a outra alteração ou descartam a sua própria.
00:15:29E talvez você também tenha notado isso.
00:15:31Eu certamente já notei.
00:15:32Se você trabalha em uma base de código junto com um ou mais agentes de IA e faz uma alteração...
00:15:38Tudo bem, eu sei que assusta, mas você ainda pode escrever código.
00:15:40Digamos que você faça uma mudança.
00:15:42Você altera algo no código.
00:15:44O agente sempre vai desfazer e sobrescrever.
00:15:48Ele não respeita essas mudanças.
00:15:50Ele tem o objetivo dele.
00:15:52E se ele decidiu que deve editar aquele arquivo, ele vai fazer isso.
00:15:57Ele não se importa se você fez alguma alteração no meio do caminho.
00:16:01É um pouco diferente se você fez um commit dessa alteração, porque esses agentes passam por pós-treinamento para não desfazerem facilmente seus commits e coisas assim.
00:16:13Mas se for uma alteração sem commit, o executor simplesmente não liga.
00:16:17O agente simplesmente não se importa.
00:16:19E foi exatamente isso que eles encontraram aqui também.
00:16:21Para corrigir isso, criamos um sistema em que um agente terceiro neutro intervém em conflitos de mesclagem e os resolve em nome de todas as partes.
00:16:29Seu único objetivo é ser imparcial e eficiente, semelhante à forma como as filas de mesclagem funcionam em equipes de engenharia.
00:16:35E acho que isso também é interessante.
00:16:38É, novamente, uma forma de reconciliação.
00:16:41Pelo que entendi, trata-se de parar esses agentes, assim como no modelo antigo, onde você tinha que parar, dar um passo atrás e encontrar uma
00:16:49solução para um conflito.
00:16:51Mas o que isso mostra claramente — e que também não é um aprendizado novo — é que ter um contexto limpo e adequado é super, super importante.
00:17:03Portanto, não importa se você está enfrentando uma tarefa de grande escala como o Cursor aqui, ou se está apenas trabalhando em um projeto menor,
00:17:12a grande vantagem de ter uma divisão entre agentes planejadores, executores e revisores é, muito frequentemente, trabalhar com janelas de contexto limpas.
00:17:24Isso não significa janelas de contexto vazias.
00:17:26Apenas significa ter sessões de agentes renovadas, preenchidas com o contexto exato necessário para uma determinada tarefa.
00:17:33Por exemplo, um executor é péssimo para revisar o próprio trabalho porque tem todo o contexto da implementação acumulado na sua janela de contexto.
00:17:41Então ele fica viesado, se você quiser chamar assim.
00:17:44É por isso que um agente revisor deve começar em uma janela de contexto limpa, recebendo as informações sobre o que o executor fez, qual era o plano e quais arquivos foram alterados, mas nada além disso.
00:17:55Para que ele possa revisar honestamente aquele trabalho.
00:17:59É por isso que janelas de contexto limpas, preenchidas com o contexto correto, são tão importantes.
00:18:04E foi exatamente o mesmo caso aqui, onde eles resolveram conflitos de mesclagem por meio de um novo agente com o contexto exato, sem vieses, que pudesse solucionar o conflito.
00:18:17E aí presumo que o sistema foi configurado de forma que os agentes executores recebessem a informação de que aquela era a resolução do conflito e não deveriam sobrescrevê-la, ou novos agentes executores fossem iniciados.
00:18:30Isso não ficou totalmente claro para mim aqui.
00:18:32Outro problema que eles encontraram foram os megagrandes arquivos.
00:18:35Alguns arquivos são locais particularmente populares para os agentes trabalharem.
00:18:39Cada agente pode adicionar apenas uma pequena quantidade de código, e nenhum agente é responsável por manter o arquivo pequeno.
00:18:45Esses megaarquivos gargalam tudo.
00:18:49Eles são caros para transportar, comparar diffs, mesclar e se tornam o local de constantes colisões.
00:18:54Novamente, isso é algo que, em uma escala muito menor, você também já deve ter encontrado.
00:19:00Eu certamente já encontrei.
00:19:01Uma das coisas que temos.
00:19:02Especialmente para testes.
00:19:03A minha experiência é que os agentes adoram adicionar mais e mais testes no mesmo arquivo.
00:19:08E claro que não é só com testes, mas é uma área onde vejo isso com frequência.
00:19:13E especialmente se você tem múltiplos agentes trabalhando e cada um tem sua própria pauta.
00:19:18Eles não se importam, porque não são humanos.
00:19:21Como poderiam se importar com algo?
00:19:23Eles estão apenas executando tarefas, certo?
00:19:24Eles não se importam com o tamanho de um arquivo ou com a arquitetura geral de um sistema.
00:19:30Se você só tiver um grupo de agentes executando suas tarefas, sua base de código descambará para o caos em algum momento.
00:19:37Porque os agentes não se importam.
00:19:39Eles se importam em executar a tarefa deles.
00:19:42E esses mega-arquivos, claro, são um indicador claro desse problema.
00:19:48Eles se tornam uma realidade quanto mais agentes trabalham por mais tempo no seu projeto.
00:19:55Não há nenhum agente ali responsável por dividir esse arquivo ou manter sua base de código bem arquitetada.
00:20:02Essa simplesmente não é a função deles.
00:20:04Então, para resolver isso, demos aos agentes trabalhadores uma forma de sinalizar arquivos inflados.
00:20:09Uma vez sinalizado, bloqueamos novos commits e um agente separado decompõe o arquivo gigante em módulos menores.
00:20:16Portanto, novamente, um agente novo entra em ação.
00:20:19É um padrão que vemos aqui.
00:20:21Para todos esses problemas, tratava-se de identificar a falha e depois usar agentes novos com a tarefa certa,
00:20:28com o contexto certo, para resolver esse problema para que os outros agentes pudessem continuar o trabalho.
00:20:35E é a mesma coisa aqui para os mega-arquivos.
00:20:38Ossificação, outro problema que eles enfrentaram.
00:20:40Os agentes aprenderam, ao trabalhar em bases de código existentes com humanos no processo,
00:20:44a não mexer no código principal, mesmo quando ele precisa mudar.
00:20:48Então, isso não é o que eu quis dizer antes.
00:20:50Quando você faz uma alteração em um arquivo no qual o agente está trabalhando e ele simplesmente a descarta.
00:20:55Trata-se, em vez disso, do contexto geral.
00:20:57Um agente tem uma tarefa clara baseada em um plano, baseada em um prompt que você forneceu.
00:21:03E isso envolve, obviamente, alterar certos arquivos.
00:21:07Agora, algo que já sabemos ou vemos todos os dias ao trabalhar com agentes é que, dependendo do modelo,
00:21:16alguns modelos são super hesitantes em abrir mão do código existente.
00:21:21Eles preferem adicionar 10 alternativas, 10 verificações “if” e cada vez mais código legado a uma base de código em vez de deletar e limpar.
00:21:31Você precisa solicitar explicitamente para garantir que o agente realmente delete uma função ou remova algum arquivo de código.
00:21:39Eles não fazem isso por conta própria devido ao ajuste fino (fine-tuning), pois esses provedores de modelos não querem criar modelos
00:21:47que ajam livremente e quebrem todo tipo de código em produção.
00:21:50Mas quando não se está trabalhando em um projeto antigo ou em uma base de código existente que talvez rode em produção,
00:21:57essa tendência de não mexer no código e mantê-lo todo para sempre pode ser super problemática e irritante.
00:22:05E também pode levar a outros efeitos colaterais, como os que enfrentaram aqui, onde os agentes simplesmente não melhoravam o código escrito por outros agentes,
00:22:16mas apenas construíam por cima várias e várias vezes, levando, por fim, a uma base de código inflada.
00:22:23Para resolver isso, autorizamos a quebra intencional de código.
00:22:27Um agente que julga válida uma mudança estrutural pode fazer um ajuste focado fora do seu escopo e deixar um comentário explicando por que o fez.
00:22:36E isso é, novamente em menor escala, o que você pode fazer nos seus projetos, algo parecido com o que eu faço.
00:22:41Você quer autorizar explicitamente e dizer aos seus agentes: “Ei, estamos construindo isso.
00:22:46Estamos na fase inicial de desenvolvimento.
00:22:48Isso ainda não está no ar.
00:22:49Eu quero alterações que causem quebras.
00:22:51Portanto, limpem o código agressivamente.
00:22:54Refatorações são bem-vindas”.
00:22:56Coisas desse tipo.
00:22:58Você quer incentivar os agentes e esses modelos de IA e sobrescrever suas instruções de ajuste fino.
00:23:04Por assim dizer, seu conhecimento nativo, e se livrar disso para garantir que eles possam realmente evoluir uma base de código em vez de só adicionar mais código.
00:23:14Então, novamente, algo que podemos ver em menor escala aqui, é claro, visto em grande escala.
00:23:19Agora, para a revisão, eles usaram uma abordagem chamada lentes de revisão.
00:23:24Temos os agentes planejadores e trabalhadores, mas é claro que esse trabalho precisa ser revisado para criar tarefas de acompanhamento e reiniciar o ciclo até que um erro seja corrigido ou a base de código melhore.
00:23:38Em um sistema de longa execução e multiagente, os erros se acumulam, e o enxame precisa de uma forma de se autocorrigir antes que pequenos erros se tornem estruturais.
00:23:47Mais uma vez, faz todo sentido.
00:23:48Todos nós também já vimos isso em menor escala.
00:23:50Experimentamos muitos tipos de lentes de revisão, como dar ao agente revisor o histórico completo do trabalhador, apenas sua saída ou nada além da base de código.
00:24:00Também testamos revisores rodando em modelos diferentes, com treinamentos diferentes e personalidades distintas.
00:24:05Nenhuma lente isolada pega tudo, mas o conjunto de lentes correlacionadas se sobrepõe como em sistemas autônomos, alcançando confiabilidade sobre-humana sem um componente perfeito.
00:24:16O processamento gasto na revisão traz alto retorno, pois revisar é muito mais barato do que o trabalho auditado.
00:24:21Suspeitamos que esse sistema de revisão em camadas foi um grande fator para a qualidade sustentada das execuções.
00:24:28Portanto, a principal lição aqui.
00:24:30É impossível ter um ou mais agentes revisores revisando toda a base de código.
00:24:39É coisa demais.
00:24:41Em vez disso, eles experimentaram diferentes abordagens, como dar o histórico completo, apenas a saída ou somente a base de código.
00:24:47E o que descobriram no final foi que ter revisores diferentes, com personas distintas e lentes de foco variáveis, ajudou a focar em múltiplos aspectos.
00:25:00Fornecer a base de código, pelo que entendi, e talvez algumas informações sobre o que o trabalhador fez.
00:25:06E então foi a combinação, a saída combinada de múltiplos revisores que levou a um resultado geral de revisão, o qual pôde ser pego por um planejador para virar um plano e fazer os trabalhadores corrigirem o código.
00:25:23E novamente, em menor escala, acho que isso é algo que você ou nós podemos aplicar.
00:25:28Obviamente, nós não estamos construindo coisas assim.
00:25:34Mas o que funciona muito bem na minha experiência também é ter múltiplos agentes revisores com tarefas diferentes, onde um pode focar em: “Ei, isso é Rust idiomático?”.
00:25:46Outro pode focar em problemas de desempenho e segurança, se as regras permitirem.
00:25:51Outro revisor pode focar em padrões de nomenclatura, se for algo em que você queira focar, e assim por diante.
00:25:58Assim, você tem lentes diferentes e dá a esses revisores exatamente o contexto adequado.
00:26:03De novo, algo como: “Ei, tivemos trabalhadores atuando nessa funcionalidade”.
00:26:07Talvez dar a eles o plano do trabalhador e algumas informações sobre os passos gerais executados, mas nada além disso.
00:26:15E aí você tem todo esse resultado dos diferentes revisores e pode combiná-lo, quem sabe usando outro revisor.
00:26:22O que também gosto é ter um revisor para avaliar os resultados das revisões, o que parte da ideia de que, dependendo do modelo, eles tendem a gostar de achar problemas.
00:26:36Não importa o código que você entregue, poderia ser uma única linha.
00:26:40Às vezes sinto que eles achariam cinco problemas nela.
00:26:43Então ter um revisor para categorizar esses achados e descartar o que não é problema real pode funcionar muito bem, na minha experiência.
00:26:55E é essa combinação de revisores, essa camada de revisores que ajuda a produzir bons resultados, que depois podem ser pegos e implementados novamente.
00:27:06Agora, novamente, sempre depende da escala da sua tarefa e do software que está construindo.
00:27:11Obviamente, para muitos softwares, tudo isso é complexo demais, mas é um ótimo vislumbre de como a engenharia de software pode ser no futuro, o que acho pessoalmente muito interessante.
00:27:27Uma última coisa que fizeram foi deixar os agentes moldarem o ambiente.
00:27:32Aqui, a ideia era permitir que os agentes escrevessem um guia de campo, um documento ou coleção de documentos sem dar instruções além de servir como contexto para a tarefa geral, permitindo criar uma memória compartilhada sobre aprendizados e problemas identificados.
00:28:00Para que tivessem esse sistema extra de memória para os agentes anotarem e documentarem decisões.
00:28:10E no geral, assim como a reescrita do BUN em Rust, acho esse experimento muito, muito interessante.
00:28:16Também pode ser assustador.
00:28:17Eu entendo totalmente isso.
00:28:18E acho que não devíamos deduzir que é assim que todo software deve ser construído a partir de agora.
00:28:24Para começar, este nem é um software pronto para produção.
00:28:28E deixá-lo pronto para produção certamente levaria um tempo considerável.
00:28:33Isso não deve ser subestimado.
00:28:35Não é como se você pudesse construir algo assim em poucas horas e depois deixá-lo pronto para produção em mais algumas horas.
00:28:43Os primeiros 80% podem ser muito mais rápidos de alcançar do que os últimos 20%.
00:28:48Todos nós sabemos disso.
00:28:49Então essa é uma lição importante.
00:28:51Também é importante perceber que essa tarefa específica de reescrever o SQLite pode ter recebido apenas essa documentação e a suíte de testes usada.
00:29:04Mas obviamente, para começar, esta é uma especificação incrivelmente detalhada, algo que você não tem em novos projetos.
00:29:13Se você está criando um novo software, não tem uma especificação tão detalhada quanto a documentação de um software com mais de 20 anos.
00:29:24E claro, mesmo que apenas a documentação tenha sido dada a esses agentes, o código-fonte do SQLite e outras reimplementações (como em Rust pela Turso) muito provavelmente fazem parte dos dados de treinamento da maioria desses modelos.
00:29:46Então não é como se fosse algo totalmente inédito para esses modelos.
00:29:51Não é o mesmo que criar um software do zero, onde a iteração é parte fundamental do desenvolvimento.
00:29:58Seria muito difícil, diria até impossível, criar um novo software do zero sem que ele mude o tempo todo.
00:30:11Porque você não pode escrever uma especificação perfeita de início e dar o trabalho por encerrado.
00:30:17Você sempre descobre coisas novas ou aspectos que quer mudar enquanto constrói algo, em qualquer escala.
00:30:26E por isso, claro, isso não representa como o software será ou deveria ser construído em geral.
00:30:34No entanto, é um experimento muito interessante.
00:30:37É um experimento muito interessante e traz aprendizados importantes para todos nós.
00:30:43Lições que não são inéditas, como dividir o trabalho e usar janelas de contexto limpas com a informação exata.
00:30:50Insights interessantes de que novos sistemas de controle de versão podem surgir e ser necessários no futuro.
00:30:57E, claro, que as orquestrações multiagente estão se tornando uma realidade.
00:31:01Tudo isso prova que humanos projetando esses sistemas de agentes — e humanos decidindo a arquitetura de novos softwares — continuam essenciais.
00:31:21Escrever especificações, definir arquiteturas, criar sistemas de agentes para implementá-las e revisar tudo depois é fundamental.
00:31:33É para onde estamos indo e, embora seja diferente de como fazíamos há seis anos, é algo que me empolga muito.
00:31:45Acho incrível estarmos caminhando para essa visão sistêmica, tanto na criação dos sistemas agênticos quanto no design da arquitetura de software.
00:31:59E depois ver ambos trabalhando juntos.
00:32:01Acho experimentos como este muito, muito interessantes.
00:32:04Os aprendizados aqui são muito válidos.
00:32:07E algumas dessas lições, em uma escala menor e mais simples, podem ser úteis para projetos do dia a dia.
00:32:17Mas como sempre, me conte o que você acha e qual a sua opinião sobre experimentos como este.

Key Takeaway

A reescrita funcional do SQLite em Rust por enxames de agentes da Cursor demonstra que dividir tarefas entre modelos avançados de planejamento e modelos baratos de execução, suportados por controle de versão customizado e revisões especializadas, reduz o custo de desenvolvimento de US$ 10.000 para US$ 1.300.

Highlights

  • A reescrita do SQLite em Rust realizada pela equipe do Cursor utilizou 835 páginas de documentação oficial e a suíte de testes SQLogicTest para validar a implementação.

  • O uso do GPT 5.5 em todas as etapas elevou o custo do projeto para US$ 10.000, enquanto a combinação do Opus 4.8 para planejamento com o Composer 2.5 para execução reduziu o custo para US$ 1.300 mantendo a mesma qualidade.

  • Para suportar um volume de até 1.000 commits por segundo gerados por centenas de agentes simultâneos, foi necessário criar um novo sistema de controle de versão do zero, já que o Git depende de bloqueios de concorrência incompatíveis com essa escala.

  • Agentes executores tendem a ignorar alterações não commitadas feitas por outros agentes ou humanos, sobrescrevendo arquivos para atingir seus objetivos individuais.

  • A alocação de múltiplos agentes revisores com personas e focos específicos (como desempenho ou padrões de código) gera confiabilidade superior sem depender de um único componente perfeito.

Timeline

O experimento da Cursor e a infraestrutura de modelos

  • O mini SQLite é um experimento focado na engenharia de sistemas de agentes de IA e enxames autônomos, não em um produto voltado para produção.
  • A documentação de 835 páginas do SQLite serviu como especificação técnica detalhada para a reconstrução do sistema em Rust.
  • A combinação de modelos especializados reduz os custos de execução sem comprometer a taxa de aprovação nos testes.

O projeto utilizou a suíte oficial SQLogicTest para validar as consultas e comportamentos da implementação gerada por IA. A utilização exclusiva do GPT 5.5 em todas as funções gerou um custo total de US$ 10.000. Ao delegar o planejamento arquitetural ao Opus 4.8 e a geração de código ao Composer 2.5, o custo caiu para US$ 1.300 com a mesma taxa de sucesso nos testes.

Gargalos no controle de versão e conflitos de concorrência

  • O controle de versão tradicional com Git falha sob a carga de trabalho de centenas de agentes simultâneos.
  • Engenharia de prompts previne o problema de cérebro dividido entre planejadores paralelos.
  • Documentos de design compartilhados e agentes reconciliadores evitam disputas de implementação.

O enxame de agentes atingiu um pico de 1.000 commits por segundo, superando a capacidade do Git e do Cargo baseada em bloqueios de arquivos. A solução exigiu a criação de um sistema de controle de versão próprio do zero. Para conter a duplicação de lógica por planejadores isolados, os prompts foram ajustados para restringir decisões arquiteturais às subárvores designadas, enquanto reconciliadores unificaram especificações divergentes.

Resolução de colisões, mega-arquivos e refatoração

  • Um agente neutro atua como mediador imparcial em conflitos de mesclagem de código.
  • Arquivos gigantescos gerados por múltiplos agentes exigem bloqueio e modularização por agentes dedicados.
  • A autorização explícita para quebrar código é necessária para superar o viés de conservação do fine-tuning dos modelos.

Agentes executores tendem a sobrescrever edições de terceiros ao encontrarem conflitos de arquivo. A intervenção de um agente imparcial resolve essas colisões sem viés de contexto. Quando a proliferação de código cria mega-arquivos que atrasam a compilação, o sistema bloqueia novos commits e aciona um agente para dividir o arquivo em módulos. Para combater a acumulação de código legado, o sistema autoriza refatorações agressivas através de comentários explicativos.

Lentes de revisão e limitações do desenvolvimento autônomo

  • O uso de múltiplas lentes de revisão com diferentes personas e contextos limpos garante a qualidade sustentada do código.
  • Especificações pré-existentes de alta precisão não refletem a dinâmica de criação de novos softwares comerciais.
  • A arquitetura de software e o design de sistemas de agentes permanecem como atribuições humanas indispensáveis.

Revisores operando com janelas de contexto limpas e focos variados (como idiomática da linguagem ou segurança) capturam falhas que um único agente ignoraria. A reconstrução bem-sucedida do SQLite dependeu da existência prévia de 835 páginas de documentação e dados de treino existentes nos modelos, condições ausentes no desenvolvimento de novos produtos. A definição de arquiteturas e a orquestração do ambiente agêntico continuam dependendo da orientação humana.

Community Posts

View all posts