Alura > Cursos de Inteligência Artificial > Cursos de Engenharia de LLMs & Agentes > Conteúdos de Engenharia de LLMs & Agentes > Primeiras aulas do curso Spec-Driven Development: desenvolvimento assistido por agentes

Spec-Driven Development: desenvolvimento assistido por agentes

Fundamentos do Spec-Driven Development - Apresentação

Apresentando o curso

Boas-vindas a mais um curso da Alura! Neste curso, vamos estudar o Spec-Driven Development (desenvolvimento orientado por especificação).

Vamos olhar para o tema com o olhar de quem desenvolve: como usamos as ferramentas de LLM para nos ajudar a desenvolver software. As empresas já pedem isso há algum tempo e querem que usemos mais os LLMs no dia a dia para gerar código. Aqui, vamos colocar um pouco de estrutura nesse desenvolvimento.

Escolhendo a ferramenta

Estamos com o Claude aberto, mas é possível seguir o curso com o Claude, o Gemini, o Codex, o Llama ou a ferramenta que preferir: qualquer LLM funciona hoje. Neste curso, vamos seguir com o Claude.

Estruturando o desenvolvimento com especificações

Nosso processo de desenvolvimento não vai ser só pedir para o LLM fazer o código ou uma feature (funcionalidade) de maneira desorganizada e aleatória. Vamos entender o que precisamos fazer para que o LLM não perca tanto o contexto, não se perca na tarefa e entenda com clareza o que tem que ser feito. Também vamos discutir os problemas e as diferenças entre escrever código diretamente e pedir para um LLM fazer, escrevendo em linguagem natural.

Para isso, vamos partir de um projeto que já existe: um e-commerce. Escolhemos um domínio muito comum, que entendemos intuitivamente mesmo sem ter trabalhado na área, e nele vamos implementar o nosso Spec-Driven.

Documentando e testando o sistema

Vamos ter a documentação da arquitetura do sistema, a forma de registrar as regras de negócio e de descrever um módulo, o que é de fato uma especificação, como a fazemos, de onde a tiramos e por que a fazemos dessa maneira. Com esses documentos, ao final, teremos o sistema implementado.

No nosso caso, vamos implementar o cancelamento de pedido, e precisamos testar isso também. Para isso, temos uma rotina de testes no Postman e, no código, testes que garantem que o que pedimos foi feito da maneira correta.

Mas quem escreveu esse código, tanto o de teste quanto o de implementação, foi o LLM. Qual problema podemos ter com isso? É uma discussão muito aberta, em uma área que está mudando bastante, mas super interessante para o dia a dia de quem desenvolve. Vamos estudar!

Fundamentos do Spec-Driven Development - Conhecendo o projeto da API

Partindo de um projeto existente

Vamos começar nosso curso de Spec-Driven Development. Estamos com o projeto do curso, com o código que já temos feito. Vamos começar em um projeto já iniciado para adicionar o Spec-Driven, um caso muito mais real e parecido com o que a maioria de vocês deve estar vivendo: vocês já têm uma base de código e dificilmente vão começar em um Greenfield (projeto do zero), que pode ser feito do jeito que quiser.

Temos um código já preparado, com algumas rotas. É uma API REST, um back-end, rodando no Docker. Com o Docker aberto, temos três containers separados rodando:

Conhecendo a coleção do Postman

Também fizemos alguns testes e temos o Postman com toda a documentação: as rotas de health check (verificação de saúde), registro de pessoa usuária nova, registro de pessoa usuária duplicada, lista de produtos e assim por diante. Tudo isso está organizado para rodarmos.

Vamos começar o Spec-Driven Development neste projeto com a ferramenta do Claude, que também está aberta. Temos a API de e-commerce, estamos trabalhando na main, e vamos usar o Claude como nosso agente de IA para executar o Spec-Driven.

Fazendo alguns avisos

