cd /news/large-language-models/java-moderno-com-ia-langchain4j-quar… · home topics large-language-models article
[ARTICLE · art-37066] src=dev.to ↗ pub= topic=large-language-models verified=true sentiment=↑ positive

Java Moderno com IA: LangChain4j, Quarkus, RAG e MCP na Prática Enterprise

The Java ecosystem is formalizing AI in production with stable contracts. LangChain4j provides a Java-native LLM orchestration layer with declarative annotations and seamless integration with Quarkus and Spring Boot. RAG (Retrieval-Augmented Generation) enables context injection from proprietary data without fine-tuning, while MCP (Model Context Protocol) standardizes tool and data boundaries. Quarkus 3.37's default reflection-free Jackson serialization and the A2A Java SDK reaching GA further solidify the production-ready stack.

read8 min views6 publishedJun 24, 2026

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.

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:

"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."

— Elder Moraes, Newsletter Java Weekly, jun. 2026 (eldermoraes.ai)

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 se usar IA em Java, mas saber como construir em cima do que já é contrato estável.

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.

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.

O conceito central é o AI Service: 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.

// Declaração da interface — tudo que o dev precisa escrever
@RegisterAiService(retriever = EmbeddingStoreRetriever.class)
public interface DocumentAssistant {

    @SystemMessage("Você é um assistente especialista em regulatório financeiro.")
    @UserMessage("Com base nos documentos disponíveis, responda: {{question}}")
    String answer(@V("question") String question);
}

Com Quarkus, a extensão quarkus-langchain4j

injeta o serviço via CDI, resolve o provider de LLM pelo application.properties

, 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.

quarkus.langchain4j.ollama.base-url=http://localhost:11434
quarkus.langchain4j.ollama.chat-model.model-id=llama3
quarkus.langchain4j.ollama.embedding-model.model-id=nomic-embed-text
quarkus.langchain4j.ollama.timeout=60s

Para produção, troca-se o bloco ollama

por openai

ou anthropic

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.

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.

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.

@ApplicationScoped
public class DocumentIngestionService {

    @Inject EmbeddingModel embeddingModel;
    @Inject EmbeddingStore<TextSegment> embeddingStore;

    public void ingest(Path filePath) {
        // 1. Carrega o documento (PDF, TXT, HTML...)
        Document document = FileSystemDocument.loadDocument(filePath);

        // 2. Divide em chunks com overlap para preservar contexto
        DocumentSplitter splitter = DocumentSplitters
            .recursive(512, 64, new OpenAiTokenizer());

        // 3. Gera embeddings e persiste na vector store
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
            .documentSplitter(splitter)
            .embeddingModel(embeddingModel)
            .embeddingStore(embeddingStore)
            .build();

        ingestor.ingest(document);
    }
}
@ApplicationScoped
public class EmbeddingStoreRetriever implements ContentRetriever {

    @Inject EmbeddingModel embeddingModel;
    @Inject EmbeddingStore<TextSegment> embeddingStore;

    @Override
    public List<Content> retrieve(Query query) {
        Embedding queryEmbedding = embeddingModel
            .embed(query.text()).content();

        List<EmbeddingMatch<TextSegment>> matches =
            embeddingStore.findRelevant(queryEmbedding, 5, 0.75);

        return matches.stream()
            .map(m -> Content.from(m.embedded()))
            .toList();
    }
}

Para ambientes enterprise com Oracle ou PostgreSQL (via pgvector), o EmbeddingStore

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.

"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."

— Elder Moraes, Newsletter Java Weekly, jun. 2026 (eldermoraes.ai)

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.

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 conhecimento (o que o modelo sabe), o MCP resolve o problema de ação (o que o modelo pode fazer).

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.

A extensão quarkus-mcp-server

expõe beans CDI como ferramentas MCP com uma única anotação:

@ApplicationScoped
public class ContaCorrenteTools {

    @Inject ContaCorrenteRepository repository;

    @Tool("Consulta o saldo atual de uma conta corrente pelo número da conta")
    public SaldoResponse consultarSaldo(
        @P("Número da conta no formato XXXXXXX-D") String numeroConta) {

        return repository.findSaldo(numeroConta)
            .map(SaldoResponse::of)
            .orElseThrow(() -> new ContaNaoEncontradaException(numeroConta));
    }

    @Tool("Lista os últimos lançamentos de uma conta em um período")
    public List<LancamentoResponse> listarLancamentos(
        @P("Número da conta") String numeroConta,
        @P("Data inicial no formato yyyy-MM-dd") String dataInicio,
        @P("Data final no formato yyyy-MM-dd") String dataFim) {

        return repository.findLancamentos(numeroConta,
            LocalDate.parse(dataInicio), LocalDate.parse(dataFim));
    }
}

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.

@RegisterAiService(tools = McpToolProvider.class)
public interface AssistenteFinanceiro {

    @SystemMessage("""
        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.
        """)
    String conversar(@MemoryId String sessionId,
                     @UserMessage String mensagem);
}

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.

O fluxo completo de uma pergunta do usuário até a resposta com dados reais e contexto documental:

Usuário
  |
  v
[AssistenteFinanceiro — AI Service]
  |
  |-- (1) Recuperação RAG --> EmbeddingStoreRetriever
  |                               |
  |                           Vector Store
  |                               |
  |                           Fragmentos relevantes <--|
  |
  |-- (2) Tool calls via MCP --> ContaCorrenteTools
  |                               |
  |                           Repository / Oracle DB
  |                               |
  |                           Dados transacionais <--|
  |
  v
[LLM: Prompt = contexto RAG + dados MCP + histórico de sessão]
  |
  v
Resposta fundamentada

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.

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 governar o uso de IA no time.

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:

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.

Voltando à divisão que o professor Moraes propõe — contrato estável versus empolgante-mas-instável:

Construa agora:

Acompanhe, não deploya ainda:

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.

[1] MORAES, Elder. A2A Java SDK 1.0.0.Final: o primeiro GA. Newsletter Java Weekly, jun. 2026. Disponível em: https://quarkus.io/blog/a2a-java-sdk-1-0-0-final-released/ (citado via newsletter eldermoraes.ai).

[2] MORAES, Elder. Quarkus 3.37 liga o Jackson reflection-free por padrão. Newsletter Java Weekly, jun. 2026. Disponível em: https://github.com/quarkusio/quarkus/releases/tag/3.37.0.CR1 (citado via newsletter eldermoraes.ai).

[3] MORAES, Elder. OpenJDK proíbe contribuição gerada por IA; a GraalVM, da mesma Oracle, permite. Newsletter Java Weekly, jun. 2026. Disponível em: https://www.infoq.com/news/2026/06/oracle-genai-policies/ (citado via newsletter eldermoraes.ai).

[4] MORAES, Elder. Método Java AI Specialist. Disponível em: https://eldermoraes.ai. Acesso em: jun. 2026.

[5] LangChain4j. Documentation. Disponível em: https://docs.langchain4j.dev.

[6] Quarkus. LangChain4j Extension Guide. Disponível em: https://quarkus.io/guides/langchain4j.

[7] Anthropic. Model Context Protocol Specification. Disponível em: https://modelcontextprotocol.io.

── more in #large-language-models 4 stories · sorted by recency
── more on @langchain4j 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/java-moderno-com-ia-…] indexed:0 read:8min 2026-06-24 ·