Skip to main content

Welcome to a Grasp lesson

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

Lesson 36

Database Migration: Is It Necessary?

Recommended resources

Olá! Seja bem-vindo de volta.

Na lição anterior, estabelecemos como o agente pode analisar um ticket do Jira para criar um plano inicial, identificando os arquivos que precisam ser modificados nos seus repositórios de backend, frontend e mobile. Esse plano é o "mapa" que guiará as próximas ações do agente.

Hoje, vamos aprofundar uma das decisões mais críticas e de alto risco nesse processo de planejamento, que está diretamente ligada ao seu objetivo de ter um agente que também lida com o banco de dados. O nosso foco é o resultado de aprendizagem: Guiar o agente para decidir se uma migração de banco de dados é necessária com base na descrição da tarefa.

Esta não é uma etapa trivial. Uma alteração no esquema do banco de dados (schema) pode ter efeitos em cascata por toda a aplicação. Instruir o agente a tomar essa decisão corretamente é fundamental para sua autonomia e confiabilidade.

1. Da Análise da Tarefa à Decisão sobre o Schema

O agente não "adivinha" que uma migração é necessária. Ele realiza um processo lógico de correlação, comparando as exigências da tarefa com o estado atual do sistema, que ele conhece através do código-fonte.

O processo de pensamento do agente pode ser modelado da seguinte forma:

  1. Análise Semântica da Tarefa: O agente processa a descrição do ticket do Jira, procurando por intenções que impliquem armazenamento de novos dados ou modificação da estrutura de dados existente. Frases como "adicionar um novo campo", "armazenar a preferência do usuário", "alterar o tipo de dado" ou "remover uma propriedade" são gatilhos fortes.
  2. Verificação no Código-Fonte: Ao identificar uma intenção de mudança de dados, o agente consulta sua "memória" — o mapa semântico do código que discutimos na lição anterior. Especificamente, ele irá inspecionar os arquivos que definem o esquema do banco de dados. No seu caso, com um backend em C#/.NET, isso significa analisar os modelos do Entity Framework (as classes POCO - Plain Old CLR Object).
  3. Tomada de Decisão: Se a tarefa exige, por exemplo, o armazenamento do "cargo do usuário" (job title) e o agente verifica que a classe User.cs não possui uma propriedade JobTitle, ele conclui que uma alteração no esquema é necessária.

Este processo destaca a importância de fornecer ao agente um contexto claro e as ferramentas para analisar esse contexto.


2. Especificações Claras: Guiando o Agente com Prompts Estruturados

Para garantir que o agente execute essa análise de forma confiável, não podemos depender de prompts vagos. Precisamos guiá-lo explicitamente. A abordagem de "planejamento orientado por especificações" (specification-driven planning) é ideal aqui.

Spec-Driven Migration Planning with Context-Aware AI Systems

Para aprofundar essa ideia, o artigo 'Spec-Driven Migration Planning with Context-Aware AI Systems' da Augment Code oferece um excelente framework. Ele argumenta que, ao fornecer requisitos estruturados, podemos transformar a complexidade da migração em um plano de execução de baixo risco para um agente de IA.

Leia as seguintes seções para entender como estruturar os requisitos para o agente (aproximadamente 5 minutos): 'Why Writing Everything Down First Actually Works': Entenda o conceito de capturar requisitos em formatos que os sistemas de IA possam processar sistematicamente. 'Write Database Migration Requirements That Cover Everything': Esta é a seção mais importante. Observe o padrão de prompt que define um papel ('Role'), um objetivo ('Goal') e restrições ('Constraints'). Este é um modelo prático para instruirmos nosso agente. 'Incomplete Constraint Discovery' e 'Rollback Procedure Gaps': Estas seções em 'Common Migration Planning Challenges' reforçam por que a análise inicial e a decisão sobre a migração são tão críticas para evitar problemas futuros.

Inspirados por essa abordagem, podemos aprimorar o prompt que usamos para instruir nosso agente Rovo a realizar o planejamento. Além de pedir a lista de arquivos a serem modificados, adicionamos uma seção específica para a análise do banco de dados:

Você é um engenheiro de software sênior de IA. Sua tarefa é analisar o seguinte ticket do Jira e criar um plano de implementação.

... [As instruções da lição anterior sobre identificação de arquivos] ...

5. **Análise de Migração de Banco de Dados**:
   - Analise a descrição da tarefa e compare-a com os modelos de dados existentes no projeto de backend (localizados em `backend-csharp/MyProject.Data/Models`).
   - Determine explicitamente se uma migração de esquema de banco de dados (schema migration) é necessária. Responda com 'Sim' ou 'Não'.
   - Se 'Sim', descreva a mudança necessária em alto nível. Por exemplo: "Adicionar uma coluna 'JobTitle' do tipo string, que pode ser nula, à tabela 'Users'".
   - Justifique sua decisão com base na comparação entre a tarefa e o código existente.

Este prompt direcionado transforma a decisão de uma suposição para um item de ação explícito, forçando o agente a registrar seu raciocínio.


3. O Código como Fonte da Verdade