Antes de começar, precisamos fazer alguns avisos. Tudo o que vamos falar neste curso ainda está muito em discussão. Não há um ponto final nem um consenso geral sobre a melhor maneira de fazer ou sobre a relevância disso. O tema está muito em alta com as IAs, mas como vai ser o futuro daqui a alguns anos? O que vai mudar e o que não vai? Na velocidade em que as coisas estão indo, isso pode mudar em alguns meses.

Por isso, tudo o que vamos passar neste curso é uma discussão ampla: ideias de como implementar o Spec-Driven e discussões importantes para levar ao seu dia a dia, quando estiver mexendo em uma base de código com ele. Muita coisa pode mudar nos próximos meses, nos próximos semestres ou no ano que vem, porque a tecnologia está evoluindo muito rápido.

Entendendo o papel do harness

A evolução acontece nas IAs e também nas ferramentas. Cada modelo novo traz novas capacidades, e cada versão nova de harness também. O próprio Claude Code é um harness, ou seja, uma ferramenta que fica em volta do LLM. O LLM é uma parte e o harness é outra, que traz habilidades e features diferentes para usarmos, como as próprias skills, os workflows e a maneira de navegar e fazer o scaffold (criação da estrutura) nas pastas. Isso não é feito necessariamente pelo LLM, e sim pelo harness. Por isso, conforme o harness for atualizado, teremos novas features e vantagens.

Conhecendo os módulos da API

Neste curso, vamos usar este projeto de API de e-commerce. Temos os módulos de autorização, carrinho, categorias, pedidos, pagamento, produto e, como temos autorização, usuários. Vamos trabalhar com esses módulos usando Spec-Driven: partindo de uma base de código já iniciada, como trazemos o Spec-Driven para esse projeto?

Fundamentos do Spec-Driven Development - Definindo a fonte da verdade

Contextualizando o projeto e o Spec-Driven Development

Como comentamos, temos o projeto da nossa API. Vamos pegar esse projeto, que já tem código, e tratá-lo como um projeto em que, a partir de agora, vamos usar o Spec-Driven Development (desenvolvimento orientado por especificação). Para isso, vamos entender melhor o que isso significa e quais são algumas possibilidades e metodologias.

De novo, tudo o que vamos falar aqui pode mudar. O tema ainda está sendo muito discutido e não há um consenso geral sobre como abordar essa maneira de desenvolver software, que é muito nova.

Comparando código e especificação como fonte da verdade

Entre as metodologias, podemos começar pelo código como fonte da verdade, o code as source. É como trabalhávamos antes da IA, antes dos agentes de LLM, antes de conseguirmos gerar código com nossos assistentes. É a maneira como sempre trabalhamos: escrevemos o código, o código dita as regras, é ele que está em produção e é ele a fonte da verdade.

Isso está mudando. Com os LLMs e as IAs, agora temos uma especificação. Fazemos uma documentação que descreve e especifica (por isso falamos em spec) o que queremos: quais features (funcionalidades), quais módulos, quais são as regras de negócio e como cada funcionalidade tem que funcionar. A especificação vira a fonte da verdade, uma vez que o LLM consegue pegar a especificação e transformá-la em código.

No mundo ideal, geramos uma especificação bem organizada, com todos os detalhes, e o assistente lê e gera o código exatamente como queremos, cumprindo todas as regras da especificação. Saímos do código como fonte da verdade, com a pessoa mexendo direto no código, para a especificação como fonte da verdade, com a pessoa mexendo só na especificação. Quando conseguirmos ter isso bem estruturado, uma das possibilidades é não mexermos mais em código: quem lida com 100% do código é o assistente, o LLM.

Apresentando a ancoragem na especificação

No mundo real, o que mais deve acontecer hoje, principalmente para quem é dev, é algo no meio. O código é a fonte da verdade, mas a especificação ainda dita bastante coisa. É aí que podemos falar de spec anchor, o ancorado na especificação.

