🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 10 Min Lesezeit
0

Agente de IA confiável em prod com Java + Quarkus + Langchain4j - Parte 2 - Memória

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht
📺
dev.to




Autores









Partes do artigo




  1. caso não se tome os devidos cuidados. Pra não termos mais esse problema e também para que seja possível utilizarmos nosso agente em um ambiente de escalabilidade, precisamos de um ChatMemoryStore.





    Conceitos



    Utilizamos um chat para interagir com o nosso agente e há conceitos importantes que devemos conhecer para que a nossa interação com ele possa ocorrer da melhor forma possível e não ocasione bugs em produção. Primeiramente precisamos conhecer os tipos de mensagens que utilizamos na hora de interagir com ele, são eles:




    • Mensagens do usuário (UserMessage): A mensagem ou solicitação enviada pelo cliente final. Quando enviamos a mensagem no DevUI do quarkus, sempre estamos enviando uma UserMessage. Além disso, ela também é utilizada nos resultados de chamadas das ferramentas (tools) que vimos antes.


    • Mensagens da IA (AiMessage): A mensagem de resposta do modelo. Sempre que o LLM responder pro nosso agente, ele receberá uma mensagem desse tipo. Este tipo de mensagem fica alternando o seu conteúdo entre uma resposta textual e solicitações de execução de ferramentas (tools).


    • Mensagem do Sistema (SystemMessage): Esta mensagem pode ser definida somente 1 vez e é somente em tempo de desenvolvimento.




    Agora que você conhece os 3 tipos de mensagens que temos, vamos explicar como elas devem se comportar com alguns gráficos. Todos os gráficos foram tirados da apresentação



    Neste segundo gráfico, demonstra-se como que a "memória" deve ser gerenciada. Um detalhe interessante é que devemos manter uma certa ordem nas mensagens e algumas premissas devem ser respeitadas.



    e subimos uma instância no docker. Sinta-se a vontade pra configurar ele como bem desejar.





    Adicionando nossa conexão com o MongoDB



    Vamos iniciar adicionando a dependência necessária para termos uma conexão com o MongoDB utilizando o Quarkus.




    CODE
    <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-mongodb-panache</artifactId>
    </dependency>






    Após as dependências, precisamos adicionar as configurações de conexão no nosso src/main/resources/application.properties.




    CODE
    quarkus.mongodb.connection-string=mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@localhost:27017
    quarkus.mongodb.database=chat_memory






    Ainda não iremos conseguir testar a nossa conexão com a base, pois antes precisamos criar nossas entidades e repositórios.






    Criando nossa entidade e nosso repositório



    Agora vamos implementar nossa entidade Interaction. Essa entidade terá a nossa lista de mensagens realizadas. Sempre que um cliente novo se conectar, será gerada uma nova Interaction. Se precisarmos reaproveitar essa Interaction, basta informamos o mesmo identificador da Interaction.




    CODE
    package <seupacote>;

    import dev.langchain4j.data.message.ChatMessage;
    import io.quarkus.mongodb.panache.common.MongoEntity;
    import org.bson.codecs.pojo.annotations.BsonId;

    import java.util.List;
    import java.util.Objects;

    @MongoEntity(collection = "interactions")
    public class InteractionEntity {

    @BsonId
    private String interactionId;
    private List<ChatMessage> messages;

    public InteractionEntity() {
    }

    public InteractionEntity(String interactionId, List<ChatMessage> messages) {
    this.interactionId = interactionId;
    this.messages = messages;
    }

    public String getInteractionId() {
    return interactionId;
    }

    public void setInteractionId(String interactionId) {
    this.interactionId = interactionId;
    }

    public List<ChatMessage> getMessages() {
    return messages;
    }

    public void setMessages(List<ChatMessage> messages) {
    this.messages = messages;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    InteractionEntity that = (InteractionEntity) o;
    return Objects.equals(interactionId, that.interactionId);
    }

    @Override
    public int hashCode() {
    return Objects.hash(interactionId, messages);
    }
    }






    Podemos agora criar o nosso repositório.




    CODE
    package <seupacote>;

    import dev.langchain4j.data.message.ChatMessage;
    import io.quarkus.mongodb.panache.PanacheMongoRepositoryBase;

    import java.util.List;

    public class InteractionRepository implements PanacheMongoRepositoryBase<InteractionEntity, String> {

    public InteractionEntity findByInteractionId(String interactionId) {
    return findById(interactionId);
    }

    public void updateMessages(String interactionId, List<ChatMessage> messages) {
    persistOrUpdate(new InteractionEntity(interactionId, messages));
    }

    public void deleteMessages(String interactionId) {
    deleteById(interactionId);
    }

    }






    Agora iremos implementar alguns componentes do langchain4j, o ChatMemoryStore e o ChatMemoryProvider. O ChatMemoryProvider é a classe que utilizaremos no nosso Agent. Nele iremos adicionar uma ChatMemoryStore que irá utilizar nosso repositório para armazenar as mensagens no nosso MongoDB. Segue o ChatMemoryStore:




    CODE
    package <seupacote>;

    import dev.langchain4j.data.message.ChatMessage;
    import dev.langchain4j.store.memory.chat.ChatMemoryStore;

    import java.util.List;
    import java.util.Objects;

    public class MongoDBChatMemoryStore implements ChatMemoryStore {

    private InteractionRepository interactionRepository = new InteractionRepository();

    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
    var interactionEntity = interactionRepository.findByInteractionId(memoryId.toString());
    return Objects.isNull(interactionEntity) ? List.of() : interactionEntity.getMessages();
    }

    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
    interactionRepository.updateMessages(memoryId.toString(), messages);
    }

    @Override
    public void deleteMessages(Object memoryId) {
    interactionRepository.deleteMessages(memoryId.toString());
    }
    }







    O ChatMemoryProvider ficará desse jeito:




    CODE
    package <seupacote>;

    import dev.langchain4j.memory.chat.ChatMemoryProvider;
    import dev.langchain4j.memory.chat.MessageWindowChatMemory;

    import java.util.function.Supplier;

    public class MongoDBChatMemoryProvider implements Supplier<ChatMemoryProvider> {

    private MongoDBChatMemoryStore mongoDBChatMemoryStore = new MongoDBChatMemoryStore();

    @Override
    public ChatMemoryProvider get() {
    return memoryId -> MessageWindowChatMemory.builder()
    .maxMessages(100)
    .id(memoryId)
    .chatMemoryStore(mongoDBChatMemoryStore)
    .build();
    }
    }






    Repare no MessageWindowChatMemory. É nele que implementamos a janela de mensagens que mencionamos no começo do artigo. No método maxMessages(), você deve alterar pro número que achar melhor pro seu cenário. O que recomendo é utilizar o maior número de mensagens que já existiu no seu cenário, ou utilizar a média. Aqui definimos o número arbitrário 100.



    Vamos agora alterar o nosso agente para utilizar o nosso ChatMemoryProvider novo e adicionar MemoryId. Ele deve ficar assim:




    CODE
    package <seupacote>;

    import dev.langchain4j.service.SystemMessage;
    import dev.langchain4j.service.UserMessage;
    import io.quarkiverse.langchain4j.RegisterAiService;
    import io.quarkiverse.langchain4j.ToolBox;
    import jakarta.enterprise.context.ApplicationScoped;

    @ApplicationScoped
    @RegisterAiService(
    chatMemoryProviderSupplier = MongoDBChatMemoryProvider.class
    )
    public interface Agent {

    @ToolBox(AgentTools.class)
    @SystemMessage("""
    Você é um agente especializado em futebol brasileiro, seu nome é FutAgentBR
    Você sabe responder sobre os principais títulos dos principais times brasileiros e da seleção brasileira
    Sua resposta precisa ser educada, você pode deve responder em Português brasileiro e de forma relevante a pergunta feita

    Quando você não souber a resposta, responda que você não sabe responder nesse momento mas saberá em futuras versões.
    """
    )
    String chat(@MemoryId String interactionId, @UserMessage String message);
    }






    Isso deve quebrar o nosso AgentWSEndpoint. Vamos alterá-lo para que ele receba o identificador da Interaction e possamos utilizar como nosso MemoryId:




    CODE
    package <seupacote>;

    import io.quarkus.websockets.next.OnTextMessage;
    import io.quarkus.websockets.next.WebSocket;
    import io.quarkus.websockets.next.WebSocketConnection;
    import jakarta.inject.Inject;

    import java.util.Objects;
    import java.util.UUID;

    @WebSocket(path = "/ws/{interactionId}")
    public class AgentWSEndpoint {

    private final Agent agent;

    private final WebSocketConnection connection;

    @Inject
    AgentWSEndpoint(Agent agent, WebSocketConnection connection) {
    this.agent = agent;
    this.connection = connection;
    }

    @OnTextMessage
    String reply(String message) {
    var interactionId = connection.pathParam("interactionId");
    return agent.chat(
    Objects.isNull(interactionId) || interactionId.isBlank()
    ? UUID.randomUUID().toString()
    : interactionId,
    message
    );
    }

    }






    Já podemos testar o nosso agente novamente. Para isso basta conectar-mos no websocket passando um UUID sempre que quisermos. Você pode gerar um novo UUID



    Isso encerra a segunda parte da nossa série. Esperamos que tenham gostado e até a parte 3.

    Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
    ↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Agente de IA confiável em prod com Java + Quarkus + Langchain4j - Parte 2 - Memória

Thematisch verwandte Begriffe: Agente, confiável, prod, Java · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...