1O problema
Em empresas de tecnologia, dois tipos de conteúdo vivem desacoplados: a documentação técnica (o que o produto faz de verdade) e os artigos da central de ajuda (o que o usuário final lê). Quando o produto muda, alguém precisa lembrar de atualizar a documentação — e depois lembrar de quais artigos aquela mudança afetou, e reescrever cada um na mão. Esse laço quebra o tempo todo: a doc anda para frente e os artigos envelhecem no silêncio.
Queríamos fechar esse laço com IA, mas sem tirar o humano da decisão. A ideia: a doc técnica é a fonte única da verdade e vive dentro do próprio app. Quando uma nova versão de uma doc é subida, o sistema descobre quais artigos foram impactados e redige as revisões — mas nada vai ao ar sem uma pessoa aprovar. A IA faz o trabalho pesado; o humano mantém a palavra final.
2A stack
"Stack" é a palavra para o conjunto de peças de software que sustentam um produto. A escolha-guia do BaseViva foi se apoiar numa stack de nuvem gerenciada e deixar que ela cuide do encanamento, para o esforço ir para a IA e para a detecção de impacto. O front é um app web em React (feito com Vite); o backend é o AWS Amplify Gen 2 — um kit que conecta login, banco de dados e API a partir de código TypeScript. Veja o termo para a versão em linguagem simples.
O login roda sobre o Amazon Cognito, e toda a API é uma camada (AppSync) gerada automaticamente a partir dos modelos de dados — não há CRUD escrito à mão nem um gateway de API separado. Os dados moram no , e cada modelo é isolado : cada usuário só enxerga os próprios dados. A IA generativa roda no , alcançada por um punhado de pequenas funções .
O app React no navegador. Duas coisas rodam aqui mesmo no cliente: quebrar o markdown em seções (chunking) e a detecção de impacto, calculada sobre vetores carregados do servidor.
Login por email pelo Amazon Cognito. O token que ele emite carrega a identidade que marca cada registro como pertencente àquele usuário.
Toda a API é uma camada que o Amplify gera a partir dos modelos de dados — sem CRUD à mão, sem gateway de API separado.
Dez modelos no , cada um isolado . Entre eles, o modelo Embedding guarda um item por vetor de seção.
Quatro pequenas funções — embed, rewrite, outline e draftArticle — existem por um motivo só: chamar a IA. Cada uma com a permissão mínima para o modelo que usa.
O roda dois modelos: o Titan v2 para transformar texto em vetores (embeddings) e o Claude para escrever os rascunhos de artigos.
Uma nota deliberada sobre onde a lógica roda: a IA (no Bedrock) e a persistência (no DynamoDB) ficam no servidor, mas o chunking do markdown e a detecção de impacto são funções puras que rodam no navegador, sobre vetores carregados sob demanda. Essa divisão importa para a próxima seção.
3Como a IA foi usada
A IA aparece em dois momentos. O primeiro é quando você sobe uma doc pela primeira vez: ainda não há artigos, então a IA propõe os iniciais. O segundo — o coração do produto — é quando você sobe uma nova versão de uma doc que já tem artigos: o sistema detecta o que mudou, acha os artigos impactados e redige as revisões. Toque em cada passo para seguir esse segundo fluxo.
Você sobe uma nova versão de uma doc técnica (Markdown ou .docx). O app extrai o texto e guarda o arquivo original; cada upload vira uma nova versão, nunca sobrescrevendo a anterior.
O markdown é quebrado em seções pelos seus headings, e o sistema compara a versão antiga com a nova seção por seção para ver exatamente quais seções mudaram. Isso acontece sobre por seção, não sobre o documento inteiro.
Cada artigo lembra de qual seção da doc ele veio (seu ). Então os artigos impactados são simplesmente os ligados a uma seção que mudou — um sinal confiável, em vez de um frágil score de similaridade artigo-vs-doc.
Para cada artigo impactado, a IA (Claude, no Bedrock) escreve uma revisão como rascunho — uma . Ela nunca sobrescreve o artigo publicado; produz uma versão proposta mais um resumo curto do que mudou.
Uma pessoa revisa a proposta ao lado de um diff contra a versão publicada, e decide: aprovar, editar e aprovar, ou rejeitar. Só na aprovação uma nova versão publicada do artigo é criada. Nada vai ao ar sozinho.
No primeiro upload de uma doc, o fluxo é um pouco diferente: ainda não há artigos, então você escolhe como gerá-los — a doc inteira como um artigo, ou vários artigos divididos pelos headings. De qualquer forma, cada rascunho entra como uma proposta do tipo "novo artigo", e a mesma revisão humana decide se ele vira um artigo publicado.
4Principais decisões
Manter um humano no laço, sempre. Teria sido mais simples deixar a IA publicar as revisões automaticamente. Escolhemos o oposto: a IA só produz um rascunho, e nada chega ao usuário final sem uma pessoa aprovar. Uma central de ajuda é uma promessa ao cliente — errar em escala é pior do que atualizar um pouco mais devagar.
A doc técnica é a fonte única da verdade, dentro do app. Em vez de depender de Git ou de serviços externos, a fonte da verdade é o arquivo que você sobe — e o gatilho de tudo é simplesmente subir uma nova versão. Sem integração para configurar, sem pipeline para vigiar. Sobe uma doc, e o laço começa.
Upload em vez de GitHub. A premissa original era outra: as docs morariam num repositório do GitHub, e um push ali dispararia a atualização. Abrimos mão disso de propósito — uma integração com Git traz autenticação, webhooks e um passo de configuração inteiro antes de alguém ter qualquer valor. Como isso foi construído ao vivo num curso, escolhemos o caminho que vai direto ao ponto: a pessoa sobe a documentação técnica direto na plataforma, e a IA gera os artigos a partir dela. O modelo ainda trata o upload como "uma nova versão", então reconectar o Git mais tarde é um acréscimo, não uma reescrita.
Nunca sobrescrever — sempre versionar. Tanto docs técnicas quanto artigos são versionados: um novo upload ou uma nova revisão aprovada cria uma versão nova, a anterior permanece. É isso que deixa o sistema mostrar um diff, manter uma trilha de auditoria, e deixar um humano comparar o artigo publicado com a mudança proposta lado a lado.
Trabalhar por seção, não por documento inteiro. Docs técnicas reais são grandes. Tratar uma doc como um blob único quebra de várias formas, então fizemos da a unidade de trabalho — para dividir em artigos, para embeddings e para detecção de impacto. Essa decisão sozinha é o que faz o resto funcionar; a próxima seção explica por quê.
5Sendo mais técnico…
Esta seção é para quem quer olhar por baixo do capô. Nada aqui é necessário para entender o produto — mas essas decisões são as que fizeram a detecção de impacto ser confiável em vez de frágil.
Detecção de impacto ancorada na seção, não em similaridade artigo-vs-doc. Nosso primeiro instinto foi comparar cada artigo de ajuda contra cada seção da doc por . A medição real matou essa ideia: um artigo amigável e uma seção técnica seca pontuam baixo mesmo quando são sobre a mesma coisa, então qualquer limiar nessa escala é frágil — causou um bug de "não propõe nada". O sinal confiável é outro: comparar doc v1 contra doc v2, seção por seção (mesmo tipo de texto), separa com nitidez. Então o gatilho real virou: cada artigo registra o heading de onde veio; quando essa seção muda entre versões, o artigo é impactado — direto, sem o score frágil.
Um embedding por seção, guardado uma linha por vez. Um embedding do documento inteiro é truncado pelo limite de entrada do modelo e dilui uma mudança localizada num único vetor — duas versões podem até parecer idênticas porque ambas truncam no mesmo começo. Então geramos um embedding por seção. Cada (cerca de 1024 números, ~21 KB) é guardado como uma linha no banco, indexado pela versão a que pertence. Uma tentativa anterior guardava tudo isso no armazenamento local do navegador e estourava a cota de ~5 MB em docs grandes; mover para o servidor resolveu de vez.
Dividir o markdown programaticamente, usar a IA só para os títulos. Pedir à IA um JSON com o texto de todas as seções estoura o limite de tokens de saída — o JSON volta truncado, o parse falha, e cai no fallback de "um artigo". Então a divisão por headings é feita de forma determinística no código, e a IA é usada só para melhorar os títulos dos artigos, nunca para devolver o conteúdo. Uma pequena troca de responsabilidade que, no silêncio, removeu uma classe inteira de falhas.
Permissão de mínimo privilégio por função de IA. Cada só pode chamar o modelo exato de que precisa: a função de embedding alcança só o Titan; as de escrita alcançam só o Claude. Nenhum segredo vive no repositório — as funções falam com a IA pela sua role de execução, nunca por uma chave no código.
6Aprendizados
Meça antes de confiar numa métrica. Assumimos que a similaridade semântica entre um artigo e uma doc seria um bom sinal de impacto. Não era — e só a medição real mostrou isso. O aprendizado com IA é validar o sinal contra números reais antes de construir uma feature inteira em cima dele.
A granularidade decide tudo. Trabalhar no nível do documento falhou em três frentes de uma vez — embeddings truncados, JSON quebrado, progresso invisível. Descer para o nível da seção consertou os três. Com IA, o tamanho da unidade que você processa costuma importar mais do que o prompt em si.
Operações longas de IA precisam de progresso visível. Gerar N artigos ou embutir N seções leva tempo, e um único spinner global parece uma tela travada. Quebrar o trabalho pesado em passos pequenos e mostrar "item X de N" transforma a espera em algo que parece estar sendo construído — o mesmo aprendizado que levamos em cada produto.