<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: He4rt Developers</title>
    <description>The latest articles on DEV Community by He4rt Developers (he4rt).</description>
    <link>https://dev.to/he4rt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F5490%2Fef471ad5-dbd9-40be-9951-743a6026d59c.png</url>
      <title>DEV Community: He4rt Developers</title>
      <link>https://dev.to/he4rt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/he4rt"/>
    <language>en</language>
    <item>
      <title>Claude e Obsidian - Como uma QA utiliza essas ferramentas no dia-a-dia</title>
      <dc:creator>Alicia Marianne Gonçalves</dc:creator>
      <pubDate>Mon, 28 Sep 2026 23:03:40 +0000</pubDate>
      <link>https://dev.to/he4rt/claude-e-obsidian-como-uma-qa-utiliza-essas-ferramentas-no-dia-a-dia-51jc</link>
      <guid>https://dev.to/he4rt/claude-e-obsidian-como-uma-qa-utiliza-essas-ferramentas-no-dia-a-dia-51jc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🇺🇸 &lt;em&gt;You can also read the English version of this article on &lt;a href="https://builder.aws.com/content/3Jybv1TohV8qpvJ80e1JopCd9pN/claude-and-obsidian-how-a-qa-professional-uses-these-tools-on-a-daily-basis" rel="noopener noreferrer"&gt;AWS Community Builders&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ser QA nessa era de IA tem sido bem desafiador, principalmente quando a velocidade de entrega é maior, fica o grande questionamento: Como eu vou conseguir garantir que não me esqueci de nada? Será que estou cobrindo os cenários que realmente precisam ser cobertos? Ter uma boa organização é essencial pra todas áreas da vida, e dentro da área de QA não seria diferente, por isso atualmente o Obsidian tem sido uma ferramenta bem presente no meu dia-a-dia, e vim falar pra vocês como eu tenho utilizado ela. &lt;/p&gt;

&lt;h2&gt;
  
  
  Por que o Obsidian?
&lt;/h2&gt;

&lt;p&gt;Basicamente, o Obsidian é um aplicativo de anotações e gestão de conhecimento que funciona com arquivos Markdown(.md) que são guardados localmente no seu computador, tendo a possibilidade de te-los na nuvem utilizando a versão paga ou algum plugin da comunidade. &lt;/p&gt;

&lt;p&gt;E diversos fatores me fizeram migrar para essa ferramenta. Antes, eu utilizava o Notion que apesar de ser uma boa ferramenta, pra mim, ser tão personalizável visualmente me fazia perder mais tempo criando templates do que realmente adicionando conteúdo a eles. &lt;/p&gt;

&lt;p&gt;O fato do Obsidian ser uma ferramenta bem mais "clean" e focada em notas, faz com que menos coisas me tirem do foco. Outro fator é que minhas notas ficam registradas localmente. No ambiente de trabalho a segurança de dados é essencial, então a certeza de que minhas anotações estão seguras me deixa mais tranquila em relação a outras ferramentas. Dentro do obsidian também é possível adicionar plugins externos que possam te auxiliar na produtividade e sem deixar a tela tão poluída, o que é um grande diferencial para mim. &lt;/p&gt;

&lt;p&gt;E por ultimo, e mais importante: como tenho utilizado bastante IA em determinadas tarefas, a produção de conteúdos em Markdown já facilita a integração com elas, basicamente o meu Obsidian se tornou meu segundo cérebro. &lt;/p&gt;

&lt;h2&gt;
  
  
  Uso e integração com IA
&lt;/h2&gt;

&lt;p&gt;Antes de ir para como tudo se integra, primeiro preciso passar um breve contexto dos recursos que tenho utilizado, que são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os Templates&lt;/li&gt;
&lt;li&gt;As Skills&lt;/li&gt;
&lt;li&gt;E os Plugins do Obsidian&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Templates
&lt;/h3&gt;

&lt;p&gt;A primeira coisa que fiz quando comecei a utilizar o Obsidian, foi a criação de templates para os documentos que normalmente preciso. &lt;/p&gt;

&lt;p&gt;Templates são notas que você pode criar, com um padrão específico e sempre que criar uma nota, você pode reutilizar esse template.&lt;/p&gt;

&lt;p&gt;Como QA, por enquanto tenho os seguintes templates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Template tasks técnicas&lt;/strong&gt;: é um arquivo de template que sempre que preciso gerar planos de teste para tarefas técnicas(migração de banco de dados, criação de consumers, APIs) esse template será usado de referência. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template de tasks de business&lt;/strong&gt;: segue a mesma lógica do arquivo de template da tasks técnicas, mas o utilizo uma etapa anterior, quando estou dentro do product discovery juntamente com o Product Owner, para definir quais camadas de testes podem ser adicionados para aquela nova funcionalidade, riscos e mitigação dos mesmos, como medir o sucesso daquela nova funcionalidade. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template para notas de reuniões&lt;/strong&gt;: Nesse template tenho os dados principais sobre uma reunião e eu uso ele para tomar notas ou criar roteiros de reuniões que irei estar a frente. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Skills
&lt;/h3&gt;

&lt;p&gt;A gente sabe que as skills é um recurso muito bom para reduzirmos o tempo em tarefas repetitivas, e manter um padrão enquanto utilizamos a IA, dentro do meu contexto criei algumas skills, sendo elas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Criação de plano de testes&lt;/strong&gt;: Essa é uma skill que sempre que chamo ela passando o ID de uma tarefa do Jira, ela irá buscar o contexto daquela tarefa, em seguida, vai procurar conteúdos de referencia dentro do confluence(eu especifiquei dentro do meu &lt;code&gt;CLAUDE.md&lt;/code&gt;), e após essa contextualização, ela irá criar um arquivo .md de plano de teste, utilizando os templates que eu criei anteriormente. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Busca de tarefas que não possuem planos de teste&lt;/strong&gt;: É uma skill simples integrada ao MCP da Atlassian, que irá buscar todas as tarefas que possuo com uma flag específica para criação de plano de testes, e irá adicionar a um arquivo .md que utilizo com o plugin &lt;strong&gt;Kanban&lt;/strong&gt;, para controle do que eu preciso fazer, já fiz.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publicar casos de teste do Zephyr&lt;/strong&gt;: Essa é uma skill de integração para pegar os testes planejados e publica-los no Zephyr, que é a ferramenta que utilizo para gestão de testes. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Já comecei a citar um plugin que utilizo, que é o &lt;strong&gt;Kanban&lt;/strong&gt; para a gestão das tarefas, mas recentemente vi a necessidade de dois novos plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um plugin que se integre diretamente ao Claude Code, sem a necessidade de sair do Obsidian&lt;/li&gt;
&lt;li&gt;Um plugin para ter fácil acesso as minhas skills.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como não os encontrei na loja, decidi criar os dois. &lt;/p&gt;

&lt;p&gt;O primeiro é um plugin que abre o terminal dentro do vault(pasta) que estou trabalhando, assim fica fácil utilizar o Claude Code dentro do próprio Obsidian:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febik0wvs0rmyg5sptzrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febik0wvs0rmyg5sptzrf.png" alt="Terminal Plugin" width="800" height="933"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O segundo, foi um plugin simples para exibir e executar minhas skills, onde consigo ver todas as skills disponíveis e executa-las diretamente do Obsidian.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0arvznrrxlk5xssizhgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0arvznrrxlk5xssizhgy.png" alt="Claude Skill plugin" width="800" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Como tudo se integra
&lt;/h3&gt;

&lt;p&gt;Agora já sabemos tudo que eu uso de  Templates, Skills e Plugins vou dar um exemplo de como isso funciona na vida real. &lt;/p&gt;

&lt;p&gt;Suponha que tenha uma tarefa AB-123, que é um épico ou product discovery vindo de produto, o fluxo para o plano de teste para essa tarefa seria:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywan2sspnhz4hbf36wlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywan2sspnhz4hbf36wlf.png" alt="Product task" width="800" height="1266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em tasks técnicas, o processo seria similar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsjygel1zkrrindnu5hhz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsjygel1zkrrindnu5hhz.png" alt="Tech tasks" width="800" height="1750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Notas finais
&lt;/h2&gt;

&lt;p&gt;Confesso que tem sido divertido me aventurar em formas de organização para melhor desempenho utilizando ferramentas de IA. Ainda existe o desafio de revisar o conteúdo gerado por ela, para isso sempre tento coletar feedback do time em relação aos testes gerados, massa de dados fornecidas, validando se está claro ou algo não foi coberto. &lt;/p&gt;

&lt;p&gt;Também utilizo a mesma lógica para os Templates. Sempre estou atualizando meus templates, baseado nas revisões que vou fazendo, sempre adiciono um contexto a mais, ou retiro um contexto que não faz sentido para o que preciso.&lt;/p&gt;

&lt;p&gt;Sobre os plugins, tenho me aventurado em alguns da comunidade, e também me diverti bastante fazendo um novo. Ainda não estão em uma versão final e nem na loja da comunidade, mas caso você queira se aventurar, dentro do repositório tem o passo-a-passo de como utiliza-los localmente, o link está no final deste artigo. &lt;/p&gt;

&lt;p&gt;Enfim, espero que esse artigo seja uma inspiração para você integrar mais coisas ao seu Obsidian ou até mesmo rever seus pensamentos sobre o mesmo. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/m4rri4nne/claude-skills-obsidian" rel="noopener noreferrer"&gt;Claude Skills Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/m4rri4nne/open-terminal-obsidian" rel="noopener noreferrer"&gt;Open Terminal Plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>braziliandevs</category>
      <category>claude</category>
    </item>
    <item>
      <title>Como uma gestão despreparada pode custar a sua carreira</title>
      <dc:creator>Evelyn Lacerda</dc:creator>
      <pubDate>Fri, 25 Sep 2026 19:00:15 +0000</pubDate>
      <link>https://dev.to/he4rt/como-uma-gestao-despreparada-pode-custar-a-sua-carreira-1k9k</link>
      <guid>https://dev.to/he4rt/como-uma-gestao-despreparada-pode-custar-a-sua-carreira-1k9k</guid>
      <description>&lt;p&gt;Quantas vezes você já ouviu a seguinte frase "a empresa é assim, lide com isso" e engoliu seco porque parecia a única opção? Essa frase costuma ser tratada como "algo comum", como "personalidade de gestor". Raramente mencionam o termo correto que é &lt;strong&gt;despreparo para gerir pessoas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A história abaixo não é sobre uma grande empresa com RH ineficiente, ou uma startup sem controle. A empresa era pequena, que seguiu pequena, onde o gestor era o dono e não havia ninguém acima dele para trazer à tona um despreparo que era evidente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Os fatos descritos aqui aconteceram com uma pessoa próxima, que chamarei de Maria, e que autorizou o uso da sua história na carreira tech.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O início do conflito: Quando a pressa substitui o planejamento
&lt;/h2&gt;

&lt;p&gt;O projeto era grande: &lt;strong&gt;refazer um SaaS inteiro, com frontend e backend construídos do zero&lt;/strong&gt;. Quando ela entrou na equipe, o backend já estava encaminhado, faltava o frontend. A decisão do gestor foi comprar um template pronto e construir tudo em cima dele. Parece prático, mas não é: um template genérico, feito para qualquer tipo de aplicação, carrega dependências e estruturas depreciadas que nada têm a ver com o projeto proposto, e boa parte do tempo da equipe acaba consumida limpando código desnecessário e torcendo para tudo continuar funcionando.&lt;/p&gt;

&lt;p&gt;Maria ficou de analisar o primeiro template. Percebeu que a quantidade de dependências depreciadas e bugs atrasaria o projeto, e sugeriu construir o frontend do zero. A sugestão foi aceita, e &lt;strong&gt;ela passou os 7 meses seguintes construindo sozinha uma base sólida, eficiente e confiável&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Com a entrada de um novo desenvolvedor sênior na equipe, o que Maria esperava ser uma colaboração alimentada pela experiência do colega, se transformou em &lt;strong&gt;mais 14 meses de trabalho em cima de uma nova compra de template&lt;/strong&gt;. Imposto sem debate técnico prévio, e que resultaram no descarte de todo o trabalho prévio de Maria com desenvolvimento de uma base correta.&lt;/p&gt;

&lt;p&gt;A decisão não foi tomada com base em qual abordagem era tecnicamente melhor, foi tomada com base em &lt;strong&gt;quem falou por último e com mais anos de experiência no currículo&lt;/strong&gt;. Isso não é um erro técnico, é um erro de processo. Quando a palavra de quem tem mais cargo ou mais tempo de casa pesa mais do que meses de entrega comprovada, a equipe aprende que &lt;strong&gt;propor, testar e validar não importa tanto quanto convencer quem decide&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;É esse tipo de ambiente que ensina gente boa a parar de sugerir.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O risco real apareceu 4 meses antes da nova e última data de lançamento, já sem margem para mais adiamentos. Uma das tecnologias base do template sofreu uma atualização de versão, o gestor pediu a atualização no projeto, e &lt;strong&gt;o template simplesmente parou de funcionar&lt;/strong&gt;. Nem o sênior conseguiu resolver os erros de incompatibilidade gerados. Reverter para a versão anterior lançaria o projeto já obsoleto, então tudo foi &lt;strong&gt;refeito pela terceira vez&lt;/strong&gt;, em um terceiro template diferente que também trazia depreciações e erros na base.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Um projeto com prazo de lançamento de menos de 1 ano chegou a 2 anos sem estimativa de conclusão.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em nenhum momento houve uma avaliação real do risco de construir a base inteira de um SaaS em cima de templates prontos e genéricos. Comprar pronto parece economizar tempo, mas só empurra o custo para frente, e quando ele chega, vem maior. &lt;strong&gt;É gestão de projeto amadora tratar prazo e tecnologia como decisões independentes uma da outra&lt;/strong&gt;, e quem paga por essa desconexão não é quem decide, é quem está na ponta reescrevendo o mesmo projeto pela terceira vez.&lt;/p&gt;

