Blog

  • Construindo um aplicativo de bate-papo de IA simples com Spring AI e Angular

    Construindo um aplicativo de bate-papo de IA simples com Spring AI e Angular

    Neste tutorial, criaremos um aplicativo de bate-papo simples com IA usando Spring AI no backend e Angular no frontend. Este é um ótimo ponto de partida para quem busca integrar recursos de IA em seus aplicativos web.

    O que construiremos

    Criaremos uma interface de bate-papo simples onde os usuários podem:

    • Enviar mensagens para um assistente de IA
    • Receba respostas inteligentes fornecidas pela Gemini

    espaço reservado

    A aplicação consistirá em:

    • Um backend Spring Boot com integração Spring AI
    • Um frontend Angular com uma interface de chat responsiva
    • Comunicação em tempo real entre frontend e backend

    Pré-requisitos

    Antes de começar, certifique-se de ter:

    • Java 21 ou superior
    • Node.js e npm
    • CLI Angular ( npm install -g @angular/cli)
    • Um ID de Projeto Gemini (veja como criar um aqui Gemini )
    • Seu IDE favorito (usarei VS Code e IntelliJ )

    💡 Ganhe 3 meses grátis do IntelliJ Ultimate com o cupom: LoianeGroner.

    Estrutura do Projeto

    Veja como nosso projeto está organizado:

    spring-ai-angular/
    ├── api-ai/                          # Spring Boot backend
    │   └── src/main/java/com/loiane/api_ai/
    │       └── chat/
    │           ├── SimpleChatService.java
    │           ├── ChatController.java
    │           └── ChatResponse.java
    └── angular-ai/                      # Angular frontend
        └── src/app/
            └── chat/
                ├── chat-service.ts
                ├── chat-response.ts
                └── simple-chat/
                    ├── simple-chat.ts
                    ├── simple-chat.html
                    └── simple-chat.scss
    

    Criaremos um projeto Spring Boot e um projeto Angular CLI e colocaremos ambos na pasta spring-ai-angular

    Configurando o Spring AI Backend

    Crie um novo projeto Spring Boot usando o Spring Initializr ou seu IDE.

    Seleções:

    • Projeto: Maven
    • Linguagem: Java
    • Spring Boot: 3.5.3 (selecione a versão mais recente)
    • Insira os metadados do seu projeto (nome do pacote, nome do artefato) conforme desejado
    • Java: 24 (ou mais recente disponível)

    Dependências:

    • Spring Web: Para criar endpoints REST.
    • Vertex AI Gemini: Para integração com os modelos de linguagem do Google.

    Ou selecione a dependência de IA de sua preferência.

    Verifique o arquivo pom.xml

    Certifique-se pom.xmlde incluir as dependências necessárias para a integração do Google Gemini:

    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-vertex-ai-gemini-spring-boot-starter</artifactId>
      </dependency>
    </dependencies>
    

    A dependência spring-ai-vertex-ai-gemini-spring-boot-starterfornece os componentes necessários e a autoconfiguração para usar a API do Gemini em um aplicativo Spring Boot, semelhante ao que spring-ai-openai-spring-boot-starteré fornecido pelo OpenAI.

    Etapa 1: Configure seu ambiente

    Ao usar a IA do Google em um projeto Spring AI, precisamos configurar duas propriedades no application.propertiesarquivo (ou yaml):

    spring.ai.vertex.ai.gemini.projectId=${GEMINI_PROJECT_ID}
    spring.ai.vertex.ai.gemini.location=us-east4
    

    Embora o ID do projeto possa ser compartilhado, é uma boa prática também passar esse valor como uma variável de ambiente caso você esteja usando projetos diferentes para ambientes diferentes (DEV, QA, PROD).

    Etapa 2: Crie o serviço de bate-papo

    Vamos criar nosso SimpleChatServiceque lida com as interações da IA:

    // filepath: api-ai/src/main/java/com/loiane/api_ai/chat/SimpleChatService.java
    package com.loiane.api_ai.chat;
    
    import org.springframework.ai.chat.client.ChatClient;
    import org.springframework.stereotype.Service;
    
    @Service
    public class SimpleChatService {
    
        private final ChatClient chatClient;
    
        public SimpleChatService(ChatClient.Builder chatClientBuilder) {
            this.chatClient = chatClientBuilder.build();
        }
    
        public String chat(String message) {
            return chatClient.prompt()
                    .user(message)
                    .call()
                    .content();
        }
    }
    

    Onde:

    • Oferece ChatClientuma API para comunicação com um modelo de IA. Suporta modelos de programação síncrona e de streaming.
    • ChatClienté criado usando um ChatClient.Builderobjeto. Você pode obter uma instância autoconfigurada ChatClient.Builderpara qualquer configuração automática do ChatModel Spring Boot ou criar uma programaticamente.
    • chat methodrecebe um message. Usaremos o Promptobjeto do ChatCliente definiremos a entrada do usuário, passando a mensagem recebida. O call()método envia uma solicitação ao modelo de IA e content()retorna a resposta do modelo de IA como uma String.

    E o que está acontecendo aqui?

    • Estamos usando o Spring AI ChatClientpara interagir com o OpenAI.
    • O serviço é anotado @Servicepara injeção de dependência.
    • chatmétodo recebe uma mensagem do usuário e retorna a resposta da IA.

    Etapa 3: Crie o controlador REST

    Agora vamos criar o controlador que expõe nossa funcionalidade de bate-papo:

    // filepath: api-ai/src/main/java/com/loiane/api_ai/chat/ChatController.java
    package com.loiane.api_ai.chat;
    
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/api/chat")
    public class ChatController {
    
        private final SimpleChatService chatService;
    
        public ChatController(SimpleChatService chatService) {
            this.chatService = chatService;
        }
    
        @PostMapping
        public ChatResponse chat(@RequestBody String message) {
            return new ChatResponse(this.simpleChatService.chat(message));
        }
    }
    

    Pontos principais:

    • Estamos usando injeção de construtor para a dependência de serviço como prática recomendada (e não a @Autowiredanotação).
    • Este controlador manipula solicitações POST para o /api/chatendpoint, extraindo a mensagem do corpo da solicitação.

    ChatResponseé um recordpara que possamos formatar a saída:

    public record ChatResponse(String message) {}
    

    Etapa 4: Teste via solicitação HTTP

    Se você estiver usando o IntelliJ IDEA Ultimate , poderá criar um arquivo api.httpcom o seguinte conteúdo (isso é muito conveniente para testes de solicitações HTTP):

    POST http://localhost:8080/api/chat
    Content-Type: application/json
    
    {
        "message": "Tell me a joke"
    }
    

    Como alternativa, você também pode usar o PostMan ou ferramentas semelhantes para simular a solicitação HTTP.

    Se enviarmos a solicitação, poderemos obter algo como a seguinte saída:

    {
      "message": "Why don't scientists trust atoms? \n\nBecause they make up everything! \n \nLet me know if you'd like to hear another one! 😄  \n"
    }
    

    Criando o Frontend Angular

    Gere um novo projeto Angular usando Angular CLI:

    ng new angular-ai --routing
    

    Etapa 1: adicionar material angular ao projeto

    Antes de começar a adicionar componentes e serviços, vamos instalar o Angular Material como nossa biblioteca de componentes:

    ng add @angular/material
    

    Siga as instruções selecionando seu tema preferido (estou usando Azure and Blue) e se você gostaria de adicionar a tipografia.

    Todas as etapas também estão documentadas aqui: https://material.angular.dev/guide/getting-started

    Etapa 2: Crie o serviço de bate-papo

    Primeiro, vamos criar um serviço para lidar com a comunicação da API:

    ng generate service chat/chat-service
    

    Observe que, desde o Angular v20, a convenção de nomenclatura mudou e, em vez de um arquivo chat-service.ts, não estamos sufixando o servicenome com um hiffen.

    // filepath: angular-ai/src/app/chat/chat-service.ts
    import { HttpClient } from '@angular/common/http';
    import { inject, Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { ChatResponse } from './chat-response';
    
    @Injectable({
      providedIn: 'root'
    })
    export class ChatService {
    
      private readonly API = '/api/chat';
      private readonly http = inject(HttpClient);
    
      sendChatMessage(message: string): Observable<ChatResponse> {
        return this.http.post<ChatResponse>(this.API, { message });
      }
    }
    

    O que está acontecendo aqui?

    • private readonly API = '/api/chat': Definimos uma constante para o ponto de extremidade da nossa API. O uso readonlygarante que esse valor não possa ser alterado após a inicialização, o que é uma boa prática para valores de configuração.
    • private readonly http = inject(HttpClient): Esta é a sintaxe moderna de injeção de dependência do Angular usando a inject()função. É uma alternativa à injeção de construtor e é particularmente útil em serviços. A função HttpClienté injetada para lidar com solicitações HTTP.
    • sendChatMessage(message: string): Observable<ChatResponse>: Este método recebe uma mensagem do usuário como parâmetro de string e retorna um Observable<ChatResponse>. O Observable nos permite lidar com respostas HTTP assíncronas de forma reativa.
    • return this.http.post<ChatResponse>(this.API, { message }): Fazemos uma solicitação POST para o nosso backend Spring Boot. O tipo <ChatResponse>informa ao TypeScript qual tipo de resposta esperar. O segundo parâmetro { message }cria um objeto JSON com a mensagem do usuário que corresponde ao que o nosso controlador Spring Boot espera.

    Pontos principais:

    • Estamos usando inject()a função moderna do Angular para injeção de dependência em vez de injeção de construtor.
    • O serviço gerencia a comunicação HTTP com nosso backend Spring Boot.
    • O método retorna um Observable, pois, neste momento, httpResourcenão é recomendado para requisições POST, então continuamos usando HttpClient.
    • { message }sintaxe cria uma carga JSON que nosso Spring Boot @RequestBodypode desserializar.

    Em seguida, vamos criar a ChatResponseinterface que corresponde ao ChatResponseregistro. Use o seguinte comando para criar o arquivo:

    ng generate interface chat/chat-response
    

    Com o seguinte conteúdo:

    // filepath: angular-ai/src/app/chat/chat-response.ts
    export interface ChatMessage {
      message: string;
    }
    

    Etapa 3: gerar o componente de bate-papo

    Vamos criar nosso componente de bate-papo simples:

    ng generate component chat/simple-chat
    

    Confira o novo estilo Angular v2025+: https://angular.dev/style-guide . Observe que o nome não é mais simple-chat.componentts, mas simple-chat.tssim uma convenção de nomenclatura mais clara!

    Agora vamos implementar nosso componente de bate-papo:

    // filepath: angular-ai/src/app/chat/simple-chat/simple-chat.ts
    import { Component, effect, ElementRef, inject, signal, viewChild } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { MatButtonModule } from '@angular/material/button';
    import { MatCardModule } from '@angular/material/card';
    import { MatIconModule } from '@angular/material/icon';
    import { MatInputModule } from '@angular/material/input';
    import { MatToolbar } from '@angular/material/toolbar';
    import { catchError, of } from 'rxjs';
    import { ChatResponse } from '../chat-response';
    import { ChatService } from '../chat-service';
    
    @Component({
      selector: 'app-simple-chat',
      imports: [MatCardModule, MatInputModule, MatButtonModule, FormsModule, MatToolbar, MatIconModule],
      templateUrl: './simple-chat.html',
      styleUrl: './simple-chat.scss'
    })
    export class SimpleChat {
    
      private readonly chatHistory = viewChild.required<ElementRef>('chatHistory');
      private readonly chatService = inject(ChatService);
      private readonly local = true;
    
      userInput = '';
      isLoading = false;
    
      messages = signal<ChatResponse[]>([
        { message: 'Hello, how can I help you today?', isBot: true },
      ]);
    
      // Effect to auto-scroll when messages change
      private readonly autoScrollEffect = effect(() => {
        this.messages(); // Read the signal to track changes
        setTimeout(() => this.scrollToBottom(), 0); // Use setTimeout to ensure DOM is updated
      });
    
      sendMessage(): void {
        this.trimUserMessage();
        if (this.userInput !== '' && !this.isLoading) {
          this.updateMessages(this.userInput);
          this.isLoading = true;
          if (this.local) {
            this.simulateResponse();
          } else {
            this.sendChatMessage();
          }
        }
      }
    
      private trimUserMessage() {
        this.userInput = this.userInput.trim();
      }
    
      private updateMessages(message: string, isBot = false) {
        this.messages.update(messages => [...messages, { message, isBot }]);
      }
    
      private getResponse() {
        setTimeout(() => {
          const response = 'This is a simulated response from the AI model.';
          this.updateMessages(response, true);
          this.isLoading = false;
        }, 2000);
      }
    
      private simulateResponse() {
        this.getResponse();
        this.userInput = '';
      }
    
      private scrollToBottom(): void {
        try {
          const chatElement = this.chatHistory();
          if (chatElement?.nativeElement) {
            chatElement.nativeElement.scrollTop = chatElement.nativeElement.scrollHeight;
          }
        } catch (err) {
          console.error('Failed to scroll chat history:', err);
        }
      }
    
      private sendChatMessage() {
        this.chatService.sendChatMessage(this.userInput)
        .pipe(
          catchError(() => {
            this.updateMessages('Sorry, I am unable to process your request at the moment.', true);
            this.isLoading = false;
            return of();
          })
        )
        .subscribe((response: ChatResponse) => {
          if (response) {
            this.updateMessages(response.message, true);
          }
          this.userInput = '';
          this.isLoading = false;
        });
      }
    }
    

    O que está acontecendo aqui?

    • private readonly chatHistory = viewChild.required<ElementRef>('chatHistory'): Isso usa o sinal moderno do Angular viewChildpara obter uma referência ao elemento DOM do histórico de bate-papo. O requiredmétodo garante que o elemento exista, e usaremos essa referência para a funcionalidade de rolagem automática.
    • private readonly chatService = inject(ChatService): Estamos injetando nosso serviço de chat usando inject()a função moderna do Angular em vez da injeção de construtor. Esta é a abordagem recomendada em aplicações Angular modernas.
    • private readonly local = true: Este é um sinalizador de alternância que nos permite alternar entre o modo de simulação local (para testes) e chamadas de API reais. Quando true, simula respostas; quando false, chama o backend real do Spring Boot.
    • messages = signal<ChatResponse[]>([...]): Estamos usando sinais do Angular para gerenciar o estado das nossas mensagens de bate-papo. Os sinais são a nova primitiva reativa do Angular que rastreia alterações automaticamente e atualiza a interface do usuário com eficiência. Inicializamos isso com uma mensagem de boas-vindas do bot.
    • private readonly autoScrollEffect = effect(() => {...}): Isso cria um efeito que rola automaticamente para o final do chat sempre que novas mensagens são adicionadas. Os efeitos no Angular são executados sempre que suas dependências (neste caso, o messagessinal) mudam. Este é um dos meus casos de uso favoritos effectsem vez de console.log.
    • sendMessage(): Este é o método principal que lida com o envio de mensagens. Ele valida a entrada, adiciona a mensagem do usuário ao chat e simula uma resposta ou chama a API real com base no localsinalizador.
    • private updateMessages(message: string, isBot = false): Um método utilitário que atualiza o sinal de mensagens criando uma nova matriz com a mensagem adicional. O isBotparâmetro determina se a mensagem é do usuário ou do assistente de IA.
    • private sendChatMessage(): Este método manipula a solicitação HTTP real para o nosso backend Spring Boot. Ele usa operadores RxJS como catchErrorpara lidar com erros de forma elegante e subscribeprocessar a resposta.

    Principais conceitos angulares utilizados:

    • Sinais : Para gerenciamento de estado reativo ( messagessinal).
    • Efeitos : Para efeitos colaterais automáticos, como rolagem ( autoScrollEffect).
    • ViewChild : Para referências de elementos DOM ( chatHistory).
    • Injeção de dependência moderna : usando inject()função.
    • Componentes autônomos : não há necessidade de declarações NgModule.
    • RxJS : Para manipular operações HTTP assíncronas para a chamada POST para a API Spring.

    Este componente demonstra padrões Angular modernos e fornece uma interface de bate-papo limpa e reativa que pode funcionar tanto no modo de simulação para testes quanto com o backend real do Spring Boot.

    Etapa 4: Crie o modelo de bate-papo

    Aqui está o HTML que se conecta ao nosso componente:

    <!-- filepath: angular-ai/src/app/chat/simple-chat/simple-chat.html -->
    <mat-card class="chat-container">
      <div class="chat-header">
        <mat-toolbar>
          <span>Simple Chat</span>
        </mat-toolbar>
      </div>
      <div class="chat-history" #chatHistory>
        <div class="messages">
        @for (message of messages(); track message) {
          <div class="message">
            <div class="message-bubble" [class.user]="!message.isBot">
              
            </div>
          </div>
        }
        @if (isLoading) {
          <div class="message">
            <div class="message-bubble">
              <span class="typing">...</span>
            </div>
          </div>
        }
      </div>
      </div>
    
      <div class="chat-input">
        <mat-form-field class="full-width">
          <mat-label>Ask anything</mat-label>
          <input matInput [(ngModel)]="userInput" (keyup.enter)="sendMessage()">
          @if (userInput) {
            <button matSuffix mat-icon-button aria-label="Send" (click)="sendMessage()" [disabled]="isLoading">
              <mat-icon>send</mat-icon>
            </button>
         }
        </mat-form-field>
      </div>
    </mat-card>
    

    O que está acontecendo aqui?

    • <mat-card class="chat-container">:Estamos usando o componente card do Angular Material como o contêiner principal para nossa interface de bate-papo.
    • <div class="chat-header">com <mat-toolbar>: Cria uma seção de cabeçalho usando o componente de barra de ferramentas do Angular Material.
    • <div class="chat-history" #chatHistory>: Este é o nosso contêiner de mensagens rolável. A #chatHistoryvariável de referência do modelo nos permite acessar este elemento DOM a partir do nosso componente usando viewChilda funcionalidade de rolagem automática.
    • @for (message of messages(); track message; let system = $even): Esta é a nova sintaxe de fluxo de controle do Angular (introduzida no Angular v17). Estamos iterando sobre nosso messages()sinal, usando a trackcláusula para otimização de desempenho.
    • [class.user]="!message.isBot": Esta é uma vinculação de classe que aplica condicionalmente a userclasse CSS quando a mensagem NÃO é do bot. Isso nos permite estilizar as mensagens do usuário de forma diferente das mensagens do bot (normalmente alinhadas à direita e à esquerda) e de uma forma preferencial em vez de NgClassdiretivas.
    • @if (isLoading): Outro exemplo da nova sintaxe de fluxo de controle do Angular. Isso mostra condicionalmente um indicador de carregamento com pontos de digitação ( ...) quando a IA está processando uma resposta.
    • <mat-form-field class="full-width">: Componente de campo de formulário do Angular Material que fornece o estilo de entrada e a funcionalidade de rótulo. A full-widthclasse garante que ocupe o espaço disponível.
    • [(ngModel)]="userInput": Vinculação de dados bidirecional que conecta o campo de entrada à userInputpropriedade do nosso componente. Quando o usuário digita, ele atualiza a propriedade; quando a propriedade muda, ele atualiza a entrada. Como temos apenas um campo, não há necessidade de formulários complexos aqui.
    • (keyup.enter)="sendMessage()": Vinculação de evento que chama nosso sendMessage()método quando o usuário pressiona a tecla Enter. Isso fornece uma maneira conveniente de enviar mensagens sem clicar no botão.
    • @if (userInput): Exibe o botão de envio apenas quando há texto no campo de entrada. Este é um toque agradável de UX que evita o envio de mensagens vazias.
    • [disabled]="isLoading": Vinculação de propriedade que desabilita o botão de envio enquanto uma solicitação está em andamento, impedindo múltiplos envios.

    Principais conceitos angulares utilizados:

    • Nova sintaxe de fluxo de controle : @for@ifem vez de *ngFore*ngIf
    • Variáveis de referência de modelo : #chatHistorypara acesso DOM
    • Ligação de classe : [class.user]para estilo condicional
    • Vinculação de eventos : (click)(keyup.enter)para interações do usuário
    • Vinculação de propriedade : [disabled]para estados de botões dinâmicos
    • Ligação de dados bidirecional : [(ngModel)]para entrada de formulário
    • Componentes de materiais angulares : mat-cardmat-toolbarmat-form-field, etc.

    Etapa 5: estilize a interface de bate-papo

    Agora vamos adicionar algum estilo ao nosso HTML:

    // filepath: angular-ai/src/app/chat/simple-chat/simple-chat.component.scss
    .chat-container {
      display: flex;
      flex-direction: column;
      height: 80vh;
      margin: 36px;
    }
    
    .chat-header {
      flex: 0 0 auto; /* Header doesn't grow or shrink */
    }
    
    .chat-history {
      flex: 1 1 auto; /* Chat history takes up available space */
      overflow-y: auto; /* Add scrollbar if content overflows */
      padding: 10px;
    }
    
    .messages {
      flex: 1;
      margin-bottom: 16px;
      overflow-y: auto;
      padding-right: 8px;
    }
    
    .message {
      margin-bottom: 8px;
    }
    
    .message-bubble {
      padding: 10px;
      border-radius: 10px;
      max-width: 80%;
      display: inline-block;
    }
    
    .user {
      background-color: #d7e3ff; /* Light blue for user messages */
      border-radius: 10px;
      align-self: flex-end; /* Align to the right */
      margin-left: auto;
    }
    
    
    .chat-input {
      flex: 0 0 auto; /* Input bar doesn't grow or shrink */
      padding: 10px;
    }
    
    .full-width {
      width: 100%;
    }
    
    .typing {
      display: inline-block;
      overflow: hidden;
      white-space: nowrap;
      animation: typing 1s steps(10) infinite alternate; // changed from 2s to 1s
    }
    
    @keyframes typing {
      from {
        width: 0;
      }
      to {
        width: 100%;
      }
    }
    

    O que está acontecendo aqui?

    • .chat-container: Este é o nosso contêiner principal usando CSS Flexbox. Definimos que ele flex-direction: columnempilhe elementos verticalmente, com uma altura fixa de 80vh(80% da altura da janela de visualização) e margem consistente. Isso cria a base para o layout do nosso chat.
    • .chat-header: Usos flex: 0 0 autoque significam que ele não cresce nem encolhe — mantém seu tamanho natural. Isso garante que nosso cabeçalho permaneça no topo com altura consistente, independentemente das alterações de conteúdo.
    • .chat-history: Esta é a área de mensagens rolável. Usamos flex: 1 1 autopara que ocupe todo o espaço disponível entre o cabeçalho e a entrada. overflow-y: autoAdiciona uma barra de rolagem quando as mensagens excedem a altura do contêiner.
    • .messages: Estilo adicional para o contêiner de mensagens com espaçamento e preenchimento adequados. padding-right: 8pxConsidera o espaço da barra de rolagem.
    • .message: Espaçamento simples entre mensagens individuais usado margin-bottom: 8pxpara criar separação visual.
    • .message-bubble: Isso estiliza cada balão de mensagem com cantos arredondados, preenchimento e uma largura máxima de 80% para evitar que as mensagens ocupem toda a largura. Isso display: inline-blockpermite o alinhamento adequado.
    • .user: Esta classe é aplicada condicionalmente às mensagens do usuário (lembre-se [class.user]="!message.isBot"do modelo). Ela usa um fundo azul-claro margin-left: autopara empurrar as mensagens do usuário para o lado direito do chat, criando o padrão típico de alinhamento de chat.
    • .chat-input: Semelhante ao cabeçalho, este serve flex: 0 0 autopara manter seu tamanho na parte inferior do contêiner. O preenchimento garante o espaçamento adequado das bordas.
    • .full-width: Uma classe utilitária que faz com que o campo de entrada ocupe toda a largura disponível dentro de seu contêiner.
    • .typing: Isso cria o indicador de digitação animado. Usamos overflow: hiddenwhite-space: nowrappara controlar a exibição do texto e, em seguida, aplicamos uma animação personalizada que cria o efeito de digitação.
    • @keyframes typing: Isso define a animação que faz com que os pontos de digitação pareçam “digitar”, animando a largura de 0 a 100%. Isso steps(10) infinite alternatecria um efeito de digitação suave e contínua.

    Etapa 6: Atualizar o componente do aplicativo

    Agora que nossa interface de bate-papo está pronta, vamos voltar ao componente principal e adicionar o código restante.

    // filepath: angular-ai/src/app/app.ts
    import { Component } from '@angular/core';
    import { MatButtonModule } from '@angular/material/button';
    import { MatIconModule } from '@angular/material/icon';
    import { MatToolbarModule } from '@angular/material/toolbar';
    import { RouterLink, RouterOutlet } from '@angular/router';
    
    @Component({
      selector: 'app-root',
      imports: [RouterOutlet, MatToolbarModule, MatButtonModule, MatIconModule, RouterLink],
      templateUrl: './app.html',
      styleUrl: './app.scss'
    })
    export class App {
      readonly title = 'AI-Spring-Angular';
    }
    

    Este componente de aplicativo serve como nosso shell de aplicativo, fornecendo a barra de ferramentas de navegação principal e uma saída de roteador onde nosso componente de bate-papo será exibido.

    app.htmlarquivo:

    <mat-toolbar>
      <span class="title"></span>
      <button mat-button aria-label="Simple Chat" routerLink="/simple-chat">Simple Chat</button>
    </mat-toolbar>
    <router-outlet></router-outlet>
    

    E finalmente, o arquivo SCSS:

    .title {
      margin-right: 20px;
    }
    

    Etapa 7: Rotas e configuração principal

    Se um app.routesarquivo não foi criado durante a criação do projeto, vá em frente e crie um com o seguinte conteúdo:

    import { Routes } from '@angular/router';
    
    export const routes: Routes = [
      { path: '', redirectTo: 'simple-chat', pathMatch: 'full' },
      { path: 'simple-chat',
        loadComponent: () => import('./chat/simple-chat/simple-chat').then(c => c.SimpleChat)
      },
      { path: '**', redirectTo: 'simple-chat' }
    ];
    

    O que está acontecendo aqui?

    • { path: '', redirectTo: 'simple-chat', pathMatch: 'full' }: Esta é a configuração de rota padrão. Quando os usuários acessam a URL raiz ( /), eles serão redirecionados automaticamente para /simple-chat. Isso pathMatch: 'full'garante que esse redirecionamento só aconteça quando o caminho estiver exatamente vazio (não apenas quando começar com vazio).
    • { path: 'simple-chat', loadComponent: () => import('./chat/simple-chat/simple-chat').then(c => c.SimpleChat) }: Isso define nossa rota de bate-papo usando carregamento lento .
      • loadComponent: Usa importações dinâmicas para componentes autônomos.
      • import('./chat/simple-chat/simple-chat'): Importa dinamicamente nosso componente de bate-papo
      • .then(c => c.SimpleChat): Extrai a SimpleChatclasse do módulo importado
    • { path: '**', redirectTo: 'simple-chat' }: Esta é a rota curinga que captura quaisquer URLs não correspondentes. Se alguém tentar acessar uma rota inexistente, será redirecionado para o nosso componente de chat. Esta é uma boa prática de UX para lidar com cenários do tipo 404.

    E finalmente, vamos revisar o app.config.tsarquivo:

    import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core';
    import { provideRouter } from '@angular/router';
    
    import { provideHttpClient } from '@angular/common/http';
    import { routes } from './app.routes';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideBrowserGlobalErrorListeners(),
        provideZonelessChangeDetection(),
        provideRouter(routes),
        provideHttpClient()
      ]
    };
    

    O que está acontecendo aqui?

    • import { provideHttpClient } from '@angular/common/http': Isso importa o provedor de cliente HTTP que precisamos para fazer chamadas de API para nosso backend do Spring Boot.
    • provideZonelessChangeDetection(): Esta é a nova estratégia experimental de detecção de alterações do Angular que não depende do Zone.js. Ela tem melhor desempenho e funciona particularmente bem com sinais, que estamos usando em todo o nosso componente de bate-papo.
    • provideRouter(routes): Isso configura o sistema de roteamento do Angular com nossas definições de rota. Ele pega nosso routesarray e configura o sistema de navegação para nossa aplicação.
    • provideHttpClient(): Isso configura o cliente HTTP do Angular para fazer solicitações de API. Precisamos disso para nos comunicar com nosso backend do Spring Boot ao enviar mensagens de bate-papo.

    Esta configuração representa a abordagem moderna do Angular para a configuração de aplicações. É mais explícita, adaptável a árvores e com melhor desempenho do que a abordagem tradicional do NgModule. provideZonelessChangeDetection()É particularmente interessante, pois funciona perfeitamente com nosso componente de bate-papo baseado em sinais, proporcionando melhor desempenho sem a sobrecarga do Zone.js.

    Etapa 8: Proxy para a API

    Pessoalmente, não sou muito fã de usar CORS se não for necessário. Para desenvolvimento local, isso definitivamente não é necessário e considero uma boa prática não usar CORS localmente. Por esse motivo, prefiro sempre criar um proxy.conf.jsarquivo na pasta raiz do projeto:

    // file path: angular-ai/proxy.conf.js
    const PROXY_CONFIG = [
      {
        context: ["/api"],
        target: "http://localhost:8080/",
        secure: false,
        logLevel: "debug",
      },
    ];
    module.exports = PROXY_CONFIG;
    

    O que está acontecendo aqui?

    • const PROXY_CONFIG = [...]: Isso cria uma matriz de configuração de proxy que informa ao servidor de desenvolvimento do Angular como lidar com solicitações de API durante o desenvolvimento.
    • context: ["/api"]: Especifica quais caminhos de URL devem ser proxy. Qualquer solicitação que comece com /apiserá interceptada e encaminhada para o nosso backend Spring Boot. Isso corresponde ao endpoint que definimos em nosso ChatServiceprivate readonly API = '/api/chat').
    • target: "http://localhost:8080/": Este é o destino para onde as solicitações proxy serão encaminhadas. Como nosso aplicativo Spring Boot roda na porta 8080 por padrão, todas as /apisolicitações do nosso aplicativo Angular (rodando na porta 4200) serão enviadas para .http://localhost:8080/api
    • secure: false: Isso desabilita a verificação do certificado SSL. Como estamos trabalhando com HTTP (não HTTPS) no desenvolvimento local, configuramos essa opção falsepara evitar problemas relacionados a SSL.
    • logLevel: "debug": Isso permite o registro detalhado das operações de proxy no console. É útil para depurar problemas de proxy durante o desenvolvimento — você verá exatamente quais solicitações estão sendo processadas por proxy e para onde estão indo.
    • module.exports = PROXY_CONFIG: Isso exporta a configuração para que o Angular CLI possa usá-la ao iniciar o servidor de desenvolvimento.

    Por que usar um proxy em vez do CORS?

    • Desenvolvimento mais limpo: não há necessidade de configurar cabeçalhos CORS no seu aplicativo Spring Boot para desenvolvimento local.
    • Ambiente semelhante ao de produção: seu frontend faz solicitações para a mesma origem, o que é mais semelhante à configuração de produção.
    • Segurança: evita a complexidade e potenciais problemas de segurança da configuração do CORS.
    • Simplicidade: um único arquivo de configuração lida com todo o roteamento da API.

    Para usar este proxy, você precisará iniciar seu servidor de desenvolvimento Angular com ( package.json):

    "start": "ng serve --proxy-config proxy.conf.js -o"
    

    Use npm run startem vez de ng servediretamente.

    Ou adicione-o ao seu angular.jsonarquivo na configuração de serviço:

    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "proxyConfig": "proxy.conf.js"
      }
    }
    

    Essa configuração garante que, quando seu aplicativo Angular fizer uma solicitação /api/chat, ela seja encaminhada automaticamente para onde nosso backend do Spring Boot está escutando.http://localhost:8080/api/chat

    Testando o aplicativo

    Etapa 1: iniciar o backend

    Navegue até o api-aidiretório e execute:

    ./mvnw spring-boot:run
    

    O backend deve iniciar na porta 8080.

    Etapa 2: iniciar o frontend

    No angular-aidiretório, execute:

    npm start
    

    O aplicativo Angular iniciará na porta 4200 e será aberto automaticamente no seu navegador ( -oparâmetro que adicionamos ao startscript).

    Etapa 3: Teste o bate-papo

    1. Abra seu navegador e vá parahttp://localhost:4200
    2. Navegue até a seção Bate-papo Simples
    3. Digite uma mensagem e pressione Enter ou clique em Enviar
    4. Você deverá ver a resposta da IA aparecer no chat

    Dica : Tente fazer perguntas como “O que é Spring AI?” ou “Explique a injeção de dependência no Spring” para testar o conhecimento da IA.

    espaço reservado

    Conclusão

    Parabéns! 🎉 Você construiu com sucesso um aplicativo de bate-papo com IA simples usando Spring AI e Angular. Esta base oferece tudo o que você precisa para criar aplicativos mais sofisticados com IA.

    Neste tutorial, abordamos:

    • Configurando o Spring AI com a integração do Gemini
    • Criando uma API RESTful para funcionalidade de chat
    • Construindo uma interface de bate-papo Angular responsiva
    • Conectando o frontend e o backend
    • Lidando com interações do usuário em tempo real

    O que vem a seguir?

    • Adicione memória de bate-papo para manter o contexto da conversa
    • Implementar diferentes modelos ou provedores de IA
    • Adicionar autenticação de usuário
    • Armazene o histórico de bate-papo em um banco de dados

    Boa codificação! 🚀

    Quer o código? Acesse o GitHub : https://github.com/loiane/spring-ai-angular

    Referências

  • Monorepo vs. Monolito: Um Estudo Comparativo em Aplicações .NET

    Monorepo vs. Monolito: Um Estudo Comparativo em Aplicações .NET

    Nos últimos anos, o desenvolvimento de software tem evoluído rapidamente, trazendo novas abordagens e arquiteturas para a construção de aplicações. Entre essas abordagens, o monorepo e o monolito se destacam como opções populares, especialmente em ambientes .NET. Este artigo aborda as características, vantagens e desvantagens de cada uma dessas estratégias, permitindo uma compreensão mais profunda para desenvolvedores e arquitetos de software.

    Imagem SVG do Artigo

    Introdução ao Monorepo

    Um monorepo, ou repositório monolítico, é uma abordagem em que múltiplos projetos e pacotes são armazenados em um único repositório. Essa estratégia é comumente utilizada por grandes organizações que buscam simplificar o gerenciamento de dependências e promover a colaboração entre equipes (TONIN, 2024). Ao adotar um monorepo, as empresas podem aproveitar uma estrutura que permite a interação e a sinergia entre diferentes projetos, reduzindo a duplicação de esforços e aumentando a eficiência (SHAKIKHANLI; BILICKI, 2024).

    Um exemplo de configuração de um monorepo em .NET pode ser visto abaixo:

    Imagem SVG do Artigo

    Vantagens do Monorepo

    Uma das principais vantagens do monorepo é a facilidade de gerenciamento de dependências. Com todos os projetos em um único lugar, é mais simples garantir que todos eles estejam usando versões compatíveis de bibliotecas comuns (TONIN, 2024). Além disso, a colaboração entre equipes é facilitada, uma vez que as alterações em um projeto podem ser facilmente integradas a outros. Isso é particularmente útil em equipes grandes que trabalham em vários componentes de uma aplicação complexa.

    Outro ponto positivo é a consistência no estilo de codificação e nas ferramentas utilizadas, já que todos os desenvolvedores estão trabalhando dentro do mesmo repositório. Isso promove uma cultura de código mais coesa e integrada, onde padrões e melhores práticas podem ser aplicados de forma uniforme. Assim, a manutenção do código se torna mais simples e eficiente.

    Além disso, os monorepos permitem a utilização de ferramentas de automação de build e testes que podem ser aplicadas de maneira centralizada, garantindo que todos os projetos estejam sempre funcionando corretamente, o que aumenta a confiabilidade do sistema como um todo.

    Desvantagens do Monorepo

    Apesar das vantagens, o uso de um monorepo é acompanhado de desafios. Um dos mais significativos é o aumento do tempo de build e testes, que pode se tornar um gargalo à medida que o repositório cresce. Testes que antes eram rápidos podem se tornar lentos e custosos, especialmente se a estrutura do código não for otimizada. Além disso, a complexidade de gerenciamento pode aumentar, especialmente se diferentes equipes estiverem trabalhando em partes não relacionadas do código.

    A escalabilidade é outro ponto crítico: repositórios muito grandes podem se tornar difíceis de navegar e gerenciar, exigindo ferramentas e processos adicionais para manter a eficiência. Em muitos casos, as equipes precisam de estratégias específicas para lidar com essas dificuldades, como a segmentação de projetos dentro do monorepo, o que pode adicionar mais camadas de complexidade.

    Por último, a gestão de permissões e acessos pode se tornar mais complexa, uma vez que um único repositório abriga múltiplos projetos que podem ter diferentes níveis de sensibilidade e segurança.

    Introdução ao Monolito

    Em contraste, um monolito é uma arquitetura onde todos os componentes de uma aplicação são integrados em uma única solução (SABBAG FILHO, 2025). Essa abordagem tem sido tradicionalmente utilizada em aplicações .NET, onde o código é frequentemente organizado em uma única base de código. O monolito é muitas vezes a escolha inicial para muitas startups e projetos pequenos devido à sua simplicidade e rapidez de desenvolvimento.

    Um exemplo de uma aplicação monolítica em .NET pode ser vista abaixo:

    Imagem SVG do Artigo

    Vantagens do Monolito

    Os monolitos têm algumas vantagens claras, especialmente em projetos menores ou em fases iniciais de desenvolvimento. A simplicidade na configuração e no deployment é um grande atrativo, pois toda a aplicação é implantada como uma única unidade, reduzindo a complexidade do ambiente de produção. Isso também reduz o tempo necessário para configurar e gerenciar ambientes de desenvolvimento e teste.

    Além disso, as aplicações monolíticas podem ter um desempenho melhor em algumas situações, já que todas as partes do sistema estão dentro do mesmo processo, permitindo chamadas de função mais rápidas entre os componentes. Isso é particularmente importante em aplicações onde a latência e a velocidade são cruciais.

    Outra vantagem é que a arquitetura monolítica torna mais fácil o monitoramento e a análise de logs, pois todas as interações da aplicação estão centralizadas em um único local. Isso facilita a identificação de problemas e a depuração quando ocorrem falhas.

    Desvantagens do Monolito

    No entanto, os monolitos também apresentam desvantagens significativas. A escalabilidade pode ser um problema, já que a aplicação inteira deve ser escalada, mesmo que apenas uma parte dela esteja sob carga. Isso pode levar a um uso ineficiente de recursos, onde, por exemplo, um componente que deve ser escalado para lidar com um aumento de carga pode forçar toda a aplicação a ser replicada, resultando em custos desnecessários.

    Além disso, a manutenção pode se tornar difícil à medida que a aplicação cresce, já que pequenas mudanças podem ter impactos em várias partes do sistema. Essa interdependência entre componentes pode resultar em um aumento do tempo de desenvolvimento e testes, já que qualquer alteração pode necessitar de uma validação extensiva.

    A dependência de tecnologia única pode limitar a capacidade da equipe em adotar novas tecnologias, já que a mudança de uma parte do monolito pode exigir modificações em todo o código, tornando a evolução tecnológica um processo mais lento e complicado.

    Comparação Direta: Monorepo vs. Monolito

    Quando se trata de comparar o monorepo e o monolito, é essencial considerar o contexto em que cada um é utilizado. O monorepo é mais adequado para projetos que envolvem múltiplos componentes ou serviços interdependentes, enquanto o monolito pode ser a escolha ideal para aplicações menores que não exigem tal complexidade. A escolha entre um monorepo e um monolito deve ser guiada pelas necessidades específicas do projeto.

    Além disso, enquanto o monorepo facilita a colaboração entre equipes, o monolito pode oferecer uma curva de aprendizado menor para novos desenvolvedores, já que toda a lógica da aplicação está consolidada em um único lugar (JASPAN et al., 2018). Isso pode ser particularmente vantajoso em equipes que estão se formando ou em ambientes onde a rotatividade de pessoal é alta.

    Outro ponto a considerar é a integração contínua: um monorepo pode permitir uma integração mais suave entre diferentes partes do código, enquanto um monolito pode exigir testes mais rigorosos para garantir que mudanças em uma parte não quebrem funcionalidades em outra.

    Casos de Uso e Cenários

    Em um cenário onde uma equipe está desenvolvendo uma aplicação de grande escala com múltiplos serviços (por exemplo, um sistema de gerenciamento de pedidos e um sistema de inventário), um monorepo pode ser a escolha ideal. Essa abordagem permite que as equipes trabalhem em diferentes serviços de forma coordenada, aplicando mudanças em toda a aplicação de forma mais eficiente.

    Por outro lado, se a equipe está construindo um aplicativo de gerenciamento de tarefas simples, um monolito pode ser mais prático. Em projetos menores, a complexidade adicional de um monorepo pode não justificar os benefícios, tornando o monolito uma escolha mais lógica.

    Além disso, muitas organizações estão adotando abordagens híbridas, onde partes de uma aplicação podem ser desenvolvidas como um monolito, enquanto outras são extraídas para um monorepo. Isso permite o melhor dos dois mundos, onde a complexidade e a escalabilidade podem ser gerenciadas de forma mais eficaz.

    Um exemplo disso é uma aplicação que possui um módulo central monolítico, responsável por funcionalidades essenciais, enquanto módulos auxiliares que são mais dinâmicos ou que mudam com frequência são desenvolvidos como serviços independentes em um monorepo. Essa estratégia oferece flexibilidade e permite que as equipes adotem novas tecnologias conforme necessário.

    Considerações Finais

    Ambas as abordagens, monorepo e monolito, oferecem vantagens e desvantagens que devem ser cuidadosamente consideradas antes da escolha. Entender as necessidades do projeto, a estrutura da equipe e a escalabilidade desejada são fatores cruciais para determinar qual abordagem será mais eficaz. À medida que a tecnologia continua a evoluir e as práticas de desenvolvimento se transformam, a escolha entre monorepo e monolito pode muito bem depender do contexto específico de cada projeto.

    Além disso, é importante que as equipes estejam abertas a revisitar suas escolhas ao longo do tempo. À medida que um projeto cresce e suas necessidades mudam, o que pode ter sido uma escolha ideal em um estágio inicial pode não ser mais a melhor opção. Portanto, monitorar e avaliar continuamente a arquitetura e a estrutura do código é essencial para garantir que o projeto permaneça eficiente e sustentável a longo prazo.

    Por fim, a adoção de uma abordagem de desenvolvimento ágil e iterativa pode ajudar a mitigar muitos dos problemas associados tanto ao monorepo quanto ao monolito. Ao permitir que as equipes experimentem, aprendam com falhas e ajustem suas práticas de desenvolvimento, as organizações podem aproveitar ao máximo as oportunidades que cada abordagem oferece.

    Referências

    • TONIN, Rangel Cristiano. Estratégias de código-fonte centralizado para a gestão eficiente de variantes de produtos de software. 2024.
    • SABBAG FILHO, Nagib. Comparative Analysis between Monolithic Architecture and Microservices in. NET Applications. Leaders Tec, v. 2, n. 13, 2025.
    • SHAKIKHANLI, Ulvi; BILICKI, Vilmos. Optimizing branching strategies in Mono-and Multi-repository environments: A comprehensive analysis. Computer Assisted Methods in Engineering and Science, v. 31, n. 1, p. 81-111, 2024.
    • JASPAN, Ciera et al. Advantages and disadvantages of a monolithic repository: a case study at google. In: Proceedings of the 40th International Conference on Software Engineering: Software Engineering in Practice. 2018. p. 225-234.
  • MCP: O que é e por que você vai ouvir falar disso em breve?

    MCP: O que é e por que você vai ouvir falar disso em breve?

    Entenda como a tecnologia está transformando a relação entre IAs e sistemas operacionais, com impacto direto em automação, segurança e hospedagem de sites

    Foto: Reprodução/Freepik

    A inteligência artificial deu um novo passo com a chegada do Model Context Protocol (MCP). Esse protocolo surgiu em 2024, lançado pela Anthropic, e abriu caminho para que modelos executem ações reais com autonomia, segurança e rastreabilidade.

    Mas afinal, o que torna o MCP tão especial? Em vez de apenas responder a perguntas ou gerar textos, ele permite que a IA interaja com sistemas de forma contextualizada, realizando tarefas operacionais completas.

    Estamos diante do surgimento da chamada “IA operacional”, um conceito que coloca os modelos no centro da automação inteligente. A tecnologia foi rapidamente adotada por empresas importantes do setor, como OpenAI e Google.

    Para que o MCP funcione com eficiência, ele se organiza em três componentes principais. Essa arquitetura modular ajuda a distribuir responsabilidades e simplificar integrações entre modelos de linguagem e ferramentas.

    Hosts: aplicativos baseados em grandes modelos de linguagem (LLM) que iniciam a comunicação, como IDEs, terminais inteligentes ou ferramentas como Claude Desktop. É nesse ambiente que começa a experiência do usuário.

    Clientes: mantêm conexões diretas (1:1) com os servidores e operam dentro do ambiente host. Fazem a ponte entre o modelo e os recursos externos.

    Servidores: oferecem o contexto necessário, comandos disponíveis e prompts úteis aos clientes. Essa camada expõe as capacidades de forma segura e compreensível para a IA.

    O MCP surgiu com o objetivo de expandir a utilidade dos modelos de linguagem em ambientes operacionais. Em vez de apenas gerar respostas, esses modelos passam a ter capacidade de ação real, baseada no contexto em que atuam.

    MCP permite ações autônomas e conscientes

    O MCP funciona como uma ponte segura entre modelos de IA e sistemas reais. Ele define um protocolo claro sobre o que a IA pode fazer, quando e como, garantindo controle e segurança.

    Diferente de APIs ou scripts pré-configurados, a tecnologia é dinâmica e contextual. Isso significa que a IA entende o ambiente atual, as permissões disponíveis e as limitações antes de agir.

    Na prática, um modelo pode, por exemplo, renovar um domínio, escalar um servidor ou rodar testes, sem que um humano precise intervir manualmente.

    Antes, a automação dependia de scripts rígidos que exigiam ajustes a cada mudança no cenário. Com o MCP, a IA se adapta ao contexto e decide o melhor caminho para alcançar o objetivo.

    Isso eleva o nível da automação. Os sistemas deixam de apenas seguir ordens e passam a tomar decisões inteligentes, reduzindo erros e aumentando a eficiência. Para equipes de DevOps e squads ágeis, esse avanço significa menos retrabalho e mais foco em inovação.

    Segurança e rastreabilidade integradas ao protocolo

    Toda ação realizada via MCP é rastreável e gera um registro completo com autorizações, horários, parâmetros e resultados. Dessa forma, o processo cria um histórico seguro e auditável.

    Além disso, o sistema impõe limites explícitos e só pode agir dentro do que foi autorizado. É como dar chaves específicas para uma IA, com regras claras do que pode ser feito.

    Ao integrar o Model Context Protocol na operação, deixa-se de lado a rigidez dos scripts e passa-se a trabalhar com uma estrutura mais inteligente, segura e adaptável.

    Para quem atua com desenvolvimento, DevOps ou automações no-code, essas são as principais vantagens que tornam o protocolo uma tendência técnica a ser observada:

    Comunicação padronizada: permite que modelos interajam com sistemas de forma clara e consistente, reduzindo erros e mal-entendidos.

    Gestão com base no contexto: a IA executa ações considerando o ambiente atual, as permissões vigentes e as limitações específicas, evitando comportamentos genéricos.

    Segurança reforçada: toda ação passa por autenticação, controle de escopo e registro detalhado, garantindo rastreabilidade e controle real de acesso.

    Estrutura extensível: o protocolo pode ser adaptado para diferentes domínios e casos de uso, facilitando a adoção por equipes com processos consolidados.

    Ambiente amigável para o desenvolvedor: reduz a complexidade das automações operacionais, permitindo que os desenvolvedores foquem na lógica do produto.

    Crescimento escalável e flexível: permite delegar tarefas com segurança à medida que a operação cresce, sem criar gargalos manuais ou dependência de scripts frágeis.

    Serviços de hospedagem também podem ser impactados

    Com a automação inteligente baseada em IA operacional, tarefas rotineiras como renovação de domínios, escalonamento de servidores e atualizações podem ser executadas de forma autônoma e segura na gestão de um site.

    Para provedores de hospedagem, como a Hostinger, isso representa ganho de eficiência e redução de erros humanos, além de uma experiência mais ágil para desenvolvedores e clientes.

    À medida que o MCP amadurece, deve se tornar um padrão na infraestrutura de hospedagem, integrando‑se a painéis de controle e ferramentas internas. Essa evolução contribui para que as equipes técnicas possam focar em inovação, deixando as operações repetitivas sob responsabilidade da IA.

    Na prática, o MCP permite que a IA realize tarefas como a renovação automática de certificados SSL, garantindo a segurança sem intervenção manual. Além disso, pode monitorar a saúde dos servidores e ajustar recursos em tempo real conforme a demanda.

    Outra aplicação é a automação na criação e configuração de ambientes para clientes, acelerando o processo de entrega e reduzindo erros. Com a rastreabilidade integrada, cada ação fica registrada, oferecendo mais transparência para equipes técnicas e usuários.

    MCP tem obstáculos a superar, mas futuro indica otimismo

    O Model Context Protocol traz otimismo para o futuro da automação inteligente. Ainda assim, o suporte é limitado e a dependência do modelo de IA utilizado pode impactar a performance.

    Pesquisas recentes avaliam a saúde e segurança dos servidores MCP em código aberto. Um estudo da arXiv, por exemplo, analisou 1.899 servidores e identificou vulnerabilidades, como a presença de code smell em 66% deles, indicador comum em tecnologias emergentes.

    Mesmo assim, o MCP tem mostrado benefícios na integração entre IA e sistemas operacionais. O protocolo representa uma nova camada de interface com a tecnologia, menos sobre “como programar” e mais sobre “como delegar com segurança e contexto”.

    Com o avanço da tecnologia, entender a IA operacional será tão importante quanto saber versionar código. Desenvolvedores, DevOps, gerentes de produto e makers que dominarem esse ecossistema estarão um passo à frente.

    De modo geral, o MCP é uma tecnologia que equilibra inovação e maturidade em construção. Seu potencial para transformar operações técnicas é real, e acompanhar sua evolução é essencial para profissionais que querem se destacar.

  • Vibe Coding com GitHub Copilot

    Vibe Coding com GitHub Copilot

    Nem todo momento de código precisa ser sobre produtividade ou resolver bugs, sabe? Às vezes, tudo o que a gente quer é abrir um projeto pessoal, daqueles bem aleatórios, colocar uma música boa e deixar o código fluir. Isso é vibe coding: programar de forma leve, criativa, e, com um pouco de ajuda do GitHub Copilot (ou às vezes, muita ajuda haha).

    Não sei vocês, mas trabalhando oito horas por dia, cuidando da casa, dos gatos, da saúde e da família, eu tenho pouco tempo pra codar! E com isso muitas das minhas ideias de projetos pessoas foram deixadas de lado. Isso até o GitHub copilot aparecer na minha vida!

    (Fica o aviso de sempre: Isso não vai substituir seu trabalho tá, por isso que chama co – pilot)

    Esse ano tirei vários projetinhos do papel graças a esse tal e vibe coding. Vamos aprender mais?

    O que é vibe coding?

    Vibe coding é uma abordagem moderna de desenvolvimento de software que combina o uso de linguagem natural, inteligência artificial avançada, como o GitHub Copilot, e um modo de programar mais fluido, colaborativo e iterativo. O termo, popularizado por Andrej Karpathy, descreve um estilo em que você explica o que quer em palavras simples no seu idioma natural, e a IA transforma suas ideias em código. Assim, você foca na intenção e na funcionalidade, enquanto a IA cuida dos detalhes da implementação.

    No vibe coding, a pessoa desenvolvedora fornece comandos em linguagem natural para o LLM, que age como parceiro na programação. O GitHub Copilot gera, refina e até ajuda a depurar o código, criando uma troca constante que acelera o desenvolvimento e torna a experiência mais leve e criativa.

    Para uma boa vibe, o ideal é montar um ambiente confortável, como uma playlist ambiente, um editor configurado do seu jeito e o Copilot ativado. O Agent Mode no VS Code potencializa essa experiência ao permitir que o Copilot compreenda múltiplos arquivos, sugira comandos no terminal e corrija erros automaticamente. Com o suporte ao Model Context Protocol (MCP), a ferramenta acessa informações do fluxo de trabalho, como pull requests e issues, oferecendo uma experiência mais integrada.

    Dicas para criar a vibe perfeita

    Crie um espaço acolhedor para codar. Use sua música preferida para ajudar no foco e mantenha o editor configurado para o seu conforto visual e funcional. Aproveite o Agent Mode do Copilot para delegar tarefas repetitivas e automatizar subtarefas, o que ajuda a manter o ritmo sem perder energia. Além disso, use prompts claros e iterativos, ajustando o que a IA gera para que o resultado fique exatamente do seu jeito.

    Quando vibe “codar” e seus benefícios

    Vibe coding é ideal para momentos em que você quer relaxar após um dia intenso, programar por prazer no fim de semana, participar de lives descontraídas ou experimentar novas linguagens, isso é ótimo pra te ajudar a aprender coisas novas. Também é ótimo para testar ideias e explorar projetos sem pressão, mantendo o processo leve e divertido.

    Como eu mencionei no começo, te ajuda muito a tirar ideias do papel, e criar MVPs.

    Agora vamos aos benefícios:

    • Acelera o desenvolvimento ao assumir tarefas repetitivas e burocráticas
    • Facilita a prototipagem rápida e a experimentação de ideias
    • Torna o código mais acessível para iniciantes, que podem focar na lógica e no que querem construir
    • Estimula a criatividade ao liberar o desenvolvimento das tarefas mecânicas
    • Promove aprendizado prático, com a oportunidade de observar e absorver padrões e soluções da IA

    Quando não usar vibe coding

    Nem tudo são flores né pessoal? Vibe code confia muito na IA, e como eu sempre digo, a IA é limitada e não substitui a inteligência, experiência e contexto humano.

    Evite usar essa abordagem ao trabalhar com código em produção, quando estiver sob prazos apertados ou em tarefas que demandem concentração absoluta. E claro, no seu trabalho!

    Também não é indicado se você estiver cansado ou precisando de descanso mental, pois revisar o código gerado pela IA exige atenção e energia (sim, você tem que revisar o código! SEMPRE!).

    Desafios e limitações

    Além dos motivos acima pra não sair vibe “codando” tudo, toda hora, trabalhar de forma tão integrada com a ia tem seus problemas:

    • O código gerado pode não ser otimizado, seguro ou claro, principalmente em projetos complexos
    • É necessário revisar cuidadosamente para evitar falhas e vulnerabilidades
    • Depender demais da IA pode prejudicar a compreensão profunda do código, dificultando manutenção e depuração
    • Nem sempre a IA consegue identificar ou corrigir problemas complexos na lógica do programa
    • A dependência excessiva pode afetar o desenvolvimento das suas habilidades técnicas

    No fim das contas

    Vibe coding é um convite para redescobrir o prazer de programar, combinando criatividade humana e inteligência artificial. Com o GitHub Copilot, especialmente com recursos avançados como Agent Mode e MCP, essa experiência está mais acessível, eficiente e divertida do que nunca. Então, abra seu editor, escolha sua música favorita e deixe o código fluir com leveza e propósito.

    E para quem quiser mergulhar de vez no vibe coding, que tal se juntar a gente na Quinta do Patinho? É um live stream semanal descontraído onde eu codo ao vivo, explorar o GitHub Copilot, respondendo dúvidas e trocando ideias com a comunidade. Uma ótima oportunidade para praticar, aprender junto e manter a vibe sempre alta. Te espero lá!

    Extra: O que eu escuto durante minhas sessões de Vibe Coding

    Eu amo o soundtrack de Mr. Robot! Tem muita aquela vibe de “Hackerman”

    E no Youtube, eu gosto de colocar essa live super fofa de animal crossing em uma segunda tela, nela você ve os animaizinhos curtindo a paz deles, com um jazz suave de fundo, super recomeno.

  • Conectividade sem Exposição: como manter sua PME atualizada, online e segura em tempos de IA

    Conectividade sem Exposição: como manter sua PME atualizada, online e segura em tempos de IA

    Em quase duas décadas atuando com tecnologia — entre servidores barulhentos em salas improvisadas e sistemas críticos que simplesmente não podiam falhar — aprendi uma lição que se tornou meu norte profissional: a tecnologia só é útil se for segura, compreensível e sob controle. E hoje, em um cenário onde a inteligência artificial invade tudo — dos e-mails aos contratos, dos relatórios financeiros ao comportamento de consumo — vejo um novo tipo de urgência bater à porta das pequenas e médias empresas (PMEs): como crescer tecnologicamente sem expor seus dados, sua equipe e, principalmente, seus clientes? 

    Essa pergunta não tem uma resposta única. Mas tem caminhos possíveis. E alguns deles, eu já percorri — ora como gestor de TI no setor público e industrial no Brasil, ora como fundador de uma empresa de tecnologia nos Estados Unidos, dedicada justamente a oferecer soluções escaláveis e seguras para quem, muitas vezes, é deixado de lado pelas grandes plataformas. 

    O paradoxo do crescimento digital 

    Lembro bem de um cliente no interior de Minas Gerais, há mais de dez anos, que me dizia com orgulho: “Aqui está tudo na planilha, e com senha!”. Na época, a tecnologia era quase um luxo para empresas fora dos grandes centros. Hoje, esse mesmo perfil de negócio usa Google Workspace, sistemas de gestão em nuvem, WhatsApp API, VoIP e até controle remoto de câmeras e estoques. A transformação foi vertiginosa. Mas a proteção não acompanhou o mesmo ritmo. 

    É aí que mora o problema

    A mesma infraestrutura que permite agilidade, colaboração e escala, também abre portas para ataques digitais, se não for bem desenhada. E os dados comprovam isso: ataques cibernéticos contra PMEs cresceram mais de 600% nos últimos anos. Eu mesmo já atendi empresas que perderam anos de contratos e históricos de clientes por não terem backup estruturado — ou por confiarem demais no “isso nunca vai acontecer com a gente”.

    Cinco pilares para inovar com segurança 

    Com base em tudo que vivi, montei uma estrutura de cinco pilares que costumo aplicar com meus clientes. Eles não são uma receita pronta, mas um guia realista, especialmente para quem não tem uma equipe de TI dedicada, mas precisa operar com o mesmo nível de responsabilidade de uma grande corporação. 

    1. Conheça sua maturidade digital (antes de investir mais) 

    Parece óbvio, mas muitos empresários saem comprando licenças, softwares e ferramentas sem saber como está sua rede local, quem tem acesso aos dados, se o Wi-Fi da empresa tem senha forte ou se o antivírus foi renovado. Já ajudei empresas que usavam soluções de ponta, mas deixavam o servidor exposto com senha “admin123”. Primeiro passo: diagnóstico técnico e comportamental. 

    1. Use infraestrutura escalável, mas controlada 

    Soluções como Google Workspace ou Zoho são excelentes para colaboração. Mas precisam ser configuradas com lógica de permissão, autenticação em dois fatores e controle de acesso. Escalar, sim. Desordenar, nunca. Já presenciei equipes inteiras com acesso irrestrito a documentos financeiros, apenas por “facilidade”. 

    1. Traga a segurança para o centro da operação 

    Aqui entra o que mais defendo: firewalls bem configurados, segregação de rede, backups automatizados, VoIP com criptografia e acesso físico protegido aos equipamentos. Já ajudei uma empresa de comércio eletrônico a se recuperar de um ataque que bloqueou o estoque inteiro — a chave estava no fato de o banco de dados estar num servidor sem senha de root. 

    1. Treine sua equipe — sempre 

    Segurança digital não é apenas técnica. É cultura organizacional. Já perdi a conta de quantas vezes vi colaboradores clicando em links de phishing, baixando “atualizações” de remetentes falsos ou compartilhando senhas no grupo do WhatsApp. Segurança é um processo educacional contínuo, e o custo de um incidente é infinitamente maior do que o de um bom treinamento anual.

    1. A IA deve ser aliada — mas sob vigilância 

    Sim, eu uso inteligência artificial no meu dia a dia. Automatizo tarefas, faço análises preditivas, melhoro luxos. Mas sempre com governança. A IA pode ajudar a proteger (com monitoramento de tráfego, reconhecimento de padrões anômalos, etc.), mas também pode ser usada para atacar. Deepfakes, bots que invadem CRMs, scripts que simulam clientes. Usar IA sem critérios éticos e técnicos é brincar com fogo. 

    Conclusão: 

    A segurança como parte do crescimento, não como obstáculo 

    Depois de tantos anos vivenciando a TI no chão da fábrica, nos bastidores de empresas públicas, na rotina de pequenas empresas e agora liderando uma empresa de tecnologia aqui nos EUA, posso afirmar com convicção: proteger dados não atrasa o crescimento. Pelo contrário, acelera com confiança. 

    Já vi empresas perderem tudo por não terem um backup fora do servidor físico. Já vi outras florescerem após implantarem um ERP seguro e parametrizado. Em todos os casos, o que fez a diferença não foi o tamanho da empresa, mas a mentalidade do líder. 

    Se você é gestor de uma PME e sente que precisa evoluir, mas teme os riscos… saiba que o maior risco é não agir. Investir em segurança hoje é mais barato — e muito menos doloroso — do que explicar amanhã para um cliente que seus dados foram vazados. 

    Transformação digital sem blindagem é avanço com prazo de validade. Já com estratégia, treinamento e ferramentas certas, ela vira um motor de crescimento — contínuo, ético e sustentável. 

    E no final das contas, como sempre digo: não basta estar online. É preciso estar preparado.

  • UX, IA e Front-End: quando experiência, inteligência e código se encontram para criar o futuro digital

    UX, IA e Front-End: quando experiência, inteligência e código se encontram para criar o futuro digital

    A evolução da experiência digital não acontece mais em camadas isoladas. Hoje, UX, IA e Front-End formam um trio estratégico que molda a forma como interagimos com produtos, marcas e serviços. O ponto de encontro entre essas três áreas é onde nasce a inovação real: personalizada, fluida e inteligente.

    Mas como elas se conectam? Quais os impactos práticos de cruzar inteligência artificial com design e desenvolvimento de interfaces? Como isso melhora a vida dos usuários – e os resultados das empresas?

    Neste artigo, vamos explorar conceitos, exemplos reais, tecnologias emergentes e indicadores de impacto, olhando para o futuro de uma experiência cada vez mais personalizada, preditiva e eficiente.

    UX: a base de tudo

    User Experience (UX) não é apenas sobre telas bonitas. É sobre entregar valor, gerar confiança, reduzir fricções e guiar o usuário para seus objetivos de forma intuitiva.

    Segundo a Forrester, cada R$ 1 investido em UX pode gerar até R$ 100 em retorno. Isso se dá porque uma boa experiência:

    • Aumenta a retenção de clientes;
    • Reduz custos com suporte;
    • Melhora indicadores como NPS, CSAT e conversão.

    Agora imagine potencializar tudo isso com inteligência artificial e aplicações front-end inteligentes.

    IA no UX: de reativo para proativo

    A Inteligência Artificial já está transformando o UX em áreas como:

    1. Personalização em tempo real

    Ferramentas como Dynamic Yield e Adobe Target permitem personalizar conteúdos da interface com base no comportamento do usuário.

    🔸 Exemplo: Um usuário frequente de um app bancário que consulta investimentos vê, na home, gráficos e sugestões personalizadas, enquanto outro que só paga boletos vê atalhos para pagamento.

    2. Design adaptativo com IA

    Frameworks e engines como Uizard e Galileo AI já são capazes de gerar wireframes e componentes com base em prompts textuais ou esboços.

    🔸 Exemplo: Um designer digita “dashboard para startup de logística com mapa e KPIs em tempo real”, e o sistema gera um protótipo responsivo com base em padrões.

    3. Chatbots com NLP avançado

    Com IA conversacional, interfaces se tornam pontos de entrada interativos, capazes de resolver problemas e automatizar fluxos.

    🔸 Exemplo: Um chatbot de suporte técnico que entende linguagem natural, reconhece o problema e oferece soluções, sem menus engessados.

    Front-End inteligente: IA no código

    Do lado técnico, o front-end também tem evoluído com IA integrada. Algumas aplicações incluem:

    1. Componentes dinâmicos com IA

    Frameworks modernos (React, Vue, Angular) podem integrar bibliotecas como TensorFlow.js para:

    • Reconhecimento facial;
    • Leitura de sentimentos;
    • Comandos por voz.

    🔸 Exemplo prático: Um e-commerce ajusta a paleta de cores ou recomenda produtos com base na emoção facial detectada do usuário (feliz, neutro, frustrado).

    2. IA para acessibilidade (A11Y)

    Plugins como Stark, Able ou o novo Figma Accessibility Checker ajudam o front-end a garantir conformidade com WCAG.

    🔸 Benefício: Design com contraste adequado, navegação por teclado e texto alternativo, que garante acessibilidade real para todos.

    3. Geração de código assistida

    Ferramentas como GitHub Copilot, Cursor AI ou Amazon CodeWhisperer otimizam o trabalho de desenvolvedores, gerando códigos com base em contexto e boas práticas.

    🔸 Exemplo: Um desenvolvedor escreve “componente de botão acessível com ARIA e foco visível” e a IA gera a base do código automaticamente.

    Indicadores e benefícios reais

    A combinação de UX + IA + Front-End gera impactos que podem ser mensurados. Veja alguns dados:

    Esses dados vêm de relatórios da Nielsen Norman Group, McKinsey, Accenture e da WebAIM.

    Implementação na prática: dicas para times de produto

    1. Mapeie as jornadas com foco em dados comportamentais. IA precisa de dados para gerar valor. Trace onde a personalização faz sentido.
    2. Implemente Design Tokens adaptáveis. Crie sistemas de design que respondem ao contexto (modo escuro, acessibilidade, localização, etc.)
    3. Use HTML Semântico e Atributos ARIA. Isso garante que qualquer IA – e qualquer usuário – consiga entender o conteúdo de forma clara e acessível.
    4. Valide com usuários reais e IA. Faça testes com IA para prever reações e depois valide com testes reais de usabilidade.
    5. Coloque a ética no centro. UX com IA precisa ser transparente, respeitoso e responsável. Explique o uso de dados, evite viéses e preserve a privacidade.

    O futuro é colaborativo, responsivo e inteligente

    A fronteira entre UX, IA e Front-End não existe mais. Ela foi dissolvida por interfaces que aprendem, códigos que se adaptam e experiências que se moldam ao usuário.

    A pergunta agora não é “quando” aplicar IA ao UX, mas sim “como fazer isso com propósito”.

    Como designer, desenvolvedor ou gestor, seu papel é garantir que a tecnologia sirva à experiência humana – e não o contrário.

    “A melhor interface é aquela que entende você antes mesmo que você saiba o que precisa.” – Anônimo

    Se você atua em UX, Front-End ou Produto, está na hora de olhar para a IA não como ameaça, mas como aliada criativa.

    Gostou do conteúdo? Bora conversar!

    Me siga para mais artigos sobre UX, IA, acessibilidade, inovação e design centrado no usuário.

    #UXDesign #InteligenciaArtificial #FrontEnd #AcessibilidadeDigital #UXComIA #DesignResponsivo #DesignComPropósito #IAnoDesign #TransformaçãoDigital

     

  • C# par ou impar?

    C# par ou impar?

    Em C#, para determinar se um número é par ou ímpar, você pode usar o operador módulo (%). Este operador retorna o restante de uma operação de divisão.

    Veja como funciona:

    • Se um número dividido por 2 tiver um restante de 0, o número é par.
    • Se um número dividido por 2 tiver um restante de 1, o número é ímpar.

    O código C# fornecido funciona da seguinte forma:

    • Uma variável inteira, número, armazena a entrada do usuário.
    • Console.WriteLine() solicita ao usuário que insira um número.
    • Console.ReadLine() lê a entrada como uma string.
    • Convert.ToInt32() converte a entrada de string em um inteiro.
    • A instrução if (número % 2 == 0) verifica se dividir o número por 2 resulta em um restante de 0.
    • Se a condição for verdadeira (o remanescente for 0), uma mensagem indicando um número par será impressa.
    • Se a condição for falsa (o remanescente não for 0), uma mensagem indicando um número ímpar será impressa.

    Este código usa o operador módulo para determinar se um número é par ou ímpar em C#. O código pode ser modificado para retornar um valor booleano (verdadeiro para par, falso para ímpar) ou executar outras ações com base no resultado. 

    Code – Verifique o número

     

  • OWASP SAMM: O Guia Prático para Integrar DevSecOps ao seu SDLC

    OWASP SAMM: O Guia Prático para Integrar DevSecOps ao seu SDLC

    A integração da segurança ao ciclo de vida de desenvolvimento de software (SDLC) não é mais uma opção, mas uma necessidade estratégica. Em um cenário onde vulnerabilidades geram riscos crescentes, o OWASP SAMM (Software Assurance Maturity Model) surge como um guia essencial para estruturar, executar e medir a evolução da segurança de forma contínua.

    Este artigo demonstra como aplicar o modelo de maturidade do OWASP SAMM de forma prática e incremental, permitindo que as equipes adotem o DevSecOps de maneira sustentável e eficaz.

    Por que adotar um modelo de maturidade?

    Iniciativas de segurança em DevSecOps, quando isoladas — uma análise de código aqui, um teste de penetração ali — carecem de consistência e não garantem uma evolução real do processo. Reconhecendo esse desafio aqui na Facti, entendemos que adotar o DevSecOps é, antes de tudo, uma mudança de cultura que exige um norte claro. É exatamente por isso que um modelo de maturidade como o SAMM resolve o problema, ao fornecer:

    • Direcionamento Estratégico: Define metas claras de curto e longo prazo.
    • Evolução Gradual: Estrutura a jornada em etapas progressivas, do manual ao automatizado.
    • Métricas Objetivas: Permite acompanhar o progresso e demonstrar o valor das ações de segurança dentro da adoção de metodologias ágeis para orquestração das atividades.

    O OWASP SAMM organiza as práticas de segurança em cinco funções de negócio, com cada uma sendo avaliada em três níveis de maturidade.

    Aplicação Prática: Integrando o SAMM ao seu dia a dia

    A implementação bem-sucedida do OWASP SAMM depende do seu mapeamento direto no ciclo de vida dos projetos.

    1. Mapeamento com o Processo de Desenvolvimento Integração de cada função do SAMM às fases do seu SDLC:
    • Governança: Alinhe as políticas de segurança a normas como a LGPD e a ISO/IEC 27001.
    • Design: Realize a modelagem de ameaças e defina requisitos de segurança desde a fase de concepção.
    • Implementação: Adote padrões de arquitetura segura e automatize builds com verificações de segurança.
    • Verificação: Integre ferramentas SAST, DAST e SCA (como SonarQube, OWASP ZAP e Trivy) aos pipelines de CI/CD.
    • Operações: Automatize a gestão de infraestrutura (Infrastructure as Code – IaC) e mantenha um plano proativo de resposta a incidentes.
    1. As Fases da Maturidade: Uma Jornada Incremental O avanço pode ser estruturado em quatro fases:
    • Fase 1: Fundacional
      • Implementação inicial de SAST e linting no CI/CD.
      • Definição de requisitos mínimos de segurança.
    • Fase 2: Expansão
      • Introdução de DAST (análise dinâmica) e SCA (análise de componentes).
      • Criação de políticas de qualidade (Quality Gates).
    • Fase 3: Fortalecimento
      • Execução periódica de testes de penetração (pentests).
      • Coleta e análise de métricas de segurança.
      • Formalização do processo de gestão de incidentes.
    • Fase 4: Otimização
      • Integração da segurança na arquitetura como padrão.
      • Automação da conformidade com frameworks (NIST SSDF, ISO 27034).
      • Provisionamento de ambientes totalmente via IaC.

    1. Ferramentas Essenciais Para apoiar essa jornada, considere ferramentas como:
    • Análise de Código e Qualidade: SonarQube (SAST).
    • Análise de Aplicação em Execução: OWASP ZAP (DAST).
    • Análise de Dependências: Trivy (SCA).
    • Gestão de Segredos: HashiCorp Vault.
    • Infraestrutura como Código: Terraform, Ansible (com validação de segurança via tfsec).
    • Monitoramento: Grafana.

    Medindo o progresso

    A grande vantagem de um modelo de maturidade é a capacidade de medir o avanço com indicadores-chave de desempenho (KPIs), como:

    • Percentual de builds com verificação SCA > 95% (nível ideal: 100% para builds de produção).
    • Tempo médio para correção de vulnerabilidades (MTTR) 

    Críticas: < 7 dias

    Altas: < 14 dias

    Médias: < 30 dias

    Baixas: < 60 dias

    • Nível de aderência aos padrões de arquitetura segura.

    Novos projetos: > 90%

    Legados (críticos/modernizados): > 70%

    Global (em maturidade avançada): 80-100%

    • Taxa de sucesso na resposta a incidentes > 80%

    Isso permite não apenas justificar investimentos, mas também ajustar prioridades de forma inteligente através do que chamamos de Shift Left, ou seja, antecipar as atividades de segurança e testes para as fases iniciais do ciclo de vida de desenvolvimento de software (SDLC).

    Conclusão

    Construir um SDLC seguro é uma jornada contínua, não um projeto com data de término. Ao adotar um modelo como o OWASP SAMM, as equipes transformam o DevSecOps em um processo estruturado e mensurável. A segurança deixa de ser um “freio” e se torna um pilar de confiança e uma vantagem competitiva.

    O segredo é começar: escolha as práticas mais críticas para o seu contexto, integre-as ao seu pipeline e evolua com consistência e visibilidade.

     

  • Cibersegurança no Brasil: 6 passos para sair da estagnação

    O Brasil está parado quando o assunto é maturidade em Cibersegurança, ou segurança digital. Segundo uma recente pesquisa da Cisco, apenas 5% das empresas brasileiras atingem esse nível, o mesmo percentual de 2023. Enquanto isso, países emergentes como Vietnã e Singapura deram saltos significativos mesmo com menos recursos.

    Cibersegurança no Brasil: 6 passos para sair da estagnação

    Diante disso, chegou a hora de sair da estabilidade e buscar uma evolução real. O Brasil tem potencial, mas precisa agir com mais rapidez e visão de futuro para alcançar os próximos patamares. A maturidade cibernética será um diferencial competitivo e quem se mexer agora, sairá na frente.

    Mas como virar esse jogo? Veja abaixo seis passos que o Brasil pode adotar para acelerar sua evolução em cibersegurança.

    1. Digitalizar as PMEs com segurança desde o início

    Boa parte das pequenas e médias empresas ainda não investe em medidas básicas de proteção digital. Criar soluções simples, acessíveis e de fácil adoção é fundamental para evitar que esse setor continue vulnerável e arraste a média nacional para baixo.

    2. Formar profissionais rapidamente

    O déficit de talentos em cibersegurança no Brasil é enorme. É preciso acelerar a formação com cursos técnicos de curta duração, programas de certificação e parcerias com empresas que topem treinar novos profissionais em vez de esperar especialistas prontos no mercado.

    3. Transformar segurança em política pública

    Outros países avançaram porque fizeram da cibersegurança uma prioridade estratégica nacional. O Brasil precisa seguir o mesmo caminho: estabelecer metas, destinar orçamento, criar um plano integrado e incentivar a cooperação entre empresas, governo e sociedade.

    4. Incluir segurança na cultura das empresas

    Não basta investir em tecnologia se os colaboradores continuam clicando em links suspeitos. Treinamentos frequentes, campanhas internas e apoio da liderança são essenciais para que a segurança se torne parte do dia a dia corporativo e não um item esquecido na TI.

    5. Apoiar o ecossistema nacional de cibersegurança

    Startups brasileiras oferecem soluções competitivas, mas ainda são pouco valorizadas por empresas médias e governos locais. Fortalecer esse ecossistema impulsiona inovação, reduz custos e cria uma rede de proteção mais conectada à realidade do país.

    6. Observar e adaptar os bons exemplos

    Vietnã e Singapura mostraram que é possível avançar com foco e decisões assertivas. O Brasil pode – e deve – estudar o que esses países fizeram, adaptar as práticas que funcionaram e criar ambientes colaborativos para troca de experiências entre setores.

  • Ciclos de Similaridade Web: como identificar padrões e rupturas na era dos dados

    Ciclos de Similaridade Web: como identificar padrões e rupturas na era dos dados

    A Nova Fronteira da Análise Digital

    Imagine um mundo onde cada website que surge na internet é automaticamente comparado com milhões de outros sites, identificando não apenas suas semelhanças visuais, mas também seus padrões de comportamento, estrutura de conteúdo e performance. Essa realidade já existe, e está transformando como entendemos os ciclos de inovação digital.

    O Que São Ciclos de Similaridade Web?

    Os ciclos de similaridade web representam períodos onde múltiplos websites seguem padrões similares de design, funcionalidade ou estratégia de conteúdo. Tradicionalmente, identificar esses padrões exigia análise manual extensiva e muito tempo. Hoje, através da combinação de tecnologias como Apache Flink, Large Language Models (LLMs) e sistemas de busca vetorial como Qdrant, podemos detectar essas tendências em tempo real.

    Como Funciona a Detecção Inteligente de Padrões

    Neste artigo vou pegar por exemplo o Apache Flink 2.0 como o sistema nervoso central, processando milhões de eventos de campanha e interações de website simultaneamente. Cada clique, scroll, tempo de permanência e conversão é capturado e analisado instantaneamente.

    2. Extração Semântica de Conteúdo

    Aqui entra a magia dos LLMs integrados ao Flink CDC 3.3. Esses modelos não apenas “leem” o conteúdo das páginas, mas compreendem seu contexto, extraindo insights sobre títulos, estrutura narrativa, tom de comunicação e proposta de valor. É como ter um analista de conteúdo que nunca dorme, examinando cada novo site que surge.

    3. Armazenamento Vetorial Inteligente

    O Qdrant funciona como uma memória coletiva da internet, armazenando não apenas os dados brutos, mas representações vetoriais que capturam a “essência” de cada website. Quando um novo site é analisado, o sistema pode instantaneamente identificar suas similaridades com milhares de outros sites.

    Identificando Rupturas de Padrão

    O verdadeiro valor desta arquitetura emerge quando ela identifica websites que quebram padrões estabelecidos. O agente de IA realiza uma análise tridimensional:

    Consulta Histórica: Examina sites similares em estrutura e segmento Análise de Performance: Compara métricas de engajamento e conversão Detecção de Gaps: Identifica lacunas entre performance esperada versus real

    O Poder da Otimização Preditiva

    Diferentemente das abordagens tradicionais que esperam dados de performance se acumularem, esta arquitetura permite otimização desde o primeiro dia. Baseando-se em conhecimento de contextos similares, o sistema pode:

    • Prever quais elementos de design terão maior impacto
    • Sugerir estratégias de conteúdo baseadas em sucessos similares
    • Identificar oportunidades de diferenciação antes da concorrência

    Implicações para o Futuro Digital

    Esta abordagem representa uma mudança fundamental: da análise reativa para a inteligência preditiva. Em vez de esperar meses para entender o que funciona, podemos iniciar com hipóteses baseadas em milhares de casos similares, acelerando exponencialmente os ciclos de feedback e inovação.

    Insights em Tempo Real: O Novo Padrão

    A capacidade de obter insights imediatos sobre padrões de mercado transforma como pensamos sobre competitividade digital. Empresas podem identificar tendências emergentes antes que se tornem mainstream, posicionando-se como pioneiras em novos padrões de experiência digital.

    Arquitetura para essa captura, analise e otimização preditiva

    Visão Geral da Arquitetura

    Esta arquitetura implementa um sistema completo de detecção de padrões web usando exclusivamente tecnologias open source, dividida em 7 camadas principais que trabalham em conjunto para oferecer análise inteligente em tempo real. Preferi montar open source não só por que sou facionado pela comunidade como também a infinidade de produtos sensacionais que temos hoje que vieram da Apache Foundation.

    1. Camada de Coleta de Dados (Data Ingestion Layer)

    Apache Kafka + Kafka Connect

    1. Função: Hub central de eventos e streaming de dados.
    2. Conectores: Debezium: Captura mudanças (CDC) de bases de dados.
    3. HTTP Source Connector: Ingere dados de APIs web.
    4. File Connector: Processa logs de servidores web.

    Scrapy Cluster

    1. Função: Web scraping distribuído e escalável
    2. Componentes:

    – Redis: Fila de URLs para scraping.

    -Kafka: Pipeline de dados extraídos.

    – Scrapyd: Gestão de spiders distribuídos.

    Fluentd – É Sensacional

    1. Função: Coleta e roteamento de logs
    2. Integrações: Nginx, Apache, aplicações web
    3. Output: Kafka tópicos estruturados

    2. Camada de Processamento em Tempo Real (Stream Processing)

    Apache Flink

    • Função: Processamento de stream principal
    • Jobs:
    1. Web Content Analyzer: Extrai metadados de HTML/CSS/JS.
    2. Performance Metrics Calculator: Calcula métricas de UX em tempo real.
    3. Pattern Detector: Identifica similaridades estruturais.
    4. Anomaly Detector: Detecta desvios de padrões.

    Apache Storm (alternativa/complemento)

    • Função: Processamento de eventos complexos
    • Topologias: Análise de comportamento de usuário em tempo real.

    3. Camada de Inteligência Artificial (AI Layer)

    Ollama + Modelos Open Source

    • Modelos sugeridos: CodeLlama: Análise de código HTML/CSS/JavaScript
    • Llama 2/3: Análise semântica de conteúdo
    • Mistral 7B: Classificação e categorização
    • Deployment: Kubernetes com GPU support

    Hugging Face Transformers

    • Modelos especializados:
    • BERT: Embeddings de texto para similaridade semântica
    • CLIP: Análise de imagens e layouts visuais
    • T5: Geração de insights e resumos

    spaCy + Custom Models

    • Função: NLP especializado para conteúdo web
    • Pipelines: Extração de entidades, análise de sentimento, classificação de tópicos

    4. Camada de Armazenamento Vetorial (Vector Storage)

    Qdrant

    • Função: Armazenamento e busca de embeddings
    • Collections:
    1. website_content: Embeddings de conteúdo textual
    2. visual_layouts: Representações visuais de layouts
    3. user_behavior: Padrões de interação do usuário
    4. performance_profiles: Perfis de performance técnica

    5. Camada de Dados Estruturados (Structured Data Layer)

    Apache Cassandra

    • Função: Armazenamento de séries temporais
    • Tables:
    1. website_metrics: Métricas de performance por timestamp.
    2. crawl_history: Histórico de crawling.
    3. pattern_evolution: Evolução de padrões ao longo do tempo.

    6. Camada de Orquestração e Workflow (Orchestration Layer)

    Apache Airflow

    DAGs principais:

    1. daily_pattern_analysis: Análise diária de novos padrões.
    2. model_retraining: Retreino de modelos ML.
    3. data_quality_checks: Validação de qualidade dos dados.
    4. competitive_analysis: Análise competitiva automatizada.

    Kubernetes + Helm (ou Docker/Swarm):

    • Função: Orquestração de containers
    • Operators: Flink, Kafka, Spark para gestão declarativa

    7. Camada de API e Interface (API & Interface Layer)

    FastAPI

    • Endpoints:
    • /analyze/website: Análise de um website específico
    • /patterns/similar: Busca por websites similares
    • /insights/trends: Tendências emergentes
    • /compare/websites: Comparação entre múltiplos sites

    Apache Superset

    • Função: Dashboards e visualizações
    • Dashboards:
    • Real-time Pattern Detection: Padrões em tempo real
    • Competitive Intelligence: Inteligência competitiva
    • Performance Benchmarks: Benchmarks de performance

    Grafana + Prometheus

    • Função: Monitoramento da infraestrutura
    • Métricas: Latência, throughput, saúde dos componentes

    Agora saindo do técnico esse assunto é realmente relevante: qual seu peso? qual seu ganho?

    Olhando para o mercado de web, mais especificamente a parte de experiência de usuário e de buscas por AI movimentou USD 56,82 bilhões em 2024 e deve crescer para USD 109,12 bilhões até 2032, com CAGR de 8,5% segundo fontes (https://www.businessresearchinsights.com/market-reports/web-design-market-117595 e https://www.wiseguyreports.com/reports/web-design-market)

    IA em Marketing: ROI Comprovado:

    49% dos líderes de tecnologia já integraram IA totalmente na estratégia de negócios das empresas, com ganhos de 20% a 30% em produtividade, velocidade de mercado e receita 2025 AI Business Predictions: PwC. Empresas que fazem IA corretamente alcançam 13% de ROI em projetos de IA, comparado à média de 5,9% How to Secure the Best ROI from Your AI Investment in 2024.

    Vantagem Competitiva Comprovada

    O mercado de Revenue Intelligence Platform cresceu para USD 2,18 bilhões em 2024 e deve atingir USD 3,95 bilhões até 2033 Top 10 Revenue Intelligence Tools to Boost Your Sales Strategy in 2024 – SuperAGI. Empresas que usam arquiteturas cloud de próxima geração e IA têm maior probabilidade de melhorar lucratividade, produtividade e time-to-market In the age of AI: Speed matters more, scale matters less, innovation matters most.

    O conceito não é apenas relevante – é inevitável para empresas que querem manter vantagem competitiva no ambiente digital de 2025+.

    Me sigam no Linkedin para dúvidas ou acompanhar mais artigos/post sobre temas desse tipo. E quem é AI Engineer & Data Engineer e quer ver uma POC da arquitetura montada conforme mencionado no artigo, deixa nos comentários para eu fazer um parte 2 só da construção da arquitetura.