O design de arquitetura de software é um processo de alta alavancagem. As decisões tomadas nas fases iniciais de um projeto ecoam por anos, definindo a velocidade de desenvolvimento, a escalabilidade e a facilidade de manutenção de um sistema. Tradicionalmente, este é um processo deliberado, muitas vezes solitário ou confinado a um pequeno grupo de engenheiros sênior, envolvendo quadros brancos, diagramas e longos documentos de design. Mas e se pudéssemos injetar um acelerador nesse processo? E se pudéssemos ter um parceiro incansável para debater ideias, prototipar conceitos e validar hipóteses em minutos, não em dias?
Recentemente, mergulhei fundo no design da arquitetura para uma nova plataforma de análise de métricas de engenharia. O desafio era complexo: como modelar e processar dados para extrair insights sobre cycle time, bus factor, e eficiência de equipes de desenvolvimento. Para acelerar esse processo, decidi usar um Grande Modelo de Linguagem (LLM) como um verdadeiro co-piloto de arquitetura. Ao longo de 11 sessões de trabalho focado, com uma interação que ultrapassou a marca de 100 milhões de tokens, a IA deixou de ser uma mera ferramenta de autocompletar código para se tornar uma parceira colaborativa no design.
Este artigo compartilha as estratégias e os fluxos de trabalho práticos que descobri para alavancar LLMs, movendo-se além da simples geração de código para uma verdadeira colaboração no design de sistemas complexos.
Do Rascunho ao Modelo: Usando IA para Explorar Alternativas de Design
Todo grande sistema começa com um modelo de dados. Acertar na estrutura fundamental dos dados é crucial. Errar aqui pode levar a refatorações caras e dolorosas no futuro. A fase de exploração inicial é onde a IA brilha, permitindo que você explore múltiplas avenidas de design com um custo muito baixo.
Nosso objetivo era criar um sistema que pudesse responder a perguntas como: "Qual é o cycle time médio para features versus correções de bugs?" ou "Qual é o risco de conhecimento concentrado (bus factor) em nosso serviço de autenticação?".
Em vez de gastar horas desenhando ERDs (Diagramas de Entidade-Relacionamento), iniciei uma conversa com a IA. A chave é fornecer um prompt rico em contexto, agindo menos como um programador e mais como um gerente de produto para a IA.
Exemplo de Prompt Inicial:
Estou projetando o backend para uma plataforma de análise de métricas de engenharia em Python. Preciso modelar os seguintes conceitos:
- Entidades de Trabalho (Work Items): Podem ser 'features', 'bugs', 'chores'. Elas têm um ciclo de vida (ex: 'A Fazer', 'Em Progresso', 'Em Revisão', 'Concluído').
- Desenvolvedores: Pessoas que trabalham nos itens.
- Times (Teams): Agrupamentos de desenvolvedores.
- Repositórios de Código: Onde o trabalho é realizado.
- Eventos: Mudanças de estado em um item de trabalho (ex: 'commit', 'pull request aberto', 'deploy').
O objetivo é calcular métricas como cycle time (tempo de 'Em Progresso' até 'Concluído') e bus factor (quantos desenvolvedores possuem conhecimento crítico sobre um módulo de código).
Proponha três modelos de dados diferentes usando classes Python com
dataclasses. Compare as abordagens em termos de flexibilidade para novas métricas, complexidade de consulta e desempenho de escrita.
A resposta da IA não é um ponto final, mas um ponto de partida. Normalmente, ela oferece algumas alternativas:
- Modelo Normalizado (Relacional): Tabelas separadas para cada entidade, ideal para consistência de dados, mas pode exigir joins complexos.
- Modelo Denormalizado (Documento/NoSQL): Um grande documento por "Item de Trabalho" que contém informações aninhadas sobre desenvolvedores e eventos. Ótimo para leituras rápidas, mas pode ter dados duplicados.
- Modelo Baseado em Eventos (Event Sourcing): Foca em registrar cada evento como um fato imutável. Flexível, mas complexo de consultar o estado atual.
Após escolher uma direção — digamos, um híbrido do modelo relacional para as entidades principais — a iteração começa. Rapidamente, chegamos a uma estrutura inicial sólida.
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import List, Dict, UUID
class WorkItemStatus(Enum):
TODO = "todo"
IN_PROGRESS = "in_progress"
IN_REVIEW = "in_review"
DONE = "done"
@dataclass
class StatusChangeEvent:
status_to: WorkItemStatus
timestamp: datetime
actor_id: UUID
@dataclass
class WorkItem:
id: UUID
title: str
project_id: UUID
current_status: WorkItemStatus
assignee_ids: List[UUID] = field(default_factory=list)
history: List[StatusChangeEvent] = field(default_factory=list)
metadata: Dict[str, str] = field(default_factory=dict)
def change_status(self, new_status: WorkItemStatus, actor_id: UUID):
self.current_status = new_status
self.history.append(
StatusChangeEvent(
status_to=new_status,
timestamp=datetime.utcnow(),
actor_id=actor_id
)
)
Este ciclo de "prompt-resposta-refinamento" permite explorar o espaço de design de forma muito mais ampla e rápida do que o trabalho manual. Em uma única sessão, você pode avaliar as implicações de diferentes modelos que levariam dias para serem desenhados e debatidos por uma equipe.
Validação Rápida de Conceitos com um Parceiro Incansável
Uma ideia no papel é uma coisa; um conceito que sobrevive ao contato com a realidade é outra. Uma das maiores barreiras entre o design e a implementação é a energia de ativação necessária para criar um ambiente de teste ou um protótipo.
É aqui que a IA se torna um acelerador fenomenal. Uma vez que tínhamos um modelo de dados candidato, o próximo passo era validá-lo. As perguntas eram:
- Quão difícil é consultar esses dados para calcular o cycle time?
- A estrutura suporta a geração de eventos para um sistema de streaming?
- Como seria a performance com 1 milhão de eventos?
Em vez de começar a configurar uma infraestrutura complexa, pedi à IA para me ajudar a criar um ambiente de teste descartável.
Exemplo de Prompt para Validação:
Com base na classe
WorkItemem Python, escreva um script que:
- Crie um banco de dados SQLite local chamado
analytics_poc.db.- Defina uma tabela
work_itemsque armazene uma versão serializada (JSON) do objetoWorkItem.- Gere 10.000
WorkItems falsos com históricos de eventos realistas (itens movendo-se de TODO -> IN_PROGRESS -> DONE ao longo de vários dias).- Escreva uma função que leia todos os itens do banco de dados e calcule o cycle time médio para itens concluídos (tempo entre o primeiro timestamp 'IN_PROGRESS' e o timestamp 'DONE').
- Imprima o resultado e o tempo total de execução.
Em questão de segundos, eu tinha um script executável. Isso me permitiu testar a lógica de consulta e identificar gargalos ou complexidades no modelo de dados sem escrever uma única linha de código de infraestrutura.
Podemos levar isso um passo adiante. Muitas vezes, a validação requer a orquestração de múltiplos componentes. A IA é excelente em gerar os comandos de terminal e arquivos de configuração necessários para isso.
Exemplo de Prompt para Infraestrutura:
Gere um arquivo
docker-compose.ymle os comandosbashnecessários para iniciar um contêiner PostgreSQL e um serviço simples em Python que se conecta a ele. O serviço Python deve usar a bibliotecapsycopg2e apenas verificar se a conexão foi bem-sucedida. Inclua variáveis de ambiente para as credenciais do banco de dados.
# Comando para iniciar os serviços em segundo plano
docker-compose up -d
# Verificar os logs do serviço de aplicação para confirmar a conexão
docker-compose logs -f app-service
# Parar e remover os contêineres quando o teste terminar
docker-compose down
Essa capacidade de gerar instantaneamente scripts de teste, configurações de infraestrutura e comandos de validação reduz drasticamente o atrito para testar uma ideia arquitetural. Isso incentiva a experimentação e leva a decisões mais robustas e testadas.
Da Arquitetura ao Código Base: Acelerando a Implementação
Com um modelo de dados validado, o próximo passo é traduzir a arquitetura em um código base bem estruturado. É aqui que a capacidade da IA de entender o contexto do código existente se torna um superpoder.
Em vez de apenas pedir para "criar uma API", o truque é alimentar a IA com os padrões e abstrações já existentes no seu projeto. Isso garante que o código gerado seja consistente e se integre perfeitamente.
Exemplo de Prompt para Implementação Contextual:
Estou trabalhando em um projeto TypeScript com NestJS. Já temos um padrão de repositório genérico definido no arquivo
base.repository.ts(conteúdo abaixo). Com base no modeloContentViewEvent(definição abaixo), gere a classeContentViewRepositoryque estende nossoBaseRepositorye implementa um método específico:findUniqueViewsByContentId(contentId: string): Promise<number>. A lógica deve contar visualizações únicas com base emviewerId.Conteúdo de
base.repository.ts:// ... (código do repositório base aqui) export abstract class BaseRepository<T> { ... }Definição de
ContentViewEvent:interface ContentViewEvent { id: string; contentId: string; viewerId: string; // Pode ser um fingerprint de IP + user agent timestamp: Date; }
A IA não apenas gerará o código, mas o fará seguindo os padrões que você forneceu, economizando tempo não apenas na escrita, mas também na revisão e refatoração posteriores para adequação ao padrão.
import { Injectable } from '@nestjs/common';
import { BaseRepository } from './base.repository';
import { ContentViewEvent } from '../models/content-view.model';
import { DatabaseService } from '../services/database.service';
@Injectable()
export class ContentViewRepository extends BaseRepository<ContentViewEvent> {
constructor(dbService: DatabaseService) {
super(dbService, 'content_views');
}
/**
* Calcula o número de visualizadores únicos para um determinado conteúdo.
* @param contentId O ID do conteúdo.
* @returns Uma promessa que resolve para o número de visualizadores únicos.
*/
async findUniqueViewsByContentId(contentId: string): Promise<number> {
const result = await this.collection.distinct('viewerId', {
contentId: contentId
});
return result.length;
}
}
Essa abordagem transforma a implementação inicial de um exercício de digitação em um exercício de direção estratégica. Você define a estrutura, e a IA preenche os detalhes, seguindo suas regras.
Dicas Práticas para uma Colaboração Eficaz
Trabalhar com LLMs em tarefas complexas é uma habilidade. Aqui estão algumas lições aprendidas:
- Seja um Gerente de Produto, Não um Ditador: Forneça contexto, objetivos e restrições claras. Em vez de "Crie uma API", diga "Crie um endpoint RESTful em FastAPI que aceite um
WorkIteme o salve em um banco de dados PostgreSQL, retornando o objeto criado com um ID." - Pense em Sessões, Não em Perguntas: O verdadeiro poder emerge de uma conversa contínua. Mantenha o chat aberto e refine iterativamente a solução. Cada pergunta se baseia no contexto anterior, permitindo que você mergulhe mais fundo no problema.
- Forneça Contexto Relevante (Code-as-Context): Sempre que possível, cole trechos de código existentes, esquemas de banco de dados ou mensagens de erro no seu prompt. Quanto mais contexto a IA tiver, mais relevante e preciso será o resultado.
- Verifique, Não Confie Cegamente: A IA é uma ferramenta poderosa, mas não infalível. Sempre revise o código e a lógica gerados. Use-a para criar a primeira versão (o "primeiro rascunho"), que você então, como especialista, refina e valida.
Conclusão: O Arquiteto Aumentado
Após 11 sessões e dezenas de milhões de tokens, a lição mais clara é que os LLMs estão fundamentalmente mudando o ciclo de vida do desenvolvimento de software. Eles não estão substituindo o arquiteto ou o desenvolvedor sênior; eles estão os aumentando, criando um novo fluxo de trabalho que pode ser descrito como design de arquitetura conversacional.
Ao usar a IA como uma parceira para explorar modelos de dados, validar conceitos com protótipos descartáveis e acelerar a implementação da estrutura fundamental, podemos tomar decisões mais bem informadas e mais rápidas. Reduzimos o custo da experimentação, o que nos encoraja a explorar mais opções e, finalmente, a construir sistemas melhores.
O futuro não é sobre a IA escrevendo todo o código, mas sobre uma simbiose onde a criatividade e a visão estratégica do engenheiro são amplificadas pela velocidade e capacidade de processamento da máquina. Estamos apenas arranhando a superfície do que é possível, e aprender a colaborar efetivamente com esses novos parceiros digitais será uma das habilidades mais importantes para os desenvolvedores na próxima década.
Top comments (0)