&lt;h2&gt;
  
  
  Duas vozes que não se alinhavam e o trabalho que não chegava a lugar nenhum
&lt;/h2&gt;

&lt;p&gt;A comunicação interna era um ponto extremo a se questionar, principalmente entre gestor e sênior, raramente consistentes entre si. Quando Maria buscava resolver alguma dúvida, um dizia uma coisa, o outro dizia o oposto. Ela virou &lt;strong&gt;o ponto de contato involuntário&lt;/strong&gt; entre os dois, tentando alinhar o que já deveria estar alinhado antes de chegar até ela. Levou as divergências para um canal aberto a todos, mas raramente isso resolvia algo.&lt;/p&gt;

&lt;p&gt;Havia também um desgaste diário nas trocas de direção sem comunicação: PRs ficavam semanas ou meses sem revisão, acumulando conflitos impossíveis de resolver e obrigando Maria a refazer a mesma PR 5, 6, 7 vezes. Via seu trabalho parado, sem avançar nem retroceder, enquanto cobranças chegavam como se ela não estivesse entregando: "&lt;em&gt;você não está entregando o suficiente&lt;/em&gt;" ou "&lt;em&gt;há muitas PRs suas paradas&lt;/em&gt;", as mesmas PRs que esperavam validação de quem simplesmente deixava pra mais tarde.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Em paralelo, seu trabalho podia ser jogado fora a qualquer momento, sem aviso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repare o tamanho da inversão aqui, quando duas pessoas em posições diferentes de decisão que não se alinham entre si. O custo desse desalinhamento não fica apenas com elas, ele chega até quem tem menos poder de recusa para um papel de intermediário. &lt;strong&gt;Cobrar entrega de quem está travado esperando revisão não podemos chamar de gestão de performance, isso é confundir sintoma e causa sem observar quem controla o gargalo.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Um ambiente que normalizava o desconforto
&lt;/h2&gt;

&lt;p&gt;Além dessa instabilidade técnica que ela enfrentava no dia a dia, havia um padrão constante nas reuniões: piadas constrangedoras, algumas colocando Maria como alvo e fazendo dela o "palhaço" da vez. Aparentemente ninguém percebia, ou ninguém se importava com o quanto aquilo a incomodava. Em certo momento ficou implícito, uma piada feita onde todos riram menos ela, o que significava que não merecia aumento. Isso foi verbalizado na frente de todos, e ela ficou sem palavras. &lt;strong&gt;Não rir foi tratado como sinal de que ela não queria aumento ou não queria ser promovida.&lt;/strong&gt; Talvez até uma forma de coação sutil, porém eficaz, o tipo de coisa que ensina a engolir o desconforto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isso não é cultura descontraída nem falta de jeito social, é condicionar reconhecimento profissional a uma performance emocional que nada tem a ver com entrega de trabalho.&lt;/strong&gt; Quando rir de uma piada vira pré-requisito informal para crescer na empresa, o problema não é falta de senso de humor de quem não riu, é gestão de pessoas tratando desconforto alheio como moeda de troca.&lt;/p&gt;

&lt;h2&gt;
  
  
  O corpo começou a cobrar
&lt;/h2&gt;

&lt;p&gt;O primeiro episódio de burnout Maria não percebeu, mas o segundo e o terceiro não vieram sozinhos. Acompanhados de ansiedade, noites mal dormidas e depois um quadro depressivo que chegou devagar. A imunidade caiu e a fez verbalizar que estava no limite, um pedido de ajuda. A resposta veio em poucos minutos: "&lt;em&gt;A empresa é assim, lide com isso.&lt;/em&gt;", a mesma empresa que prometia um ambiente familiar, amigável e compreensível quando a contrataram.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aqui o despreparo deixa de ser só falta de experiência e passa a ser negligência.&lt;/strong&gt; Ninguém espera que um líder de equipe tenha resposta pronta para tudo, muito menos para a saúde mental de alguém. Mas existe uma diferença enorme entre não saber o que fazer e escolher não fazer nada diante de um pedido de ajuda direto, e a segunda opção é omissão.&lt;/p&gt;

&lt;h2&gt;
  
  
  O alívio misturado com a perda e a incerteza na carreira
&lt;/h2&gt;

&lt;p&gt;Finalmente a demissão chegou, e o primeiro sentimento foi de alívio. Mas, passadas algumas semanas, veio a famosa &lt;strong&gt;sensação de estar perdida sem saber o que fazer&lt;/strong&gt;. Se 7 meses de trabalho podiam ser descartados com uma conversa, se em 2 anos e meio de trabalho tudo o que fez sempre foi visto como errado e questionável, o que ela realmente sabia fazer? Foi o suficiente para fazer com que ela se afastasse da carreira, por sentir que perdeu todo o seu tempo durante todos esses meses de trabalho, um tempo que foi gasto tentando sobreviver em um ambiente que deveria ser de crescimento profissional e pessoal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Depois de quase 6 meses, Maria está retornando aos poucos e entendendo que, ao contrário do que imaginava, ela estava certa em boa parte do tempo, se não o tempo todo.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O que fica dessa história
&lt;/h2&gt;

&lt;p&gt;Maria terminou esses dois anos e meio se perguntando o que ela realmente sabia fazer, mas &lt;strong&gt;nada do que ela viveu foi sobre incompetência técnica&lt;/strong&gt;. Templates falham, códigos quebram, tecnologias são atualizadas e bugs aparecem, isso faz parte do trabalho de qualquer time. O que a fez duvidar de si mesma não foi o próprio trabalho, &lt;strong&gt;foi ver 7 meses de entrega descartados sem debate, foi ser cobrada por PRs que ela não podia validar sozinha, foi ter o silêncio diante de uma piada usado contra ela como prova de que não merecia crescer&lt;/strong&gt;. Nada disso mede competência. Mede o quanto alguém aguenta absorver a desorganização de quem deveria estar organizando.&lt;/p&gt;

&lt;p&gt;Um gestor que tomou decisões sem avaliar o que já havia sido construído, que deixou a palavra de quem falava mais alto pesar mais do que meses de entregas, que não conseguiu alinhar a própria comunicação com a da equipe que ele mesmo montou. Foi esse gestor quem tolerou, quando não incentivou, um ambiente onde desconforto virava moeda de troca por reconhecimento, e que, diante de um pedido de ajuda real, escolheu responder que a empresa era assim. &lt;strong&gt;Essa parte não se dilui em "cultura de empresa", é responsabilidade de uma pessoa específica, e também não é exclusividade de negócios pequenos: é o retrato de um tipo de gestão que existe aos montes&lt;/strong&gt;, seja numa empresa pequena onde o gestor é o dono, seja numa empresa grande com uma liderança que não cumpre seu papel, onde não há ninguém disposto a dizer que aquilo precisa mudar e o despreparo nunca é confrontado.&lt;/p&gt;

&lt;p&gt;Liderar bem não é sobre nunca errar numa escolha feita. &lt;strong&gt;É escutar quem está no dia a dia do projeto antes de descartar o trabalho dessa pessoa, alinhar antes de cobrar, garantir que ninguém precise se sentir mal para provar seu valor&lt;/strong&gt;. Quando isso falta, o custo não aparece só em atrasos de cronograma, aparece depois, na carreira de quem saiu de lá achando que o problema era ela. Se você reconheceu esse padrão em algum lugar onde trabalha ou já trabalhou, vale se perguntar se o que te fez duvidar de você foi mesmo o seu trabalho ou foi a bagunça de quem deveria estar te dando direção, e prestar atenção em quem pode estar carregando esse peso sozinho agora.&lt;/p&gt;




&lt;h3&gt;
  
  
  - Agradecimentos
&lt;/h3&gt;

&lt;p&gt;Quero agradecer ao &lt;a class="mentioned-user" href="https://dev.to/clintonrocha98"&gt;@clintonrocha98&lt;/a&gt; pelo feedback quando apresentei minha primeira versão, a &lt;a class="mentioned-user" href="https://dev.to/szaranct"&gt;@szaranct&lt;/a&gt; pelo review minucioso quando a segunda versão chegou, e a &lt;a class="mentioned-user" href="https://dev.to/cherryramatis"&gt;@cherryramatis&lt;/a&gt; que me ajudou muito com seu artigo de &lt;a href="https://dev.to/he4rt/compartilhando-seu-conhecimento-com-o-mundo-como-escrever-artigos-5ghc"&gt;como escrever artigos&lt;/a&gt;. 💜&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>career</category>
      <category>leadership</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>Velocidade de entrega e custo de manutenção pós IA</title>
      <dc:creator>Elves Santos</dc:creator>
      <pubDate>Thu, 27 Aug 2026 13:58:08 +0000</pubDate>
      <link>https://dev.to/he4rt/velocidade-de-entrega-e-custo-de-manutencao-pos-ia-5gei</link>
      <guid>https://dev.to/he4rt/velocidade-de-entrega-e-custo-de-manutencao-pos-ia-5gei</guid>
      <description>&lt;p&gt;Entregar ficou rápido demais. O problema é que manter continuou custando o mesmo preço de sempre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tabela de Conteúdo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;O dia que a conta chegou&lt;/li&gt;
&lt;li&gt;A gente tá comemorando a parte barata&lt;/li&gt;
&lt;li&gt;Se isso quebrar às 3 da manhã, eu consigo debugar sem reabrir o chat?&lt;/li&gt;
&lt;li&gt;O gargalo só mudou de lugar&lt;/li&gt;
&lt;li&gt;O que eu faço hoje&lt;/li&gt;
&lt;li&gt;No fim das contas, o trabalho virou escolher&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  O dia que a conta chegou
&lt;/h2&gt;

&lt;p&gt;Vou começar confessando uma coisa.&lt;/p&gt;

&lt;p&gt;Teve uma feature esse ano que eu entreguei numa manhã. Uma manhã. CRUD de fórmulas de análise: o cliente queria configurar a própria conta de infestação em vez de pedir pra gente cravar no código. Migration, 4 rotas novas, uma tela de 949 linhas, e o melhor pedaço, que foi trocar 208 linhas de estratégia de cálculo hardcoded por 50 linhas chamando um avaliador de fórmula. 11h17 da manhã o PR do front tava aberto. 11h32 o do back. Fui almoçar me achando o cara.&lt;/p&gt;

&lt;p&gt;Duas semanas depois apareceram 3 tipos de análise novos. E alguém (eu) entrou no servidor e adicionou as 3 estratégias hardcoded de volta, no mapa que o motor genérico tinha aposentado 14 dias antes. O diff parte da versão antiga do arquivo. Quem escreveu aquilo não achou o caminho novo. Não entendeu que existia um caminho novo.&lt;/p&gt;

&lt;p&gt;27 dias depois eu voltei de novo, porque quando um tipo de análise não tinha fórmula o código fazia &lt;code&gt;throw new Error(JSON.stringify({...}))&lt;/code&gt;. Uma exceção com JSON dentro da mensagem, que o handler HTTP tinha que abrir pra saber o que dizer pro usuário. Consertar isso custou 35 linhas de código e 175 de teste. 5 vezes mais teste que código, escrevendo teste pra um caso que eu deveria ter pensado na manhã em que "entreguei".&lt;/p&gt;

&lt;p&gt;Hoje, 5 meses depois, o arquivo tem 268 linhas e ainda carrega um comentário meu: &lt;code&gt;// Keep for backwards compatibility with tests&lt;/code&gt;. Um mapa de 16 entradas que nenhuma linha de produção lê. Ele tá lá porque 14 asserções do teste dependem dele, e ninguém (eu) teve a tarde sobrando pra desmontar. O arquivo de teste tem 351 linhas. É maior que o serviço que ele testa.&lt;/p&gt;

&lt;p&gt;A manhã eu economizei. Os três retornos ao arquivo, não.&lt;/p&gt;

&lt;p&gt;Ó, e antes que alguém entenda errado: eu uso IA todo santo dia, em tudo. Não é papo de "IA é ruim" não. É outra coisa.&lt;/p&gt;

&lt;h2&gt;
  
  
  A gente tá comemorando a parte barata
&lt;/h2&gt;

&lt;p&gt;Pensa comigo no que a IA realmente barateou.&lt;/p&gt;

&lt;p&gt;Boilerplate, DTO, migration, aquele CRUD que você já fez 40 vezes na vida, o esqueleto de um módulo novo, entender uma lib que você nunca tinha aberto. Tudo isso ficou absurdamente mais barato e eu não quero de volta nem por decreto.&lt;/p&gt;

&lt;p&gt;Mas repara: tudo isso é o momento em que o código &lt;strong&gt;nasce&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;E software não passa a vida nascendo. Software passa a vida sendo lido, debugado, alterado às pressas na sexta e explicado pra alguém que entrou no time mês passado. Essa parte aí continua custando o mesmo tanto que custava em 2019. Talvez mais, porque agora tem mais código.&lt;/p&gt;

