Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 44

Incremental Code Generation

Recommended resources

Olá! Bem-vindo de volta ao nosso curso.

Nas lições anteriores, você aprendeu a instruir um agente para gerar os diferentes "artefatos" de uma tarefa de desenvolvimento: código de backend em C#, código de frontend em React e, mais recentemente, scripts de migração de banco de dados para MariaDB. Cada lição se concentrou em gerar uma peça específica e autônoma.

No entanto, uma tarefa real, como a descrita em um ticket do Jira, raramente é tão simples. Geralmente, ela envolve alterações coordenadas em vários locais. Tentar resolver uma tarefa complexa com um único prompt para o agente — uma abordagem que podemos chamar de "one-shot" ou "vibe coding" — é uma receita para a instabilidade. O agente pode esquecer o contexto, fazer suposições incorretas ou simplesmente falhar em gerar uma solução completa e funcional.

Para construir um agente robusto e confiável, precisamos de uma abordagem mais estruturada. É aqui que entra o resultado de aprendizagem de hoje: Aplicar técnicas de geração incremental, onde o agente produz e verifica o código em partes menores e gerenciáveis.

Vamos explorar como transformar o processo de geração de código de um único grande salto para uma série de passos deliberados e verificáveis, uma metodologia muito mais alinhada com as práticas de engenharia de software que você já conhece.

1. Da Geração "One-Shot" ao Desenvolvimento Orientado por Especificação (SDD)

A primeira mudança de mentalidade é abandonar a ideia de que o agente deve produzir todo o código de uma vez. Em vez disso, devemos instruí-lo a primeiro planejar e depois executar esse plano passo a passo. Esse processo é formalizado como Spec-Driven Development (SDD).

Spec Driven Development with Rovo Dev - Work Life by Atlassian

Para entender a fundo o conceito de SDD, vamos começar com este artigo do blog da Atlassian. Ele contrasta o 'vibe coding' com uma abordagem de engenharia estruturada, que é exatamente o que queremos para o nosso agente.

Leia as seções iniciais até 'What do the prompts look like?'. Preste atenção especial em: A crítica ao 'vibe coding': Entenda por que prompts de um só tiro falham em tarefas complexas. O ciclo do SDD: O ciclo 'plan, review, iterate on the plan, and then execute' é o cerne da nossa lição. O papel do .agents.md: A ideia de ter um arquivo com diretrizes compartilhadas é uma forma de estabelecer as 'regras do jogo' para o agente, incluindo a obrigação de seguir o SDD.

A ideia principal do SDD é que o primeiro resultado do agente não é o código, mas sim um plano de execução. Esse plano detalha as etapas que ele seguirá, os arquivos que modificará e as dependências entre as etapas. Isso oferece um ponto de intervenção crucial: você (ou outro processo) pode revisar e aprovar o plano antes que qualquer linha de código seja escrita.

Esse fluxo é muito semelhante a um processo de desenvolvimento ágil, onde uma feature é quebrada em tasks menores e gerenciada em sprints.

LLM Agent in Agile Software Development Lifecycle
Nesta imagem, vemos como um agente de LLM se encaixa em um ciclo de desenvolvimento ágil. O processo é iterativo (Sprint 1, Sprint 2...), com fases de planejamento, desenvolvimento e teste. A geração incremental segue essa mesma filosofia, quebrando um grande trabalho em partes menores e verificáveis.

2. O Ciclo Incremental: Planejar, Gerar, Verificar

Vamos detalhar as três fases do nosso ciclo de geração incremental.

Fase 1: Planejar

O agente deve analisar a tarefa do Jira e, em vez de começar a codificar, deve gerar um plano detalhado. Já vimos a importância de prompts bem estruturados; agora, vamos usá-los para solicitar um plano.

Everything You Need to Know About Coding with AI // NOT vibe coding

Este vídeo, de uma perspectiva de desenvolvedor, mostra como usar um LLM para planejar o trabalho antes de executá-lo. É um exemplo prático do primeiro passo do SDD.

Assista ao trecho de 04:44 a 05:33. Observe como o prompt é formulado explicitamente para gerar um plano: 'create a detailed implementation plan...' e 'Don't write any code yet'. Essa separação de 'planejar' e 'fazer' é a chave.