Se pensarmos bem, isso não é necessariamente novo. Para escrever código, quando íamos começar uma feature, havia uma pessoa PM que vinha falar conosco sobre o que deveria ser feito, uma pessoa PO que definia a sprint e com quem tirávamos dúvidas, e uma pessoa BA fazendo análise de negócio e montando as regras. Havia uma série de estruturas ao redor do time de TI que nos davam as regras. Obviamente, algumas regras descobríamos que precisavam ser definidas durante o desenvolvimento, mas tínhamos uma boa infraestrutura para criar documentações sobre as regras de negócio, e então codávamos enquanto equipe de TI.

O spec anchor é mais ou menos isso. A especificação fica junto do código e é usada para evoluir o sistema, sendo mantida junto com ele, mas isso não nos impede de colocar a mão no código e alterar o que for necessário. Temos, então, os extremos e o meio:

Definindo especificação segundo Martin Fowler

Antes de falar desses motivos, vamos pensar no que estamos chamando de especificação. Vamos usar a definição de Martin Fowler, que tem um blog bem conhecido. Ele tem um artigo sobre Spec-Driven com vários questionamentos interessantes e, quando tenta definir o que é uma especificação, diz que ela é uma estrutura, um artefato orientado a comportamento, ou um conjunto de artefatos (não precisa ser um documento só), escrito em linguagem natural, que expressa a funcionalidade e serve de guia para os agentes de código baseados em IA.

Ou seja, quando falarmos de especificação, não vamos falar em linguagem de código, e sim em linguagem natural. É essa definição de Martin Fowler que vamos usar quando falarmos de spec. Antes da IA, já existiam muitas metodologias para gerar documentação: especificação técnica, funcional e não funcional, análise de requisitos. Quando falamos de spec, estamos falando de um documento que vai servir principalmente de guia para o nosso agente de IA.

Ele continua dizendo que existem variantes: cada variante de desenvolvimento baseado em especificação define sua própria abordagem para essa estrutura. É o que comentamos: ainda não há um senso comum bem definido, uma boa prática que todo mundo siga do mesmo jeito. Há várias metodologias e abordagens de Spec-Driven, e cada uma define o nível de detalhe, como os artefatos são organizados no projeto e a própria estrutura dos artefatos. É uma definição ampla, mas, basicamente, quando falarmos de spec, estamos falando de qualquer documento que guia o nosso agente de código, escrito em linguagem natural, que descreve a funcionalidade do software.

Organizando o que o agente leva em conta

No nosso dia a dia, teremos o assistente de IA no meio, e ele precisa levar em consideração algumas coisas, os artefatos, na hora de fazer o código, assim como nós levamos quando escrevemos código. Podemos dividir essas coisas em algumas categorias:

As regras podem ser, por exemplo, que vamos usar só uma determinada stack de tecnologia: TypeScript com React, Jest para os testes, tudo rodando em Docker no back-end e um banco de dados MySQL. Essas são as políticas, as regras. A arquitetura define como essas coisas se comportam e se comunicam: é a arquitetura do software. As necessidades de negócio são as regras gerais. Para criar qualquer feature, temos que levar isso em consideração.

Regras, necessidades e arquitetura são mais fixas e não mudam com tanta frequência. Em cima delas, temos a especificação, o documento que descreve uma feature específica, um módulo específico, uma área detalhada do projeto, com um nível maior de detalhe. A partir dela, o agente gera o nosso código, que pode ser tanto código de teste quanto código de produção. O assistente de IA, representado no meio, tem que levar tudo isso em consideração para gerar o código, porque o que queremos é o sistema funcionando. Esse agente parte da especificação e gera código.

Separando memory bank e skills

As outras partes (necessidades de negócio, arquitetura, políticas ou regras) vamos colocar no que hoje tem se chamado de memory bank (banco de memória), que é basicamente o que fica do lado do harness: do lado do Claude, do Gemini ou do Codex que estivermos usando. Também são documentos, mas, diferente da especificação, que descreve a funcionalidade do software, eles descrevem a arquitetura, uma regra maior, e limitam um pouco o que o agente vai fazer. São decisões tomadas antes da própria especificação, que ficam guardadas nesse memory bank, do lado do harness.