&lt;p&gt;Então quando você olha e fala "cara, eu tô 3x mais produtivo", pode ser verdade. Mas provavelmente você tá medindo só o pedaço que já era o mais rápido do processo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Se isso quebrar às 3 da manhã, eu consigo debugar sem reabrir o chat?
&lt;/h2&gt;

&lt;p&gt;Se eu pudesse deixar uma pergunta só desse artigo, seria o título dessa seção. Faz ela antes de mergear.&lt;/p&gt;

&lt;p&gt;Se a resposta for não, você não terminou. Você só empurrou.&lt;/p&gt;

&lt;p&gt;Tem uma versão mais dura dessa pergunta, que é: você consegue explicar por que aquilo tá daquele jeito pra uma pessoa que nunca viu esse código? Porque se você não consegue, quem tem ownership daquele arquivo não é você. E o modelo não vai estar de plantão com você no dia do incidente, isso eu garanto.&lt;/p&gt;

&lt;p&gt;De novo, não é pra escrever tudo na mão. É pra ler antes de aceitar. Ler de verdade, linha por linha, com o dedo na tela se precisar.&lt;/p&gt;

&lt;p&gt;Ler 200 linhas leva uns 10 minutos. Debugar 200 linhas que você nunca leu leva um dia. Essa conta nunca mudou e não vai mudar.&lt;/p&gt;

&lt;p&gt;E olha, tem um detalhe que eu demorei pra perceber: a IA quase nunca te devolve a solução mínima. Ela te devolve a completa. Com uma abstração que você não pediu, um parâmetro opcional "pra ficar flexível", uma interface pra um caso de uso que não existe no seu projeto. Você pediu uma função, voltou um framework.&lt;/p&gt;

&lt;p&gt;E cada uma dessas linhas é uma linha que alguém do time vai ter que ler algum dia. Ninguém escreve isso no card, mas tá lá.&lt;/p&gt;

&lt;h2&gt;
  
  
  O gargalo só mudou de lugar
&lt;/h2&gt;

&lt;p&gt;Essa aqui eu vi acontecer no time e demorei pra entender. E ela corta dos dois lados.&lt;/p&gt;

&lt;p&gt;O primeiro corte é no review. A gente aumentou muito a velocidade de quem escreve e não aumentou nada a de quem revisa. Continua sendo o mesmo cérebro humano, com as mesmas 24 horas, agora com PR de 40 arquivos caindo na fila.&lt;/p&gt;

&lt;p&gt;Aí acontece o que sempre acontece quando a fila cresce. O revisor começa a bater o olho no resumo das mudanças (o diff), ver que os testes passaram e mandar aquele "por mim tá bom" (o famoso LGTM, de &lt;em&gt;looks good to me&lt;/em&gt;). Todo mundo aqui já fez isso, inclusive eu. Não vamos fingir que não.&lt;/p&gt;

&lt;p&gt;Só que aí você tem código que ninguém escreveu de verdade sendo aprovado por ninguém de verdade, indo pra produção onde tem cliente pagando. E quando quebra, tem duas pessoas envolvidas e nenhuma das duas sabe o que aquilo faz.&lt;/p&gt;

&lt;p&gt;Passar o review pra IA também não resolve. Na minha opinião, ajuda a pegar coisa boba, tipo, ajuda mesmo. Mas o review não existe só pra achar bug; existe pra pelo menos duas pessoas do time saberem que aquele código existe.&lt;/p&gt;

&lt;p&gt;O segundo corte é no seu preço, e esse é o que mais me incomoda.&lt;/p&gt;

&lt;p&gt;No dia em que você entrega em 2 horas uma coisa que levaria 2 dias, o prazo daquela coisa virou 2 horas. Pra sempre. Ninguém volta atrás e pergunta "opa, mas quanto disso foi porque a IA acertou de primeira e quanto foi sorte?". A régua sobe e ela não desce nunca mais.&lt;/p&gt;

&lt;p&gt;Aí chega o problema chato de verdade, aquele que não tem resposta pronta em lugar nenhum, que exige você sentar e pensar por 3 dias. E agora você tá devendo uma velocidade que na real você nunca teve.&lt;/p&gt;

&lt;p&gt;Se você é PJ e cobra por escopo então, pior ainda. Você acabou de deflacionar seu próprio preço e ficou com a manutenção no colo de graça. Eu entreguei numa manhã e voltei naquele arquivo 3 vezes depois. Cobrei a manhã. As 3 voltas eu paguei do meu bolso, com o meu tempo.&lt;/p&gt;

&lt;p&gt;E é aí que eu fico travado: como é que eu continuo usando isso, que é bom demais pra abrir mão, sem entregar de graça o controle do que entra no código e o preço do meu trabalho?&lt;/p&gt;

&lt;h2&gt;
  
  
  O que eu faço hoje
&lt;/h2&gt;

&lt;p&gt;Hoje eu atuo como desenvolvedor PJ, e eu elaborei um processo de pensamento pra me ajudar a lidar com situações como essa. Esse processo, como estou chamando, foi resultado de muitos erros que eu cometi durante o uso de IA no meu trabalho.&lt;/p&gt;

&lt;p&gt;Eu descrevo o problema, não o código. Antes eu pedia "escreve uma função que faz X" e recebia a tal solução completa. Hoje eu falo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o que já existe no projeto,&lt;/li&gt;
&lt;li&gt;qual a restrição,&lt;/li&gt;
&lt;li&gt;e principalmente o que eu &lt;strong&gt;não&lt;/strong&gt; quero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cortou muita abstração aleatória. E continuo:&lt;/p&gt;

&lt;p&gt;Eu peço a versão pequena, explicitamente. "Faz o mais simples que resolve, sem generalizar". Você não faz ideia do tanto de código que some quando você pede isso.&lt;/p&gt;

&lt;p&gt;A descrição do PR eu escrevo eu mesmo, do zero. O "como" pode vir gerado, tudo bem. O "por quê" é a única parte que não dá pra regenerar depois, e é justamente a que o meu eu de daqui a 6 meses vai precisar.&lt;/p&gt;

&lt;p&gt;Se saiu um PR monstro, eu quebro. Mesmo dando trabalho. O tamanho que cabe na cabeça de uma pessoa não mudou porque a IA chegou.&lt;/p&gt;

&lt;p&gt;E teste eu concentro onde dói. Caso feliz a IA cobre sozinha e é justamente o que menos quebra. O que quebra é falha de rede, payload torto, aquele dado legado que só existe naquele cliente antigo. É lá que mora o prejuízo.&lt;/p&gt;

&lt;p&gt;Sobre o preço, mudou uma coisa também: eu parei de estimar código e comecei a estimar problema resolvido. Não é a manhã que eu vou passar escrevendo, é o mês em que aquilo vai ficar de pé.&lt;/p&gt;

&lt;h2&gt;
  
  
  No fim das contas, o trabalho virou escolher
&lt;/h2&gt;

&lt;p&gt;Eu não sei se essa é a leitura certa, é o que eu enxerguei até agora mexendo com isso no dia a dia.&lt;/p&gt;

&lt;p&gt;Mas acho que a IA não acabou com o trabalho de engenharia, ela acabou com a parte mecânica dele. E ao acabar com a parte mecânica, ela deixou exposta a parte que a gente sempre conseguiu empurrar com a barriga: entender o sistema, decidir com critério, e sustentar aquilo em produção depois.&lt;/p&gt;

&lt;p&gt;Quem só digitava rápido perdeu vantagem. Quem consegue olhar pra 200 linhas geradas e falar "isso aqui tá errado, e o motivo é esse" ficou mais valioso, não menos. E repara no que essa pessoa tá fazendo de verdade: ela avaliou as opções e escolheu qual desvantagem ela topa carregar. O mercado chama isso de trade-off, e é literalmente o trabalho que sobrou pra gente. Generalizar agora e pagar complexidade, ou hardcodar hoje e pagar depois. Não existe escolha sem conta pra pagar, existe escolha feita com os olhos abertos e escolha feita no automático.&lt;/p&gt;

&lt;p&gt;Velocidade de entrega é fácil de mostrar em daily. Custo de manutenção fica escondido até o dia que ele te acha.&lt;/p&gt;

&lt;p&gt;Então gera, sim, gera bastante. Só lê o que você gerou antes de assinar embaixo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Da comunidade para a comunidade.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bebe água e a gente se vê no próximo artigo.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>braziliandevs</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>1ª vez trabalhando com git em um time: tudo que você precisa saber</title>
      <dc:creator>vitoriazzp</dc:creator>
      <pubDate>Thu, 20 Aug 2026 06:52:21 +0000</pubDate>
      <link>https://dev.to/he4rt/1a-vez-trabalhando-com-git-com-time-tudo-que-voce-precisa-saber-19il</link>
      <guid>https://dev.to/he4rt/1a-vez-trabalhando-com-git-com-time-tudo-que-voce-precisa-saber-19il</guid>
      <description>&lt;p&gt;Faz mais de 5 anos que eu não abria um PR ou issue técnica no Github, mas essa semana tenho aprendido algumas boas práticas e termos que reuni neste artigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Essa semana eu fiz uma coisa simples: atualizei o README de um projeto open source, o &lt;a href="https://github.com/he4rt/4noobs" rel="noopener noreferrer"&gt;4noobs&lt;/a&gt;, da comunidade He4rt. Troquei um badge, ajustei o contraste de um logo, organizei umas pastas e adicionei um índice pra facilitar a navegação. Nada muito complexo no fim das contas.&lt;/p&gt;

&lt;p&gt;Só que antes de chegar no "nada muito complexo", eu passei um tempo enrolada com uma pergunta boba: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"E se eu mandar isso direto pra branch principal e bagunçar tudo?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se tu já sentiu esse friozinho na barriga antes de mexer num repositório que não é só teu, esse artigo é pra ti. Não importa se tu é dev há anos ou se nunca abriu um terminal na vida... A lógica por trás de "como contribuir sem quebrar nada" é a mesma e bem mais simples do que parece.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definição de Git Colaborativo
&lt;/h2&gt;

&lt;p&gt;Quando eu aprendi git há uns anos, aprendi somente o versionamento e a enviar os arquivos pra dentro do Github, mas ele é bem mais que isso, né?&lt;/p&gt;

&lt;p&gt;É através dele que times enormes interagem a respeito de um mesmo projeto de forma organizada, comentando, gerenciando tarefas, sugerindo melhorias e conhecendo o que os outros envolvidos estão fazendo. Isso é a parte do &lt;strong&gt;Git Colaborativo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O Git resolve isso com um conceito central: &lt;strong&gt;branches&lt;/strong&gt; (ou "ramificações"). Cada branch é tipo uma cópia paralela do projeto, onde tu pode mexer à vontade sem afetar a versão "oficial" (geralmente chamada de &lt;code&gt;main&lt;/code&gt; ou &lt;code&gt;master&lt;/code&gt;). Quando tu termina sua parte, tu propõe que essas mudanças sejam incorporadas de volta pelo &lt;strong&gt;Pull Request (PR)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ou seja, o fluxo básico é:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tu cria uma branch nova a partir do projeto principal&lt;/li&gt;
&lt;li&gt;Faz as alterações lá, no seu espaço isolado&lt;/li&gt;
&lt;li&gt;Envia (&lt;code&gt;push&lt;/code&gt;) essa branch pro repositório remoto&lt;/li&gt;
&lt;li&gt;Abre um Pull Request pedindo pra essas mudanças serem revisadas e, se aprovadas, unidas (&lt;code&gt;merge&lt;/code&gt;) à branch principal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ninguém mexe direto na versão "de produção" do projeto. Isso é o que torna possível centenas de pessoas contribuírem pro mesmo repositório sem o caos se instalar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principais Aprendizados
&lt;/h2&gt;

&lt;p&gt;Bom, na prática, foi mexendo que aprendi (e relembrei) algumas coisas que acho que valem ser compartilhadas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Branch nova não é sobre desconfiança, é sobre segurança.&lt;/strong&gt; Criar uma branch pra cada contribuição não é burocracia sem sentido — é o que garante que, se algo der errado, o "errado" fica isolado ali, sem afetar o projeto principal. Isso vale tanto pra quem tá contribuindo quanto pra quem revisa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git push&lt;/code&gt; não é a mesma coisa que abrir um Pull Request.&lt;/strong&gt; Isso me pegou de surpresa: o push só envia sua branch pro GitHub. O PR é um passo separado, onde tu formaliza o pedido de revisão. O próprio terminal, inclusive, já te entrega o link pronto pra criar o PR depois do push.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Não precisa ter issue aberta pra contribuir.&lt;/strong&gt; Eu fiquei presa nessa por um tempo. Pensei: "Ah, mas ninguém pediu essa melhoria, será que posso mandar mesmo assim?" &lt;strong&gt;Pode!&lt;/strong&gt; Principalmente em documentação: se tu enxergou algo que pode melhorar, a contribuição em si já é a justificativa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Descrição de PR boa não é uma lista de tudo o que mudou linha por linha.&lt;/strong&gt; É um resumo categorizado, por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o que foi feito, &lt;/li&gt;
&lt;li&gt;por quê, &lt;/li&gt;
&lt;li&gt;e os principais pontos agrupados por tema. 
Isso poupa um tempo enorme para quem vai revisar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A pasta &lt;code&gt;.github&lt;/code&gt; pode ser local ao repositório ou um "padrão" pra organização inteira&lt;/strong&gt;, dependendo se existe um repositório especial chamado literalmente &lt;code&gt;.github&lt;/code&gt; na conta. Detalhe pequeno, mas que ajuda a entender por que às vezes umas configurações "aparecem" em vários repositórios sem alguém ter copiado e colado em cada um.&lt;/p&gt;