O artigo sobre SDD que você leu nos dá um exemplo de como instruir o agente a criar esse plano. As regras podem ser incluídas em um arquivo .agents.md ou diretamente no prompt:

Spec Driven Development — Rule set
- Break large requests into small, verifiable steps and present a plan.
- Document the plan...
- Each step of the plan should have its own file with detailed specifications...
- Always plan never jump straight into changes.
- After completing a step, summarize results and ask me to review and if you should continue.

O resultado dessa fase é um conjunto de artefatos que descrevem o plano, como os arquivos markdown que o Rovo Dev gera no exemplo do artigo.

Fase 2: Gerar

Com o plano aprovado, o agente começa a executar cada etapa. Cada etapa do plano torna-se uma tarefa de geração de código menor e muito mais focada. Por exemplo, uma etapa pode ser: "Adicionar a propriedade Bio à classe UserViewModel no arquivo UserViewModel.cs".

Nesse ponto, o agente usaria as técnicas que aprendemos nas lições anteriores, construindo um prompt altamente contextualizado para essa tarefa específica e gerando apenas aquele trecho de código.

Fase 3: Verificar

Após cada geração incremental, uma verificação é necessária. Sem verificação, estamos apenas gerando código em pedaços, sem garantia de que eles funcionam juntos. A verificação é o que torna o processo robusto.

Existem vários níveis de verificação:

  1. Revisão Humana: O agente pode parar após cada etapa e solicitar sua aprovação para continuar, como instruído no rule set do SDD.
  2. Validação Automatizada: Após modificar um arquivo, o agente pode ser instruído a executar ferramentas de linting, compilar o projeto (dotnet build) ou rodar testes unitários relevantes. Abordaremos isso em detalhes no Módulo 9.
  3. Verificação por Outro Agente: Uma abordagem avançada é usar uma equipe de agentes. Um agente escreve o código, e um segundo agente, com um prompt focado em revisão, analisa o código gerado em busca de bugs ou desvios das melhores práticas.

Everything You Need to Know About Coding with AI // NOT vibe coding

Vamos revisitar o vídeo anterior para ver essa ideia de verificação e colaboração entre agentes.

Assista aos trechos de 05:33 a 07:16 e 08:10 a 08:44. Preste atenção aos seguintes pontos: Revisão do código: A mentalidade de 'pair programming com um desenvolvedor júnior' é crucial. O código gerado deve ser questionado e verificado. Múltiplos agentes: A ideia de usar um agente para escrever código, outro para revisar e um terceiro para escrever testes é um padrão poderoso para implementar o ciclo de geração e verificação.


3. Gerenciando o Estado em Tarefas de Longa Duração

Um desafio fundamental em processos incrementais é o gerenciamento de estado. Se o agente para e recomeça, como ele sabe o que já foi feito e o que fazer a seguir?

Effective harnesses for long-running agents

Este artigo da Anthropic aborda exatamente esse problema para agentes de longa duração. Ele oferece uma solução de engenharia elegante, inspirada em como desenvolvedores humanos trabalham.

Leia as seções 'The long-running agent problem', 'This decomposes the problem into two parts', 'Incremental progress' e a tabela de resumo 'Agent failure modes and solutions'. Os pontos chave são: Falhas comuns: Identifique as razões pelas quais os agentes falham (tentam fazer muito de uma vez, declaram vitória cedo demais). Solução em duas partes: A distinção entre um 'agente inicializador' e um 'agente de codificação'. Artefatos de estado: A importância de deixar um rastro claro para as próximas sessões, como fazer commits no Git com mensagens descritivas e manter um arquivo de progresso.

Inspirados nesse artigo, podemos definir que nosso agente, para gerenciar seu estado, deve:

  1. Criar uma "lista de verificação": Na fase de planejamento, o agente pode gerar um arquivo (ex: task_checklist.json) listando todas as funcionalidades ou etapas a serem implementadas, cada uma marcada como "pendente".
  2. Trabalhar em uma etapa de cada vez: O agente é instruído a selecionar apenas uma tarefa "pendente" da lista para trabalhar em cada sessão.
  3. Confirmar o progresso no Git: Após concluir e verificar uma etapa, o agente deve fazer um commit das alterações com uma mensagem descritiva (ex: "feat: Add Bio property to UserViewModel"). O histórico do Git se torna uma fonte da verdade sobre o progresso.
  4. Atualizar a lista de verificação: Como último passo, o agente atualiza o status da tarefa para "concluído" no arquivo task_checklist.json.

