<?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: OChimenes Rocha</title>
    <description>The latest articles on DEV Community by OChimenes Rocha (@ochimenes_rocha_f78f5dbb0).</description>
    <link>https://dev.to/ochimenes_rocha_f78f5dbb0</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%2F3999574%2F987dd45f-61d3-461f-9bbd-57b20433dd07.png</url>
      <title>DEV Community: OChimenes Rocha</title>
      <link>https://dev.to/ochimenes_rocha_f78f5dbb0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ochimenes_rocha_f78f5dbb0"/>
    <language>en</language>
    <item>
      <title>Java Moderno com IA: LangChain4j, Quarkus, RAG e MCP na Prática Enterprise</title>
      <dc:creator>OChimenes Rocha</dc:creator>
      <pubDate>Wed, 24 Jun 2026 01:02:41 +0000</pubDate>
      <link>https://dev.to/ochimenes_rocha_f78f5dbb0/java-moderno-com-ia-langchain4j-quarkus-rag-e-mcp-na-pratica-enterprise-52po</link>
      <guid>https://dev.to/ochimenes_rocha_f78f5dbb0/java-moderno-com-ia-langchain4j-quarkus-rag-e-mcp-na-pratica-enterprise-52po</guid>
      <description>&lt;p&gt;O ecossistema Java está formalizando IA em produção. Este artigo apresenta os blocos concretos de construção para quem quer sair do protótipo e chegar ao contrato estável.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contexto: o sinal que o ecossistema está dando
&lt;/h2&gt;

&lt;p&gt;Antes de entrar no código, vale nomear o momento. Na sua newsletter de junho de 2026, o professor Elder Moraes — referência no ecossistema Java e criador do Método Java AI Specialist — sintetizou com precisão o que está acontecendo na plataforma:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"O ecossistema Java está colocando estrutura formal em volta do que já roda em produção: padrão de interop, governança de contribuição, default de framework."&lt;/p&gt;

&lt;p&gt;— Elder Moraes, Newsletter Java Weekly, jun. 2026 (eldermoraes.ai)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A leitura do professor Moraes é precisa e serve como bússola para este artigo. O A2A Java SDK atingiu GA (1.0.0.Final), o Quarkus 3.37 ativou serialização Jackson livre de reflexão por padrão, e o próprio OpenJDK teve que legislar sobre código gerado por IA — um sinal de que a adoção já acontece em escala. O trabalho do desenvolvedor agora não é mais avaliar &lt;em&gt;se&lt;/em&gt; usar IA em Java, mas saber &lt;em&gt;como&lt;/em&gt; construir em cima do que já é contrato estável.&lt;/p&gt;

&lt;p&gt;Este artigo trata exatamente disso: os três pilares concretos que você pode colocar em produção hoje — LangChain4j como camada de orquestração de LLM, RAG (Retrieval-Augmented Generation) como estratégia de contexto, e MCP (Model Context Protocol) como borda de tool e dados.&lt;/p&gt;




&lt;h2&gt;
  
  
  LangChain4j: o SDK que já conhece o seu stack
&lt;/h2&gt;

&lt;p&gt;LangChain4j é a port Java do ecossistema LangChain, mas construída com idioma Java de verdade: anotações declarativas, integração nativa com Spring Boot e Quarkus, e suporte a múltiplos provedores de LLM (OpenAI, Anthropic, Ollama, Azure OpenAI, Bedrock, entre outros) trocáveis via configuração, sem alterar a lógica de negócio.&lt;/p&gt;

&lt;p&gt;O conceito central é o &lt;strong&gt;AI Service&lt;/strong&gt;: uma interface Java anotada que o framework implementa em tempo de build (ou runtime), abstraindo o ciclo completo de prompt, chamada ao modelo e parse da resposta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Declaração da interface — tudo que o dev precisa escrever&lt;/span&gt;
&lt;span class="nd"&gt;@RegisterAiService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingStoreRetriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DocumentAssistant&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@SystemMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Você é um assistente especialista em regulatório financeiro."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@UserMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Com base nos documentos disponíveis, responda: {{question}}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@V&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"question"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com Quarkus, a extensão &lt;code&gt;quarkus-langchain4j&lt;/code&gt; injeta o serviço via CDI, resolve o provider de LLM pelo &lt;code&gt;application.properties&lt;/code&gt;, e aplica os ganhos de native image automaticamente — incluindo o flip de Jackson reflection-free que o Quarkus 3.37 ativou por padrão, reduzindo cold start e consumo de heap sem nenhuma mudança no código da aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração mínima com Quarkus + Ollama local
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# application.properties
&lt;/span&gt;&lt;span class="py"&gt;quarkus.langchain4j.ollama.base-url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434&lt;/span&gt;
&lt;span class="py"&gt;quarkus.langchain4j.ollama.chat-model.model-id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;llama3&lt;/span&gt;
&lt;span class="py"&gt;quarkus.langchain4j.ollama.embedding-model.model-id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;nomic-embed-text&lt;/span&gt;
&lt;span class="py"&gt;quarkus.langchain4j.ollama.timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;60s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para produção, troca-se o bloco &lt;code&gt;ollama&lt;/code&gt; por &lt;code&gt;openai&lt;/code&gt; ou &lt;code&gt;anthropic&lt;/code&gt; sem tocar em nenhuma linha Java. Esse isolamento é o primeiro contrato estável que o arquiteto precisa firmar: a lógica de negócio nunca deve conhecer o provedor de LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  RAG: contexto sem alucinação
&lt;/h2&gt;

&lt;p&gt;Modelos de linguagem sabem muito, mas não sabem nada sobre os seus dados. RAG — Retrieval Augmented Generation — é o padrão que resolve isso: em vez de treinar ou fazer fine-tuning (caro e lento), você recupera os fragmentos mais relevantes dos seus próprios dados no momento da pergunta e os injeta no contexto do prompt.&lt;/p&gt;

&lt;p&gt;O pipeline tem três etapas fixas: ingestão (parse e chunking dos documentos), indexação (geração de embeddings e armazenamento em vector store) e recuperação (busca por similaridade no momento da query). LangChain4j cobre todas as três com APIs unificadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipeline de ingestão
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DocumentIngestionService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingModel&lt;/span&gt; &lt;span class="n"&gt;embeddingModel&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@Inject&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextSegment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;embeddingStore&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ingest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Carrega o documento (PDF, TXT, HTML...)&lt;/span&gt;
        &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FileSystemDocumentLoader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadDocument&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Divide em chunks com overlap para preservar contexto&lt;/span&gt;
        &lt;span class="nc"&gt;DocumentSplitter&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DocumentSplitters&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAiTokenizer&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Gera embeddings e persiste na vector store&lt;/span&gt;
        &lt;span class="nc"&gt;EmbeddingStoreIngestor&lt;/span&gt; &lt;span class="n"&gt;ingestor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingStoreIngestor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;documentSplitter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;embeddingModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddingModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;embeddingStore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddingStore&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;ingestor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recuperação no momento da query
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingStoreRetriever&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ContentRetriever&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingModel&lt;/span&gt; &lt;span class="n"&gt;embeddingModel&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@Inject&lt;/span&gt; &lt;span class="nc"&gt;EmbeddingStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextSegment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;embeddingStore&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Embedding&lt;/span&gt; &lt;span class="n"&gt;queryEmbedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embeddingModel&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;embed&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;EmbeddingMatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextSegment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;embeddingStore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findRelevant&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryEmbedding&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;embedded&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para ambientes enterprise com Oracle ou PostgreSQL (via pgvector), o &lt;code&gt;EmbeddingStore&lt;/code&gt; troca de implementação pela configuração — nenhuma linha de recuperação muda. Em produção com base Oracle, o Oracle AI Vector Search (disponível desde o Oracle 23ai) é uma opção que elimina um componente de infraestrutura extra.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A regra de decisão que eu usaria é separar o que é contrato estável pra construir em cima do que ainda é empolgante-mas-instável."&lt;/p&gt;

&lt;p&gt;— Elder Moraes, Newsletter Java Weekly, jun. 2026 (eldermoraes.ai)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aplicando a regra do professor Moraes ao RAG: o padrão de pipeline (ingestão, embedding, busca por similaridade, augmented prompt) é contrato estável. O que ainda varia é a escolha de vector store e o tamanho ótimo de chunk para o seu domínio. Mexa no segundo, confie no primeiro.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP: a borda de ferramenta que o seu agente precisa
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol (MCP) é o padrão aberto, governado pela Anthropic e adotado pela indústria, para expor ferramentas e fontes de dados a modelos de linguagem de forma interoperável. Se o RAG resolve o problema de &lt;em&gt;conhecimento&lt;/em&gt; (o que o modelo sabe), o MCP resolve o problema de &lt;em&gt;ação&lt;/em&gt; (o que o modelo pode fazer).&lt;/p&gt;

&lt;p&gt;A distinção entre o A2A (Agent2Agent, para comunicação agente-a-agente) e o MCP (para a borda de tool e dados) é fundamental para uma arquitetura limpa. Misturar os dois papéis em um único componente é o caminho mais curto para um sistema impossível de testar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Servidor MCP em Quarkus
&lt;/h3&gt;

&lt;p&gt;A extensão &lt;code&gt;quarkus-mcp-server&lt;/code&gt; permite expor métodos Java como ferramentas MCP usando anotações:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContaCorrenteTools&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt; &lt;span class="nc"&gt;ContaCorrenteRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Tool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Consulta o saldo atual de uma conta corrente pelo número da conta"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;SaldoResponse&lt;/span&gt; &lt;span class="nf"&gt;consultarSaldo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;@P&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Número da conta no formato XXXXXXX-D"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;numeroConta&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findSaldo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroConta&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;SaldoResponse:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ContaNaoEncontradaException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroConta&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Tool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lista os últimos lançamentos de uma conta em um período"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LancamentoResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;listarLancamentos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;@P&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Número da conta"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;numeroConta&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nd"&gt;@P&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Data inicial no formato yyyy-MM-dd"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dataInicio&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nd"&gt;@P&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Data final no formato yyyy-MM-dd"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dataFim&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findLancamentos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroConta&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nc"&gt;LocalDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataInicio&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;LocalDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataFim&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Quarkus registra automaticamente essas ferramentas no endpoint MCP da aplicação. Um agente externo — seja um assistente Claude, seja um orquestrador LangChain4j do próprio sistema — descobre e chama as ferramentas via protocolo padrão sem conhecer a implementação Java.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumindo ferramentas MCP a partir de um AI Service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RegisterAiService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;McpToolProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;AssistenteFinanceiro&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@SystemMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
        Você é um assistente financeiro cooperativista.
        Use as ferramentas disponíveis para consultar dados reais antes de responder.
        Nunca invente números. Se não tiver dados suficientes, diga claramente.
        """&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;conversar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@MemoryId&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sessionId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                     &lt;span class="nd"&gt;@UserMessage&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O ciclo completo fica assim: o usuário envia uma mensagem, o LLM decide quais ferramentas chamar, o Quarkus executa as chamadas MCP contra os seus próprios endpoints Java, os resultados retornam ao LLM como contexto, e a resposta final é gerada com dados reais. Tudo rastreável, tudo testável.&lt;/p&gt;




&lt;h2&gt;
  
  
  Juntando os três: arquitetura de referência
&lt;/h2&gt;

&lt;p&gt;O fluxo completo de uma pergunta do usuário até a resposta com dados reais e contexto documental:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuário
  |
  v
[AssistenteFinanceiro — AI Service]
  |
  |-- (1) Recuperação RAG --&amp;gt; EmbeddingStoreRetriever
  |                               |
  |                           Vector Store
  |                               |
  |                           Fragmentos relevantes &amp;lt;--|
  |
  |-- (2) Tool calls via MCP --&amp;gt; ContaCorrenteTools
  |                               |
  |                           Repository / Oracle DB
  |                               |
  |                           Dados transacionais &amp;lt;--|
  |
  v
[LLM: Prompt = contexto RAG + dados MCP + histórico de sessão]
  |
  v
Resposta fundamentada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada camada tem uma responsabilidade única. O AI Service orquestra. O RAG fornece conhecimento documental. O MCP fornece dados transacionais em tempo real. O LLM sintetiza. Nenhuma camada precisa conhecer as outras diretamente — apenas o contrato de interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  A questão que ninguém está fazendo: governança de código gerado por IA
&lt;/h2&gt;

&lt;p&gt;Há um aspecto que vai além da arquitetura técnica e que o professor Moraes nomeia com precisão na sua newsletter: a oportunidade real não está em adotar o framework mais novo, mas em ser o desenvolvedor que sabe &lt;em&gt;governar&lt;/em&gt; o uso de IA no time.&lt;/p&gt;

&lt;p&gt;A decisão do OpenJDK de barrar contribuições geradas por LLM — mantendo o uso privado para entender, debugar e revisar — e a decisão oposta da GraalVM ilustram que não existe uma resposta única. O que existe é a necessidade de uma política deliberada. Para um time que usa assistentes de IA no dia a dia, as perguntas práticas são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quais artefatos gerados por IA exigem revisão humana obrigatória antes do merge?&lt;/li&gt;
&lt;li&gt;Como o time documenta a origem de um trecho crítico de lógica de negócio?&lt;/li&gt;
&lt;li&gt;O pipeline de CI valida cobertura de testes mesmo quando o código é gerado automaticamente?&lt;/li&gt;
&lt;li&gt;Existe um critério explícito para o que é "plausível mas errado" — o risco que o OpenJDK identificou como custo real de review?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas perguntas têm respostas técnicas (regras de linter, gates no pipeline, cobertura mínima), mas a decisão de fazer as perguntas é liderança de engenharia.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que construir agora e o que esperar
&lt;/h2&gt;

&lt;p&gt;Voltando à divisão que o professor Moraes propõe — contrato estável versus empolgante-mas-instável:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Construa agora:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI Service com LangChain4j declarativo&lt;/li&gt;
&lt;li&gt;Pipeline RAG com vector store já disponível na sua infraestrutura (Oracle ou Postgres)&lt;/li&gt;
&lt;li&gt;Exposição de ferramentas via MCP a partir de beans CDI existentes&lt;/li&gt;
&lt;li&gt;Política interna de governança de código gerado por IA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Acompanhe, não deploya ainda:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A2A SDK (GA, mas o ecossistema de frameworks ao redor ainda está em movimento)&lt;/li&gt;
&lt;li&gt;Project Valhalla value classes (preview no JDK 28, provavelmente ainda em preview no próximo LTS)&lt;/li&gt;
&lt;li&gt;TLS pós-quântico do JDK 27 (meça latência de handshake e compatibilidade com load balancers antes de assumir que vem de graça)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O ecossistema Java tem histórico de levar tempo para padronizar e, quando padroniza, padronizar de forma que dura décadas. O desenvolvedor que entender os contratos estáveis hoje vai construir sobre fundação sólida enquanto o restante ainda debate qual framework adotar.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt; MORAES, Elder. &lt;em&gt;A2A Java SDK 1.0.0.Final: o primeiro GA.&lt;/em&gt; Newsletter Java Weekly, jun. 2026. Disponível em: &lt;a href="https://quarkus.io/blog/a2a-java-sdk-1-0-0-final-released/" rel="noopener noreferrer"&gt;https://quarkus.io/blog/a2a-java-sdk-1-0-0-final-released/&lt;/a&gt; (citado via newsletter eldermoraes.ai).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[2]&lt;/strong&gt; MORAES, Elder. &lt;em&gt;Quarkus 3.37 liga o Jackson reflection-free por padrão.&lt;/em&gt; Newsletter Java Weekly, jun. 2026. Disponível em: &lt;a href="https://github.com/quarkusio/quarkus/releases/tag/3.37.0.CR1" rel="noopener noreferrer"&gt;https://github.com/quarkusio/quarkus/releases/tag/3.37.0.CR1&lt;/a&gt; (citado via newsletter eldermoraes.ai).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[3]&lt;/strong&gt; MORAES, Elder. &lt;em&gt;OpenJDK proíbe contribuição gerada por IA; a GraalVM, da mesma Oracle, permite.&lt;/em&gt; Newsletter Java Weekly, jun. 2026. Disponível em: &lt;a href="https://www.infoq.com/news/2026/06/oracle-genai-policies/" rel="noopener noreferrer"&gt;https://www.infoq.com/news/2026/06/oracle-genai-policies/&lt;/a&gt; (citado via newsletter eldermoraes.ai).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[4]&lt;/strong&gt; MORAES, Elder. &lt;em&gt;Método Java AI Specialist.&lt;/em&gt; Disponível em: &lt;a href="https://eldermoraes.ai" rel="noopener noreferrer"&gt;https://eldermoraes.ai&lt;/a&gt;. Acesso em: jun. 2026.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[5]&lt;/strong&gt; LangChain4j. &lt;em&gt;Documentation.&lt;/em&gt; Disponível em: &lt;a href="https://docs.langchain4j.dev" rel="noopener noreferrer"&gt;https://docs.langchain4j.dev&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[6]&lt;/strong&gt; Quarkus. &lt;em&gt;LangChain4j Extension Guide.&lt;/em&gt; Disponível em: &lt;a href="https://quarkus.io/guides/langchain4j" rel="noopener noreferrer"&gt;https://quarkus.io/guides/langchain4j&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[7]&lt;/strong&gt; Anthropic. &lt;em&gt;Model Context Protocol Specification.&lt;/em&gt; Disponível em: &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>quarkus</category>
      <category>ai</category>
      <category>langchain4j</category>
    </item>
  </channel>
</rss>