&lt;p&gt;Nenhum desses pontos é complicado isoladamente. O que trava a gente, geralmente, não é a técnica — &lt;strong&gt;é o medo&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerenciando o medo de fazer errado
&lt;/h2&gt;

&lt;p&gt;Aqui vai a parte que eu acho mais importante desse artigo, sinceramente.&lt;/p&gt;

&lt;p&gt;Toda vez que eu vou mexer num repositório que não é só meu, seja um projeto open source, seja no trabalho, bate aquele receio: "e se eu errar? E se eu quebrar algo? E se acharem que eu não sei o que tô fazendo?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E olha, isso não passa de uma hora pra outra. Mas duas coisas mudaram bastante minha relação com esse medo:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Entender a ferramenta tira o poder do medo.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Muito do que a gente teme é o desconhecido. Quando eu entendi que uma branch é literalmente um espaço isolado, que nada do que eu fizesse lá afetaria a &lt;code&gt;main&lt;/code&gt; até alguém aprovar um merge, o medo diminuiu bastante. Não é sobre ser corajosa, é sobre saber que o sistema já foi desenhado pra proteger contra erro.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Errar em público faz parte do processo; não é uma falha nele.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;comunidade open source&lt;/em&gt; inteira é &lt;strong&gt;construída em cima de gente errando&lt;/strong&gt;, corrigindo, revisando o trabalho umas das outras. Um PR rejeitado ou com pedido de ajuste não é um veredito sobre tua competência, é literalmente o sistema funcionando como devia.&lt;/p&gt;

&lt;p&gt;Se tem uma coisa que eu queria ter escutado antes de começar a contribuir, é isso: ninguém espera que tu chegue sabendo tudo. As branches, os PRs, as revisões, tudo isso existe justamente porque errar faz parte.&lt;/p&gt;

&lt;p&gt;Então, se tu tá enrolando para abrir aquele primeiro PR por medo de fazer besteira: cria a branch, faz a mudança e manda ver. O pior que pode acontecer é alguém te dar um feedback — e isso, no fim das contas, é como a gente aprende e melhora&lt;/p&gt;

&lt;h2&gt;
  
  
  Materiais Complementares
&lt;/h2&gt;

&lt;p&gt;Esses são todos os materiais que me foram indicados ou lidos durante as práticas descritas acima. Alguns ensinam sobre estrutura e outros sobre boas práticas. Também tive muita ajuda de amigos e fiz pesquisas com IA pra compreender exatamente termos ou partes de código que eu não estava entendendo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marker.io/blog/how-to-write-bug-report" rel="noopener noreferrer"&gt;How to Write a Bug Report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marker.io/blog/bug-report" rel="noopener noreferrer"&gt;What Makes a Good Bug Report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/pt/pull-requests/how-tos/review-pull-requests/reviewing-proposed-changes-in-a-pull-request" rel="noopener noreferrer"&gt;Revisando alterações propostas em um Pull Request — Documentação do GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.frontiersin.org/for-authors/where-to-publish/article-types#article-types-brief-research-report" rel="noopener noreferrer"&gt;Where to Publish: Article Types — Frontiers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://conventionalbranch.org" rel="noopener noreferrer"&gt;Conventional Branch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://semver.org/lang/pt-BR/" rel="noopener noreferrer"&gt;Semantic Versioning (SemVer) em português&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Se esse artigo te ajudou de alguma forma, deixa o coraçãozinho aí 💜 e conta nos comentários: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;qual foi teu primeiro PR ou tua primeira contribuição pra um projeto que não era seu? Bora trocar ideia!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>braziliandevs</category>
      <category>opensource</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Como criei um agente de IA para selecionar testes automaticamente em PRs (Parte 1)</title>
      <dc:creator>Alicia Marianne Gonçalves</dc:creator>
      <pubDate>Tue, 11 Aug 2026 16:22:22 +0000</pubDate>
      <link>https://dev.to/he4rt/como-criei-um-agente-de-ia-para-selecionar-testes-automaticamente-em-prs-parte-1-1kid</link>
      <guid>https://dev.to/he4rt/como-criei-um-agente-de-ia-para-selecionar-testes-automaticamente-em-prs-parte-1-1kid</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🇺🇸 &lt;em&gt;You can also read the English version of this article on &lt;a href="https://builder.aws.com/content/3HmEAY82eSScnTRAOWa2VQH7tfz/how-i-created-an-ai-agent-to-select-tests-in-prs-part-1" rel="noopener noreferrer"&gt;AWS Community Builders&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma das coisas mais comuns em grandes projetos pelos quais já passei são pipelines com muitos testes, levando muito tempo para serem executados. E com isso eu pensei: por que não ter um agente de IA para analisar meus PRs e, a partir das modificações, selecionar apenas os testes que precisam ser executados? Nesse artigo vou te mostrar como eu fiz isso e já adianto que provavelmente isso vai virar uma série de artigos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Se você não conhece o termo, o que estou descrevendo aqui é uma versão simplificada de **Test Impact Analysis&lt;/em&gt;&lt;em&gt;: em vez de rodar a suíte inteira a cada PR, o objetivo é mapear quais testes realmente têm relação com o que foi alterado.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompts utilizados
&lt;/h2&gt;

&lt;p&gt;Um dos feedbacks que recebi nos meus últimos artigos foi para deixar mais explícitos os prompts que utilizei para criar o projeto, e nesse eu usei apenas dois:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;claude poderia me ajudar a fazer um projeto onde vou ter um agente de IA para analisar as linhas de códigos que foram modificadas em um PR e selecionar testes relacionados a essa modificação?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como resposta para essa primeira pergunta, ele criou pra mim um diagrama de como basicamente isso poderia funcionar, sem nenhuma integração a pipeline ou coisa do tipo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg27ayllgyojcophjc3r2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg27ayllgyojcophjc3r2.png" alt="Workflow" width="799" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois disso, simplesmente pedi para ele criar um prompt para o Claude Code (a IA que utilizo) e, depois de colar o prompt gerado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkn9cnlpxlx8a6xe09q1h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkn9cnlpxlx8a6xe09q1h.gif" alt="Magic" width="220" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A primeira versão do projeto foi criado no seguinte formato:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;main.py                  CLI entrypoint — wires everything together
config.py                Loads &amp;amp; validates ANTHROPIC_API_KEY / GITHUB_TOKEN
src/
  github_client.py       Fetches PR files &amp;amp; metadata from the GitHub API (with retries)
  diff_parser.py         Maps diff hunks to changed functions/classes via AST
  test_discovery.py      Indexes pytest test functions across the repo
  ai_agent.py            Calls Claude to select relevant tests
  reporter.py            Renders results as a table or JSON
tests/                   Unit tests for the parser &amp;amp; discovery modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vale destacar o &lt;code&gt;diff_parser.py&lt;/code&gt;: em vez de simplesmente olhar quais &lt;em&gt;linhas&lt;/em&gt; mudaram no diff, ele usa AST (Abstract Syntax Tree) para entender quais &lt;em&gt;funções e classes&lt;/em&gt; foram alteradas. Essa diferença importa bastante — duas linhas modificadas dentro da mesma função valem como uma única mudança de símbolo, o que deixa a seleção de testes mais precisa do que uma comparação puramente textual.&lt;/p&gt;

&lt;p&gt;Dando destaque ao nosso &lt;code&gt;ai_agent.py&lt;/code&gt;, pois é nele que acontece a mágica, temos alguns argumentos interessantes de entender:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Relevance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ter um filtro de relevância é importante para auxiliar a IA no momento em que ela for analisar, entre os testes disponíveis, quais realmente precisam ser executados. Na prática, esse filtro também vira um dial de confiança para quem está usando a ferramenta: em um pipeline de CI mais crítico, faz sentido rodar só os testes marcados como &lt;code&gt;high&lt;/code&gt;; em uma verificação mais exploratória, pode valer incluir &lt;code&gt;low&lt;/code&gt; e &lt;code&gt;medium&lt;/code&gt; também.&lt;/p&gt;

&lt;p&gt;O prompt utilizado foi esse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;_SYSTEM_PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s"&gt;You are a senior software engineer who selects which pytest tests are relevant &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s"&gt;to review for a given pull request.

You will receive a JSON object with:
- &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_relevance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: the minimum relevance level to include (&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, or &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)
- &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;changed_symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: a list of functions/classes/methods (or whole files) modified in the PR,
  each with file_path, symbol_name, symbol_type, and lines_changed
- &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;available_tests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: a list of test functions discovered in the repository, each with
  test_path, test_name, imports, and source_references

Decide which of the available tests are relevant to the changed symbols by considering:
- Whether a test&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s source_references directly name a changed symbol
- Whether a test&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s imports point to the module containing a changed symbol
- One level of transitivity: a test that references something which itself references
  a changed symbol (e.g. a helper that calls the changed function)
- The semantic similarity between test names/paths and changed symbol names

Respond with ONLY a JSON array (no prose, no markdown fences, no text outside the array).
Each element must have exactly this shape:
{
  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test_path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,
  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,
  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;relevance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;low|medium|high&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,
  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confidence_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &amp;lt;float between 0.0 and 1.0&amp;gt;,
  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;short string explaining why this test is relevant&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;
}

Only include tests whose relevance is greater than or equal to the given min_relevance
(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &amp;lt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &amp;lt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;). If no tests are relevant, return an empty array: []
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um ponto que vale destacar nesse prompt é a "um nível de transitividade": o agente não olha só se um teste referencia diretamente o símbolo alterado, mas também se ele referencia algo que, por sua vez, referencia o símbolo alterado (por exemplo, um helper chamado pela função modificada). Isso ajuda a pegar casos de teste que passariam despercebidos numa busca só por nome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seleção do AI Agent
&lt;/h2&gt;

&lt;p&gt;A primeira mudança que fiz foi pedir para a IA adaptar o código de forma que fosse possível passar qual IA utilizar como parâmetro, em vez de deixá-la fixa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Thin wrappers so AIAgent can call Claude, Gemini, or ChatGPT interchangeably.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LLMProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Something that can turn a system + user prompt into a text completion.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClaudeProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calls Anthropic&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s Claude models.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Anthropic&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GeminiProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calls Google&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s Gemini models.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.genai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;

        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GenerateContentConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;system_instruction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatGPTProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calls OpenAI&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s ChatGPT models.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LLMProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Builds the LLMProvider for config.provider, using the matching API key and model.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;anthropic_api_key&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ClaudeProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;anthropic_api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;claude_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemini_api_key&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GeminiProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemini_api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemini_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chatgpt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;openai_api_key&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ChatGPTProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;openai_api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chatgpt_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown provider: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="si"&gt;!r}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O uso do &lt;code&gt;Protocol&lt;/code&gt; aqui é o que permite trocar de provedor sem alterar o restante do código: qualquer classe que implemente &lt;code&gt;complete(system_prompt, user_prompt)&lt;/code&gt; serve, então &lt;code&gt;AIAgent&lt;/code&gt; nunca precisa saber se está falando com Claude, Gemini ou ChatGPT.&lt;/p&gt;

&lt;p&gt;Dessa forma, fica a critério de quem está utilizando o pacote selecionar qual IA será usada, podendo isso ser passado como parâmetro no momento da execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py &lt;span class="nt"&gt;--pr&lt;/span&gt; 42 &lt;span class="nt"&gt;--repo&lt;/span&gt; owner/repo &lt;span class="nt"&gt;--provider&lt;/span&gt; gemini
python main.py &lt;span class="nt"&gt;--pr&lt;/span&gt; 42 &lt;span class="nt"&gt;--repo&lt;/span&gt; owner/repo &lt;span class="nt"&gt;--provider&lt;/span&gt; chatgpt
python main.py &lt;span class="nt"&gt;--pr&lt;/span&gt; 42 &lt;span class="nt"&gt;--repo&lt;/span&gt; owner/repo               &lt;span class="c"&gt;# default: claude&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Validando se o que foi gerado realmente está certo
&lt;/h2&gt;

&lt;p&gt;Para a primeira validação, pesquisei alguns repositórios públicos no GitHub e, nesse caso, selecionei este PR: &lt;a href="https://github.com/pallets/flask/pull/6043" rel="noopener noreferrer"&gt;https://github.com/pallets/flask/pull/6043&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py &lt;span class="nt"&gt;--repo&lt;/span&gt; pallets/flask  &lt;span class="nt"&gt;--pr&lt;/span&gt; 6043  &lt;span class="nt"&gt;--provider&lt;/span&gt; gemini 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E obtive o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fspm5bpmwbygoeegu0pob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fspm5bpmwbygoeegu0pob.png" alt="First result" width="798" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Só que agora entra a parte complicada, sempre temos nos perguntar quando utilizamos IA:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Essa resposta faz sentido?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E, de cara, dá para ver que não — não está certo. Quando passamos um repositório diferente, ele continua buscando no repositório local, ignorando completamente o repositório do PR informado. Para corrigir isso, precisamos garantir que, sempre que for um repositório externo, o agente acesse as informações diretamente dele e para isso, vamos clonar temporariamente uma branch do repositório:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Clones a single branch of a GitHub repository into a temporary directory for local scanning.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;shutil&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tempfile&lt;/span&gt;

&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepoFetchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Raised when the target repository/branch cannot be cloned.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepoFetcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Shallow-clones a single branch of a repository so its tests can be scanned locally.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Clones `repo` (owner/name) at branch `ref` and returns the local checkout path.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdtemp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai-test-selector-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;git&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;clone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--depth&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--branch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--single-branch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_clone_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;returncode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rmtree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RepoFetchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Failed to clone &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;@&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Removes the temporary checkout, if one was created.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rmtree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_tmp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_clone_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://x-access-token:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;@github.com/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.git&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.git&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare no &lt;code&gt;--depth 1&lt;/code&gt; e &lt;code&gt;--single-branch&lt;/code&gt; do clone: como o objetivo aqui é só escanear os testes do repositório naquele ponto específico, não faz sentido trazer todo o histórico de commits — um shallow clone resolve o problema mais rápido e consumindo bem menos espaço em disco.&lt;/p&gt;

&lt;p&gt;Rodando o mesmo comando, temos o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpalxjxcsv6y6ama3w61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpalxjxcsv6y6ama3w61.png" alt="Correct results" width="799" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em resumo, ele selecionou:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Selected 192/403 tests &lt;span class="o"&gt;(&lt;/span&gt;avg confidence: 0.76&lt;span class="o"&gt;)&lt;/span&gt;
pytest tests/test_appctx.py tests/test_async.py tests/test_basic.py tests/test_blueprints.py tests/test_cli.py tests/test_converters.py
tests/test_helpers.py tests/test_json.py tests/test_logging.py tests/test_regression.py tests/test_reqctx.py tests/test_request.py
tests/test_session_interface.py tests/test_signals.py tests/test_subclassing.py tests/test_templating.py tests/test_testing.py
tests/test_user_error_handler.py tests/test_views.py &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É possível ver que com a IA, ao invés de rodarmos toda a suite, poderíamos rodar apenas 48% dela, reduzindo o tempo de execução e retornando um feedback muito mais rápido para quem está desenvolvendo a feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Como o artigo já está ficando grande, vou parar por aqui nesta primeira etapa. Revisando, o foco desta primeira parte foi refinar o prompt utilizado pela IA para gerar o código e, a partir disso, revisar o que foi gerado. Nela tivemos duas mudanças significativas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adaptação do código para utilizar diferentes provedores de IA, de forma que o projeto não ficasse preso a um único modelo.&lt;/li&gt;
&lt;li&gt;Ajuste na busca dos testes, para que ela considerasse os testes disponíveis no repositório relacionado ao PR informado, e não no repositório local.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Próximos passos
&lt;/h2&gt;

&lt;p&gt;Esse projeto ainda está bem no início, e pretendo continuar evoluindo ele nos próximos artigos. Já durante essa primeira parte, revisando o que foi gerado e testando em repositórios reais, surgiram algumas ideias novas que quero explorar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integração com pipelines: hoje o projeto roda de forma isolada, via linha de comando, mas o próximo passo natural é pensar em como plugar isso direto no CI/CD — por exemplo, como uma action do GitHub Actions que roda automaticamente a cada PR aberto e comenta com os testes selecionados, ou até já dispara só o subconjunto relevante.&lt;/li&gt;
&lt;li&gt;Performance na parte de IA: com repositórios maiores, o número de testes disponíveis para avaliar cresce bastante, e isso significa prompts maiores e mais tempo de resposta. Quero investigar formas de otimizar essa etapa — seja filtrando os candidatos antes de mandar para a IA, seja quebrando a avaliação em lotes menores, ou até testando modelos diferentes para essa tarefa específica de classificação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você quiser acompanhar a evolução do projeto (ou já colocar a mão na massa também), o código está aberto no meu repositório: &lt;a href="https://github.com/m4rri4nne/ai-agent-test-selector" rel="noopener noreferrer"&gt;ai-agent-test-selector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No próximo artigo, vou focar no prompt utilizado pela IA para selecionar os testes propriamente dito, além de adaptar o wrapper para ler repositórios que não sejam apenas em Python, mas também em outras linguagens.&lt;/p&gt;

&lt;p&gt;Ficou alguma dúvida sobre alguma parte do código, do prompt ou da arquitetura? Deixa nos comentários — quero muito saber o que vocês acharam e trocar ideia sobre outros cenários onde isso poderia ser aplicado.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>testing</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Programação Criativa: Vamos desenhar com código?</title>
      <dc:creator>Sara Aniceto</dc:creator>
      <pubDate>Sun, 02 Aug 2026 01:36:54 +0000</pubDate>
      <link>https://dev.to/he4rt/programacao-criativa-vamos-desenhar-com-codigo-4a1</link>
      <guid>https://dev.to/he4rt/programacao-criativa-vamos-desenhar-com-codigo-4a1</guid>
      <description>&lt;p&gt;Quem acha que a discussão entre arte gerada por computadores começou com a popularização das ferramentas de IA provavelmente perdeu boa parte das discussões envolvidas em arte generativa, arte computacional e design paramétrico que surgiram ainda no século passado. A Programação Criativa, que vamos entender melhor nesse artigo, é uma das formas possíveis de gerar arte a partir de algoritmos que vai muito além de mandar um prompt pra IA e esperar sua arte ser gerada. É construção, linha a linha, onde o programador faz da tela do computador e das linhas de código seu papel e pincel. Vem comigo entender melhor como usar suas habilidades de desenvolvimento para se divertir, experimentar e deixar a criatividade rolar solta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3tvy3qaij4mb4caju7gj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3tvy3qaij4mb4caju7gj.gif" alt="Animação no estilo partículas com fundo preto e partículas brancas" width="540" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é Programação Criativa?
&lt;/h2&gt;

&lt;p&gt;Uma das coisas mais legais que ouvi me adentrando nos estudos de &lt;em&gt;creative coding&lt;/em&gt; (termo em inglês para programação criativa) é que existem muitas pessoas que programam, mas que não são necessariamente "programadoras". A programação não precisa estar presa apenas à sua carreira, ela pode ser uma paixão, um hobby ou um playground lúdico.&lt;/p&gt;

&lt;p&gt;A Programação Criativa é exatamente isso: usar o código para desenhar, criar animações e "brincar" com o computador. Em vez de focar apenas na criação de sistemas ou análise de dados o objetivo aqui é a exploração visual.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8fzc3ntg9wbly6dmaya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8fzc3ntg9wbly6dmaya.png" alt="Imagem de busto de escultura com efeito no estilo halftone" width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você consegue acreditar que a imagem acima foi gerada com 0 linhas de um código Java? Em seguida vou te explicar melhor sobre o Processing e outras ferramentas de programação criativa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Processing e p5.js: Onde o desenho encontra o algoritmo
&lt;/h2&gt;

&lt;p&gt;Processing e o p5.js são duas das ferramentas mais populares criadas para facilitar o contato de artistas, ilustradores, designers e pessoas não programadoras em geral que queiram criar arte usando código.&lt;/p&gt;