Ao iniciar uma nova sessão, a primeira ação do agente é ler o task_checklist.json e o git log para entender o estado atual do trabalho antes de prosseguir.


4. Orquestrando o Ciclo no Ecossistema Atlassian

Finalmente, vamos conectar essa teoria às ferramentas que você planeja usar. Como um orquestrador (como o Atlassian Automation) pode gerenciar esse ciclo incremental? A chave está na capacidade do agente de retornar saídas estruturadas, como JSON.

Atlassian Rovo Dev CLI Interface
Esta é a interface do Rovo Dev, a ferramenta que você usará. Note que ela é projetada para interagir com o Jira ('start with one of these Jira work items'), que é o ponto de partida do nosso agente.

Imagine que o plano gerado pelo seu agente na Fase 1 não seja apenas texto, mas um objeto JSON:

{
  "steps": [
    {
      "id": 1,
      "summary": "Add 'bio' column to 'users' table",
      "type": "database_migration",
      "details": "Create a new MariaDB migration script to add a TEXT column named 'bio' to the 'users' table."
    },
    {
      "id": 2,
      "summary": "Update backend C# entity and DTOs",
      "type": "backend_code",
      "files_to_modify": ["User.cs", "UserDto.cs"],
      "details": "Add a 'Bio' string property to the User entity and UserDto."
    },
    {
      "id": 3,
      "summary": "Update frontend React component",
      "type": "frontend_code",
      "files_to_modify": ["UserProfile.js"],
      "details": "Add a new text area to the user profile form to display and edit the user's bio."
    }
  ]
}

Este JSON pode ser passado para o Atlassian Automation.

From zero to hero: Building Rovo agents

Este vídeo sobre Rovo agents mostra como usar a saída JSON de um agente dentro do Atlassian Automation para criar fluxos de trabalho avançados.

Assista ao trecho de 31:58 a 36:08. O conceito mais importante aqui é o uso de 'branching' (ramificação) na automação para iterar sobre a saída JSON do agente. Veja como eles fazem um loop em cada 'ideia' retornada pelo agente para criar um item de trabalho. No nosso caso, faríamos um loop em cada 'step' do nosso plano para executar a ação correspondente.

Usando a funcionalidade de branch do Atlassian Automation, você pode iterar sobre o array steps do JSON. Para cada etapa, você pode usar uma condição (if step.type == 'database_migration') para invocar um cenário de agente Rovo diferente, cada um especializado em sua tarefa (gerar DDL, gerar C#, etc.), passando os detalhes daquela etapa como contexto.


Conclusão

Hoje, demos um passo fundamental para transformar nosso agente de um simples gerador de código em um verdadeiro assistente de engenharia de software. Em vez de tentar resolver problemas complexos de uma só vez, ensinamos a ele um processo metódico e robusto.

Principais Pontos:

  • Abandone o "Vibe Coding": Tarefas complexas exigem um processo estruturado. A geração "one-shot" é frágil e não confiável.
  • Adote o Ciclo Plan-Generate-Verify: Sempre comece gerando um plano detalhado (Spec-Driven Development). Em seguida, execute cada etapa do plano de forma isolada e verifique o resultado antes de prosseguir.
  • Gerencie o Estado Explicitamente: Use artefatos como listas de verificação (JSON), logs de progresso e commits do Git para que o agente sempre saiba o estado do trabalho, permitindo que tarefas de longa duração sejam pausadas e retomadas.
  • Use Saídas Estruturadas para Orquestração: Faça com que seu agente retorne planos em formatos como JSON, que podem ser facilmente processados por ferramentas de automação como o Atlassian Automation para orquestrar o fluxo de trabalho incremental.

Na próxima lição, daremos início ao Módulo 8: Orchestrating the End-to-End Workflow. Com nossa compreensão sobre como gerar planos e executá-los incrementalmente, estaremos prontos para abordar o primeiro resultado de aprendizagem desse módulo: Implementar a lógica de orquestração principal que executa o plano do agente passo a passo. Vamos começar a construir o "maestro" que rege todas as peças que montamos até agora.