image

Unlimited bootcamps and 750+ courses forever

70
%OFF
Daniel Bartholdy
Daniel Bartholdy03/09/2026 21:45
Share
IBM Bob: IA de Nível Empresarial para Desenvolvedores e Tech LeadersRecommended for youIBM Bob: IA de Nível Empresarial para Desenvolvedores e Tech Leaders

Como um Portfólio em Angular Evoluiu para uma Plataforma de Conhecimento com IA

    Introdução

    Todo desenvolvedor, em algum momento da carreira, cria um portfólio.

    Normalmente ele possui uma página inicial, uma seção "Sobre mim", uma lista de projetos, experiências profissionais e certificações. É suficiente para apresentar um resumo da carreira, mas existe uma limitação importante: o visitante só consegue acessar aquilo que está visível na interface.

    Foi exatamente assim que este projeto começou.

    Meu objetivo inicial era aprender Angular desenvolvendo uma aplicação real para substituir meu antigo portfólio. Naquele momento, não existia backend, banco de dados ou qualquer recurso de Inteligência Artificial.

    Com o tempo, porém, cada nova necessidade levou a uma mudança arquitetural. O projeto deixou de ser apenas uma interface e passou a evoluir até se tornar uma plataforma capaz de compreender e responder perguntas sobre minha própria trajetória profissional.

    Neste artigo compartilho essa evolução, as decisões de arquitetura tomadas em cada etapa e os principais aprendizados obtidos durante o desenvolvimento.

    Fase 1 -> O primeiro MVP

    O projeto começou da maneira mais simples possível.

    Toda a aplicação era construída em Angular e todos os dados eram armazenados diretamente em arquivos TypeScript.

    A estrutura era semelhante a esta:

    src/
     ├── projects.data.ts
     ├── experience.data.ts
     ├── certifications.data.ts
     └── technologies.data.ts
    

    Cada componente carregava esses objetos e apenas os renderizava na tela.

    A arquitetura era extremamente simples. A jornada de transformar uma aplicação estática em uma arquitetura baseada em Spring Boot, Spring AI, PostgreSQL, pgvector e RAG para responder perguntas sobre minha trajetória profissional.

    Introdução

    Durante muitos anos, um portfólio de desenvolvedor seguia praticamente o mesmo padrão.

    Uma página inicial, uma lista de projetos, uma seção sobre experiência profissional e alguns links para GitHub e LinkedIn.

    Funciona.

    Mas existe um problema.

    A maior parte da minha experiência profissional nunca aparece completamente.

    Um recrutador normalmente dedica poucos minutos para analisar um currículo ou um portfólio. Mesmo que todas as informações estejam disponíveis, elas continuam distribuídas entre diferentes páginas, documentos e projetos.

    Foi então que surgiu uma pergunta.

    E se meu próprio portfólio fosse capaz de responder perguntas sobre minha trajetória profissional?

    Essa ideia evoluiu para muito mais do que um chatbot.

    Ela se tornou uma plataforma de conhecimento construída sobre Spring Boot, Angular, PostgreSQL, pgvector e Spring AI.

    O problema

    Não queria criar apenas uma interface para conversar com um LLM.

    Queria que as respostas fossem baseadas exclusivamente na minha experiência profissional.

    Isso trouxe vários desafios.

    • Como organizar o conhecimento?
    • Como evitar respostas inventadas?
    • Como permitir crescimento da base de conhecimento?
    • Como controlar custos da OpenAI?
    • Como tornar a solução preparada para produção?

    Primeira versão

    Inicialmente a arquitetura era simples.

    Ver credenciais de conteúdo

    image

    Essa abordagem possuía algumas vantagens.

    • Desenvolvimento extremamente rápido.
    • Nenhuma dependência de infraestrutura.
    • Deploy simples.

    Por outro lado, conforme o projeto crescia, algumas limitações começaram a aparecer.

    Cada alteração exigia recompilar toda a aplicação.

    Não existia reutilização dos dados por outras aplicações.

    Todo o conteúdo estava acoplado ao frontend.

    Naquele momento ficou claro que os dados precisavam deixar de fazer parte da interface.

    Fase 2 -> Separando a aplicação dos dados

    O próximo passo foi criar um backend responsável por fornecer todas as informações do portfólio.

    A escolha foi o ecossistema Java com Spring Boot, utilizando uma arquitetura organizada por funcionalidades e baseada em princípios de Clean Architecture.

    A aplicação passou a possuir duas responsabilidades distintas.

    O frontend tornou-se apenas responsável pela experiência do usuário.

    O backend passou a concentrar regras de negócio, persistência, internacionalização e exposição das APIs.

    A arquitetura evoluiu para:

    image

    Os dados deixaram de existir em arquivos TypeScript e passaram a ser armazenados em um banco PostgreSQL, utilizando Flyway para controle de versão do schema e das migrações.

    Essa mudança trouxe benefícios importantes.

    • Atualizações passaram a ser realizadas diretamente no banco de dados.
    • O frontend tornou-se desacoplado do conteúdo.
    • Novas integrações passaram a ser possíveis.
    • A API ficou disponível para outros consumidores.

    Era um backend tradicional.

    Até que surgiu uma nova ideia.

    Fase 3 -> E se o portfólio pudesse responder perguntas?

    Mesmo com uma interface mais rica, continuava existindo uma limitação.

    Imagine que um recrutador queira descobrir rapidamente:

    Daniel já trabalhou com ERP?

    Ou então:

    Qual foi a maior equipe que ele liderou?

    Ou ainda:

    Em quais projetos utilizou Java?

    Todas essas respostas existiam.

    Mas estavam distribuídas entre páginas diferentes.

    O usuário precisava navegar manualmente pelo site.

    Foi então que surgiu a ideia de adicionar um assistente conversacional.

    A primeira implementação parecia simples.v

    image

    Na prática, porém, o resultado ficou muito distante do esperado.

    O modelo respondia utilizando apenas seu conhecimento geral.

    Ele não conhecia minha experiência profissional.

    Não sabia em quais empresas trabalhei.

    Não conhecia meus projetos.

    Nem minhas certificações.

    Era necessário fornecer contexto.

    Fase 4 -> Descobrindo o Retrieval-Augmented Generation (RAG)

    Ao estudar diferentes arquiteturas para aplicações baseadas em IA, encontrei uma abordagem que fazia muito sentido para esse cenário: Retrieval-Augmented Generation (RAG).

    Em vez de enviar diretamente a pergunta para o modelo, a aplicação passou a executar uma etapa intermediária de recuperação de contexto.

    O fluxo passou a ser:

    Ver credenciais de conteúdo

    image

    Essa mudança representou um enorme salto na qualidade das respostas.

    Mas um novo problema apareceu.

    Fase 5 -> O problema não era o modelo

    No início imaginei que respostas incompletas significavam que eu precisava utilizar um modelo maior.

    Na prática, descobri exatamente o contrário.

    O problema estava na organização do conhecimento.

    Inicialmente eu havia criado poucos documentos grandes contendo praticamente toda minha trajetória.

    Isso fazia com que o mecanismo de recuperação retornasse chunks muito genéricos.

    Em algumas perguntas, informações importantes simplesmente não eram recuperadas.

    Foi nesse momento que comecei a estudar um assunto que, até então, eu conhecia muito pouco: Knowledge Engineering.

    Ao invés de um único documento sobre minha carreira, passei a criar documentos especializados.

    knowledge/
    
    ├── career/
    │   ├── empresa1.md
    │   ├── empresa2.md
    │   ├── empresa3.md
    │   └── empresa4.md
    │
    ├── projects/
    │   ├── projeto1.md
    │   ├── projeto2.md
    │   └── projeto3.md
    │
    ├── leadership/
    │   ├── management.md
    │   └── agile.md
    │
    └── certifications/
    

    Cada documento passou a representar um único assunto.

    Essa reorganização melhorou significativamente a precisão da recuperação sem alterar uma única linha relacionada ao modelo de IA.

    Foi uma das maiores lições do projeto.

    Fase 6 -> Automatizando a construção da base de conhecimento

    Depois de reorganizar os documentos, surgiu outra preocupação.

    Como manter essa base atualizada?

    Foi então que desenvolvi um pipeline responsável por preparar automaticamente cada documento antes de sua ingestão.

    Ver credenciais de conteúdo

    image

    Cada documento recebe metadados, é dividido em partes semanticamente coerentes, convertido em embeddings e armazenado em um banco vetorial utilizando PostgreSQL com pgvector.

    Quando uma pergunta é realizada, apenas os trechos mais relevantes são enviados ao modelo.

    Fase 7 -> Pensando como um sistema de produção

    Nesse momento o projeto deixou de ser apenas um experimento de IA.

    Passei então a tratar a aplicação como faria em um ambiente corporativo.

    Ao longo das últimas semanas foram incorporadas diversas melhorias arquiteturais.

    • Clean Architecture
    • Spring AI
    • PostgreSQL + pgvector
    • Busca híbrida
    • Prompt Engineering
    • Hardening contra Prompt Injection
    • Rate Limiting com Bucket4j
    • Retry, Timeout e Circuit Breaker com Resilience4j
    • Flyway
    • Docker otimizado para produção
    • Observabilidade
    • Testcontainers
    • OpenAPI

    Curiosamente, nenhuma dessas melhorias alterou a experiência visual do usuário.

    Elas aumentaram algo ainda mais importante: a confiabilidade da plataforma.

    Principais aprendizados

    Ao olhar para trás, percebo que a maior parte do trabalho não esteve relacionada à Inteligência Artificial em si.

    Ela esteve relacionada à engenharia em torno dela.

    Hoje acredito que a qualidade de uma aplicação baseada em RAG depende muito mais de fatores como:

    • organização da base de conhecimento;
    • qualidade dos documentos;
    • engenharia de contexto;
    • estratégia de recuperação;
    • arquitetura da aplicação;
    • observabilidade;
    • segurança;
    • resiliência.

    Trocar o modelo de IA costuma produzir ganhos muito menores do que melhorar essas etapas.

    Próximos passos

    O projeto continua evoluindo.

    Entre as próximas melhorias planejadas estão:

    • reranking dos documentos recuperados;
    • classificação de intenção antes da recuperação;
    • filtros por metadados;
    • cache semântico;
    • streaming de respostas;
    • OpenTelemetry;
    • suporte a múltiplos modelos de linguagem.

    Conclusão

    Este projeto começou como um simples exercício para aprender Angular.

    Depois evoluiu para uma API em Spring Boot.

    Em seguida tornou-se um backend estruturado para um portfólio multilíngue.

    Por fim, transformou-se em uma plataforma de conhecimento capaz de responder perguntas sobre minha trajetória profissional utilizando Inteligência Artificial.

    Mais do que aprender um conjunto de frameworks, esse projeto mostrou na prática como sistemas evoluem: novas necessidades surgem, a arquitetura se adapta e a engenharia passa a ser tão importante quanto a própria IA.

    Se existe uma conclusão que levo dessa jornada, é esta:

    Construir aplicações inteligentes não significa apenas integrar um modelo de linguagem. Significa projetar cuidadosamente como o conhecimento é organizado, recuperado e entregue ao modelo para produzir respostas realmente úteis.
    Share
    Recommended for you
    CI&T - Java AI Copilot
    Itaú - Java com Inteligência Artificial
    Nublify - Primeiros passos em IA e Cloud
    Comments (0)
    Recommended for youIBM Bob: IA de Nível Empresarial para Desenvolvedores e Tech Leaders