A decisão do agente depende inteiramente da qualidade do contexto que ele possui. No seu ambiente de desenvolvimento, a fonte da verdade para o esquema do banco de dados é o próprio código do backend.

Using AI Agents to Automate Database Schema Migrations ...

O artigo 'Using AI Agents to Automate Database Schema Migrations' da Kinde detalha como os agentes de IA interagem com uma base de código para entender e gerar migrações. Isso é diretamente aplicável ao nosso cenário.

Leia a seção 'How AI agents understand and generate migration scripts' (aproximadamente 3 minutos). Preste atenção especial às etapas de 'Context gathering' e 'Pattern recognition'. O artigo menciona a análise de 'ORM models' e 'previous migrations', que é exatamente o que nosso agente fará.

Para o seu projeto, o agente focaria em duas áreas principais dentro do repositório backend-csharp:

  • Modelos do Entity Framework (POCOs): Arquivos como User.cs, Product.cs, etc., dentro do seu projeto de dados, são a representação canônica das tabelas do banco de dados. O agente pode ler e analisar a estrutura dessas classes (propriedades, tipos, atributos de anotação de dados) para entender o esquema atual.
  • Pasta Migrations: Em um projeto EF Core, esta pasta contém um histórico de todas as alterações de esquema já aplicadas. Ao analisar os arquivos de migração existentes, o agente pode confirmar o estado exato do banco de dados, incluindo tipos de coluna, restrições e índices.

Quando o agente Rovo for acionado, ele usará seus conectores de conhecimento (que configuraremos em um módulo futuro) para indexar esses arquivos. A instrução no nosso prompt (...analise os modelos de dados...) fará com que ele execute uma busca RAG sobre esse índice para encontrar as definições de modelo relevantes e tomar sua decisão.


Exemplo Prático: O Processo de Pensamento do Agente

Vamos simular como o agente lidaria com um ticket do Jira.

Ticket do Jira:

Título: Adicionar data de nascimento ao perfil do usuário
Descrição: Precisamos coletar e exibir a data de nascimento dos usuários em sua página de perfil para futuras campanhas de aniversário. O campo deve ser opcional.

Cadeia de Pensamento (Chain-of-Thought) do Agente:

  1. Tarefa: Adicionar "data de nascimento" (date of birth) ao perfil do usuário. A informação precisa ser armazenada.
  2. Hipótese: Isso provavelmente exigirá uma alteração no banco de dados.
  3. Verificação: Preciso verificar o modelo User no backend para ver se já existe um campo para data de nascimento.
  4. Ação (Conceitual): Executar uma busca de contexto no meu conhecimento indexado pelo Rovo com a query "definição do modelo de usuário". A busca retorna o conteúdo do arquivo backend-csharp/MyProject.Data/Models/User.cs.
  5. Observação:
    public class User 
    {
        public Guid Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        // ... outras propriedades, mas nenhuma para data de nascimento.
    }
    
  6. Conclusão: O modelo User não tem uma propriedade para DateOfBirth. Portanto, uma alteração no esquema é necessária para adicionar essa coluna.
  7. Resultado para o Plano:
    • requires_migration: Sim.
    • migration_description: "Adicionar uma coluna DateOfBirth do tipo DateTime? (nulável) à tabela Users."
    • justification: "A tarefa requer o armazenamento da data de nascimento do usuário, mas o modelo User existente não possui uma propriedade para armazenar essa informação."

Este resultado se tornará parte do plano de implementação geral, sinalizando que uma etapa de geração de migração será necessária posteriormente.


Conclusão

Nesta lição, você aprendeu a projetar a lógica que permite ao seu agente tomar uma decisão informada e crucial: a necessidade de uma migração de banco de dados. Vimos que isso não é mágica, mas sim um processo metódico de análise e comparação, guiado por instruções precisas.

Principais Pontos:

  • Decisão Baseada em Evidências: O agente decide sobre a necessidade de uma migração comparando a descrição da tarefa com a "verdade" encontrada no código-fonte, especificamente nos modelos ORM.
  • Prompts Estruturados são a Chave: Ao usar uma abordagem orientada por especificações e prompts detalhados, você guia o agente para realizar a análise correta e justificar suas conclusões, aumentando a previsibilidade e a confiabilidade.
  • Contexto é Tudo: A capacidade do agente de tomar essa decisão depende diretamente do seu acesso e compreensão do código relevante, como os modelos do Entity Framework e o histórico de migrações.
  • Planejamento Antes da Execução: A decisão sobre a migração é uma parte crucial da fase de planejamento. O resultado é uma diretiva clara no plano do agente, não a geração imediata do código de migração.

Na Próxima Lição

Com a lista de arquivos a serem alterados e a decisão sobre a migração de banco de dados em mãos, o agente concluiu sua fase de investigação. Agora, precisamos consolidar tudo isso em um formato que possa ser executado.

Na próxima lição, vamos focar em: "Estruturar o plano de saída do agente em um formato legível por máquina (por exemplo, JSON) para execução subsequente". Este plano estruturado será o roteiro final que o agente seguirá para escrever o código, criar a migração e, finalmente, abrir os Pull Requests.