Também temos as skills. Se temos um processo padrão para fazer um PR, podemos ter uma skill para isso. Se temos um processo padrão, um template de como a feature tem que ser descrita para a especificação sair certinha, podemos ter uma skill para isso. A arquitetura do sistema e as limitações de arquitetura que queremos ter podem ficar no documento. Teremos mais ou menos essa separação de conceitos enquanto desenvolvemos.

No memory bank, teremos:

Mas cada pessoa e cada abordagem de Spec-Driven Development pode variar isso, adicionando ou retirando coisas do memory bank, essa caixinha de acessórios e artefatos que o agente vai consultar de tempos em tempos.

Lidando com os problemas do desenvolvimento com IA

Também teremos que lidar com problemas. No desenvolvimento de software direto no código, já tínhamos problemas conhecidos, porque há muitos anos se desenvolve assim: transferência de informação entre equipes, desacoplamento, conhecimento de negócio concentrado em uma pessoa ou em um time, o que dificulta a manutenção porque o conhecimento não está disseminado pela equipe.

Com o LLM, teremos outros problemas. Ele pode ter uma janela de contexto pequena. Apesar de a janela de contexto ter ficado maior com os novos modelos, ela ainda pode ser insuficiente para o tamanho do código ou da feature que estamos descrevendo.

Além disso, as regras de negócio podem ser mal interpretadas. Como escrevemos em linguagem natural (em português, no nosso caso, mas vale para qualquer língua natural), há ambiguidade e a possibilidade de descrevermos algo que será mal interpretado. A sintaxe de uma linguagem de programação é muito diferente do jeito que falamos e escrevemos em linguagem natural, e é aí que muita gente trava ao aprender programação: a sintaxe do código, seja JavaScript, C# ou qualquer outra linguagem, é muito estrita, feita para tirar a ambiguidade. Já a linguagem humana é cheia de ambiguidade e de possibilidades de interpretação, não é tão exata. Por isso, há uma discussão interessante sobre como e o que descrever para não sermos mal interpretados pelo agente.

O Dave Farley, engenheiro de software que, se não nos enganamos, também assinou o Manifesto Ágil, tem um canal no YouTube sobre engenharia de software. Ele tem um vídeo, de um ano ou um ano e meio atrás, que fala dessa diferença entre linguagem de programação e linguagem natural. Vale muito assistir.

Tratando conflitos e conhecimento implícito

Na forma como escrevemos nossos documentos, artefatos e especificações, também podemos ter regras conflitantes. Se o sistema for grande demais, podemos ter módulos com regras conflitantes: em um lugar a especificação diz uma coisa e, em outro, diz outra. Como resolvemos conflitos nesse caso? Como damos contexto suficiente para o agente entender se é um conflito de fato ou se há uma separação implícita que nós, que conhecemos o negócio e o sistema, sabemos que não é conflitante? Ou, se realmente há um conflito, como lidamos com ele?

Às vezes também deixamos coisas implícitas e não falamos tudo o que o agente precisa. Quando trabalhamos em equipe, temos um conhecimento comum que facilita a comunicação. O jargão técnico de qualquer área faz isso: uma palavra significa algo muito maior e acelera a comunicação. Muitas vezes esquecemos de passar esse conhecimento implícito para a IA, que não o tem. Por isso, precisamos ser muito mais rigorosos ao escrever a especificação.

Vamos ter que lidar com esses problemas, e há várias abordagens diferentes para fazer Spec-Driven. Agora, vamos olhar para a nossa base e pensar no primeiro passo para transformar uma base de código que já existe em algo Spec-Driven e conseguir desenvolver uma feature nela.

Sobre o curso Spec-Driven Development: desenvolvimento assistido por agentes

O curso Spec-Driven Development: desenvolvimento assistido por agentes possui 166 minutos de vídeos, em um total de 44 atividades. Gostou? Conheça nossos outros cursos de Engenharia de LLMs & Agentes em Inteligência Artificial, ou leia nossos artigos de Inteligência Artificial.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Engenharia de LLMs & Agentes acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas