<?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: Von Grossi</title>
    <description>The latest articles on DEV Community by Von Grossi (@vongrossi).</description>
    <link>https://dev.to/vongrossi</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%2Fuser%2Fprofile_image%2F114110%2Fd4a238fa-5a9e-440c-99b4-bff78085d4fb.jpeg</url>
      <title>DEV Community: Von Grossi</title>
      <link>https://dev.to/vongrossi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vongrossi"/>
    <language>en</language>
    <item>
      <title>Como testar Sistemas multiagentes com ADK</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Tue, 29 Sep 2026 21:05:52 +0000</pubDate>
      <link>https://dev.to/vongrossi/como-testar-sistemas-multiagentes-com-adk-39ne</link>
      <guid>https://dev.to/vongrossi/como-testar-sistemas-multiagentes-com-adk-39ne</guid>
      <description>&lt;h2&gt;
  
  
  O que aprendi construindo um pipeline com Google ADK, MCP e modelos locais
&lt;/h2&gt;

&lt;p&gt;Sistemas multiagentes costumam ser apresentados de uma maneira muito atraente. Um agente pesquisa, outro escreve, um terceiro revisa e o resultado parece pronto para produção.&lt;/p&gt;

&lt;p&gt;O problema aparece quando o resultado está quase certo.&lt;/p&gt;

&lt;p&gt;Um título passa do limite permitido. Uma URL parece real, mas não existe. Um agente de revisão recebe o caminho errado. Um validador deveria interromper o fluxo, mas não consegue enxergar o estado produzido na etapa anterior.&lt;/p&gt;

&lt;p&gt;Foi justamente para explorar esse tipo de problema que organizei o repositório &lt;a href="https://github.com/vongrossi/adk-multiagent/" rel="noopener noreferrer"&gt;adk-multiagent&lt;/a&gt;. Ele reúne oito agentes em Python usando o Google Agent Development Kit, conhecido como ADK, além de um servidor local MCP, testes offline, integração com RAG, revisão de código, verificação de links e uma cadeia de modelos hospedados e locais.&lt;/p&gt;

&lt;p&gt;A ideia central do projeto é simples:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O modelo deve interpretar, decidir e explicar. O código deve medir, limitar, buscar e rejeitar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa separação torna o comportamento dos agentes mais previsível e também mais fácil de testar.&lt;/p&gt;

&lt;h2&gt;
  
  
  O projeto não é apenas uma coleção de agentes
&lt;/h2&gt;

&lt;p&gt;Cada agente fica em sua própria pasta e expõe um &lt;code&gt;root_agent&lt;/code&gt; em &lt;code&gt;agent.py&lt;/code&gt;. Existe também um &lt;code&gt;common.py&lt;/code&gt;, responsável por montar a cadeia de modelos usada pelos agentes.&lt;/p&gt;

&lt;p&gt;A estrutura prática é parecida com esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogger          planejamento, escrita e validação
linkcheck        verificação de URLs e fontes
seo              metadados para publicação
rag              documentos indexados e respostas com citações
codereview       leitura segura de arquivos e heurísticas
triage           classificação e roteamento por confiança
mcp_text_audit   agente que consome um servidor MCP local
researcher       exemplo mínimo de um agente
common.py        cadeia de modelos e fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O ADK trata agentes como unidades de execução com modelo, instruções e ferramentas. Aplicações maiores podem combinar essas unidades em hierarquias ou workflows. A documentação oficial explica os conceitos em &lt;a href="https://google.github.io/adk-docs/agents/" rel="noopener noreferrer"&gt;ADK Agents&lt;/a&gt; e &lt;a href="https://google.github.io/adk-docs/workflows/" rel="noopener noreferrer"&gt;ADK Workflows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;No projeto, a divisão de pastas também representa uma divisão de responsabilidades. Cada fronteira existe para controlar um tipo diferente de falha.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problema&lt;/th&gt;
&lt;th&gt;Solução usada no projeto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;O modelo erra uma contagem de caracteres&lt;/td&gt;
&lt;td&gt;Validação em Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uma URL parece plausível, mas é falsa&lt;/td&gt;
&lt;td&gt;HTTP e busca de fontes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O agente tenta ler um arquivo indevido&lt;/td&gt;
&lt;td&gt;Caminho limitado ao diretório do projeto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Um segredo passa despercebido&lt;/td&gt;
&lt;td&gt;Heurísticas executadas antes do modelo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O validador não enxerga o resultado anterior&lt;/td&gt;
&lt;td&gt;Interpolação explícita do estado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Um servidor MCP apresenta comportamento difícil de reproduzir&lt;/td&gt;
&lt;td&gt;Servidor local e testes offline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Por isso, o projeto é mais interessante como estudo de fronteiras de controle do que como demonstração de vários agentes conversando entre si.&lt;/p&gt;

&lt;h3&gt;
  
  
  O fluxo em uma imagem
&lt;/h3&gt;

&lt;p&gt;O repositório já inclui dois diagramas do fluxo principal, um para temas claros e outro para temas escuros. Eles mostram a sequência entre o agente Blogger, o planejador, o escritor e os validadores.&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%2Fstr4yrn54yncv9nhrs91.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%2Fstr4yrn54yncv9nhrs91.png" alt="Fluxo do pipeline multiagente" width="800" height="932"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O diagrama ajuda a perceber que o sistema não é uma conversa livre entre agentes. Existe uma sequência definida, existem artefatos compartilhados e existem pontos claros em que o processo pode ser aprovado ou repetido.&lt;/p&gt;

&lt;h2&gt;
  
  
  O pipeline de blog mostra onde o estado realmente importa
&lt;/h2&gt;

&lt;p&gt;O agente &lt;code&gt;blogger&lt;/code&gt; é o exemplo mais completo do repositório. Ele recebe um tema, cria um outline, escreve o artigo e passa o resultado por validadores.&lt;/p&gt;

&lt;p&gt;O fluxo usa dois blocos principais. Um planeja o outline e outro escreve o texto. Cada bloco tem um gerador e um validador. O validador pode responder &lt;code&gt;ok&lt;/code&gt; ou &lt;code&gt;retry&lt;/code&gt;. Quando o resultado está adequado, um callback encerra o loop. Quando existe um problema, o gerador recebe o feedback e tenta novamente.&lt;/p&gt;

&lt;p&gt;Os artefatos intermediários ficam registrados no estado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blog_outline         outline produzido pelo planejador
outline_validation   resultado da validação do outline
blog_post            artigo produzido pelo escritor
post_validation      resultado da validação do artigo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui existe uma diferença importante entre armazenar um valor e torná-lo visível para o modelo.&lt;/p&gt;

&lt;p&gt;Não basta escrever no prompt algo como “verifique o conteúdo de blog_outline”. O valor precisa ser interpolado na instrução. O projeto usa expressões como &lt;code&gt;{blog_outline?}&lt;/code&gt; e &lt;code&gt;{post_validation?}&lt;/code&gt; para isso.&lt;/p&gt;

&lt;p&gt;O ponto de interrogação também é importante. Na primeira execução, a chave ainda pode não existir. A forma opcional evita que o pipeline falhe antes mesmo de produzir o primeiro resultado.&lt;/p&gt;

&lt;p&gt;Esse detalhe parece pequeno, mas é uma das diferenças entre um agente que apenas possui memória de execução e um agente que realmente consegue trabalhar com os artefatos produzidos por outros agentes.&lt;/p&gt;

&lt;p&gt;A validação também não fica restrita a um comentário no final. Ela participa do controle do fluxo. Um resultado aprovado encerra o loop. Um resultado rejeitado gera uma nova tentativa.&lt;/p&gt;

&lt;p&gt;O projeto ainda usa &lt;code&gt;LoopAgent&lt;/code&gt; nessa parte porque, segundo a documentação do próprio repositório, o novo &lt;code&gt;Workflow&lt;/code&gt; não pode ser usado como subagente de um &lt;code&gt;LlmAgent&lt;/code&gt; nesse arranjo específico. A documentação atual do ADK recomenda workflows para novas orquestrações determinísticas quando eles atenderem ao caso de uso. Portanto, este exemplo deve ser entendido como uma solução compatível com a arquitetura atual do projeto, não como uma regra para todo sistema novo.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que deve sair do prompt e virar código
&lt;/h2&gt;

&lt;p&gt;Uma das decisões mais importantes do projeto foi retirar algumas tarefas simples do modelo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metadados para SEO
&lt;/h3&gt;

&lt;p&gt;O agente de SEO produz título, descrição, slug, tags e texto alternativo. Os limites são verificados em Python, incluindo quantidade de caracteres, normalização do slug e número máximo de tags.&lt;/p&gt;

&lt;p&gt;O modelo continua sendo útil para escolher palavras e adaptar o texto. Mas não é razoável depender dele para provar que uma string tem menos de cem caracteres.&lt;/p&gt;

&lt;p&gt;Uma instrução pode pedir “mantenha o título abaixo de cem caracteres”. Uma função pode verificar essa condição com precisão.&lt;/p&gt;

&lt;p&gt;Essa é uma boa regra para qualquer sistema com LLM: deixe o modelo sugerir o valor e deixe o código validar o contrato.&lt;/p&gt;

&lt;h3&gt;
  
  
  Revisão de código
&lt;/h3&gt;

&lt;p&gt;O agente de revisão lê o arquivo real antes de opinar. A ferramenta de leitura aceita apenas arquivos dentro do diretório definido para o projeto. O modelo não recebe liberdade para escolher qualquer caminho do sistema.&lt;/p&gt;

&lt;p&gt;Antes de chamar o modelo, o código também procura padrões associados a chaves de API, strings de conexão com credenciais e blocos &lt;code&gt;except:&lt;/code&gt; genéricos.&lt;/p&gt;

&lt;p&gt;O modelo pode explicar a gravidade do problema e organizar os achados. Ele não deveria ser a única camada responsável por descobrir um segredo escrito literalmente em um arquivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verificação de links
&lt;/h3&gt;

&lt;p&gt;O agente &lt;code&gt;linkcheck&lt;/code&gt; separa duas perguntas diferentes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A URL responde por HTTP?&lt;/li&gt;
&lt;li&gt;Existe uma fonte sobre o assunto que a URL deveria representar?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A primeira verificação encontra domínios inválidos, páginas removidas e erros de rede. A segunda tenta encontrar URLs que parecem convincentes, mas não correspondem ao assunto informado.&lt;/p&gt;

&lt;p&gt;Isso também mostra por que “a citação está correta” não é um teste único. É necessário verificar existência, identidade, assunto e, dependendo do caso, se a fonte realmente sustenta a afirmação.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP é uma fronteira de integração
&lt;/h2&gt;

&lt;p&gt;O exemplo &lt;code&gt;mcp_text_audit&lt;/code&gt; conecta um agente ADK a um servidor MCP local por standard input e standard output.&lt;/p&gt;

&lt;p&gt;O servidor expõe três ferramentas determinísticas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Contar caracteres, palavras, linhas e URLs.&lt;/li&gt;
&lt;li&gt;Encontrar placeholders não preenchidos.&lt;/li&gt;
&lt;li&gt;Identificar padrões que podem indicar segredos gravados no código.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;São tarefas adequadas para uma ferramenta porque um modelo pode responder com muita confiança e ainda assim errar uma contagem ou ignorar um placeholder.&lt;/p&gt;

&lt;p&gt;O projeto também documenta duas armadilhas práticas.&lt;/p&gt;

&lt;p&gt;A primeira é que mensagens de diagnóstico em &lt;code&gt;stdout&lt;/code&gt; podem corromper o fluxo JSON RPC. Logs devem ir para &lt;code&gt;stderr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A segunda é que a criação dos parâmetros de conexão não significa necessariamente que a conexão já foi aberta. Alguns erros só aparecem quando a sessão é iniciada. Por isso, o tratamento de exceções precisa envolver a operação que realmente abre a conexão.&lt;/p&gt;

&lt;p&gt;Esses pontos não são exclusivos do ADK. Um servidor MCP só é confiável quando seu processo, transporte, timeout, schema e tratamento de erros também são observáveis e testados. A especificação oficial pode ser consultada no &lt;a href="https://modelcontextprotocol.io/specification/latest" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uma execução real do agente MCP
&lt;/h3&gt;

&lt;p&gt;Para testar o servidor local, foi enviada a seguinte entrada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audite o texto abaixo usando as ferramentas disponíveis:

Título: Guia de deploy {ENVIRONMENT}
API_KEY=demo_key_123456
URL: https://example.com/documentacao
Este texto possui um placeholder não preenchido e uma credencial de demonstração.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fr5r0l3v5hrdp0oms09v1.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%2Fr5r0l3v5hrdp0oms09v1.png" alt="Trace da execução do agente MCP" width="800" height="851"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O trace registrou a inicialização da sessão MCP, a listagem das ferramentas e três chamadas de ferramenta: &lt;code&gt;achar_placeholders&lt;/code&gt;, &lt;code&gt;achar_segredos&lt;/code&gt; e &lt;code&gt;contar_texto&lt;/code&gt;. A execução completa levou aproximadamente 18,43 segundos na interface observada.&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%2F4lkuthsjiy5k5mva3kk3.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%2F4lkuthsjiy5k5mva3kk3.png" alt="Resultado da auditoria MCP" width="800" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O resultado confirmou o placeholder &lt;code&gt;{ENVIRONMENT}&lt;/code&gt;, contou 180 caracteres, 24 palavras, 4 linhas e uma URL. A ferramenta de segredos retornou &lt;code&gt;limpo: true&lt;/code&gt; para esse texto de demonstração.&lt;/p&gt;

&lt;p&gt;Esse último resultado merece uma observação. O texto continha a string &lt;code&gt;API_KEY=demo_key_123456&lt;/code&gt;, mas a heurística não a classificou como segredo. Isso não significa que o detector esteja errado. A ferramenta pode ter sido desenhada para reconhecer padrões específicos, ou pode considerar valores explícitos de demonstração como não sensíveis. O que a execução comprova é mais limitado: esse formato específico não foi marcado pela regra atual.&lt;/p&gt;

&lt;p&gt;Essa é uma boa ilustração da diferença entre ter uma ferramenta e ter cobertura completa. O MCP retirou do modelo a tarefa de contar e procurar padrões, mas as regras determinísticas ainda precisam ser ampliadas e testadas contra uma coleção de exemplos positivos e negativos.&lt;/p&gt;

&lt;p&gt;O trace também mostra uma segunda chamada ao modelo depois das ferramentas. O servidor executa as operações determinísticas, o agente recebe os resultados e então produz uma resposta legível para o usuário. O fluxo observado é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inicialização MCP → descoberta das ferramentas → chamadas determinísticas → resposta do agente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Triage com classificação e confiança
&lt;/h2&gt;

&lt;p&gt;O próximo experimento foi o agente &lt;code&gt;triage&lt;/code&gt;, responsável por classificar mensagens de suporte e escolher uma fila.&lt;/p&gt;

&lt;p&gt;A entrada usada foi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;O cliente não consegue acessar o painel desde esta manhã.
A autenticação retorna erro 401 mesmo depois da redefinição da senha.
O problema afeta toda a equipe.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F4g675pnwsdeexsw17izs.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%2F4g675pnwsdeexsw17izs.png" alt="Trace da classificação de suporte" width="800" height="856"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O trace mostrou uma latência total aproximada de 8,09 segundos. Também apareceram duas chamadas ao modelo, uma chamada à função &lt;code&gt;classificar_ticket&lt;/code&gt; e uma geração final de resposta.&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%2F9ezwb7m3lrebdlz35qdf.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%2F9ezwb7m3lrebdlz35qdf.png" alt="Resultado da classificação de suporte" width="800" height="855"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O resultado observado foi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route: auto:technical
Department: technical
Confidence: 1.00
Urgency: yes
Frustration: low
Runner-up category: billing
Runner-up confidence: 0.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O chamado foi encaminhado para a área técnica porque descrevia um erro de autenticação 401 que afetava toda a equipe. A urgência foi marcada como verdadeira e a confiança retornada foi 1,00.&lt;/p&gt;

&lt;p&gt;Esse resultado mostra o comportamento do agente nessa execução, mas não prova que a confiança esteja calibrada. Para afirmar calibração seria necessário usar um conjunto de tickets rotulados, comparar as previsões com os resultados reais e medir se uma confiança de 0,80, por exemplo, corresponde aproximadamente a 80% de acertos.&lt;/p&gt;

&lt;p&gt;Também é importante distinguir o que o print comprova sobre o JEV. As imagens mostram o agente, a função de classificação, as chamadas ao modelo e o resultado final. Elas não mostram explicitamente o nome do provedor ou do modelo usado em cada chamada. Para documentar o JEV com precisão, será necessário capturar a configuração ativa ou o log que identifica o modelo.&lt;/p&gt;

&lt;p&gt;Mesmo assim, o experimento já demonstra uma propriedade importante do pipeline: a classificação não é apresentada apenas como uma categoria. Ela inclui departamento, urgência, frustração, confiança e uma alternativa de roteamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Onde o JEV entra na arquitetura
&lt;/h3&gt;

&lt;p&gt;A execução do triage usa o OpenRouter como provider para acessar o JEV. Isso é diferente de usar um modelo Gemini diretamente pelo caminho suportado pelo ADK.&lt;/p&gt;

&lt;p&gt;O OpenRouter funciona aqui como uma camada de acesso ao modelo. O agente continua sendo construído e executado pelo ADK, mas a chamada de inferência passa por um provider externo compatível com a interface utilizada pelo projeto.&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%2F09iq3cd8mbgpmvepp526.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%2F09iq3cd8mbgpmvepp526.png" alt="JEV acessado pelo OpenRouter" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na tela do OpenRouter, o modelo aparece como &lt;code&gt;Jev 1.13&lt;/code&gt;, associado à TypeSafe. A descrição também indica que o modelo retorna decisões estruturadas e foi projetado para roteamento e classificação, em vez de texto livre.&lt;/p&gt;

&lt;p&gt;Essa arquitetura explica uma diferença importante do laboratório. O ADK oferece o runtime do agente, o estado, as ferramentas e a orquestração. O OpenRouter fornece o acesso ao modelo selecionado. O JEV, por sua vez, produz a decisão estruturada usada pelo agente de triage.&lt;/p&gt;

&lt;p&gt;Não devemos descrever isso como suporte nativo do ADK ao JEV. A formulação mais precisa é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O projeto integra o JEV ao ADK por meio do OpenRouter, usando uma camada externa de acesso ao modelo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa distinção também é relevante para avaliação. O &lt;code&gt;eval&lt;/code&gt; do ADK foi projetado para o caminho de modelos Gemini usado diretamente no ambiente ADK. A execução com JEV via OpenRouter pode funcionar no runtime, mas não é automaticamente coberta pelo mesmo mecanismo de avaliação.&lt;/p&gt;

&lt;p&gt;Antes de publicar a captura do OpenRouter, é necessário ocultar o endereço de e-mail visível no canto superior esquerdo. O print também contém informações de uso e custo da conta. Podemos manter apenas o nome do modelo, a associação com a TypeSafe e os detalhes técnicos necessários para explicar a integração.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG começa com uma decisão de indexação
&lt;/h2&gt;

&lt;p&gt;O agente de RAG indexa documentos no ChromaDB e responde com citações. O projeto separa a criação do índice da consulta. Isso evita gerar embeddings novamente a cada pergunta.&lt;/p&gt;

&lt;p&gt;Também existem regras diferentes para Markdown e código. Documentos Markdown são divididos por cabeçalhos. Código é dividido por blocos de linhas que preservam melhor as funções.&lt;/p&gt;

&lt;p&gt;Essa separação revela dois custos diferentes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O custo de criar e atualizar o índice.&lt;/li&gt;
&lt;li&gt;O custo de recuperar contexto para cada pergunta.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O README do projeto relata o uso de &lt;code&gt;gemini-embedding-001&lt;/code&gt; e observa que a cota de embeddings pode ser consumida antes da cota de geração de texto. Essa observação é útil para entender o ambiente utilizado no projeto, mas não deve ser tratada como uma garantia de custo ou desempenho para qualquer aplicação.&lt;/p&gt;

&lt;p&gt;O mesmo cuidado vale para os números registrados sobre modelos locais, latência e qualidade. Eles dependem do hardware, da quantização, do prompt, da versão do modelo e da data da medição.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma execução observada no ADK Web
&lt;/h2&gt;

&lt;p&gt;Depois de executar o agente pela linha de comando, a interface Web do ADK permitiu observar o mesmo fluxo por dentro.&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%2Fp5h39h9bze1dwg83d2b2.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%2Fp5h39h9bze1dwg83d2b2.png" alt="Eventos do pipeline Blogger" width="800" height="844"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A aba de eventos mostra o agente Blogger chamando o planejador e depois o escritor. Também aparecem os artefatos registrados no estado, como &lt;code&gt;blog_outline&lt;/code&gt;, &lt;code&gt;outline_validation&lt;/code&gt;, &lt;code&gt;blog_post&lt;/code&gt; e &lt;code&gt;post_validation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Esse detalhe é mais importante do que o artigo final isoladamente. A interface mostra que o pipeline possui etapas intermediárias observáveis. O resultado não surge de uma única chamada invisível. Ele passa por planejamento, escrita e validação.&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%2Fxlgye7wc1qa2kejrr0x8.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%2Fxlgye7wc1qa2kejrr0x8.png" alt="Traces do pipeline Blogger" width="800" height="853"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A aba de traces decompõe a execução em chamadas de modelo, agentes e validadores. Nesta execução específica, a latência total exibida foi de aproximadamente 54,81 segundos. O planejador aparece com cerca de 14,49 segundos e o escritor com cerca de 20,50 segundos. Os validadores também aparecem como etapas separadas.&lt;/p&gt;

&lt;p&gt;Esses números não são um benchmark. Eles representam uma única execução em um ambiente específico. Ainda assim, são úteis para mostrar como a interface ajuda a localizar onde o tempo foi consumido.&lt;/p&gt;

&lt;p&gt;Durante a mesma análise, a interface apresentou um aviso de performance informando que as instruções do sistema haviam sido modificadas entre turnos. Isso causou um &lt;code&gt;context cache miss&lt;/code&gt; e aumentou a latência.&lt;/p&gt;

&lt;p&gt;Esse aviso não indica uma falha do agente. Ele mostra que o custo de uma execução não depende apenas do modelo. A forma como as instruções são construídas e reutilizadas também pode afetar o desempenho.&lt;/p&gt;

&lt;p&gt;Essa é uma das razões pelas quais traces são importantes em sistemas agentic. Sem eles, uma execução lenta pode parecer apenas um modelo lento. Com eles, é possível investigar chamadas individuais, retries, mudanças de instrução e etapas de validação.&lt;/p&gt;

&lt;h2&gt;
  
  
  O output completo de uma execução
&lt;/h2&gt;

&lt;p&gt;O comando utilizado foi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adk run blogger &lt;span class="s2"&gt;"Escreva um artigo técnico sobre structured concurrency em Python"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O output completo foi o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Log setup complete: /tmp/agents_log/agent.20260929_090719.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log

[ADK] Aviso experimental: FALLBACK_MODEL habilitado.
[ADK] Aviso experimental: InMemoryCredentialService habilitado.
Session ID: [omitido nesta publicação]
[ADK] Aviso experimental: JSON_SCHEMA_FOR_FUNC_DECL habilitado.

[Blogger]: Aqui está o artigo técnico solicitado sobre Concorrência Estruturada em Python.

# Concorrência Estruturada em Python: O Fim do Caos em Código Assíncrono

Se você escreve código assíncrono em Python há algum tempo, provavelmente já se deparou com tarefas que esqueceram de terminar, exceções silenciosas que derrubaram seu serviço ou vazamentos de memória causados por corrotinas que continuaram rodando em background muito depois de sua função principal ter retornado.

O culpado por esses problemas costuma ser a concorrência não estruturada.

## O Problema dos Fire and Forget

Em sistemas assíncronos tradicionais, é muito fácil disparar uma tarefa e esquecê-la:

async def processar_dados():
    asyncio.create_task(tarefa_background())
    return "Sucesso"

O problema aqui é o ciclo de vida. Se a função processar_dados falhar, a tarefa background pode continuar rodando. Se ela levantar uma exceção, essa exceção pode não ser tratada pelo bloco principal.

## O Que é Concorrência Estruturada?

A concorrência estruturada propõe que tarefas assíncronas sigam regras de escopo semelhantes às estruturas tradicionais de controle.

Uma tarefa deve ter início, meio e fim definidos dentro de um escopo. Quando o escopo termina, as tarefas relacionadas devem terminar ou ser canceladas de forma previsível.

## A Evolução: Trio e asyncio.TaskGroup

A ideia foi popularizada pela biblioteca Trio, com o conceito de Nursery. O Python 3.11 introduziu o asyncio.TaskGroup na biblioteca padrão.

Antes:

await asyncio.gather(tarefa_1(), tarefa_2())

Com Python 3.11 ou superior:

async def main():
    async with asyncio.TaskGroup() as tg:
        t1 = tg.create_task(tarefa_1())
        t2 = tg.create_task(tarefa_2())

    print("Todas finalizadas com sucesso.")

## Benefícios principais

1. Gestão de erros mais determinística.
2. Maior previsibilidade sobre o ciclo de vida das tarefas.
3. Melhor rastreabilidade durante a investigação de falhas.

## Limitações e cuidados

O uso de TaskGroup não elimina a necessidade de tratar cancelamentos. As tarefas devem executar a limpeza necessária em blocos finally e respeitar asyncio.CancelledError.

Também é importante revisar afirmações sobre asyncio.gather. Quando uma tarefa falha, gather pode propagar a primeira exceção sem cancelar automaticamente as outras tarefas. Elas podem continuar executando, dependendo do contexto.

## Títulos alternativos

1. Concorrência Estruturada: Como o Python 3.11 tornou seu código assíncrono mais seguro.
2. Por que você deve parar de usar fire and forget em Python.
3. Domando o caos assíncrono com asyncio.TaskGroup.

## Hooks para redes sociais

TaskGroup no Python 3.11 mudou a forma de estruturar tarefas assíncronas. O importante não é apenas iniciar tarefas, mas também controlar seu ciclo de vida.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse output é uma evidência de geração bem sucedida do pipeline. Ele não é, sozinho, uma prova de correção técnica. A saída ainda precisa passar por revisão humana, principalmente em afirmações sobre cancelamento, exceções e diferenças entre &lt;code&gt;asyncio.gather&lt;/code&gt; e &lt;code&gt;asyncio.TaskGroup&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando o laboratório falha
&lt;/h2&gt;

&lt;p&gt;Nem toda execução terminou com um artigo. Em uma tentativa posterior, a interface do ADK Web apresentou um erro HTTP 400 com o código &lt;code&gt;INVALID_ARGUMENT&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please ensure that a function call turn comes immediately after a user turn
or after a function response turn.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fr4q3hkzqhklz79qzgvyw.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%2Fr4q3hkzqhklz79qzgvyw.png" alt="Erro de argumento inválido durante a execução" width="659" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse erro indica que o backend rejeitou a sequência de mensagens usada durante uma chamada de ferramenta. O contrato esperado exige que uma chamada de função apareça imediatamente depois de uma mensagem do usuário ou depois de uma resposta de função.&lt;/p&gt;

&lt;p&gt;Neste ponto, é importante não transformar a mensagem em uma conclusão maior do que a evidência permite. O print comprova que a execução falhou durante o processamento de uma chamada de função. Ele não comprova, sozinho, se a causa foi o modelo, o adaptador, a montagem do histórico, uma repetição do loop ou uma combinação específica de mensagens.&lt;/p&gt;

&lt;p&gt;O próximo passo de investigação é consultar o trace da execução e verificar a sequência exata de mensagens antes da chamada que falhou. Também vale comparar essa execução com a execução bem sucedida, observando:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Qual modelo estava ativo.&lt;/li&gt;
&lt;li&gt;Qual agente estava executando.&lt;/li&gt;
&lt;li&gt;Se havia ocorrido um &lt;code&gt;retry&lt;/code&gt; antes do erro.&lt;/li&gt;
&lt;li&gt;Qual ferramenta foi chamada.&lt;/li&gt;
&lt;li&gt;Se existiam duas mensagens de ferramenta ou duas chamadas consecutivas sem a resposta intermediária esperada.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse incidente também mostra por que uma demo técnica precisa registrar falhas. Um agente pode funcionar em uma execução e falhar na seguinte por causa de uma diferença no histórico, no modelo ou no formato de tool calling. Documentar apenas o resultado final esconderia justamente a parte mais útil do experimento.&lt;/p&gt;

&lt;p&gt;Por enquanto, a conclusão segura é: o pipeline possui uma dependência sensível ao protocolo de chamadas de função, e essa dependência precisa ser observada em cada combinação de ADK, modelo e adaptador.&lt;/p&gt;

&lt;p&gt;O trace dessa tentativa acrescenta uma informação importante. A execução teve latência total de aproximadamente 898,85 milissegundos. O maior bloco aparece associado ao agente Blogger, com cerca de 708,09 milissegundos. Dentro dele, a chamada &lt;code&gt;call_llm&lt;/code&gt; levou aproximadamente 658,22 milissegundos e &lt;code&gt;generate_content&lt;/code&gt; cerca de 640,01 milissegundos.&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%2F5hm8arzem0xq83fuyn5d.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%2F5hm8arzem0xq83fuyn5d.png" alt="Trace da falha na primeira chamada ao modelo" width="554" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O trace não mostra chamadas ao &lt;code&gt;RobustBlogPlanner&lt;/code&gt;, ao &lt;code&gt;RobustBlogWriter&lt;/code&gt; ou aos validadores. Isso sugere que a falha ocorreu antes de o pipeline entrar nas etapas de planejamento e escrita. A evidência disponível aponta para a primeira chamada ao modelo, durante &lt;code&gt;generate_content&lt;/code&gt;, e não para um problema no loop de validação.&lt;/p&gt;

&lt;p&gt;Ainda não é possível concluir apenas com esse trace se o histórico já estava inválido antes da chamada ou se o backend rejeitou o formato enviado naquele momento. Para diferenciar essas hipóteses, seria necessário inspecionar o payload ou os eventos detalhados da chamada e comparar a configuração do modelo com a execução bem sucedida.&lt;/p&gt;

&lt;h3&gt;
  
  
  A mesma execução em uma sessão nova
&lt;/h3&gt;

&lt;p&gt;Para verificar se o erro era reproduzível, a mesma solicitação foi executada em uma sessão nova do ADK Web:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Escreva um artigo técnico sobre structured concurrency em Python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesta segunda tentativa, o fluxo foi concluído. A interface mostrou novamente o planejador, o escritor, os artefatos de estado e o resultado final. O estado terminou com &lt;code&gt;post_validation: "ok"&lt;/code&gt;.&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%2Fau5c91stpi4fvablgvti.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%2Fau5c91stpi4fvablgvti.png" alt="Execução bem sucedida em uma sessão nova" width="800" height="846"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa comparação é mais informativa do que olhar apenas para a mensagem de erro. O mesmo prompt falhou em uma sessão e funcionou em outra. Portanto, não há evidência suficiente para atribuir o problema diretamente ao conteúdo do artigo ou ao código do validador.&lt;/p&gt;

&lt;p&gt;O incidente passa a ser classificado como uma falha intermitente ou dependente do estado da sessão. As hipóteses mais prováveis ainda precisam ser verificadas no trace detalhado:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Histórico de mensagens deixado pela sessão anterior.&lt;/li&gt;
&lt;li&gt;Sequência de chamadas de função construída durante a execução.&lt;/li&gt;
&lt;li&gt;Estado temporário do backend ou do modelo.&lt;/li&gt;
&lt;li&gt;Diferença de contexto entre a sessão reutilizada e a sessão nova.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O resultado também mostra uma prática útil para laboratórios com agentes: quando uma execução falhar, repetir o mesmo caso em uma sessão limpa ajuda a separar um defeito determinístico de uma falha transitória.&lt;/p&gt;

&lt;h3&gt;
  
  
  Um caso com requisitos mais rígidos
&lt;/h3&gt;

&lt;p&gt;A etapa seguinte foi executada com um prompt que exigia uma estrutura explícita: comparação entre &lt;code&gt;asyncio.gather&lt;/code&gt; e &lt;code&gt;asyncio.TaskGroup&lt;/code&gt;, exemplo de código, explicação sobre &lt;code&gt;asyncio.CancelledError&lt;/code&gt;, limitações, exatamente três referências externas e uma conclusão com cinco itens.&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%2Fuqzbkiodf1k4cu1tu4l1.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%2Fuqzbkiodf1k4cu1tu4l1.png" alt="Execução com requisitos estruturados" width="800" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O agente produziu o artigo e terminou com &lt;code&gt;post_validation: "ok"&lt;/code&gt;. A sequência exibida pela interface mostra novamente o planejador, o estado do outline, o escritor e o estado final do artigo.&lt;/p&gt;

&lt;p&gt;Essa execução não provocou um &lt;code&gt;retry&lt;/code&gt;. Isso também é um resultado válido: significa que, nesse caso, o primeiro texto produzido já foi considerado compatível com os requisitos configurados no validador.&lt;/p&gt;

&lt;p&gt;É importante não interpretar esse resultado como prova de que o agente sempre acerta de primeira. Ele mostra apenas que uma execução específica satisfez o contrato. Para medir a consistência, seria necessário repetir o mesmo caso várias vezes e registrar quantas execuções terminam com &lt;code&gt;ok&lt;/code&gt; na primeira tentativa, quantas precisam de &lt;code&gt;retry&lt;/code&gt; e quantas falham.&lt;/p&gt;

&lt;p&gt;O valor da captura está justamente na combinação entre o prompt e o estado final. O leitor consegue ver os requisitos enviados, acompanhar as etapas do pipeline e confirmar que a execução terminou com aprovação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testes offline colocam um limite honesto nas conclusões
&lt;/h2&gt;

&lt;p&gt;O projeto mantém uma suíte offline para testar o máximo possível sem depender de rede ou de uma chave de API. Existem também testes e benchmarks separados que fazem chamadas reais.&lt;/p&gt;

&lt;p&gt;Essa divisão é importante porque uma suíte verde não prova que o sistema completo funciona em qualquer modelo.&lt;/p&gt;

&lt;p&gt;Um teste offline pode provar que um validador devolve &lt;code&gt;retry&lt;/code&gt; para um determinado fixture. Ele não prova que um modelo hospedado fará essa escolha de forma consistente.&lt;/p&gt;

&lt;p&gt;Um servidor falso pode provar que o adaptador envia um payload válido. Ele não prova que um GGUF específico seguirá o template correto para tool calling.&lt;/p&gt;

&lt;p&gt;Um mock pode provar que a regra de roteamento funciona. Ele não calibra um limiar de confiança sem um conjunto de dados rotulado.&lt;/p&gt;

&lt;p&gt;O próprio projeto registra essa diferença. Um modelo pode inventar o resultado de uma ferramenta, e nenhum teste puramente offline consegue detectar esse comportamento.&lt;/p&gt;

&lt;p&gt;Essa é uma boa prática para qualquer sistema de IA: declarar o que o teste prova e também declarar o que ele não prova.&lt;/p&gt;

&lt;h2&gt;
  
  
  A limitação do eval do ADK
&lt;/h2&gt;

&lt;p&gt;Existe uma diferença importante entre fazer um agente funcionar e conseguir avaliá-lo com a ferramenta oficial de avaliação.&lt;/p&gt;

&lt;p&gt;No estado atual deste projeto, o &lt;code&gt;eval&lt;/code&gt; do ADK funciona quando o fluxo usa os modelos Gemini. Quando a execução utiliza OpenRouter ou Gemma servido localmente por llama.cpp, os agentes conseguem funcionar dentro dos requisitos definidos no código, mas não entram no mesmo caminho de avaliação do ADK.&lt;/p&gt;

&lt;p&gt;Isso cria duas camadas diferentes de confiança.&lt;/p&gt;

&lt;p&gt;Na primeira camada, ficam os testes de engenharia. Eles verificam se o agente monta o estado corretamente, se as ferramentas respondem, se o fallback é acionado, se o loop termina e se os contratos de saída são respeitados.&lt;/p&gt;

&lt;p&gt;Na segunda camada, fica a avaliação oficial do ADK. Ela é útil para medir o comportamento do agente com os modelos Gemini, mas não cobre automaticamente as outras combinações de provedor e runtime presentes no projeto.&lt;/p&gt;

&lt;p&gt;O resultado é uma assimetria que pode passar despercebida. O mesmo pipeline pode ser executado com Gemini, OpenRouter e llama.cpp, mas a evidência disponível não é equivalente entre os três ambientes.&lt;/p&gt;

&lt;p&gt;Isso é particularmente relevante para modelos locais. O agente pode produzir o resultado esperado em um teste funcional e ainda apresentar diferenças no formato de tool calling, no uso do contexto, no veredito &lt;code&gt;ok&lt;/code&gt; ou &lt;code&gt;retry&lt;/code&gt; e na tendência de repetir o loop. Sem uma avaliação comparável, essas diferenças ficam mais difíceis de medir de maneira sistemática.&lt;/p&gt;

&lt;p&gt;Neste projeto, portanto, é mais correto dizer que os modelos alternativos foram validados dentro dos contratos e testes disponíveis. Não é correto dizer que eles foram avaliados pelo mesmo mecanismo do ADK usado para Gemini.&lt;/p&gt;

&lt;h2&gt;
  
  
  MLflow só que não: traces e avaliação
&lt;/h2&gt;

&lt;p&gt;Uma opção interessante para essa lacuna seria instrumentar o pipeline com MLflow.&lt;/p&gt;

&lt;p&gt;Essa integração ainda não foi testada e nem sei se isso é possível, então deve ser vista como uma possibilidade de evolução, não como uma capacidade já comprovada do repositório.&lt;/p&gt;

&lt;p&gt;O MLflow possui tracing para aplicações GenAI e agentes. A documentação atual descreve integrações automáticas com Google ADK, além de instrumentação manual com &lt;code&gt;@mlflow.trace&lt;/code&gt; e spans. Os traces podem registrar entradas, saídas e etapas intermediárias, como chamadas de ferramentas, recuperação de documentos e decisões de roteamento. Consulte a documentação de &lt;a href="https://mlflow.org/docs/latest/llms/tracing/" rel="noopener noreferrer"&gt;tracing para agentes&lt;/a&gt; e de &lt;a href="https://mlflow.org/docs/latest/genai/tracing/app-instrumentation/automatic" rel="noopener noreferrer"&gt;instrumentação automática&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Uma integração possível seria registrar cada execução com metadados como:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Campo&lt;/th&gt;
&lt;th&gt;Exemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Provedor&lt;/td&gt;
&lt;td&gt;Gemini, OpenRouter ou llama.cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modelo&lt;/td&gt;
&lt;td&gt;Nome e versão do modelo usado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agente&lt;/td&gt;
&lt;td&gt;Blogger, RAG, SEO ou Code Review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteração&lt;/td&gt;
&lt;td&gt;Primeira tentativa ou retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estado&lt;/td&gt;
&lt;td&gt;Outline, validação ou artigo final&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ferramenta&lt;/td&gt;
&lt;td&gt;HTTP, MCP, filesystem ou busca&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resultado&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ok&lt;/code&gt;, &lt;code&gt;retry&lt;/code&gt;, erro ou timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custo e latência&lt;/td&gt;
&lt;td&gt;Quando o provedor disponibilizar esses dados&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Com esses traces, seria possível comparar os mesmos casos de teste entre provedores sem depender exclusivamente do &lt;code&gt;eval&lt;/code&gt; do ADK.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;mlflow.genai.evaluate()&lt;/code&gt; também permite avaliar traces já coletados usando scorers prontos ou métricas customizadas. A documentação do MLflow cita avaliações de relevância, groundedness, aderência a guidelines e comportamento intermediário do agente. Veja &lt;a href="https://mlflow.org/docs/latest/genai/eval-monitor/running-evaluation/traces/" rel="noopener noreferrer"&gt;avaliação de traces&lt;/a&gt; e a &lt;a href="https://mlflow.org/docs/latest/api_reference/python_api/mlflow.genai.html" rel="noopener noreferrer"&gt;referência de &lt;code&gt;mlflow.genai.evaluate&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para este repositório, os scorers mais interessantes provavelmente não seriam apenas métricas de qualidade textual. Eles poderiam verificar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Se o agente chamou a ferramenta esperada.&lt;/li&gt;
&lt;li&gt;Se o arquivo acessado estava dentro do diretório permitido.&lt;/li&gt;
&lt;li&gt;Se o resultado foi validado antes de ser entregue.&lt;/li&gt;
&lt;li&gt;Se o agente interrompeu o loop depois de &lt;code&gt;ok&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se o RAG citou um trecho realmente recuperado.&lt;/li&gt;
&lt;li&gt;Se um modelo de fallback preservou o mesmo schema de saída.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essa abordagem permitiria separar três tipos de avaliação:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Testes determinísticos para regras de aplicação.&lt;/li&gt;
&lt;li&gt;Avaliação de traces para o comportamento do agente.&lt;/li&gt;
&lt;li&gt;Avaliação específica do modelo para qualidade de texto, tool calling e aderência às instruções.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O MLflow não resolveria automaticamente a diferença entre provedores. Ainda seria necessário definir um dataset comum, normalizar os campos de saída, decidir qual modelo será usado como juiz e separar qualidade do texto de correção do workflow.&lt;/p&gt;

&lt;p&gt;Mas ele poderia oferecer a camada de observabilidade e comparação que falta quando o mesmo agente roda em Gemini, OpenRouter e llama.cpp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallback melhora disponibilidade, mas não garante qualidade
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;common.py&lt;/code&gt; monta uma cadeia com modelo principal, modelo alternativo e, opcionalmente, um servidor local baseado em llama.cpp.&lt;/p&gt;

&lt;p&gt;Esse desenho ajuda quando existe um erro temporário, uma limitação de cota ou a necessidade de executar localmente. Mas trocar de modelo pode alterar várias coisas ao mesmo tempo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O formato das chamadas de ferramentas.&lt;/li&gt;
&lt;li&gt;A disposição para devolver exatamente &lt;code&gt;ok&lt;/code&gt; ou &lt;code&gt;retry&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A forma de lidar com contexto.&lt;/li&gt;
&lt;li&gt;A latência e o custo.&lt;/li&gt;
&lt;li&gt;A qualidade da revisão e não apenas a qualidade do primeiro rascunho.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essa última parte é especialmente importante em um pipeline com loops. Um modelo que critica excessivamente um resultado já aceitável pode consumir outra iteração e mais uma chamada de API.&lt;/p&gt;

&lt;p&gt;Nesse caso, o melhor modelo não é necessariamente aquele que escreve o texto mais bonito. É aquele que respeita o contrato de controle com consistência suficiente para o loop terminar.&lt;/p&gt;

&lt;p&gt;Por isso, modelos de fallback devem ser avaliados com os contratos reais do sistema. Uma pergunta genérica não é suficiente para validar um modelo que precisa produzir tool calls, obedecer schemas e decidir quando encerrar uma revisão.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que temos neste projeto
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Divide o fluxo por responsabilidade.&lt;/li&gt;
&lt;li&gt;Torna os artefatos intermediários explícitos.&lt;/li&gt;
&lt;li&gt;Usa validadores como parte do controle de fluxo.&lt;/li&gt;
&lt;li&gt;Coloca regras exatas em código.&lt;/li&gt;
&lt;li&gt;Limita o acesso a arquivos e ferramentas.&lt;/li&gt;
&lt;li&gt;Separa testes de transporte dos testes de modelo.&lt;/li&gt;
&lt;li&gt;Mantem uma suíte determinística offline.&lt;/li&gt;
&lt;li&gt;Registra limitações e tarefas pendentes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🚨 Isso não prova que oito agentes são melhores do que um. &lt;br&gt;
Também não apresenta um benchmark independente comparando ADK com outros frameworks. Os números de custo, latência, cota e qualidade dependem do ambiente descrito no projeto e podem mudar com versões futuras.&lt;/p&gt;

&lt;p&gt;🚨 Isso não reduz o valor do repositório. Apenas define melhor o que ele representa: um exemplo concreto de como tornar sistemas agentic mais observáveis, testáveis e fáceis de explicar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma lista a considerar para um sistema com ADK
&lt;/h2&gt;

&lt;p&gt;Antes de começar a criar mais um agente, vale responder estas perguntas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Existe uma responsabilidade nova ou apenas mais um prompt para a mesma responsabilidade?&lt;/li&gt;
&lt;li&gt;Qual artefato atravessa a fronteira entre as etapas?&lt;/li&gt;
&lt;li&gt;Como o próximo agente recebe esse artefato?&lt;/li&gt;
&lt;li&gt;Quais regras precisam ser verificadas por código?&lt;/li&gt;
&lt;li&gt;O que o modelo pode acessar e o que deve ficar limitado pela aplicação?&lt;/li&gt;
&lt;li&gt;Quais falhas precisam de duas verificações independentes?&lt;/li&gt;
&lt;li&gt;O comportamento pode ser testado sem modelo ao vivo ou sem rede?&lt;/li&gt;
&lt;li&gt;O modelo de fallback respeita o mesmo schema e o mesmo critério de término?&lt;/li&gt;
&lt;li&gt;Quais afirmações são testadas, quais são apenas observadas e quais ainda são desconhecidas?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os sistemas multiagentes mais maduros não são necessariamente os que têm a hierarquia mais complexa. São os que possuem contratos claros entre as etapas, condições explícitas de término e uma noção honesta do que cada teste realmente comprova.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiagentes não são uma resposta universal
&lt;/h2&gt;

&lt;p&gt;Existe muito entusiasmo em torno de arquiteturas multiagentes e de modelos especializados como o JEV. Esse entusiasmo pode ser útil para descobrir novas possibilidades, mas não deve virar uma decisão automática de arquitetura.&lt;/p&gt;

&lt;p&gt;Dividir uma aplicação em agentes especializados pode facilitar a organização das responsabilidades. Também pode tornar o sistema mais fácil de explicar, testar e evoluir. Ao mesmo tempo, cada divisão cria uma nova fronteira de comunicação, uma nova dependência e um novo ponto onde o fluxo pode falhar.&lt;/p&gt;

&lt;p&gt;Neste projeto, por exemplo, uma execução pode depender de vários componentes diferentes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O runtime do ADK.&lt;/li&gt;
&lt;li&gt;O modelo principal.&lt;/li&gt;
&lt;li&gt;O modelo de fallback.&lt;/li&gt;
&lt;li&gt;O provider usado para acessar um modelo externo.&lt;/li&gt;
&lt;li&gt;O servidor MCP.&lt;/li&gt;
&lt;li&gt;A sequência de chamadas de ferramentas.&lt;/li&gt;
&lt;li&gt;O estado compartilhado entre os agentes.&lt;/li&gt;
&lt;li&gt;Os validadores e suas condições de término.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Adicionar fallback também não garante disponibilidade. O caminho Gemini pode falhar por cota ou indisponibilidade. O OpenRouter pode apresentar erro de rede ou de autenticação. O JEV pode não responder como esperado. O llama.cpp pode estar indisponível, lento ou incompatível com determinado formato de tool calling.&lt;/p&gt;

&lt;p&gt;Um fallback aumenta as opções de recuperação, mas também aumenta a superfície que precisa ser observada e testada. Se os modelos não obedecerem ao mesmo contrato de saída, a troca de provider pode apenas transformar um erro de disponibilidade em um erro de comportamento.&lt;/p&gt;

&lt;p&gt;Por isso, a pergunta mais importante antes de adotar uma arquitetura multiagente não é “qual framework está em alta?”. É:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A divisão em agentes resolve um problema real deste caso de uso ou apenas adiciona complexidade ao sistema?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se uma única chamada bem delimitada resolve o problema, uma arquitetura com vários agentes pode ser uma escolha ruim. Se existem responsabilidades claramente diferentes, ferramentas distintas, ciclos de validação ou limites de contexto que justificam a separação, o desenho multiagente pode fazer sentido.&lt;/p&gt;

&lt;p&gt;A recomendação mais segura é experimentar e validar no próprio contexto. Comece com uma implementação simples. Meça custo, latência, taxa de erro, qualidade e facilidade de manutenção. Depois compare com uma versão multiagente usando os mesmos casos de teste.&lt;/p&gt;

&lt;p&gt;O resultado dessa comparação é mais importante do que a popularidade de uma técnica. Arquitetura deve seguir necessidade real, evidência e comportamento observado.&lt;/p&gt;

&lt;h2&gt;
  
  
  O próprio agente Blogger como guia para este post
&lt;/h2&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%2Feswz9vdz3mae2oorq9re.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%2Feswz9vdz3mae2oorq9re.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este texto também foi estruturado usando o próprio gerador de Blogger apresentado no projeto.&lt;/p&gt;

&lt;p&gt;A ideia não foi pedir que o agente escrevesse um artigo definitivo e publicar o resultado sem revisão. O gerador foi usado como guia para organizar o tema, testar o fluxo de planejamento, observar os artefatos intermediários e entender como o sistema lida com validação, falhas e novas tentativas.&lt;/p&gt;

&lt;p&gt;O processo acabou funcionando como uma demonstração do próprio argumento deste artigo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O agente ajudou a produzir uma primeira estrutura.&lt;/li&gt;
&lt;li&gt;O ADK Web permitiu observar eventos, estado e traces.&lt;/li&gt;
&lt;li&gt;O output foi revisado contra o comportamento real do repositório.&lt;/li&gt;
&lt;li&gt;As execuções bem sucedidas e as falhas foram documentadas.&lt;/li&gt;
&lt;li&gt;Afirmações que não podiam ser comprovadas foram tratadas como limitações ou hipóteses.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse ciclo é mais interessante do que a ideia de geração automática sem supervisão. O modelo acelera a organização e a produção de material, mas a qualidade final depende da combinação entre código, testes, observabilidade e revisão técnica.&lt;/p&gt;

&lt;p&gt;No fim, o objetivo de um sistema multiagente não deveria ser esconder o processo atrás de uma resposta convincente. Deveria ser tornar o processo claro o suficiente para que outra pessoa consiga entender o que aconteceu, reproduzir o experimento e decidir o que ainda precisa ser melhorado.&lt;/p&gt;

&lt;p&gt;É esse o principal aprendizado do projeto: agentes são mais úteis quando fazem parte de um sistema com contratos, ferramentas determinísticas, traces e limites explícitos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;O projeto funcional está no github em &lt;a href="https://github.com/vongrossi/adk-multiagent/" rel="noopener noreferrer"&gt;vongrossi/adk-multiagent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alguns conceitos usados neste artigo, &lt;br&gt;
&lt;a href="https://google.github.io/adk-docs/agents/" rel="noopener noreferrer"&gt;ADK Agents&lt;/a&gt;, &lt;a href="https://google.github.io/adk-docs/workflows/" rel="noopener noreferrer"&gt;ADK Workflows&lt;/a&gt;, o &lt;a href="https://github.com/google/adk-python" rel="noopener noreferrer"&gt;repositório Python do ADK&lt;/a&gt; e a &lt;a href="https://modelcontextprotocol.io/specification/latest" rel="noopener noreferrer"&gt;especificação do MCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para a estratégia de avaliação proposta, consulte a documentação de &lt;a href="https://mlflow.org/docs/latest/llms/tracing/" rel="noopener noreferrer"&gt;MLflow Tracing&lt;/a&gt;, &lt;a href="https://mlflow.org/docs/latest/genai/tracing/app-instrumentation/automatic" rel="noopener noreferrer"&gt;instrumentação automática&lt;/a&gt; e &lt;a href="https://mlflow.org/docs/latest/genai/eval-monitor/running-evaluation/traces/" rel="noopener noreferrer"&gt;avaliação de traces&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>llm</category>
      <category>python</category>
      <category>testing</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero — Sessão 08: O Fim do Começo (Por que agora tudo faz sentido?) 🚀🧠</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 01:42:01 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-08-o-fim-do-comeco-por-que-agora-tudo-faz-sentido-5f7p</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-08-o-fim-do-comeco-por-que-agora-tudo-faz-sentido-5f7p</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero — Sessão 08: O Fim do Começo (Por que agora tudo faz sentido?) 🚀🧠 &lt;br&gt;
Chegando ao fim dessa jornada. Mas, paradoxalmente, este é apenas o começo da sua verdadeira jornada com Inteligência Artificial.&lt;/p&gt;

&lt;p&gt;A Sessão 08 é diferente. Ela não está no sumário do livro de Sebastian Raschka. Ela não vai te ensinar uma nova função do PyTorch nem introduzir uma arquitetura revolucionária. Esta sessão é o que eu chamo de “O Momento Matrix”.&lt;/p&gt;

&lt;p&gt;Sabe aquela cena icônica em que o Neo finalmente para de ver as paredes, os agentes e o cenário, e começa a enxergar apenas o código verde escorrendo em cascata? É exatamente assim que me sinto agora ao olhar para qualquer aplicação de IA moderna.&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.amazonaws.com%2Fuploads%2Farticles%2F5kjx207y6l1spk8a8h3j.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kjx207y6l1spk8a8h3j.gif" alt="Image 9" width="498" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Durante meses, nós construímos cada engrenagem desse sistema. Do momento em que quebramos uma palavra em tokens até o instante em que calculamos o gradiente de erro de uma resposta complexa. Ao fazer isso, algo mudou irreversivelmente. Eu não vejo mais a “mágica”. A caixa preta foi aberta.&lt;/p&gt;

&lt;p&gt;O que eu vejo agora são probabilidades, vetores densos e multiplicações de matrizes.&lt;/p&gt;

&lt;p&gt;E acredite: perder a ilusão da mágica foi a melhor coisa que poderia ter acontecido para a minha carreira de engenheiro de software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 O Fim da “Caixa Preta”: Por que suas aplicações falham?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes dessa jornada, quando o ChatGPT inventava um fato ou quando meu sistema de busca falhava, minha reação era de frustração e confusão. “Por que ele fez isso? Não faz sentido!”. Agora, a confusão deu lugar ao diagnóstico preciso. Entender os fundamentos me deu a capacidade de olhar para o erro e identificar a causa raiz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A Anatomia da Alucinação&lt;/strong&gt;(Vibe Coding e Prompt Engineering)&lt;/p&gt;

&lt;p&gt;Aprendemos na Sessão 05 a verdade dura: um LLM é, em sua essência, uma máquina estatística treinada para prever a próxima palavra. Ele não tem compromisso com a verdade factual; ele tem compromisso com a verossimilhança estatística.&lt;/p&gt;

&lt;p&gt;Quando você está fazendo um “Vibe Coding” e o modelo sugere uma importação de biblioteca que não existe, você não fica mais bravo. Você entende:&lt;/p&gt;

&lt;p&gt;“Ah, estatisticamente, essa importação fazia todo sentido nesse contexto de código, por isso ele ‘alucinou’ esse nome”. O modelo não mentiu; ele apenas seguiu a probabilidade mais alta. Saber disso muda como você escreve seus prompts. Você para de pedir “seja criativo” e começa a impor restrições de contexto, porque você sabe que sem restrições, a estatística corre solta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. O Poder Oculto dos Embeddings (Custo, Performance e RAG)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na Sessão 02, desmistificamos os Embeddings. Vimos que para o computador, “significado” nada mais é do que distância geométrica em um espaço vetorial.&lt;/p&gt;

&lt;p&gt;Isso mudou a forma como projeto sistemas de &lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt;. Hoje, eu sei que a qualidade da resposta do meu agente não depende apenas do LLM caro que estou usando na ponta final (como o GPT-4), mas depende criticamente da qualidade do meu Embedding na busca. Se meus vetores não capturarem a nuance semântica, o LLM nunca receberá a informação correta. Escolher o modelo de embedding errado não é apenas um detalhe técnico; é uma decisão que impacta diretamente o preço e a latência da sua aplicação. Um vetor mal construído torna sua busca “burra” e sua infraestrutura cara.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Agentes Especializados e Instruction Tuning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na Sessão 07, sofremos para alinhar o modelo. Vimos como é difícil fazer a máquina parar de apenas “completar texto” e começar a &lt;strong&gt;“obedecer ordens”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Essa experiência é valiosa quando estamos criando Agentes Autônomos. Se o seu agente sai dos trilhos e começa a agir de forma imprevisível, a culpa provavelmente não é do modelo ser &lt;strong&gt;“burro”&lt;/strong&gt;, mas da falta de exemplos robustos de Instruction Tuning ou Few-Shot Prompting. Você aprendeu na prática que o modelo precisa de exemplos negativos (o que não fazer) tanto quanto de exemplos positivos. A engenharia de prompt deixou de ser &lt;strong&gt;“tentativa e erro”&lt;/strong&gt; e virou*&lt;em&gt;“ajuste de pesos via contexto”&lt;/em&gt;*.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📊 A Verdade nos Números: O que os Gráficos nos Contam&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nossa jornada não foi feita apenas de conceitos abstratos. Nossos notebooks geraram dados reais, e esses dados contam a história do aprendizado da máquina. Vale a pena revisitar três momentos visuais que definiram nossa evolução:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Momento “Eureca” da Classificação (Sessão 06)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lembra quando transformamos o GPT em um classificador de SPAM? Ver o modelo pegar uma frase como “Ganhe dinheiro rápido e fácil!!!” e cravar a categoria SPAM (99%) foi a prova definitiva.&lt;/p&gt;

&lt;p&gt;Não foi mágica. Nós vimos os pesos da Classification Head se ajustarem para reconhecer esse padrão.&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.amazonaws.com%2Fuploads%2Farticles%2F0l7v9vjfbugtfw9n1mnc.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.amazonaws.com%2Fuploads%2Farticles%2F0l7v9vjfbugtfw9n1mnc.png" alt="Image 10" width="700" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A Queda da Loss (Sessão 07)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Não há gráfico mais bonito para um cientista de dados ou engenheiro de ML do que uma curva de Loss descendo.&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.amazonaws.com%2Fuploads%2Farticles%2Fbvb98uzvd07f2n6r8ekh.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.amazonaws.com%2Fuploads%2Farticles%2Fbvb98uzvd07f2n6r8ekh.png" alt="Image 11" width="545" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa linha descendente não é apenas um gráfico; é a representação visual da “inteligência” emergindo. Cada degrau que a linha desce significa que o modelo entendeu um pouco mais sobre a estrutura da linguagem humana. O momento em que a linha se estabiliza é o momento em que a máquina encontrou o padrão ótimo. É poesia matemática.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A Matriz de Confusão: A Hora da Verdade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E, claro, a nossa “prova real”. Nenhuma IA é perfeita, e a Matriz de Confusão nos ensinou a humildade.&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.amazonaws.com%2Fuploads%2Farticles%2Fi4x9vp4r9vastzd3zu22.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.amazonaws.com%2Fuploads%2Farticles%2Fi4x9vp4r9vastzd3zu22.png" alt="Image 12" width="700" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ela nos mostrou exatamente onde o modelo tropeça. Ele confunde ironia com seriedade? Ele deixa passar falsos positivos? Aprender a ler esse gráfico é o que separa quem usa IA de quem avalia e melhora IA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔮 O Futuro: O que podemos fazer agora?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nesta sessão extra, compilamos reflexões sobre os próximos passos. O campo de LLMs está explodindo e mudando a cada semana, mas os fundamentos que aprendemos aqui — Attention, Backpropagation, Embeddings, Tokenization — são a base imutável de tudo isso.&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.amazonaws.com%2Fuploads%2Farticles%2Fiezo0n6pjaczk5zp3ld4.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.amazonaws.com%2Fuploads%2Farticles%2Fiezo0n6pjaczk5zp3ld4.png" alt="Image 13" width="700" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa base sólida, agora podemos nos aventurar em tópicos avançados sem medo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantização:&lt;/strong&gt; Como fazer esse modelo gigante caber na memória de um celular, reduzindo a precisão dos números sem perder a inteligência?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG Avançado:&lt;/strong&gt; Como conectar esse “cérebro” a um banco de dados proprietário da empresa, garantindo que ele só responda com fatos verificados?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agentes Multimodais:&lt;/strong&gt; E se, além de tokens de texto, adicionarmos tokens de imagem? A arquitetura Transformer permite isso!&lt;/p&gt;

&lt;p&gt;A base que construímos nos permite navegar por essas novidades sem nos perdermos em um &lt;strong&gt;hype&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❤️ Gratidão: O Alicerce do Open Source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nenhum conhecimento é construído no vácuo. Se conseguimos criar um LLM do zero usando apenas um navegador e o Google Colab, foi porque gigantes nos permitiram subir em seus ombros.&lt;/p&gt;

&lt;p&gt;Este projeto é, acima de tudo, um reconhecimento ao ecossistema Open Source e à comunidade científica que compartilha conhecimento abertamente.&lt;/p&gt;

&lt;p&gt;Aos mantenedores do &lt;strong&gt;PyTorch&lt;/strong&gt;, que tornaram a matemática complexa acessível através de código elegante.&lt;/p&gt;

&lt;p&gt;Ao time do &lt;strong&gt;Google Colab&lt;/strong&gt;, que democratizou o acesso às GPUs, permitindo que qualquer pessoa com internet treine uma rede neural.&lt;/p&gt;

&lt;p&gt;E, principalmente, ao autor Sebastian Raschka, cujo livro foi o farol que guiou essa jornada, transformando teoria densa em prática acessível.&lt;/p&gt;

&lt;p&gt;Escrevi uma carta aberta de agradecimento ao autor, detalhando como sua didática impactou meu aprendizado e o de todos que acompanharam essa série. Se você também aprendeu algo, recomendo a leitura como forma de celebrar o compartilhamento de conhecimento:&lt;/p&gt;

&lt;p&gt;📄&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero/blob/main/08-extras/carta-ao-autor.md" rel="noopener noreferrer"&gt;Leia a Carta ao Autor aqui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏁 O Código&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O repositório Fazendo um LLM do Zero não é apenas meu; é nosso.&lt;/p&gt;

&lt;p&gt;Todos os notebooks, todos os infográficos traduzidos, todos os experimentos e códigos comentados estão disponíveis e abertos para sempre.&lt;/p&gt;

&lt;p&gt;🔗 GitHub Oficial: &lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sinta-se livre para experimentar e extender, clone o repositório&lt;/p&gt;

&lt;p&gt;Quebre o modelo. Tente treiná-lo com outras fontes de dados. Erre. Conserte. Experimente durante a jornada eu tentei varias abordagens&lt;/p&gt;

&lt;p&gt;Acho que melhor forma de prever o futuro da Inteligência Artificial é construí-lo você mesmo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End of transmission.&lt;/strong&gt; 📡👋&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero — Sessão 07: De Gerador de Texto a Assistente (Instruction Tuning) 💬🤝</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 01:41:38 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-07-de-gerador-de-texto-a-assistente-instruction-tuning-26cg</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-07-de-gerador-de-texto-a-assistente-instruction-tuning-26cg</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero — Sessão 07: De Gerador de Texto a Assistente (Instruction Tuning) 💬🤝 &lt;br&gt;
Chegamos ao último grande marco da nossa jornada.&lt;/p&gt;

&lt;p&gt;Até aqui, construímos um modelo que sabe tudo sobre a estrutura da língua (Sessão 05) e que até aprendeu uma profissão específica (Sessão 06).&lt;/p&gt;

&lt;p&gt;Mas ainda faltava um “tempero” essencial para que ele se parecesse com o ChatGPT que usamos no dia a dia.&lt;/p&gt;

&lt;p&gt;Se você pedisse ao nosso modelo da Sessão 05: “Escreva uma receita de bolo”, ele poderia simplesmente responder: “…e uma lista de ingredientes para o jantar”. Ele não entendeu que você deu uma ordem; ele achou que você estava apenas começando um texto que ele deveria completar.&lt;/p&gt;

&lt;p&gt;Na Sessão 07, resolvemos isso com o Instruction Tuning. Como Sebastian Raschka explora no Capítulo 7 de seu livro, este é o processo de&lt;/p&gt;

&lt;p&gt;Alinhamento: ensinar o modelo a entender a intenção humana e a agir como um assistente útil.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Modelo Base vs. O Assistente&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A diferença entre um modelo treinado em texto bruto e um modelo alinhado é a diferença entre um estudante que leu todos os livros da biblioteca e um profissional que sabe atender um cliente.&lt;/p&gt;

&lt;p&gt;O modelo base é um “completador de frases”. O modelo alinhado é um seguidor de instruções.&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.amazonaws.com%2Fuploads%2Farticles%2Fnu9hhufzpvm99p3qmlgj.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.amazonaws.com%2Fuploads%2Farticles%2Fnu9hhufzpvm99p3qmlgj.png" alt="Image 9" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A Gramática das Ordens: Formato Instrução-Resposta&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que o modelo aprenda a nos obedecer, não podemos simplesmente jogar texto aleatório nele. Precisamos de exemplos estruturados. Como&lt;/p&gt;

&lt;p&gt;Sebastian Raschka detalha, usamos um formato específico que separa a Instrução, o Contexto (Input) e a Resposta Esperada.&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.amazonaws.com%2Fuploads%2Farticles%2F286hvlajejoati50ootu.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.amazonaws.com%2Fuploads%2Farticles%2F286hvlajejoati50ootu.png" alt="Image 10" width="700" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É como dar um roteiro para um ator: “Sempre que alguém te pedir X, você deve responder Y”. Com exemplos suficientes, o modelo entende o padrão de interação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. O Truque do Mestre: Mascaramento da Loss&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui entra um detalhe técnico brilhante que vimos nesta sessão. Durante o treino, nós não queremos que o modelo aprenda a “prever a pergunta”. A pergunta (instrução) já está lá! Nós queremos que ele foque toda a sua energia em aprender a Resposta.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;Para isso, usamos o Mascaramento da Loss.&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.amazonaws.com%2Fuploads%2Farticles%2Fsjmgw7ofyiovao237viv.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.amazonaws.com%2Fuploads%2Farticles%2Fsjmgw7ofyiovao237viv.png" alt="Image 11" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nós ignoramos os erros que o modelo comete enquanto lê a pergunta e só ajustamos os neurônios dele quando ele começa a escrever a resposta. Isso força o modelo a ser um “resolvedor de problemas”, não apenas um papagaio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. O Pipeline de Supervised Fine-Tuning (SFT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O processo de transformar o modelo base em assistente é chamado de SFT. É uma linha de montagem de alta precisão: pegamos os pesos pré-treinados, passamos pelo dataset de instruções e avaliamos a qualidade da conversa.&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.amazonaws.com%2Fuploads%2Farticles%2F838ebap8v5nl500qdwxi.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.amazonaws.com%2Fuploads%2Farticles%2F838ebap8v5nl500qdwxi.png" alt="Image 12" width="700" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Como Medir a Utilidade?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como saber se um assistente é bom? Diferente da classificação (Sessão 06), aqui não existe &lt;strong&gt;“certo ou errado”&lt;/strong&gt; absoluto. Uma receita de bolo pode ser escrita de mil formas diferentes.&lt;/p&gt;

&lt;p&gt;Por isso, a avaliação deixa de ser apenas matemática e passa a ser qualitativa. O modelo é coerente? Ele foi educado? Ele seguiu todas as restrições da instrução?&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.amazonaws.com%2Fuploads%2Farticles%2Ft01bzzshibsn8rlnlrb9.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.amazonaws.com%2Fuploads%2Farticles%2Ft01bzzshibsn8rlnlrb9.png" alt="Image 13" width="700" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏁 O Fim da Jornada (E o Começo da Próxima)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Com a conclusão da Sessão 07, fechamos o ciclo completo de construção de um LLM:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Preparamos o terreno (Sessão 00 e 01).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Transformamos texto em números (Sessão 02).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Criamos o mecanismo de atenção (Sessão 03).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Montamos o corpo do GPT (Sessão 04).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Ensinamos o modelo a falar (Sessão 05).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Damos a ele uma especialidade (Sessão 06).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. E, finalmente, o ensinamos a conversar e seguir instruções (Sessão 07).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O que antes era uma caixa preta mágica agora é um sistema que você construiu, peça por peça, do zero. A inteligência artificial não é mágica; é engenharia, é matemática e, acima de tudo, é a curiosidade de entender como os fios se conectam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Explore o Capítulo Final&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No notebook da Sessão 07, implementamos o treinamento de instruções e vimos o nosso GPTMini deixar de ser um gerador aleatório para se tornar um mini-assistente conversacional.&lt;/p&gt;

&lt;p&gt;👇 Confira o resultado final:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/07-instruction-tuning/notebook.ipynb" rel="noopener noreferrer"&gt;Rodar Sessão 07&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obrigado por acompanhar essa serie de posts. Agora que você sabe como um LLM é feito, o que você vai construir com esse conhecimento? 🛠️🧠&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero #03: Atenção é Tudo o que Você Precisa? 🎯👀</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-03-atencao-e-tudo-o-que-voce-precisa-3lk5</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-03-atencao-e-tudo-o-que-voce-precisa-3lk5</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero #03: Atenção é Tudo o que Você Precisa? 🎯👀 Você já parou para pensar em como é difícil entender uma frase isolada?&lt;/p&gt;

&lt;p&gt;Imagine que eu chego para você e digo:&lt;/p&gt;

&lt;p&gt;“Eu estou indo para o banco.”&lt;/p&gt;

&lt;p&gt;Você pensaria em dinheiro 💰 ou em um parque 🌳?&lt;/p&gt;

&lt;p&gt;Sem o resto da conversa, é impossível saber. A palavra “banco” é ambígua. O que define o significado dela não são as letras &lt;strong&gt;B-A-N-C-O&lt;/strong&gt;, mas sim as palavras que estão ao redor dela.&lt;/p&gt;

&lt;p&gt;Se a frase fosse “Sentei no banco da praça”, a palavra “banco” absorve o significado de “praça”.&lt;/p&gt;

&lt;p&gt;Se fosse “Saquei dinheiro no banco”, ela absorve o significado de “dinheiro”.&lt;/p&gt;

&lt;p&gt;Esse “superpoder” de misturar significados baseados no contexto é algo que nós fazemos naturalmente. Mas, para computadores, isso sempre foi um pesadelo. Até 2017.&lt;/p&gt;

&lt;p&gt;Bem-vindo ao nossa 3a jornada, onde vamos desvendar o Self-Attention (Autoatenção), o mecanismo que transformou papagaios digitais em modelos capazes de manter uma conversa coerente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Problema da Tradução “Robótica”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antigamente, modelos de linguagem liam texto como um cavalo com antolhos: focados apenas na palavra atual ou na anterior.&lt;/p&gt;

&lt;p&gt;O resultado? Traduções literais e frases sem nexo. Veja este exemplo clássico de tradução do Alemão para o Inglês:&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.amazonaws.com%2Fuploads%2Farticles%2Fd1bstjkcfu80hg0hgsx0.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.amazonaws.com%2Fuploads%2Farticles%2Fd1bstjkcfu80hg0hgsx0.png" alt="Image 13" width="700" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contexto importa na tradução&lt;/p&gt;

&lt;p&gt;Para traduzir corretamente, a palavra final da frase depende de uma palavra que apareceu lá no começo. Se o modelo não tiver “memória” ou “visão periférica”, ele erra.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A Intuição: Todo Mundo Olhando para Todo Mundo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A grande sacada do paper “Attention Is All You Need” foi dizer: e se cada palavra pudesse “olhar” para todas as outras palavras da frase e decidir quais são importantes para ela?&lt;/p&gt;

&lt;p&gt;Na frase “O gato que estava no telhado miou”, quando processamos a palavra “miou”, o modelo deve prestar muita atenção em “gato” (quem miou?) e pouca atenção em “telhado” (onde estava).&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.amazonaws.com%2Fuploads%2Farticles%2F2ls9mb4smi618ihq1qvb.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.amazonaws.com%2Fuploads%2Farticles%2F2ls9mb4smi618ihq1qvb.png" alt="Image 14" width="700" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso cria uma teia de conexões semânticas. O modelo aprende quem fez o quê, onde e como, apenas ajustando o foco da atenção.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. O Coquetel de Informações&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Matematicamente, o que acontece é que a palavra “banco” deixa de ser um vetor estático. Ela se torna uma mistura ponderada de todas as palavras da frase.&lt;/p&gt;

&lt;p&gt;Se a palavra “dinheiro” está na frase, ela “doa” um pouco do seu significado para “banco”.&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.amazonaws.com%2Fuploads%2Farticles%2Ftw5mw94oc7368t954lz5.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.amazonaws.com%2Fuploads%2Farticles%2Ftw5mw94oc7368t954lz5.png" alt="Image 15" width="700" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O resultado final (o vetor de contexto) é uma representação muito mais rica. É a diferença entre um dicionário (significado estático) e uma conversa (significado contextual).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. O Mecanismo: Query, Key e Value (A Busca no Spotify)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui a coisa fica técnica (e genial). Como o modelo decide quanto foco dar para cada palavra?&lt;/p&gt;

&lt;p&gt;Ele usa um sistema de busca parecido com o do YouTube ou Spotify.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;Para cada palavra, criamos três vetores:&lt;/p&gt;

&lt;p&gt;1. Query (Q — A Pergunta): O que eu estou procurando?&lt;/p&gt;

&lt;p&gt;2. Key (K — A Etiqueta): O que eu tenho a oferecer?&lt;/p&gt;

&lt;p&gt;3. Value (V — O Conteúdo): Se você gostar de mim, leve esta informação.&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.amazonaws.com%2Fuploads%2Farticles%2Fqubntu6f8rfbt9l7mdw9.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.amazonaws.com%2Fuploads%2Farticles%2Fqubntu6f8rfbt9l7mdw9.png" alt="Image 16" width="700" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A “Atenção” nada mais é do que o casamento (produto escalar) entre a Pergunta (Query) de uma palavra e a Etiqueta (Key) de outra. Se elas combinam, a afinidade é alta, e o modelo absorve muito do Conteúdo (Value).&lt;/p&gt;

&lt;p&gt;Mas esses vetores Q, K e V não são fixos! Eles são aprendidos. O modelo possui matrizes de pesos treináveis que ele ajusta durante o treinamento para aprender como prestar atenção melhor.&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.amazonaws.com%2Fuploads%2Farticles%2F1oh3x1im5z08gzk21saj.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.amazonaws.com%2Fuploads%2Farticles%2F1oh3x1im5z08gzk21saj.png" alt="Image 17" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Regras do Jogo: Sem Spoilers e Sem Decorar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para criar um GPT (que gera texto), temos uma regra de ouro: você não pode ler o futuro.&lt;/p&gt;

&lt;p&gt;Se o modelo pudesse ver a próxima palavra durante o treino, ele apenas copiaria a resposta em vez de aprender a prever.&lt;/p&gt;

&lt;p&gt;Para impedir essa “cola”, aplicamos uma Máscara Causal. Ela zera a atenção para qualquer palavra que venha depois da atual. É como colocar uma cortina no futuro.&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.amazonaws.com%2Fuploads%2Farticles%2Fj8ag70tcms4776f8sycs.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.amazonaws.com%2Fuploads%2Farticles%2Fj8ag70tcms4776f8sycs.png" alt="Image 18" width="700" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, para evitar que o modelo “decore” frases específicas, usamos o Dropout. Desligamos aleatoriamente algumas conexões de atenção durante o treino. Isso força o modelo a ser robusto e aprender caminhos alternativos para entender o contexto.&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.amazonaws.com%2Fuploads%2Farticles%2F9p28mgbvh7y6zgf0s22j.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.amazonaws.com%2Fuploads%2Farticles%2F9p28mgbvh7y6zgf0s22j.png" alt="Image 19" width="700" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Multi-Head Attention: Vários Pontos de Vista&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Linguagem é complexa. Uma frase pode ter uma estrutura gramatical difícil E um tom emocional sutil. É difícil focar nas duas coisas ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;A solução? Multi-Head Attention (Atenção com Múltiplas Cabeças).&lt;/p&gt;

&lt;p&gt;Em vez de fazer esse processo uma vez, fazemos 4, 8 ou 12 vezes em paralelo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Head 1 (Cabeça 1) foca na gramática&lt;/strong&gt; (quem é o sujeito?).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Head 2 (Cabeça 2) foca na relação temporal&lt;/strong&gt; (aconteceu antes ou depois?).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Head 3 (Cabeça 3) foca no vocabulário específico.&lt;/strong&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fhaloegs900l4v8ymo1cm.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.amazonaws.com%2Fuploads%2Farticles%2Fhaloegs900l4v8ymo1cm.png" alt="Image 20" width="700" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No final, juntamos tudo e temos uma compreensão super-humana do texto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Onde isso tudo se encaixa?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Atenção é o coração, mas precisa de um corpo. Ela é o primeiro grande bloco dentro da arquitetura do Transformer que estamos construindo.&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.amazonaws.com%2Fuploads%2Farticles%2Fvttsmxbwscwjgbakhll8.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.amazonaws.com%2Fuploads%2Farticles%2Fvttsmxbwscwjgbakhll8.png" alt="Image 21" width="700" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois de entender o contexto com a Atenção, a informação flui para as redes neurais (Feed Forward) que processam esse significado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Mão na Massa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A teoria é linda, mas implementar o Self-Attention do zero, multiplicando matrizes na mão, é onde você realmente entende a mágica. E é exatamente isso que fazemos no notebook deste capítulo. Nada de import attention. Nós criamos a classe MultiHeadAttention linha por linha.&lt;/p&gt;

&lt;p&gt;Quer ver como transformar essa teoria em código Python puro?&lt;/p&gt;

&lt;p&gt;👇 Acesse agora:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/03-atencao/notebook.ipynb" rel="noopener noreferrer"&gt;Rodar no colab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Código no GitHub: Ver repositório:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No proximo post, vamos pegar esses blocos de atenção e finalmente construir o corpo do GPT. Prepare-se, porque o monstro vai ganhar vida.&lt;/p&gt;

&lt;p&gt;🧟‍♂️🤖&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero #01: A Mágica é Apenas Estatística (Bem Feita) 🎩📊</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-01-a-magica-e-apenas-estatistica-bem-feita-7k</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-01-a-magica-e-apenas-estatistica-bem-feita-7k</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero #01: A Mágica é Apenas Estatística (Bem Feita) 🎩📊 &lt;/p&gt;

&lt;p&gt;Você se lembra da primeira vez que usou o ChatGPT?&lt;/p&gt;

&lt;p&gt;Para mim, houve um momento de estranhamento. Eu digitava uma pergunta complexa, e a resposta surgia na tela, palavra por palavra, como se houvesse um humano do outro lado digitando em tempo real. Parecia haver raciocínio, intenção, talvez até… consciência?&lt;/p&gt;

&lt;p&gt;É fácil se deixar levar pela ilusão da “Inteligência”.&lt;/p&gt;

&lt;p&gt;Mas, como engenheiros (ou aspirantes a), nosso trabalho não é admirar a mágica. É descobrir onde está o alçapão, os espelhos e os fios invisíveis.&lt;/p&gt;

&lt;p&gt;Nessa parte da nossa série Fazendo um LLM do Zero, nós puxamos a cortina. E a verdade é, ao mesmo tempo, decepcionante para os sonhadores e fascinante para os construtores:&lt;/p&gt;

&lt;p&gt;O modelo não sabe o que está dizendo. Ele está apenas chutando a próxima palavra.&lt;/p&gt;

&lt;p&gt;Bem-vindo ao mundo da Previsão do Próximo Token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔮 A Bola de Cristal Probabilística&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para entender um Large Language Model (LLM), você precisa esquecer a ideia de “cérebro digital” por um minuto e olhar para o seu celular.&lt;/p&gt;

&lt;p&gt;Abra o WhatsApp. Digite “Bom”.&lt;/p&gt;

&lt;p&gt;O seu teclado provavelmente vai sugerir “dia”, “trabalho” ou “fim”.&lt;/p&gt;

&lt;p&gt;O seu teclado entende o conceito de saudação matinal? Não.&lt;/p&gt;

&lt;p&gt;Ele sabe que você está feliz ou cansado? Não.&lt;/p&gt;

&lt;p&gt;Ele apenas calculou uma probabilidade condicional: “Dado que o usuário digitou ‘Bom’, existe 80% de chance da próxima palavra ser ‘dia’”.&lt;/p&gt;

&lt;p&gt;Um LLM, no fundo, é um autocompletar que tomou esteroides. 💊&lt;/p&gt;

&lt;p&gt;A diferença é a escala. Enquanto o teclado do seu celular olha para as últimas 2 ou 3 palavras, um modelo como o GPT-4 olha para milhares de palavras de contexto (livros, artigos, código, conversas) para calcular qual é o próximo pedacinho de texto (token) que faz mais sentido estatístico.&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.amazonaws.com%2Fuploads%2Farticles%2Fm17y87v6radw83dgu7sc.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.amazonaws.com%2Fuploads%2Farticles%2Fm17y87v6radw83dgu7sc.png" alt="Image 7" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O fluxo simples de Texto -&amp;gt; Modelo -&amp;gt; Probabilidade&lt;/p&gt;

&lt;p&gt;Quando o modelo escreve um poema ou um código em Python, ele não planejou o resultado final. Ele está navegando no escuro, acendendo uma luz (token) de cada vez, baseando-se apenas no caminho que já percorreu.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏗️ A Revolução Transformer: Paramos de Ler como Humanos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se a ideia é apenas “prever a próxima palavra”, por que não tínhamos IAs assim nos anos 90?&lt;/p&gt;

&lt;p&gt;O problema era a memória.&lt;/p&gt;

&lt;p&gt;Antigamente, as Redes Neurais Recorrentes (RNNs) liam texto como nós, humanos cansados: uma palavra de cada vez, da esquerda para a direita.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;“O”… (ok, guardei)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“gato”… (ok, é um animal)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“subiu”… (ação)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“telhado”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando a frase era longa, a rede já tinha “esquecido” o começo. Ela perdia o contexto.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;A grande virada de chave — e o motivo pelo qual estamos vivendo esse hype hoje — foi a introdução da arquitetura Transformer (apresentada pelo&lt;/p&gt;

&lt;p&gt;Google no paper “Attention Is All You Need” em 2017).&lt;/p&gt;

&lt;p&gt;O Transformer não lê como a gente. Ele olha para a frase inteira de uma vez só. Ele processa tudo em paralelo. É como se, em vez de ler um livro página por página, ele tirasse uma foto de todas as páginas ao mesmo tempo e entendesse as conexões entre o capítulo 1 e o capítulo 10 instantaneamente.&lt;/p&gt;

&lt;p&gt;Isso permitiu treinar modelos com quantidades absurdas de dados. E, com dados suficientes, a estatística começou a parecer inteligência.&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.amazonaws.com%2Fuploads%2Farticles%2F8vu0wlops99fxiua7bms.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.amazonaws.com%2Fuploads%2Farticles%2F8vu0wlops99fxiua7bms.png" alt="Image 8" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 O GPT é um “Decoder-Only”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Existem muitos tipos de Transformers, mas nós vamos focar na arquitetura GPT (Generative Pre-trained Transformer).&lt;/p&gt;

&lt;p&gt;O GPT é o que chamamos de modelo Decoder-Only.&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.amazonaws.com%2Fuploads%2Farticles%2F2cjnsq8gooip0uxb8svq.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.amazonaws.com%2Fuploads%2Farticles%2F2cjnsq8gooip0uxb8svq.png" alt="Image 9" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine um tradutor.&lt;/p&gt;

&lt;p&gt;1. Ele ouve a frase em inglês (Encoder).&lt;/p&gt;

&lt;p&gt;2. Ele gera a frase em português (Decoder).&lt;/p&gt;

&lt;p&gt;O GPT ignorou a primeira parte. Ele é especialista apenas na segunda: gerar. Ele é treinado para olhar para o passado e alucinar o futuro, token por token. É por isso que ele é tão bom em criar histórias e conversar, mas às vezes falha em tarefas que exigem “ver o todo” antes de responder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Mão na Massa: O Que Fizemos no Código?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chega de teoria. No notebook desta sessão, não usamos bibliotecas prontas de “caixa preta” como langchain ou openai. Nós descemos para o nível do PyTorch.&lt;/p&gt;

&lt;p&gt;Neste Passo 01, você vai encontrar:&lt;/p&gt;

&lt;p&gt;1. A intuição visual: Gráficos que explicam como o texto entra e sai do modelo.&lt;/p&gt;

&lt;p&gt;2. O conceito de Contexto: Como o tamanho da “janela” que o modelo enxerga define o quão “inteligente” ele parece.&lt;/p&gt;

&lt;p&gt;3. A estrutura do projeto: Como organizar pastas e arquivos para não se perder quando o código crescer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Por que isso importa?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quando você entende que o LLM é uma máquina de probabilidade e não um ser consciente, você se torna um usuário (e desenvolvedor) muito melhor.&lt;/p&gt;

&lt;p&gt;Você para de tentar “convencer” o chat e começa a “engenheirar” o prompt. Você entende por que ele alucina (afinal, ele só quer completar o padrão, mesmo que precise inventar um fato).&lt;/p&gt;

&lt;p&gt;A mágica desaparece, mas dá lugar a algo muito mais poderoso: o controle.&lt;/p&gt;

&lt;p&gt;Pronto para ver como transformar texto em números e começar a calcular essas probabilidades? Esse é o tema da próxima sessão.&lt;/p&gt;

&lt;p&gt;👇 Acesse o material completo e execute o código agora:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/01-o-que-e-um-llm/notebook.ipynb" rel="noopener noreferrer"&gt;Clique aqui para rodar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório no GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos adiante, onde vamos aprender a matemática necessaria para o nosso modelo. Até lá! 👋&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero — Sessão 04: A Arquitetura da Mente (Construindo o Corpo do GPT) 🏗️🤖</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-04-a-arquitetura-da-mente-construindo-o-corpo-do-gpt-5725</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-04-a-arquitetura-da-mente-construindo-o-corpo-do-gpt-5725</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero — Sessão 04: A Arquitetura da Mente (Construindo o Corpo do GPT) 🏗️🤖 Até agora, nossa jornada foi sobre coletar os materiais básicos.&lt;/p&gt;

&lt;p&gt;Aprendemos a transformar palavras em números.&lt;/p&gt;

&lt;p&gt;Entendemos como a &lt;strong&gt;&lt;em&gt;Atenção&lt;/em&gt;&lt;/strong&gt; permite que esses números se conectem.&lt;/p&gt;

&lt;p&gt;Mas ter tijolos e cimento não é o mesmo que ter uma casa. Você precisa de uma planta, de engenharia e de estrutura.&lt;/p&gt;

&lt;p&gt;Na Sessão 04, deixamos de olhar para as peças isoladas e começamos a construir o edifício. É aqui que o GPT deixa de ser uma ideia matemática e se torna um modelo funcional. Como Sebastian Raschka detalha no Capítulo 4 de seu livro Build a Large Language Model (From Scratch), o segredo da inteligência desses modelos não está em uma única peça mágica, mas na forma como empilhamos blocos simples de forma repetitiva e organizada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Bloco Fundamental: O Módulo Transformer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Um GPT não é uma &lt;strong&gt;massa&lt;/strong&gt; única de código. Ele é modular. Imagine que estamos construindo um arranha-céu onde cada andar é idêntico. Se você souber construir um andar perfeitamente, você pode construir cem.&lt;/p&gt;

&lt;p&gt;No mundo dos LLMs, esse &lt;strong&gt;andar&lt;/strong&gt; é o Bloco Transformer.&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.amazonaws.com%2Fuploads%2Farticles%2Fnwscl4p902rzxoagnhub.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.amazonaws.com%2Fuploads%2Farticles%2Fnwscl4p902rzxoagnhub.png" alt="Image 9" width="700" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada um bloco desses contém os órgãos vitais do modelo: a Atenção (para olhar o contexto) e a Rede Feedforward (para processar o que viu).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A Esteira de Produção (O Fluxo de Dados)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quando um token entra no modelo, ele não é processado de qualquer jeito. Existe uma ordem rigorosa. Como Sebastian Raschka descreve, a informação passa por uma espécie de &lt;strong&gt;esteira de produção&lt;/strong&gt; dentro de cada bloco.&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.amazonaws.com%2Fuploads%2Farticles%2Ffansuwqzu0n91jxmv4y5.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.amazonaws.com%2Fuploads%2Farticles%2Ffansuwqzu0n91jxmv4y5.png" alt="Image 10" width="700" height="831"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A informação entra, é refinada pela atenção, estabilizada por normalizações, processada pela rede neural e entregue para o próximo bloco. Esse fluxo garante que o modelo não &lt;strong&gt;&lt;em&gt;se perca&lt;/em&gt;&lt;/strong&gt; no meio do caminho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A Refinaria de Conhecimento (Feedforward Network)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se a Atenção é o “olhar” do modelo, a rede Feedforward é o &lt;strong&gt;pensar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enquanto a Atenção decide quais palavras são importantes entre si, a rede Feedforward processa cada palavra individualmente para extrair significados mais profundos.&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.amazonaws.com%2Fuploads%2Farticles%2Fk6se3ib5dks4ndt0w8jd.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.amazonaws.com%2Fuploads%2Farticles%2Fk6se3ib5dks4ndt0w8jd.png" alt="Image 11" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É como se a Atenção trouxesse as matérias-primas e a Feedforward fosse a refinaria que transforma aquilo em conhecimento útil.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Redes de Segurança: Residuais e Normalização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui entra um problema real de engenharia: quando empilhamos muitos blocos (como os 12 blocos do GPT-2 ou os 96 do GPT-3), a matemática pode começar a &lt;strong&gt;&lt;em&gt;quebrar&lt;/em&gt;&lt;/strong&gt;. Os números podem ficar grandes demais ou pequenos demais, e o modelo para de aprender.&lt;/p&gt;

&lt;p&gt;Para resolver isso, usamos dois truques essenciais que Sebastian Raschka explora em seu livro:&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Conexões Residuai&lt;/strong&gt;s: Atalhos que permitem que a informação original &lt;strong&gt;&lt;em&gt;pule&lt;/em&gt;&lt;/strong&gt; camadas, garantindo que nada importante seja esquecido.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Layer Normalization&lt;/strong&gt;: Uma técnica que mantém os números em uma escala saudável, como um regulador de voltagem que impede um curto-circuito.&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.amazonaws.com%2Fuploads%2Farticles%2Fhtt95pgq1hp8q84duqwl.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.amazonaws.com%2Fuploads%2Farticles%2Fhtt95pgq1hp8q84duqwl.png" alt="Image 12" width="700" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. O Pipeline Completo: Nasce um GPT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Juntando tudo — os embeddings que vimos na Sessão 02, a Atenção da Sessão 03 e os blocos que montamos agora — temos finalmente o pipeline completo de um modelo GPT.&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.amazonaws.com%2Fuploads%2Farticles%2Fwyag1zql2twwalxeuq05.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.amazonaws.com%2Fuploads%2Farticles%2Fwyag1zql2twwalxeuq05.png" alt="Image 13" width="700" height="831"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O modelo recebe tokens, adiciona a noção de posição, passa por vários blocos de processamento e, no final, entrega uma lista de probabilidades:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Qual é a próxima palavra mais provável?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Do Papel para o Código&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nesta Sessão 04, nosso trabalho no notebook foi de &lt;strong&gt;&lt;em&gt;Arquiteto de Sistemas&lt;/em&gt;&lt;/strong&gt;. Nós implementamos:&lt;/p&gt;

&lt;p&gt;A classe TransformerBlock unindo Atenção e Feedforward.&lt;/p&gt;

&lt;p&gt;A lógica de LayerNorm e conexões residuais.&lt;/p&gt;

&lt;p&gt;O modelo GPTMini, que é o nosso &lt;strong&gt;&lt;em&gt;cérebro&lt;/em&gt;&lt;/strong&gt; completo pronto para ser treinado.&lt;/p&gt;

&lt;p&gt;É um momento marcante: pela primeira vez, temos um modelo que, embora ainda não saiba falar (ele ainda não foi treinado!), já tem toda a estrutura física para aprender qualquer linguagem do mundo.&lt;/p&gt;

&lt;p&gt;Quer ver como essas peças se encaixam no PyTorch?&lt;/p&gt;

&lt;p&gt;👇 Acesse o laboratório prático:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/04-gpt-do-zero/notebook.ipynb" rel="noopener noreferrer"&gt;Rodar Sessão 04&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora o corpo está pronto. Na próxima sessão, vamos dar um &lt;strong&gt;&lt;em&gt;sopro de vida&lt;/em&gt;&lt;/strong&gt;: O Pré-treinamento. ⚡📖&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero — Sessão 05: Ensinando o Modelo a Falar (A Escola da Probabilidade) 🎓🗣️</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-05-ensinando-o-modelo-a-falar-a-escola-da-probabilidade-1b68</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-05-ensinando-o-modelo-a-falar-a-escola-da-probabilidade-1b68</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero — Sessão 05: Ensinando o Modelo a Falar (A Escola da Probabilidade) 🎓🗣️ &lt;br&gt;
Imagine que você acabou de construir um robô perfeito. Ele tem corpo, cérebro eletrônico e cordas vocais sintéticas. Mas quando você o liga, ele diz: “Asdfjkl çlxzkcvb”.&lt;/p&gt;

&lt;p&gt;Frustrante? Não, esperado.&lt;/p&gt;

&lt;p&gt;Na Sessão 04, nós construímos o corpo do GPT. Ele tem todas as conexões neurais necessárias, mas não tem conhecimento. Ele é como um recém-nascido: tem potencial infinito, mas ainda não viu o mundo.&lt;/p&gt;

&lt;p&gt;Na Sessão 05, entramos na fase mais mágica e demorada de todas: o Pré-Treinamento. É hora de mandar nosso modelo para a escola. E, como Sebastian Raschka explica no Capítulo 5 de seu livro, essa escola não usa gramática ou dicionários. Ela usa estatística pura.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Loop Infinito: Tentar, Errar, Ajustar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como se ensina uma máquina que não pensa?&lt;/p&gt;

&lt;p&gt;Simples: você a força a adivinhar milhões de vezes e corrige cada erro.&lt;/p&gt;

&lt;p&gt;O ciclo de vida de um LLM no treinamento é uma rotina repetitiva e exaustiva, parecida com um estudante fazendo simulados sem parar:&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.amazonaws.com%2Fuploads%2Farticles%2Fouoin8v41xkucd31sswd.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.amazonaws.com%2Fuploads%2Farticles%2Fouoin8v41xkucd31sswd.png" alt="Image 9" width="700" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1. O modelo recebe: “Era uma vez um…”&lt;/p&gt;

&lt;p&gt;2. Ele chuta: “..microondas.” ❌&lt;/p&gt;

&lt;p&gt;3. Nós dizemos: “Errado! Era ‘dragão’.”&lt;/p&gt;

&lt;p&gt;4. O algoritmo (Backpropagation) ajusta os neurônios do modelo para que, da próxima vez, a probabilidade de “dragão” seja um pouquinho maior e a de “microondas” seja menor.&lt;/p&gt;

&lt;p&gt;Multiplique isso por bilhões de frases e o modelo deixa de chutar “microondas” em contos de fadas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A Régua do Erro: Cross Entropy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mas como medimos o “tamanho” do erro?&lt;/p&gt;

&lt;p&gt;Se o modelo chutar “cachorro” em vez de “gato”, o erro é pequeno (são animais parecidos). Se ele chutar “avião”, o erro é enorme.&lt;/p&gt;

&lt;p&gt;Para medir essa distância matemática, usamos a Cross Entropy (Entropia Cruzada).&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.amazonaws.com%2Fuploads%2Farticles%2Fcjbxlq2k3k2qfsox17yg.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.amazonaws.com%2Fuploads%2Farticles%2Fcjbxlq2k3k2qfsox17yg.png" alt="Image 10" width="700" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ela é a professora rigorosa que dá uma nota para cada tentativa do modelo. O objetivo do treino é simples: fazer essa nota de erro (Loss) cair até chegar perto de zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. O Ritmo da Escola: Batches e Epochs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;Não dá para o modelo ler a internet inteira de uma vez. Ele engasgaria.&lt;/p&gt;

&lt;p&gt;Por isso, dividimos o estudo em pequenos pedaços chamados Batches (lotes). E quando ele termina de ver todos os dados uma vez, dizemos que completou uma Epoch (época).&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.amazonaws.com%2Fuploads%2Farticles%2Fyts9xpsgzemda4kgakwe.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.amazonaws.com%2Fuploads%2Farticles%2Fyts9xpsgzemda4kgakwe.png" alt="Image 11" width="700" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É um processo industrial. Entra texto, sai erro, ajusta pesos. Repete. Repete. Repete. Até que a mágica da inteligência comece a emergir dos números.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. O Dilema da Criatividade: Como o Modelo Escolhe?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Depois de treinado, o modelo não dá uma resposta. Ele dá probabilidades para todas as palavras do mundo.&lt;/p&gt;

&lt;p&gt;Quem escolhe a palavra final? Nós, através da Estratégia de Decodificação (Decoding Strategy).&lt;/p&gt;

&lt;p&gt;Isso define a &lt;strong&gt;&lt;em&gt;personalidade&lt;/em&gt;&lt;/strong&gt; do modelo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Greedy&lt;/strong&gt; (Ganancioso): Sempre escolhe a palavra mais provável. O modelo fica chato, repetitivo e robótico. 🤖&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temperature / Top-k&lt;/strong&gt;: Nós adicionamos um pouco de caos controlado. O modelo arrisca palavras menos óbvias e se torna criativo. 🎨&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.amazonaws.com%2Fuploads%2Farticles%2Fm75ah5ly0alhemni7j3p.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.amazonaws.com%2Fuploads%2Farticles%2Fm75ah5ly0alhemni7j3p.png" alt="Image 12" width="700" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Salvando o Cérebro: Checkpoints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Treinar um LLM é caro e demorado. Se a luz acabar no meio do processo, você perde dias de trabalho.&lt;/p&gt;

&lt;p&gt;Por isso, aprendemos a importância vital dos Checkpoints: salvar uma “cópia de segurança” do cérebro do modelo a cada etapa importante.&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.amazonaws.com%2Fuploads%2Farticles%2F0ripi88pz6m84j59bp4n.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.amazonaws.com%2Fuploads%2Farticles%2F0ripi88pz6m84j59bp4n.png" alt="Image 13" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Mão na Massa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na Sessão 05, o nosso notebook deixa de ser estático. Nós implementamos o loop de treinamento real. Vemos a barra de progresso avançar e a curva de erro cair (o gráfico mais satisfatório para um cientista de dados!).&lt;/p&gt;

&lt;p&gt;Nós pegamos o nosso GPTMini, alimentamos ele com texto e vimos ele aprender a formar suas primeiras frases coerentes.&lt;/p&gt;

&lt;p&gt;Quer ver o momento exato em que a máquina aprende a escrever?&lt;/p&gt;

&lt;p&gt;👇 Acesse o laboratório:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/05-pre-treinamento/notebook.ipynb" rel="noopener noreferrer"&gt;Treinar Modelo na Sessão 05&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora nosso modelo sabe falar. Mas ele sabe o que fazer? Na próxima sessão, vamos ensinar uma profissão para ele com o Fine-Tuning. 🎯👨‍⚕️&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero #02: Como Transformar Palavras em Números (Sem Perder a Alma) 🔢✨</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-02-como-transformar-palavras-em-numeros-sem-perder-a-alma-1mm3</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-02-como-transformar-palavras-em-numeros-sem-perder-a-alma-1mm3</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero #02: Como Transformar Palavras em Números (Sem Perder a Alma) 🔢✨ &lt;/p&gt;

&lt;p&gt;Se você abrir o cérebro de um computador, não vai encontrar letras, palavras ou poesias. Você vai encontrar eletricidade. Zeros e uns.&lt;/p&gt;

&lt;p&gt;Isso cria um problema fundamental para quem quer criar Inteligência Artificial: como ensinar uma máquina a ler, se a linguagem nativa dela é matemática pura?&lt;/p&gt;

&lt;p&gt;A abordagem ingênua seria criar uma tabela gigante: “Abacate” = 1, “Bola” = 2, “Casa” = 3.&lt;/p&gt;

&lt;p&gt;Funciona? Sim. O computador consegue ler.&lt;/p&gt;

&lt;p&gt;Mas ele perde o significado. Para ele, “Abacate” e “Bola” são apenas números vizinhos, sem nenhuma relação real.&lt;/p&gt;

&lt;p&gt;Nesta sessão, resolvemos esse problema. Descobrimos a alquimia que transforma texto em vetores ricos de significado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Abismo entre Texto e Máquina&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tudo o que é “dado bruto” no mundo real (texto, áudio, vídeo) precisa ser convertido para uma representação numérica densa antes de entrar em uma rede neural.&lt;/p&gt;

&lt;p&gt;Não queremos apenas números soltos. Queremos Embeddings.&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.amazonaws.com%2Fuploads%2Farticles%2Fi028vjhm5a27u9pnig7c.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.amazonaws.com%2Fuploads%2Farticles%2Fi028vjhm5a27u9pnig7c.png" alt="Image 11" width="700" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um Embedding não é apenas um número. É uma lista de números (um vetor) que funciona como uma coordenada de GPS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. O GPS das Palavras (Espaço Vetorial)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine um mapa gigante.&lt;/p&gt;

&lt;p&gt;Nesse mapa, a palavra “Rei” mora em uma coordenada. A palavra “Rainha” mora bem pertinho dela.&lt;/p&gt;

&lt;p&gt;Já a palavra “Maçã” mora do outro lado do mapa, longe da realeza, mas vizinha de “Banana”.&lt;/p&gt;

&lt;p&gt;Isso é o Espaço Vetorial.&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.amazonaws.com%2Fuploads%2Farticles%2Fqtzt1jbpwwd2hisgcqh7.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.amazonaws.com%2Fuploads%2Farticles%2Fqtzt1jbpwwd2hisgcqh7.png" alt="Image 12" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando treinamos um LLM, ele aprende a organizar esse mapa sozinho. Ele descobre que “cachorro” e “gato” compartilham muitas características, então ele os coloca próximos geometricamente. É assim que a matemática captura a semântica.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Quebrando o Texto: Tokenização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mas espere… o modelo lê palavras inteiras?&lt;/p&gt;

&lt;p&gt;Na verdade, &lt;strong&gt;não&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se o modelo tivesse que decorar todas as palavras do dicionário (mais gírias, nomes, erros de digitação), o vocabulário seria infinito.&lt;/p&gt;

&lt;p&gt;Para resolver isso, usamos a Tokenização. Nós quebramos o texto em pedacinhos chamados Tokens.&lt;/p&gt;

&lt;p&gt;1. Lemos o texto.&lt;/p&gt;

&lt;p&gt;2. Identificamos os pedaços únicos.&lt;/p&gt;

&lt;p&gt;3. Criamos um vocabulário numérico.&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.amazonaws.com%2Fuploads%2Farticles%2Fvppc35o98f2jlyysr4i6.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.amazonaws.com%2Fuploads%2Farticles%2Fvppc35o98f2jlyysr4i6.png" alt="Image 13" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. O Tradutor Universal (Encode e Decode)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;Uma vez que temos o vocabulário, criamos uma ponte de duas vias.&lt;/p&gt;

&lt;p&gt;O Encode transforma a frase “Olá Mundo” em [245, 981].&lt;/p&gt;

&lt;p&gt;O Decode pega [245, 981] e devolve “Olá Mundo”.&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.amazonaws.com%2Fuploads%2Farticles%2F3772nhlq0edpf1g8mn56.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.amazonaws.com%2Fuploads%2Farticles%2F3772nhlq0edpf1g8mn56.png" alt="Image 14" width="700" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É essa interface que permite que nós (humanos) e o modelo (máquina) conversemos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. O Lego das Palavras (BPE — Byte Pair Encoding)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E se aparecer uma palavra que o modelo nunca viu? Tipo “Supercalifragilisticexpialidocious”?&lt;/p&gt;

&lt;p&gt;Se usássemos palavras inteiras, o modelo travaria (o temido erro “Out of Vocabulary”).&lt;/p&gt;

&lt;p&gt;A solução moderna é genial: Subwords (Sub-palavras).&lt;/p&gt;

&lt;p&gt;Se o modelo não conhece a palavra inteira, ele a quebra em pedaços que ele conhece.&lt;/p&gt;

&lt;p&gt;“Infelizmente” vira: In + feliz + mente.&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.amazonaws.com%2Fuploads%2Farticles%2Foloxnt8stobmj22x6nz1.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.amazonaws.com%2Fuploads%2Farticles%2Foloxnt8stobmj22x6nz1.png" alt="Image 15" width="700" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa técnica (chamada BPE), o modelo consegue ler e escrever qualquer palavra em qualquer língua, usando apenas um conjunto limitado de peças de Lego.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Ensinando com Flashcards (Janela Deslizante)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como preparamos esses dados para o treino?&lt;/p&gt;

&lt;p&gt;Um LLM aprende a prever o futuro olhando para o passado.&lt;/p&gt;

&lt;p&gt;Nós pegamos um texto e criamos &lt;strong&gt;janelas deslizantes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrada:&lt;/strong&gt; “O gato” -&amp;gt; Alvo: “subiu”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrada:&lt;/strong&gt; “O gato subiu” -&amp;gt; Alvo: “no”&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.amazonaws.com%2Fuploads%2Farticles%2F7usitp8tq97zbvm8tyy7.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.amazonaws.com%2Fuploads%2Farticles%2F7usitp8tq97zbvm8tyy7.png" alt="Image 16" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É assim que criamos milhões de exemplos de treinamento a partir de um único livro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. O Pipeline Completo: Da Letra ao Cérebro&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Juntando tudo, temos o pipeline de entrada do nosso GPT.&lt;/p&gt;

&lt;p&gt;É uma linha de montagem de dados:&lt;/p&gt;

&lt;p&gt;Texto Bruto ➡️ Tokenização ➡️ IDs ➡️ Embeddings de Palavra + Embeddings de Posição ➡️ Entrada no Modelo.&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.amazonaws.com%2Fuploads%2Farticles%2Fq6npi5ambj03urvwxcf0.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.amazonaws.com%2Fuploads%2Farticles%2Fq6npi5ambj03urvwxcf0.png" alt="Image 17" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Mão na Massa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neste capítulo, não ficamos só na teoria. No notebook, nós implementamos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um Tokenizador do zero.&lt;/strong&gt;&lt;strong&gt;O algoritmo BPE&lt;/strong&gt; (sim, escrevemos a lógica de merge de tokens!).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A camada de Embeddings no PyTorch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quer ver como transformar Shakespeare em tensores matemáticos?&lt;/p&gt;

&lt;p&gt;👇 O código está pronto para rodar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/02-texto-vira-numero/notebook.ipynb" rel="noopener noreferrer"&gt;Acessar o notebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que transformamos texto em números, estamos prontos para a parte mais “humana” da IA. No próximo post: Atenção. 👀&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero — Sessão 06: Dando uma Profissão ao Modelo (Fine-Tuning) 🎯👨‍⚕️</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-06-dando-uma-profissao-ao-modelo-fine-tuning-19kc</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-sessao-06-dando-uma-profissao-ao-modelo-fine-tuning-19kc</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero — Sessão 06: Dando uma Profissão ao Modelo (Fine-Tuning) 🎯👨‍⚕️ &lt;br&gt;
Até a sessão anterior, nosso GPT era como um adolescente que leu a biblioteca inteira: ele conhece todas as palavras, sabe construir frases bonitas e entende a estrutura da língua. Mas se você perguntar a ele: “Este e-mail é um spam ou uma promoção?”, ele pode simplesmente começar a escrever um poema sobre e-mails.&lt;/p&gt;

&lt;p&gt;Ele tem conhecimento, mas não tem foco.&lt;/p&gt;

&lt;p&gt;Na Sessão 06, aprendemos a transformar esse “estudante geral” em um “profissional especializado”. Como Sebastian Raschka detalha no Capítulo 6 de seu livro, esse processo se chama Fine-Tuning (Ajuste Fino). É aqui que a IA deixa de ser apenas um brinquedo curioso e se torna uma ferramenta útil para resolver problemas reais.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Da Educação Básica à Especialização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Podemos comparar a vida de um LLM com a carreira de um médico.&lt;/p&gt;

&lt;p&gt;O Pré-treinamento (que vimos na Sessão 05) é a escola e a faculdade de medicina: o modelo aprende tudo sobre o corpo humano e a biologia de forma geral.&lt;/p&gt;

&lt;p&gt;O Fine-tuning é a residência médica: o modelo escolhe uma especialidade (como Cardiologia ou Dermatologia) e foca intensamente nela.&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.amazonaws.com%2Fuploads%2Farticles%2Ftnjbmh9v551nxmhgjzdv.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.amazonaws.com%2Fuploads%2Farticles%2Ftnjbmh9v551nxmhgjzdv.png" alt="Image 9" width="700" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em vez de aprender a prever qualquer palavra, o modelo agora é treinado para uma tarefa específica, como Classificação de Texto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Colocando um&lt;/strong&gt;🎩 &lt;strong&gt;“Chapéu de Decisão”&lt;/strong&gt;🧢&lt;strong&gt;(Classification Head)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Um GPT original foi desenhado para gerar texto. Para transformá-lo em um classificador (alguém que diz “&lt;strong&gt;Sim/Não&lt;/strong&gt;”, “&lt;strong&gt;Positivo/Negativo&lt;/strong&gt;”), precisamos fazer uma pequena cirurgia no seu cérebro.&lt;/p&gt;

&lt;p&gt;Nós removemos a camada que gera palavras e colocamos uma Cabeça de Classificação.&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.amazonaws.com%2Fuploads%2Farticles%2Fvfh6ecv4grwl37fzzmb6.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.amazonaws.com%2Fuploads%2Farticles%2Fvfh6ecv4grwl37fzzmb6.png" alt="Image 10" width="700" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa nova camada olha para toda a compreensão de texto que o modelo já tem e toma uma decisão final: “Baseado em tudo o que li nesta frase, a chance de ser Spam é 98%”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Inteligência Eficiente: Congelar ou não Congelar?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Treinar um modelo inteiro de novo seria um desperdício de tempo e dinheiro. Afinal, o modelo já sabe o que é um verbo ou um substantivo. Por que ensinar isso de novo?&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;Sebastian Raschka nos mostra que podemos ser inteligentes: Congelamos (Freeze) a maior parte do modelo e treinamos apenas a camada final. Ou, se tivermos mais dados, podemos Descongelar (Unfreeze) as últimas camadas para um ajuste mais fino.&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.amazonaws.com%2Fuploads%2Farticles%2F4yz41pvfstepq6vbjmpm.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.amazonaws.com%2Fuploads%2Farticles%2F4yz41pvfstepq6vbjmpm.png" alt="Image 11" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É como se você contratasse um mestre de obras experiente: você não precisa ensiná-lo a usar um martelo, apenas mostra onde quer que a nova parede seja construída.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. A Nova Linha de Montagem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O treinamento agora muda de cara. Não usamos mais apenas “texto puro”. Usamos Dados Rotulados (&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;em&gt;“Eu amei este filme” -&amp;gt;&lt;/em&gt;&lt;strong&gt;Rótulo&lt;/strong&gt;&lt;em&gt;:&lt;/em&gt;&lt;strong&gt;Positivo&lt;/strong&gt;).&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.amazonaws.com%2Fuploads%2Farticles%2Fguebheu4jx126yqvgg07.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.amazonaws.com%2Fuploads%2Farticles%2Fguebheu4jx126yqvgg07.png" alt="Image 12" width="700" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O modelo processa o texto, passa pela cabeça de classificação e nós comparamos a resposta dele com o rótulo real. O erro agora não é mais “&lt;em&gt;qual era a próxima palavra&lt;/em&gt;”, mas sim “&lt;em&gt;você acertou a categoria?&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. O Diagnóstico Final: A Matriz de Confusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como saber se o nosso especialista é realmente bom? Apenas “&lt;strong&gt;&lt;em&gt;acurácia&lt;/em&gt;&lt;/strong&gt;” pode enganar.&lt;/p&gt;

&lt;p&gt;Se 90% dos seus e-mails não são spam, e o modelo disser “não é spam” para tudo, ele terá 90% de acerto, mas será um modelo inútil para detectar spams reais.&lt;/p&gt;

&lt;p&gt;Para isso, usamos a Matriz de Confusão. Ela nos mostra onde o modelo está “confuso”: ele está deixando passar muito spam (Falso Negativo) ou está bloqueando e-mails importantes (Falso Positivo)?&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.amazonaws.com%2Fuploads%2Farticles%2Fi4x9vp4r9vastzd3zu22.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.amazonaws.com%2Fuploads%2Farticles%2Fi4x9vp4r9vastzd3zu22.png" alt="Image 13" width="700" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Mão na Massa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na Sessão 06, o nosso laboratório prático foi sobre transformar o GPTMini em um detector de sentimentos. Nós pegamos os pesos que treinamos na&lt;/p&gt;

&lt;p&gt;Sessão 05, adicionamos a camada de classificação e vimos o modelo aprender a distinguir opiniões.&lt;/p&gt;

&lt;p&gt;É a prova de que o conhecimento geral é a base para qualquer especialidade.&lt;/p&gt;

&lt;p&gt;Quer transformar seu modelo em um especialista?&lt;/p&gt;

&lt;p&gt;👇 Acesse os materiais desta sessão:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📓 Notebook no Google Colab:&lt;/strong&gt;&lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/06-fine-tuning/notebook.ipynb" rel="noopener noreferrer"&gt;Rodar Fine-Tuning na Sessão 06&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Repositório GitHub:&lt;/strong&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;vongrossi/fazendo-um-llm-do-zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora o modelo tem um emprego. Mas ele sabe conversar conosco e seguir ordens complexas? Esse é o desafio final da Sessão 07: Instruction Tuning.&lt;/p&gt;

&lt;p&gt;Nos vemos lá! 💬🤝&lt;/p&gt;

</description>
      <category>llm</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>Fazendo um LLM do Zero #00: Antes da Inteligência, a Oficina 🛠️🧠</title>
      <dc:creator>Von Grossi</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/vongrossi/fazendo-um-llm-do-zero-00-antes-da-inteligencia-a-oficina-4n6f</link>
      <guid>https://dev.to/vongrossi/fazendo-um-llm-do-zero-00-antes-da-inteligencia-a-oficina-4n6f</guid>
      <description>&lt;p&gt;Fazendo um LLM do Zero #00: Antes da Inteligência, a Oficina 🛠️🧠 “Como isso realmente funciona por dentro?”&lt;/p&gt;

&lt;p&gt;Essa foi a pergunta que me tirou do lugar de apenas usuário de Inteligência Artificial para o de estudante de seus fundamentos. Estamos vivendo a era dos modelos de linguagem gigantes, mas muitas vezes os usamos como caixas pretas mágicas.&lt;/p&gt;

&lt;p&gt;Decidi mudar isso. Baseado no excelente livro Build a Large Language Model (From Scratch), de Sebastian Raschka, iniciei uma jornada para construir um GPT do zero. Mas antes de falarmos de neurônios artificiais ou atenção, precisamos alinhar o terreno.&lt;/p&gt;

&lt;p&gt;Bem-vindo ao Passo Zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☁️ 1. O Laboratório na Nuvem: Google Colab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A primeira grande barreira para quem estuda IA costuma ser o hardware. “Preciso de uma GPU de milhares de dólares?”. A resposta curta é: Não.&lt;/p&gt;

&lt;p&gt;Para esta série, escolhi o Google Colab como nossa oficina principal. Ele remove toda a fricção técnica de configuração de ambiente.&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.amazonaws.com%2Fuploads%2Farticles%2F7qnxh9r5itnrgqyisr8d.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.amazonaws.com%2Fuploads%2Farticles%2F7qnxh9r5itnrgqyisr8d.png" alt="Image 7" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acelerando o aprendizado sem barreiras de instalação local (Na minha maquina Funciona).&lt;/p&gt;

&lt;p&gt;O Colab nos dá acesso a hardware potente (GPU/TPU) direto no navegador. Isso democratiza o estudo: o que importa agora é a sua lógica, não o seu computador. Os quatro pilares que sustentam nossa jornada no Colab são:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero Instalação:&lt;/strong&gt; O ambiente já vem pronto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nuvem:&lt;/strong&gt; Acesso de qualquer lugar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interatividade:&lt;/strong&gt; Rodamos o código bloco a bloco, testando cada ideia na hora.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Análise:&lt;/strong&gt; Gráficos e métricas integrados para entender o aprendizado do modelo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔥 2. PyTorch: A Nossa Oficina Matemática&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se o LLM é um cérebro, o PyTorch é o sistema biológico que o sustenta. Ele é a biblioteca de Deep Learning que escolhi para construir cada camada do nosso modelo.&lt;/p&gt;

&lt;p&gt;Muitas vezes, a matemática da IA parece assustadora, mas o PyTorch a transforma em algo palpável.&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.amazonaws.com%2Fuploads%2Farticles%2F1qcqeaseefyfsib74os0.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.amazonaws.com%2Fuploads%2Farticles%2F1qcqeaseefyfsib74os0.png" alt="Image 8" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O ecossistema que transforma matrizes em inteligência&lt;/p&gt;

&lt;p&gt;O que realmente &lt;strong&gt;ligou&lt;/strong&gt; para mim ao estudar o PyTorch foi entender sua hierarquia:&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Tensores&lt;/strong&gt;: São a fundação. Arrays multidimensionais que carregam nossos dados.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Autograd&lt;/strong&gt;: O motor que calcula o erro e ajusta os pesos do modelo automaticamente.&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;nn.Module&lt;/strong&gt;: As peças de LEGO (camadas lineares, funções de ativação) que vamos empilhar para criar o GPT.&lt;/p&gt;

&lt;p&gt;Join Medium for free to get updates from this writer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📦 3. O Ecossistema de Ferramentas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ninguém constrói um LLM sozinho. Em Python, temos uma “caixa de ferramentas” modular que nos permite focar no que realmente importa: o conceito&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.amazonaws.com%2Fuploads%2Farticles%2F857sehe9tcd5sf0nw0ff.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.amazonaws.com%2Fuploads%2Farticles%2F857sehe9tcd5sf0nw0ff.png" alt="Image 9" width="700" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Estamos prontos!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O objetivo deste Passo Zero foi garantir que você tenha tudo o que precisa para começar sem dores de cabeça com instalação ou hardware.&lt;/p&gt;

&lt;p&gt;Construir uma IA não é mágica; é engenharia, é tentativa e erro, e é, acima de tudo, curiosidade. Com o ambiente configurado e as bibliotecas prontas, estamos prontos para a primeira pergunta real da série: O que é um LLM de verdade?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Um pouco de experimento!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O ambiente deste capítulo já está disponível para você testar. Acesse o notebook prático no Google Colab, valide seu ambiente e rode seu primeiro tensor:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://colab.research.google.com/github/vongrossi/fazendo-um-llm-do-zero/blob/main/00-passo-zero/notebook.ipynb" rel="noopener noreferrer"&gt;Abrir Passo Zero no Google Colab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta série é um projeto Open Source e você pode acompanhar cada atualização, sugerir melhorias ou clonar o código no repositório oficial:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vongrossi/fazendo-um-llm-do-zero" rel="noopener noreferrer"&gt;🔗 GitHub: Fazendo um LLM do Zero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você já teve problemas tentando configurar ambientes de IA para rodar localmente?&lt;/p&gt;

&lt;p&gt;Conte sua experiência!&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Livro:&lt;/strong&gt; Build a Large Language Model (From Scratch) de Sebastian Raschka.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Material Inspirado no repositório:&lt;/strong&gt; rasbt/LLMs-from-scratch &lt;a href="https://github.com/rasbt/LLMs-from-scratch" rel="noopener noreferrer"&gt;https://github.com/rasbt/LLMs-from-scratch&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>llms</category>
      <category>python</category>
      <category>genai</category>
      <category>gpt</category>
    </item>
  </channel>
</rss>