&lt;p&gt;A lógica entre eles é a mesma, o que muda são especificidades da sintaxe de cada linguagem. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processing: Criado em 2001, é baseado em Java e é o "pai" de tudo isso. É um software gratuito, no formato de IDE, no qual você consegue escrever, executar e compilar os seus códigos, ou melhor suas obras (aqui chamadas de &lt;em&gt;sketches&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;p5.js: É uma versão do Processing baseada em JavaScript, mais popular atualmente e feita para rodar direto na web.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hoje em dia também é possível usar o modelo do Processing baseado em Python e para a criação de aplicativos Android. O mais importante é entender que, enquanto no Photoshop você usa o mouse para desenhar, aqui você começa a desenhar escrevendo em uma página em branco.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Anatomia Básica do Código (Para quem já coda entender)
&lt;/h2&gt;

&lt;p&gt;Diferente de um script tradicional, a estrutura básica nessas ferramentas é muito simples e visual:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;setup()&lt;/code&gt;&lt;/strong&gt;: É a função que roda uma única vez assim que o programa inicia. É aqui que você define configurações importantes da sua arte, como o tamanho do seu "papel" (canvas).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;draw()&lt;/code&gt;&lt;/strong&gt;: Aqui é onde a mágica acontece. Essa função é um &lt;strong&gt;loop infinito&lt;/strong&gt;. Ela é lida ciclicamente enquanto o programa roda. Se você desenhar algo aqui, pode criar animações ou responder a eventos, como o movimento do mouse.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Com essa estrutura pronta, vale acessar a documentação e entender as inúmeras possibilidades de formas, elementos tipográficos, animações, etc que é possível criar com essas ferramentas. Esse pedaço de código abaixo é o que gerou a imagem que eu mostrei no início do artigo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;noStroke&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;tiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mouseX&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;tileSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tiles&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;tiles&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;tiles&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;

      &lt;span class="c1"&gt;//Picks the color based on the pixel, in which the pixel is the size of the tiles&lt;/span&gt;
      &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
      &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;ellipse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tileSize&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Uma ferramenta visual de aprendizado de programação
&lt;/h2&gt;

&lt;p&gt;É possível que você ainda não tenha sido convencido de explorar o Processing e a programação criativa para despertar o lado artista que mora em você? Se sim, eu te faço uma pergunta: quando é que você parou de desenhar e virou um adulto chato sem criatividade?&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/6IFl-H9lPII" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;Brincadeiras à parte, talvez então você seja convencido de que a programação criativa pode também servir como um facilitador para o aprendizado técnico porque transforma conceitos abstratos (como laços de repetição e condicionais) em resultados visuais e imediatos na sua tela.&lt;/p&gt;

&lt;p&gt;É como um "debug visual". Afinal, ver um &lt;code&gt;for loop&lt;/code&gt; gerando 100 bolinhas coloridas na sua tela em tempo real é a melhor forma de "debugar" sua lógica mental.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão: Experimente!
&lt;/h2&gt;

&lt;p&gt;Se você sente que a programação às vezes fica um pouco "rígida" ou mecânica demais, tente criar um sketch no Processing ou p5.js. É uma forma de usar sua lógica para algo puramente estético e divertido.&lt;/p&gt;

&lt;p&gt;Abaixo deixo alguns links para encontrar referências de projetos, materiais gratuitos e comunidades pra quem quiser conhecer mais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://openprocessing.org/" rel="noopener noreferrer"&gt;OpenProcessing&lt;/a&gt;: Plataforma de hospedagem de projetos em Processing, é o GitHub da Programação Criativa&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/arteprog/programacao-criativa" rel="noopener noreferrer"&gt;Curso gratuito de Programação Criativa&lt;/a&gt;: Repositório no GitHub de curso por Monica Rizzolli e Alexandre Villares&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://codigotranscendente.github.io/livro/livro/lindex.html" rel="noopener noreferrer"&gt;Código Transcendente : Uma introdução prática à programação e arte gerativa&lt;/a&gt;: Livro de Mateus Paresqui Berruezo &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.instagram.com/compoeticabr/" rel="noopener noreferrer"&gt;Compoética&lt;/a&gt; - Encontro Brasileiro de Programação Criativa&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://t.me/programacaocriativa" rel="noopener noreferrer"&gt;Comunidade de Programação Criativa no Brasil no Telegram&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faf25yz4cg94uhg3te23l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faf25yz4cg94uhg3te23l.png" alt="Ilustração tipográfica com a palavra Explore repetida diversas vezes" width="800" height="897"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>creativecoding</category>
      <category>p5js</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Pensar demais nem sempre ajuda e o que eu aprendi com isso</title>
      <dc:creator>Yuri Souza</dc:creator>
      <pubDate>Sat, 01 Aug 2026 10:57:53 +0000</pubDate>
      <link>https://dev.to/he4rt/pensar-demais-nem-sempre-ajuda-e-o-que-eu-aprendi-com-isso-49pp</link>
      <guid>https://dev.to/he4rt/pensar-demais-nem-sempre-ajuda-e-o-que-eu-aprendi-com-isso-49pp</guid>
      <description>&lt;p&gt;Às vezes, a maior barreira para começar um projeto não é a complexidade do problema, mas a busca por uma solução perfeita antes mesmo da primeira linha de código.&lt;/p&gt;

&lt;p&gt;Na semana passada decidi criar um pacote Laravel para integrar a API do Asaas.&lt;/p&gt;

&lt;p&gt;A ideia parecia simples: construir algo reutilizável para projetos futuros e, de quebra, aprender mais sobre desenvolvimento de pacotes.&lt;/p&gt;

&lt;p&gt;Foi então que eu:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abri a IDE e comecei a criar um cliente HTTP simples para a API da Asaas.&lt;/li&gt;
&lt;li&gt;15 minutos depois, eu já estava pesquisando sobre arquitetura de pacotes open source.&lt;/li&gt;
&lt;li&gt;Pensei em DTOs.&lt;/li&gt;
&lt;li&gt;Pensei em interfaces.&lt;/li&gt;
&lt;li&gt;Pensei em Services&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  O que eu entendia por "perfeito"?
&lt;/h2&gt;

&lt;p&gt;Na minha cabeça, um projeto bem feito precisava nascer parecido com os grandes projetos open source que eu admirava.&lt;/p&gt;

&lt;p&gt;Antes mesmo de validar a ideia, eu já pensava na arquitetura, na escalabilidade e em como aquele pacote pareceria para quem abrisse o repositório. E em outros cenários como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pensar na mesma arquitetura que grandes projetos usam antes de ter o primeiro caso de uso funcionando;&lt;/li&gt;
&lt;li&gt;tentar abordar todos os pontos da API da Asaas logo no começo, mesmo sem saber quais eu realmente ia usar;&lt;/li&gt;
&lt;li&gt;imaginar os atrativos que meu pacote teria para outros quererem usá-lo, antes de ele fazer qualquer coisa útil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No papel, parecia que eu estava pensando como alguém mais experiente, mas na prática, eu estava:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;apenas adiando a parte mais importante que era escrever código que resolvesse um problema real.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O custo disso na prática
&lt;/h2&gt;

&lt;p&gt;O curioso é que eu terminava o dia com a sensação de que tinha trabalhado bastante. Tinha lido sobre arquitetura, desenhado camadas, esboçado interfaces.&lt;/p&gt;

&lt;p&gt;Só que, olhando para o projeto, praticamente nada tinha sido construído:  nenhuma requisição enviada, nenhum teste rodando, nenhuma prova de que qualquer uma daquelas decisões fazia sentido.&lt;/p&gt;

&lt;p&gt;Com o tempo, isso começou a gerar um padrão: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mais tempo buscando a estrutura "perfeita" do que resolvendo o problema real; &lt;/li&gt;
&lt;li&gt;Código difícil de entender por estar "bem arquitetado" demais, cedo demais;&lt;/li&gt;
&lt;li&gt;Medo de refatorar algo que ainda nem tinha provado valor; &lt;/li&gt;
&lt;li&gt;Uma frustração crescente por sentir que eu não estava evoluindo, só girando em torno da mesma decisão de design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não era falta de qualidade. Era complexidade antecipada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7k149dylxa01anrsh8v2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7k149dylxa01anrsh8v2.png" alt="Infográfico comparando duas abordagens no desenvolvimento de software: planejar abstrações e arquitetura antes da implementação versus resolver primeiro o problema real e deixar a arquitetura evoluir conforme o projeto cresce." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  O que eu estava realmente evitando?
&lt;/h3&gt;

&lt;p&gt;Foi só depois que comecei a me perguntar outra coisa: por que eu estava tão preso nisso?&lt;/p&gt;

&lt;p&gt;Algumas hipóteses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Eu estava evitando escrever código que eu soubesse, de antemão, que ia precisar refatorar depois?&lt;/li&gt;
&lt;li&gt;  Eu tinha medo de escrever algo "ruim" e isso aparecer publicamente num repositório open source?&lt;/li&gt;
&lt;li&gt;  Eu queria provar, pra mim mesmo, que conseguia arquitetar "como um sênior" antes mesmo de ter o problema resolvido?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A resposta provavelmente era um pouco de cada uma. E nenhuma delas tinha relação com o problema que o pacote deveria resolver.&lt;/p&gt;

&lt;p&gt;Só bem depois entendi que, no fundo, eu confundia complexidade com maturidade técnica.&lt;/p&gt;




&lt;h2&gt;
  
  
  O aprendizado que começou a aparecer
&lt;/h2&gt;

&lt;p&gt;Enquanto refletia sobre isso, lembrei de uma frase que minha mãe repetia desde que eu era pequeno:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Antes feito do que perfeito."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sempre achei que essa frase servia para tarefas do dia a dia, como arrumar o quarto, terminar um trabalho da escola. Nunca imaginei que ela fizesse tanto sentido ao escrever software.&lt;/p&gt;

&lt;p&gt;Junto com ela, veio outra ideia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bons sistemas não nascem perfeitos. Eles evoluem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nenhum dos projetos open source que eu admirava nasceu com a arquitetura que tem hoje; todos passaram por versões mais simples, mais cruas, que foram se modificando à medida que o uso real foi aparecendo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Qualidade não está em prever todos os cenários.&lt;/p&gt;

&lt;p&gt;Qualidade está em escrever código que consiga mudar quando esses cenários realmente aparecerem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Foi só quando parei de procurar a arquitetura perfeita que finalmente escrevi minha primeira requisição de verdade para a API.&lt;/p&gt;

&lt;p&gt;Antes mesmo de escrever a primeira integração, era assim que eu imaginava o pacote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;CustomerService&lt;/span&gt;
        &lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="nc"&gt;AsaasClient&lt;/span&gt;
        &lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="nc"&gt;CreateCustomerDTO&lt;/span&gt;
        &lt;span class="err"&gt;↓&lt;/span&gt;
&lt;span class="nc"&gt;Response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas não comecei com uma arquitetura cheia de camadas. Comecei com algo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$asaas&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Yuri Souza'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'cpfCnpj'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'12345678909'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desde então, passei a repensar algumas atitudes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  resolver o problema atual com clareza antes de pensar no próximo;&lt;/li&gt;
&lt;li&gt;  manter o código simples, legível e testável;&lt;/li&gt;
&lt;li&gt;  criar abstrações apenas quando um padrão se repete de fato, não quando eu imagino que ele vai se repetir;&lt;/li&gt;
&lt;li&gt;  aceitar que refatorar faz parte do processo, não uma falha dele.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não se trata de abandonar boas práticas, mas de aplicá-las &lt;strong&gt;no momento certo&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  O equilíbrio que estou buscando hoje
&lt;/h2&gt;

&lt;p&gt;Hoje tento encontrar um equilíbrio entre dois extremos: nem escrever código sem critério, nem criar uma arquitetura complexa antes que ela seja necessária.&lt;/p&gt;

&lt;p&gt;No próprio pacote do Asaas isso já mudou a forma como estou trabalhando.&lt;/p&gt;

&lt;p&gt;Hoje, a decisão que tomei foi outra: começar pelo caminho mais curto possível.&lt;/p&gt;

&lt;p&gt;Primeiro quero que o pacote consiga conversar com a API e validar os casos de uso mais importantes. Só então vou descobrir quais abstrações realmente fazem sentido.&lt;/p&gt;

&lt;p&gt;Em vez de tentar prever a arquitetura que o projeto terá daqui a um ano, prefiro deixar que ela se desenvolva à medida que novos problemas surgirem.&lt;/p&gt;

&lt;p&gt;Foi aí que entendi uma coisa importante:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arquitetura não é algo que eu preciso descobrir antes de começar. É algo que o próprio projeto vai mostrando à medida que cresce.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Ainda estou no começo desse pacote, e ainda estou aprendendo isso na prática, errando e ajustando no caminho.&lt;/p&gt;

&lt;p&gt;Mas entender que "perfeição antecipada" pode virar um problema já foi um passo importante na minha evolução como desenvolvedor. O projeto do pacote Asaas não precisa da arquitetura perfeita logo de início; precisa apenas da primeira implementação. O resto vai aparecer conforme o uso real for mostrando o caminho.&lt;/p&gt;

&lt;p&gt;Hoje prefiro um código simples que aceite mudanças a uma arquitetura impecável que resista a qualquer alteração.&lt;/p&gt;

&lt;p&gt;Se você também já caiu nessa armadilha da arquitetura perfeita antes da hora, quero saber: como você percebeu e o que fez para sair dela?&lt;/p&gt;

&lt;p&gt;A discussão continua nos comentários. Quero muito conhecer outras experiências e perspectivas sobre esse tema.&lt;/p&gt;




&lt;p&gt;Agradecimentos: obrigado a &lt;a class="mentioned-user" href="https://dev.to/vitoriazzp"&gt;@vitoriazzp&lt;/a&gt; pelo feedback sincero e pelas sugestões que ajudaram a tornar este artigo mais claro e útil.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>productivity</category>
      <category>career</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Se eu pudesse recomeçar em TI, evitaria estes erros.</title>
      <dc:creator>Aline Santana</dc:creator>
      <pubDate>Wed, 29 Jul 2026 13:39:48 +0000</pubDate>
      <link>https://dev.to/he4rt/se-eu-pudesse-recomecar-em-ti-evitaria-estes-erros-3bl8</link>
      <guid>https://dev.to/he4rt/se-eu-pudesse-recomecar-em-ti-evitaria-estes-erros-3bl8</guid>
      <description>&lt;h2&gt;
  
  
  Prólogo
&lt;/h2&gt;

&lt;p&gt;No início da faculdade, séculos atrás (&lt;em&gt;papo de 2021, foi quando entrei na he4rt developers inclusive&lt;/em&gt;) estava extremamente ansiosa e com isso cometi &lt;strong&gt;MUITOS ERROS&lt;/strong&gt;, me levou ao bornout ficando &lt;strong&gt;SEM ESTUDAR&lt;/strong&gt; por meses, até hoje vejo as pessoas cometendo a mesma coisa que eu no passado e isso atrasa MUITO os estudos! Como sempre meus artigos são super rápidos de ler, espero que gostem! &lt;/p&gt;

&lt;h2&gt;
  
  
  1º Não dê ouvidos as pessoas da área (depende)
&lt;/h2&gt;

&lt;p&gt;Acho que o maior erro na internet, inclusive através de influenciadores, é o alarme negativo pra cima de áreas na tecnologia e até mesmo linguagens de programação, fazendo com que iniciantes tenham incertezas sobre o que está estudando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 1 :&lt;/strong&gt; "&lt;em&gt;Você estudando frontend? vai passar fome.&lt;/em&gt;"&lt;br&gt;
&lt;strong&gt;Exemplo 2 :&lt;/strong&gt; "&lt;em&gt;A IA vai roubar teu emprego como desenvolvedor xxx&lt;/em&gt;"&lt;br&gt;
&lt;strong&gt;Exemplo 3 :&lt;/strong&gt; "Flutter vai morrer esse ano de xxx"&lt;/p&gt;

&lt;p&gt;Sendo bem sincera, nem ligue pra isso, tá? até hoje tem emprego pra &lt;strong&gt;COBOL&lt;/strong&gt;, imagine pra tecnologias super modernas que muitas empresas usam, escolheu frontend (&lt;strong&gt;exemplo&lt;/strong&gt;) ? estude, se esforce, converse com pessoas mais experientes nesse segmento e vai fundo, não desista por terceiros! Escolheu &lt;strong&gt;Python&lt;/strong&gt;? cai dentro, a opinião da galera não pode definir teu futuro não.&lt;/p&gt;

&lt;h2&gt;
  
  
  2º Não pula de galho em galho
&lt;/h2&gt;

&lt;p&gt;FOCA NO QUE ESCOLHEU E NÃO PULA, pois foi algo que cometi bastante, eu fui de dados até mobile com Flutter (&lt;em&gt;tô escrevendo isso e rindo alto&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vocês no outro lado da tela&lt;/strong&gt; : "&lt;em&gt;Aline, o que você faria hoje?&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Simples, &lt;a href="https://dev.to/he4rt/2-metodos-que-usei-e-uso-nos-estudos-de-programacao-4n1f"&gt;como disse no primeiro artigo&lt;/a&gt;, &lt;em&gt;&lt;strong&gt;autoconhecimento é importante&lt;/strong&gt;&lt;/em&gt;, o que você gosta? isso que você gosta é evidência no mercado? &lt;em&gt;pesquise&lt;/em&gt;, &lt;em&gt;sai na busca&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Gosta de Matemática?&lt;/strong&gt; _&lt;em&gt;Ciência de Dados seria uma boa&lt;/em&gt;._&lt;br&gt;
&lt;strong&gt;2. Gosta de celular?&lt;/strong&gt; &lt;em&gt;Por que não se envolve com criação de aplicativos?&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;3. É mais de "arte"?&lt;/strong&gt; &lt;em&gt;Já ouviu falar de UX/UI?&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;4. É visual?&lt;/strong&gt; &lt;em&gt;e desenvolvimento frontend?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Entende isso? é normal se perder com tantas informações e tantas áreas dentro de tecnologia, vai pesquisando com calma e veja qual se identifica. &lt;/p&gt;

&lt;h2&gt;
  
  
  3º IA é sua amiga, não inimiga, tenha medo não
&lt;/h2&gt;

&lt;p&gt;Não me venha com o argumento : "&lt;em&gt;Aline, não quero ser de TI pois a IA vai roubar meu emprego&lt;/em&gt;", vai nada amigo(a), LLMs em geral são feitas dentro de &lt;em&gt;pesquisas&lt;/em&gt; e trabalhadas no que chamamos de &lt;em&gt;probabilidade&lt;/em&gt;, é mais fácil tu acertar algo do que ela (&lt;em&gt;risos&lt;/em&gt;), não vou ser hipócrita em dizer que IA não ajuda em algo, CLARO que ajuda, inclusive quando se trata de &lt;em&gt;automação de tarefas&lt;/em&gt;, mas o que quero dizer é que &lt;strong&gt;&lt;em&gt;VOCÊ TEM QUE SABER O QUE TÁ FAZENDO&lt;/em&gt;&lt;/strong&gt; E &lt;strong&gt;&lt;em&gt;NÃO DEIXAR A BASE DE LADO&lt;/em&gt;&lt;/strong&gt;, ou seja : "&lt;em&gt;Ai, não vou estudar programação, vou pular pro Claudinho&lt;/em&gt;", vai nessa, prejuízo é enorme.&lt;/p&gt;

&lt;p&gt;"&lt;em&gt;Mas fulano de tal usa&lt;/em&gt;", é que o "&lt;em&gt;fulano de tal&lt;/em&gt;" já tem uma base muito sólida no conhecimento daquela linguagem, estamos entendidos? quando passei pela stack de Frontend, era um alarme com Inteligência Artificial gigantesco, tive muito medo e troquei de área, me atrasou muito. (na época)&lt;/p&gt;

&lt;h2&gt;
  
  
  4º Marca Pessoal galera, é importantíssimo!
&lt;/h2&gt;

&lt;p&gt;Depois de um bom período me tratando psicologicamente (depressão), voltarei com o linkedin, mas vejo que muita gente faz descaso com essa rede, principalmente iniciantes! Motivos? talvez timidez (comum), não gosta, preguiça? talvez, eu não sei, só você sabe. &lt;/p&gt;

&lt;p&gt;De forma geral, tenha uma marca pessoal trabalhada, isso é importante até mesmo dentro de comunidades, como os recrutadores podem analisar além do seu currículo destacado? acho um cristal quem faz conteúdo de tecnologia nessa rede, lá estão a maioria dos recrutadores e donos de empresas, seja visto!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dica geral :&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Escolha cores que lhe representam ou que você quer transmitir&lt;/li&gt;
&lt;li&gt;Traga experiência real nos seus conteúdos&lt;/li&gt;
&lt;li&gt;Não seja um personagem&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que tenham gostado desse artigo, eu poderia listar TANTAS COISAS que me atrasaram ou podem atrasar vocês, mas listei as mais importantes da minha vivência e que afeta iniciantes como eu.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agradeço a He4rt Developers por essa iniciativa dentro da comunidade em instigar membros dentro da escrita&lt;/em&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>2 métodos que usei (E USO) nos estudos de programação.</title>
      <dc:creator>Aline Santana</dc:creator>
      <pubDate>Mon, 27 Jul 2026 14:58:19 +0000</pubDate>
      <link>https://dev.to/he4rt/2-metodos-que-usei-e-uso-nos-estudos-de-programacao-4n1f</link>
      <guid>https://dev.to/he4rt/2-metodos-que-usei-e-uso-nos-estudos-de-programacao-4n1f</guid>
      <description>&lt;h2&gt;
  
  
  Prólogo
&lt;/h2&gt;

&lt;p&gt;Para uma pessoa que tem TDAH (eu), é extremamente difícil e desafiador encontrar uma maneira mais “confortável” de estudar, ainda mais quando tal assunto é de exatas (&lt;em&gt;sou de humanas e tô em TI, pasmem&lt;/em&gt;), então resolvi encontrar algumas maneiras e que claro, deu super certo pra mim e espero muitíssimo que dê certo pra vocês. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observação (dica)&lt;/strong&gt; : vai testando cada método, &lt;strong&gt;não pegue&lt;/strong&gt; um como verdade absoluta, o que ficar confortável, use &amp;lt;3 &lt;/p&gt;

&lt;p&gt;Nem todos vão se dar bem com o método X e Y, cada cérebro funciona de uma maneira diferente, alguns de vocês vão se adaptar com vídeos, textos (&lt;em&gt;artigos como esse&lt;/em&gt;), presencial ou online, o melhor jeito de encontrar o método “perfeito” é ter autoconhecimento, eu por exemplo : tem que ser mais prática do que teoria, vídeo aula ? tem que ser curto (&lt;em&gt;longo demais me perco&lt;/em&gt;), o estudo tem que ser mais ativo do que passivo, revisão ? 0 aplicativo, &lt;em&gt;&lt;strong&gt;revisão pra mim é prática&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos ser bem rápidos com os métodos para usar como um mini caderno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Método Feynman
&lt;/h2&gt;

&lt;p&gt;Criado pelo físico (&lt;em&gt;vencedor do prêmio nobel, tá?&lt;/em&gt;) &lt;strong&gt;Richard Feynman&lt;/strong&gt;, seu método é basicamente fazer autoexplicação usando palavras e analogias de forma mais simples, sem esse jargão técnico que pode mais atrapalhar do que ajudar (&lt;em&gt;ainda mais pra nós, meros iniciantes&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Já pega seu conteúdo que estuda.
&lt;/h3&gt;

&lt;p&gt;O primeiro passo é escolher o que você está estudando, especialmente o que está travando seu cérebro, aquela parte do estudo que mesmo entendendo ainda sente falta de alguma coisa.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Explique de forma &lt;em&gt;“leiga”&lt;/em&gt;.
&lt;/h3&gt;

&lt;p&gt;Imagina que você é uma criança, primo(a), esse momento é importante que tire os conceitos técnicos que possivelmente pode “impedir” de aprender de forma fácil e explique do seu jeitinho, sem conceitos técnicos, sem palavras difíceis. Um prompt que é meme, mas eu uso bastante é : “&lt;em&gt;Explique assunto xxx como se eu fosse uma criança de xxx anos, sem conceitos técnicos para que eu entenda de forma fácil e rápido&lt;/em&gt;”, após isso (&lt;em&gt;novamente como disse&lt;/em&gt;) explique para si mesmo.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 Lacunas.
&lt;/h3&gt;

&lt;p&gt;Primo(a), em algum momento da explicação vai perceber que teve algumas lacunas na sua explicação (&lt;em&gt;isso é normal, tá? você tá aprendendo, eu lembro que ficava muito chateada também rs&lt;/em&gt;), anote essas lacunas e até mesmo suas dúvidas, vamos para o último passo.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4 Refinamento.
&lt;/h3&gt;

&lt;p&gt;Último passo (&lt;em&gt;é bem simples&lt;/em&gt;), tudo que encontrou de lacunas e dúvidas você vai achar no material que estudou, anote, identifique e volte novamente ao passo 1.2, onde vai explicar com as lacunas preenchidas. (&lt;em&gt;caso ainda tiver dúvida, repita o mesmo processo até aprender&lt;/em&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  2° Active Recall - Meu querido (&lt;em&gt;O que eu faço&lt;/em&gt;)
&lt;/h2&gt;

&lt;p&gt;Active recall seria o “&lt;em&gt;método ativo&lt;/em&gt;”, iria forçar seu cérebro a relembrar assunto que estudou minutos ou horas atrás, um dos exemplos bem legais é o método feynman que expliquei anteriormente, mas vou explicar a forma que faço. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 - Assista o vídeo até determinado ponto.
&lt;/h3&gt;

&lt;p&gt;Se for uma videoaula (&lt;em&gt;ou qualquer material que esteja usando viu&lt;/em&gt;), sempre que o professor concluir a explicação de um tópico e iniciar outro, pause o vídeo e anote apenas os principais tópicos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;/em&gt; o professor começa contando como foi a experiência dele na faculdade de &lt;em&gt;Engenharia de Software&lt;/em&gt;. Em seguida, ele passa a explicar por que utilizou determinada linguagem de programação durante o curso. Assim que ele concluir esse assunto e antes de iniciar o próximo, &lt;em&gt;pause o vídeo&lt;/em&gt; e anot*&lt;em&gt;e os pontos PRINCIPAIS&lt;/em&gt;*, não sua explicação ainda. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Exemplo 2 (anotação)&lt;/strong&gt;&lt;/em&gt; : Aqui ele explicou sobre sua experiência na faculdade. (pronto, escreve mais nada)&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 - Torra seu cérebro.
&lt;/h3&gt;

&lt;p&gt;Não volte na sua vídeo aula, documentação e afins, olhe para o tópico anotado e tente lembrar com suas próprias palavras o que ele disse, sim, funciona até com código (é muito bom, mas dá um leve estresse kkk), você escolhe se fará anotação ou explicar com suas próprias palavras (feynman). &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Na realidade existem vários métodos de estudos para cada cabeça, como disse no prólogo, autoconhecimento na jornada de programação já é um passo maravilhoso, não se cobre ou até mesmo se estressa demais durante os estudos, é NORMAL não saber de primeira, só não desista.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agradeço a toda comunidade por sempre instigar a compartilhar nossos conhecimentos.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>aprendizado</category>
      <category>estudos</category>
    </item>
    <item>
      <title>Como eu venci o medo da transição de carreira</title>
      <dc:creator>Bárbara Martins da Silveira</dc:creator>
      <pubDate>Sun, 26 Jul 2026 19:12:49 +0000</pubDate>
      <link>https://dev.to/he4rt/como-eu-venci-o-medo-da-transicao-de-carreira-4b3c</link>
      <guid>https://dev.to/he4rt/como-eu-venci-o-medo-da-transicao-de-carreira-4b3c</guid>
      <description>&lt;p&gt;Migrar de carreira para a área de tecnologia pode parecer difícil no início. O mercado está cada vez mais concorrido, além de estar passando por muitas transformações. Realizar a transição não é um processo fácil, mas é totalmente possível, mesmo que você esteja em uma área completamente diferente, ou atue há muitos anos em outro setor. Nesse artigo, compartilho como foi o meu processo, além de dar algumas dicas para quem está em transição ou pensando em iniciar a mudança de carreira. &lt;/p&gt;




&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; O início da jornada&lt;/li&gt;
&lt;li&gt; Reconhecendo a insatisfação&lt;/li&gt;
&lt;li&gt; Os primeiros medos&lt;/li&gt;
&lt;li&gt; Lidando com críticas&lt;/li&gt;
&lt;li&gt; A conquista da primeira vaga&lt;/li&gt;
&lt;li&gt; Dicas para quem está em transição de carreira:&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  O início da jornada
&lt;/h2&gt;

&lt;p&gt;Nessa semana completo 1 ano da minha transição de carreira. Sei que, para quem acompanha de fora, pode parecer que foi fácil ou que tive sorte em algum momento. Mas quem está na área de TI sabe o quanto esse processo é complexo. Ao olhar para trás, sinto como se passasse um filme na minha cabeça.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reconhecendo a insatisfação
&lt;/h2&gt;

&lt;p&gt;Desde o começo, a transição foi difícil: reconhecer que eu não estava satisfeita na carreira atual, lidar com rotina dupla, exaustão, críticas de pessoas próximas e o medo de recomeçar. Antes de iniciar meus estudos em tecnologia, minha rotina era insana e eu dormia poucas horas por noite. Até que percebi que não estava evoluindo e que a carreira para a qual me preparava já não fazia sentido. Foi então que decidi tirar do papel uma vontade que surgiu na pandemia, mas que o medo de começar havia travado: estudar tecnologia.&lt;/p&gt;




&lt;h2&gt;
  
  
  Os primeiros medos
&lt;/h2&gt;

&lt;p&gt;No início, eu tinha medo de tudo: baixar uma IDE, mexer em código, enviar algo para o git, errar e falhar. Criar um post em rede social como o LinkedIn, então? Parecia absurdo compartilhar que eu estava tentando migrar de área. Mas mesmo com medo, iniciei e não deixei que minhas inseguranças me paralisassem. Consegui começar minha graduação online, muito mais flexível e adaptada aos meus horários, e descobri algo novo: a felicidade em evoluir e aprender sobre um assunto que eu realmente gostava.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lidando com críticas
&lt;/h2&gt;

&lt;p&gt;As críticas vieram. Algumas pessoas diziam que seria apenas um interesse passageiro, que eu estava desperdiçando meu curso anterior na federal, que era loucura iniciar algo novo nessa altura da carreira. Trabalhei isso em terapia e aprendi a ignorar opiniões que não acrescentavam nada.&lt;/p&gt;




&lt;h2&gt;
  
  
  A conquista da primeira vaga
&lt;/h2&gt;

&lt;p&gt;Depois de 3 meses estudando, comecei a aplicar para processos seletivos, entender como funcionava o LinkedIn, criar posts, realizar conexões e focar nas áreas que realmente me interessavam. Foi um processo construído aos poucos, mas perdi o medo de escrever e meu perfil deixou de ser invisível. Aos poucos, as oportunidades começaram a aparecer e, em 6 meses de busca, conquistei minha tão sonhada vaga (claro que depois de muitos &lt;strong&gt;nãos&lt;/strong&gt;). Mais do que isso: pude ajudar outras meninas que me procuraram em busca de dicas para ingressar na área, e isso é motivo de muito orgulho para mim.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dicas para quem está em transição de carreira:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comece com medo mesmo:&lt;/strong&gt; no início, o processo é assustador, mas comece com medo mesmo. A primeira vaga é a mais difícil de conseguir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aceite que nem todos os dias serão bons:&lt;/strong&gt; cada dia passado é um passo a menos até conquistar seu espaço. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenha o LinkedIn ativo:&lt;/strong&gt; mesmo que você não goste da rede, hoje praticamente todas as vagas passam por lá. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invista em networking:&lt;/strong&gt; em uma área tão concorrida, relacionamentos são até mais importantes que conhecimento técnico. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Participe de comunidades tech:&lt;/strong&gt; as comunidades tech como a &lt;a href="https://heartdevs.com/" rel="noopener noreferrer"&gt;He4rt&lt;/a&gt; são espaços de troca de ideias, colaboração, eventos, engajamento e projetos open source. É o melhor lugar para trocar ideias, conversar com pessoas que estão passando pelo mesmo processo que você, além de participar de projetos reais que podem somar muito ao seu currículo. &lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Se você pensa em migrar de carreira ou está passando por esse momento agora, lembre-se: essa fase exige paciência e persistência, mas cada projeto, cada conexão e cada tentativa te aproximam do tão sonhado &lt;strong&gt;sim&lt;/strong&gt;. Para quem já passou ou está passando pela transição para TI, quais foram seus maiores desafios e aprendizados? Compartilhe nos comentários! A sua experiência pode inspirar outras pessoas.&lt;/p&gt;

</description>
      <category>carreira</category>
      <category>aprendizado</category>
      <category>networking</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Começando com Redes: Camadas de uma conexão TCP/IP</title>
      <dc:creator>Cristian Magalhães</dc:creator>
      <pubDate>Fri, 24 Jul 2026 12:37:44 +0000</pubDate>
      <link>https://dev.to/he4rt/comecando-com-redes-camadas-de-uma-conexao-tcpip-1bjn</link>
      <guid>https://dev.to/he4rt/comecando-com-redes-camadas-de-uma-conexao-tcpip-1bjn</guid>
      <description>&lt;p&gt;Eae gente bonita, beleza? Depois de um longo período, resolvi voltar aqui e continuar compartilhando a minha trilha de estudos com vocês. Hoje vou começar (tentar pelo menos) uma série sobre redes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExMm8yMG9wdnJzc3dnbnpiYjQwM242NjJjaDNpaG5jeWJvbW5heDdndSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2Fm12EDnP8xGLy8%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExMm8yMG9wdnJzc3dnbnpiYjQwM242NjJjaDNpaG5jeWJvbW5heDdndSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2Fm12EDnP8xGLy8%2Fgiphy.gif" alt="child fixing a server?" width="480" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que estudar redes
&lt;/h2&gt;

&lt;p&gt;Começaremos com o porquê de aprofundar os estudos em redes. Conforme a sua senioridade vai aumentando, você vai ganhando novas responsabilidades para si e também dentro do ambiente de trabalho. Levando isso em consideração, ter o conhecimento básico de redes para poder ter mais autonomia e autoridade quando falar de cloud, arquitetura e coisas do tipo realmente não me parece ser uma má ideia. "Ah, mas na minha empresa tem devops que cuida disso", ainda assim, é necessário o mínimo de conhecimento teórico para conversar e até mesmo ajudar a entender o seu problema e criar soluções.&lt;/p&gt;

&lt;h2&gt;
  
  
  TCP/IP
&lt;/h2&gt;

&lt;p&gt;Explicando a sigla basicamente, o modelo TCP/IP é um conjunto de protocolos de comunicação que permite a conexão e a troca de informações na internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  O conjunto recebe o nome de seus dois protocolos principais:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;IP (Internet Protocol)&lt;/strong&gt; = Responsável pelo roteamento dos pacotes e endereçamento para que as informações cheguem ao seu destino.&lt;br&gt;
&lt;strong&gt;TCP (Transmission Control Protocol)&lt;/strong&gt; = Está presente na camada de transporte garantindo que nenhum pacote seja perdido ou corrompido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como funciona o modelo TCP/IP
&lt;/h2&gt;

&lt;p&gt;Gosto muito de sair do escopo macro para o micro. Basicamente, uma conexão ocorre quando duas máquinas estão trocando informações (pacotes) entre si. E não precisa ser sempre dessa forma; também temos o caso (mais comum) em que uma máquina (cliente) pede informações a outra (servidor).&lt;/p&gt;

&lt;p&gt;Ficou simples até demais, né? Para que a troca de informações funcione, existe uma série de passos a serem seguidos. Dentro de uma conexão existem algumas camadas, pelas quais a informação passa antes de chegar ao seu destino.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L7&lt;/strong&gt; = É a camada de aplicação, onde a aplicação roda e também onde roda o protocolo HTTP, SMTP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L4&lt;/strong&gt; = Camada de transporte: responsável por garantir a entrega confiável dos dados entre a origem e o destino (é aqui que atua o TCP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L3&lt;/strong&gt; = Camada de rede: responsável pelo roteamento dos pacotes e endereçamento até o destino (é aqui que atua o IP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L2&lt;/strong&gt; = Camada de enlace: responsável por transmitir os quadros de dados entre dispositivos dentro da mesma rede, através do endereço MAC.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isso é uma regra geral. A camada de cima sempre usa os recursos da camada de baixo para enviar as informações.&lt;/p&gt;

&lt;p&gt;Importante lembrar: caso uma camada de baixo não funcione, a camada de cima também não funcionará.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4b4m28pww7ag2tebsx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4b4m28pww7ag2tebsx4.png" alt=" " width="774" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é um pacote
&lt;/h2&gt;

&lt;p&gt;Basicamente um pacote é uma carta ou mesmo uma "caixa" por onde as informações são trafegadas na internet. Além das informações requisitadas, nele constam também o remetente e o destinatário, da mesma forma que em uma carta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por fim...
&lt;/h2&gt;

&lt;p&gt;Hoje falei um pouco sobre como funciona uma conexão, como é estruturada e como funciona todo o processo de troca de informações. Em breve trarei mais tópicos sobre o que existe dentro de uma mensagem HTTP e coisas do tipo.&lt;/p&gt;




&lt;p&gt;Se chegou até aqui, me segue lá nas &lt;a href="https://cristianm.dev/" rel="noopener noreferrer"&gt;redes vizinhas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/uWlpPGquhGZNFzY90z/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/uWlpPGquhGZNFzY90z/giphy.gif" alt="thank you dog" width="478" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>aws</category>
      <category>cloud</category>
      <category>programming</category>
    </item>
    <item>
      <title>Contribuir para a comunidade: como destacar isso no seu LinkedIn e currículo</title>
      <dc:creator>vitoriazzp</dc:creator>
      <pubDate>Wed, 22 Jul 2026 18:11:09 +0000</pubDate>
      <link>https://dev.to/he4rt/contribuir-para-a-comunidade-como-destacar-isso-no-seu-linkedin-e-curriculo-4cgl</link>
      <guid>https://dev.to/he4rt/contribuir-para-a-comunidade-como-destacar-isso-no-seu-linkedin-e-curriculo-4cgl</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Como eu mostro que estou contribuindo?&lt;/li&gt;
&lt;li&gt;Posso colocar no meu LinkedIn?&lt;/li&gt;
&lt;li&gt;E no meu currículo, como faço?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Foi a partir dessas dúvidas que eu elaborei esse guia pra você que quer contribuir do seu jeito e mostrar às empresas e às pessoas, de forma clara e estratégica, o que você está fazendo.&lt;/p&gt;

&lt;p&gt;Vamos lá? 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  Por que eu deveria mostrar no LinkedIn?
&lt;/h2&gt;

&lt;p&gt;LinkedIn é a porta de entrada para o mundo corporativo no Brasil e no mundo. É por meio dele que você mostra "trabalho". E tem mais: não é só experiência remunerada que conta como evidência de que você tem conhecimento e prática, mas também &lt;em&gt;tudo o que você constrói de forma voluntária&lt;/em&gt;, seja tirando dúvida de alguém, participando de um projeto open-source ou escrevendo sobre o que aprendeu. Recrutador não lê currículo pensando só em carteira assinada. &lt;strong&gt;Lê pensando em capacidade&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Você contribui com algo para a comunidade e quer colocar isso no seu perfil. Existem 3 formas que você pode usar, e elas podem ser usadas todas juntas ou só uma.&lt;/p&gt;

&lt;p&gt;Escolha aquela que fizer mais sentido pro seu perfil ou busque por outras pessoas que você admira dentro da comunidade e veja como elas colocaram no próprio perfil.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Seção de &lt;strong&gt;Experiência&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4jtif8f89vj9q6e55e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4jtif8f89vj9q6e55e4.png" alt="linkedin-experience" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use como experiência sempre que estiver contribuindo de forma profissional pra uma área que você busca. Se você participa de contribuições no GitHub, seja através de código, documentação ou outra forma, use como experiência.&lt;/p&gt;

&lt;p&gt;Pessoas que também estão ajudando na moderação ou administração (community managers) podem destacar as responsabilidades ou resultados das suas ações por aqui.&lt;/p&gt;

&lt;p&gt;Exemplo de como preencher no LinkedIn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cargo: [cargo que você faz] Open Source
Empresa: [Nome do projeto/organização]
Tipo de emprego: Meio período (ou Voluntário)
Local: Remoto, Brasil

Descrição:
- Contribuí com [X] pull requests na documentação do projeto [Nome],
  focando em clareza para novos contribuidores.
- Revisei issues abertas e sugeri melhorias de acessibilidade em
  componentes de UI usando [ferramenta/stack].
- Participei de reuniões semanais de planejamento com o time core
  do projeto.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Se estiver em dúvida sobre a sua atuação em algum projeto ou até especificamente sobre como colocar, comenta aqui ou chama a gente no Discord; ficaremos felizes em te ajudar.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  2. Seção de &lt;strong&gt;voluntariado&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fi.imgur.com%2FAfPTCeC.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fi.imgur.com%2FAfPTCeC.gif" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse espaço é um pouco mais livre. Você pode usar pra mostrar que é membro da comunidade, moderador ou outro cargo que faça sentido e descreva sua participação. Não é necessário listar ou descrever o que você faz, só se quiser 🫣&lt;/p&gt;

&lt;p&gt;Exemplo simples:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Organização: He4rt Developers
Função: Devloper Advocated
Causa: Ciência e tecnologia
Período: Março de 2025 - Presente

Descrição (opcional):
- Lidero o programa de advocacia da comunidade, conectando
  membros a oportunidades de conteúdo e mentoria.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Exemplo mínimo, sem descrição:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Organização: Friends of Figma Porto Alegre
Função: Voluntária (fotografia e recepção de convidados)
Período: 2025 - Presente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Seção de &lt;strong&gt;Projetos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1tv5093gq41qikb5z5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1tv5093gq41qikb5z5z.png" alt="linkedin-projects" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Participa de um projeto específico da comunidade?&lt;/strong&gt; Essa seção é a mais indicada pra você nesse caso, porque dá visibilidade às suas stacks e skills. Por isso é importante estruturar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome do projeto&lt;/li&gt;
&lt;li&gt;Prévia (print ou link do repositório)&lt;/li&gt;
&lt;li&gt;Descrição do que é&lt;/li&gt;
&lt;li&gt;Stacks que você aplica durante as suas contribuições&lt;/li&gt;
&lt;li&gt;(opcional) Marque quem está no projeto com você&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nome do projeto: Plataforma da He4rt 
Link: github.com/he4rt/heartdevs.com

Descrição:
Landing page da comunidade He4rt Developers,
Construída com identidade visual própria (roxo He4rt, dark mode).

Minha contribuição:
Design e desenvolvimento front-end da página, do wireframe
À implementação em PHP.

Stacks: Figma, React, Tailwind CSS, Claude Design
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Depara: quem tem experiência x quem não tem
&lt;/h2&gt;

&lt;p&gt;Um erro comum é achar que sem carteira assinada não tem o que mostrar. Não é bem assim. Muda a forma de descrever, não a legitimidade do que você fez.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flz7e8s6hr7d9k5ggqzpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flz7e8s6hr7d9k5ggqzpo.png" alt="tabela comparativa entre quem tem e não tem experiência" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nos dois casos, a régua é a mesma: se você fez, pode mostrar. O que muda é o quanto de contexto você precisa dar pra quem está lendo confiar no que está escrito.&lt;/p&gt;


&lt;h2&gt;
  
  
  Segunda parada: currículo
&lt;/h2&gt;

&lt;p&gt;É importante manter as mesmas informações que você tem no LinkedIn. Caso não tenha experiência formal, mas contribua pra comunidade, pode colocar diretamente na seção de experiência, com pelo menos 2 bullets do que você fez, como fez e qual foi o resultado.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;He4rt Developers (Tecnologia)
UI/UX Designer | Remoto, Brasil | Março 2026 - Presente

- Desenvolvi microcopy e fluxos de UI para funcionalidades internas
  da comunidade, aplicando princípios de acessibilidade e clareza.
- Colaborei com o time de desenvolvimento na construção da landing
  page de artigos, do wireframe em Figma à entrega final em React.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Exemplo pra quem já tem experiência formal em outra área e quer somar a contribuição:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Friends of Figma Porto Alegre (Comunidade)
Voluntária | Porto Alegre, Brasil | 2025 - Presente

- Apoiei a organização de eventos presenciais, atuando na recepção
  de convidados e registro fotográfico do evento.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Um modelo pra chamar de seu
&lt;/h2&gt;

&lt;p&gt;Pra facilitar essa parte do currículo, criei um modelo que passa tanto pela leitura de um recrutador humano quanto por um ATS (o robô que filtra currículo antes de chegar em alguém). Ele serve tanto pra quem já tem experiência formal e quer só organizar melhor, quanto pra quem está usando a comunidade como primeira experiência pra registrar no papel.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://docs.google.com/document/d/1F1GGFeAQKwobE1RKpjlIpkGpFfByFsm2-WKVtAZ97es/edit?usp=sharing" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2Fdocs%2FAHkbwyJFPhlyChdU0_CISoXwEy_ZiQ-BkLr_8B628PcM4RBMSkbJxC9X-4UOT0WSZ4caKl8boI6_dp3gr4CaVyK64AsPkfjkTug3r7ga3qqOaTYsyeMOY7Ii%3Dw1200-h630-p" height="630" class="m-0" width="1200"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://docs.google.com/document/d/1F1GGFeAQKwobE1RKpjlIpkGpFfByFsm2-WKVtAZ97es/edit?usp=sharing" rel="noopener noreferrer" class="c-link"&gt;
            Modelo Currículo (com e sem experiência) - Google Docs
          &lt;/a&gt;
        &lt;/h2&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fssl.gstatic.com%2Fdocs%2Fdocuments%2Fimages%2Fdocs-favicon-2026-v2.ico" width="256" height="256"&gt;
          docs.google.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;






&lt;p&gt;Contribuir pra comunidade é trabalho, mesmo sem salário no fim do mês. E o &lt;strong&gt;trabalho merece estar registrado&lt;/strong&gt; em algum lugar que outras pessoas possam ver.&lt;/p&gt;

&lt;p&gt;Se esse guia te ajudou a organizar como colocar sua contribuição no LinkedIn ou no currículo, conta aqui nos comentários: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Qual a sua maior dor hoje pra mostrar as suas contribuições no LinkedIn ou no currículo?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>braziliandevs</category>
      <category>career</category>
      <category>discuss</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
