Neste tutorial, vamos explorar um pequeno módulo Java que expõe ferramentas personalizadas, salva anotações como JSON no Oracle AI Database e as recupera com busca de texto completo.
Se você está criando agentes de IA, o histórico curto do chat geralmente não é suficiente. Assistentes de verdade precisam de um pouco de memória durável para guardar fatos importantes e recuperá-los depois.
Este tutorial mostra como implementar esse padrão com um módulo Java mínimo. Você vai usar ferramentas do LangChain4j, uma interface simples de agente e o Oracle AI Database como armazenamento. Em vez de adicionar embeddings ou um pipeline completo de recuperação, este exemplo mantém o design propositalmente enxuto: as notas são salvas como documentos JSON e pesquisadas com Oracle Text.
Ao final, você vai entender como o módulo integra:
Uma interface de agente LangChain4j
Dois métodos personalizados com @Tool
Um repositório JDBC para armazenamento durável de notas
Um aplicativo de console que orquestra todo o fluxo
O que é memória baseada em ferramentas no LangChain4j?
LangChain4j permite expor métodos Java comuns como ferramentas que o modelo pode chamar quando precisa de capacidades externas. Neste módulo, essas capacidades são voltadas à memória:
Esse padrão é útil quando você quer que um agente lembre fatos como anotações de incidentes, lembretes de runbook ou ações de follow-up sem construir um sistema de recuperação maior cedo demais.
A memória persistente baseada em banco pode ser acessada simultaneamente por um ou mais agentes sem disputa de dados.
Com memória baseada em ferramentas, o assistente pode recuperar notas existentes ou salvar novas notas em um banco de dados durável.
Principais recursos do módulo LangChain4j com Oracle AI DB
Este exemplo é pequeno, mas demonstra várias ideias importantes de design de agentes.
Ferramentas personalizadas do LangChain4j
A classe MemoryTools expõe dois métodos anotados com @Tool. Isso significa que o LangChain4j pode disponibilizá-los ao agente sem código adicional de "wrapper".
// Retrieve relevant notes and format them for the assistant.@Tool("Search saved memory notes when earlier context might help answer the user.")publicStringsearchMemories(String question){List<MemoryRepository.Note> matches = repository.search(question,3);if(matches.isEmpty()){return"No saved memory matched that question.";}StringBuilder builder =newStringBuilder();for(int i =0; i < matches.size(); i++){MemoryRepository.Note note = matches.get(i);
builder.append(i +1).append(". [M").append(note.id()).append("] ").append(note.text());if(i +1< matches.size()){
builder.append('\n');}}return builder.toString();}Tecnologia
Esse método faz duas coisas úteis: delega a recuperação ao repositório e formata os resultados de um jeito amigável ao modelo, como [M12] algum texto da nota.
Isso facilita o agente citar a saída da ferramenta na resposta final.
Memória durável no Oracle AI Database
As notas ficam em uma tabela agent_memories como documentos JSON nativos. Cada linha contém:
Uma coluna de identidade id
Uma coluna JSON chamada memory_doc
Um timestamp created_at
O módulo inicializa o schema automaticamente:
-- Create a JSON-backed table for durable agent notes.CREATETABLEIFNOTEXISTS agent_memories (
id NUMBER GENERATED ALWAYS ASIDENTITYPRIMARYKEY,
memory_doc JSON NOTNULL,
created_at TIMESTAMPDEFAULTCURRENT_TIMESTAMPNOTNULL)Tecnologia
Isso mantém o modelo de armazenamento simples, oferecendo dados estruturados e durabilidade gerenciada pelo banco.
Busca por palavras-chave com Oracle Text
O repositório não gera embeddings. Em vez disso, extrai palavras-chave da pergunta do usuário, remove stop words, monta uma expressão do Oracle Text com ACCUM e pesquisa o conteúdo do documento JSON com json_textcontains.
Isso é especialmente útil para identificadores e termos operacionais como CHG2145, em que a correspondência exata ou quase exata costuma importar mais do que similaridade semântica.
Um fluxo mínimo via console
A classe Application cria o repositório, inicializa o schema, insere algumas notas de exemplo, constrói o modelo de chat e inicia um loop no terminal. Assim, o exemplo é fácil de executar e de adaptar para outro serviço depois.
Primeiros passos no seu projeto de memória com LangChain4j
Antes de rodar o módulo, garanta que seu ambiente local atende aos requisitos do projeto.
Pré-requisitos
Você vai precisar de:
Java 21 ou superior
Maven 3.9 ou superior
Oracle AI Database Free em execução localmente ou remotamente
Uma variável de ambiente OPENAI_API_KEY
O projeto Maven depende de:
langchain4j
langchain4j-open-ai
ojdbc11
JUnit e Testcontainers para testes de integração
Execute o exemplo
Defina sua chave da OpenAI primeiro:
# Set the API key used by the chat model.exportOPENAI_API_KEY=<your key>Tecnologia
Depois, rode o app a partir do diretório do projeto:
# Compile and run the sample with the database connection details.
mvn compile exec:java \-Dexec.args="jdbc:oracle:thin:@localhost:1521/freepdb1 testuser testpwd"Tecnologia
O aplicativo espera exatamente três argumentos:
1. URL JDBC
2. Nome de usuário do banco de dados
3. Senha do banco de dados
Se algo estiver faltando, Application.main() lança um IllegalArgumentException. Se OPENAI_API_KEY não estiver definida, lança um IllegalStateException.
O que acontece ao iniciar
Quando o app inicia, ele:
1. Cria um MemoryRepository
2. Inicializa o schema do banco
3. Insere três notas de exemplo se a tabela estiver vazia
4. Constrói um OpenAiChatModel
5. Conecta o modelo e as ferramentas no AiServices
6. Inicia um loop de CLI que lê a entrada do usuário até você digitar exit
Ou seja, você pode testar a recuperação de memória imediatamente, sem inserir linhas manualmente antes.
Como criar um agente Java com memória usando LangChain4j
Agora vamos percorrer o módulo na mesma ordem em que o aplicativo o utiliza.
Defina a interface do agente
LangChain4j usa uma interface Java para descrever o contrato do agente. Neste projeto, essa interface é MemoryAssistant.
// Define the interface that receives each user message.publicinterfaceMemoryAssistant{@SystemMessage("""
You are a simple assistant with access to durable memory notes.
Use searchMemories when earlier notes might help answer the user.
If the user explicitly asks you to remember something for later, call storeMemory.
Keep answers concise.
""")@UserMessage("{{message}}")Stringchat(@V("message")String message);}Tecnologia
A parte importante é a mensagem de sistema. Ela diz ao modelo quando usar cada ferramenta:
Pesquisar quando notas anteriores podem ajudar
Armazenar quando o usuário pedir explicitamente para lembrar algo
Esse é um bom exemplo de política de ferramentas enxuta. O prompt é curto, mas específico o suficiente para orientar a seleção de ferramentas.
Exponha as operações de memória como ferramentas
O agente não fala diretamente com o repositório. Em vez disso, chama a camada MemoryTools.
Aqui está o método de armazenamento:
// Save a note and return its generated memory identifier.@Tool("Store a new memory note when the user asks you to remember something "+"important for later.")publicStringstoreMemory(String note){long id = repository.store(note);return"Stored memory M"+ id +".";}Tecnologia
Isso é propositalmente compacto. Um usuário pode dizer:
Remember that the next shift should verify the checkout retry queue stays below 50.Tecnologia
Se o modelo seguir corretamente o prompt do sistema, ele chama storeMemory(), o repositório persiste a nota e a ferramenta retorna algo como:
Nesse ponto, o agente pode chamar searchMemories() e usar a nota retornada para responder.
Crie a camada de repositório
O repositório concentra a maior parte da lógica de memória durável. Ainda é JDBC puro, o que deixa o design fácil de inspecionar.
Em alto nível, o MemoryRepository é responsável por:
Criação do schema
Seed opcional
Inserção de notas
Extração de palavras-chave
Busca com Oracle Text
Recuperação de fallback das notas recentes quando não há palavras-chave úteis
O caminho de inserção normaliza e valida o texto da nota antes de armazená-lo:
// Normalize the note, store its JSON document, and return the generated ID.publiclongstore(String note){String normalized =normalizeNote(note);Instant createdAt =Instant.now();try(Connection connection = dataSource.getConnection();PreparedStatement statement = connection.prepareStatement(INSERT_SQL,newString[]{"id"})){
statement.setObject(1,toJsonDocument(normalized, createdAt),OracleTypes.JSON);
statement.setTimestamp(2,Timestamp.from(createdAt));
statement.executeUpdate();try(ResultSet keys = statement.getGeneratedKeys()){if(keys.next()){return keys.getLong(1);}}thrownewIllegalStateException("No generated id returned for stored memory.");}catch(SQLException e){thrownewRuntimeException("Failed to store memory", e);}}Tecnologia
O documento JSON em si fica assim:
{"noteText":"Runbook note: use section 3 to validate checkout recovery after a rollback.","createdAt":"2026-04-27T17:00:00Z"}Tecnologia
Essa estrutura é simples, mas suficiente para suportar persistência e busca textual.
Entenda a estratégia de busca
A parte mais interessante do repositório é o método search():
// Search by extracted keywords or fall back to recent notes.publicList<Note>search(String question,int maxResults){List<String> keywords =extractKeywords(question);if(keywords.isEmpty()){returnfindRecent(maxResults);}returntextSearch(buildTextExpression(keywords), maxResults);}Tecnologia
Esse método segue um fluxo prático:
1. Tokeniza a pergunta do usuário
2. Converte os tokens para minúsculas
3. Remove stop words como the, what e remember
4. Mantém tokens curtos significativos quando incluem dígitos
5. Monta uma expressão do Oracle Text com ACCUM
6. Pesquisa os dados JSON com json_textcontains
Esse detalhe de “permitir dígitos” é importante. Ele ajuda termos como CHG2145 a sobreviver na extração de palavras-chave — exatamente o tipo de busca por identificadores que muitos agentes operacionais precisam.
O fluxo de busca converte a pergunta em uma expressão de palavras-chave e retorna notas de memória ranqueadas.
A consulta SQL de busca é:
-- Rank matching notes by Oracle Text relevance.SELECT id,
JSON_VALUE(
memory_doc,'$.noteText'RETURNING VARCHAR2(2000CHAR))AS note_text,
created_at,
SCORE(1)AS text_score
FROM agent_memories
WHERE JSON_TEXTCONTAINS(memory_doc,'$', ?,1)ORDERBY SCORE(1)DESC, id DESCFETCHFIRST ? ROWS ONLYTecnologia
Se a pergunta não gerar boas palavras-chave, o repositório faz fallback para notas recentes. Assim, o agente tem um padrão razoável em vez de retornar uma busca vazia cedo demais.
Conecte tudo no aplicativo
O aplicativo integra as peças com AiServices.builder():
// Build the chat model, then attach the memory tools to the assistant.ChatModel chatModel =OpenAiChatModel.builder().apiKey(apiKey).modelName("gpt-5-nano").build();MemoryAssistant assistant =AiServices.builder(MemoryAssistant.class).chatModel(chatModel).tools(newMemoryTools(repository)).build();Tecnologia
Esse é o padrão completo em um só lugar:
Construir um modelo de chat
Expor métodos como ferramentas
Vincular essas ferramentas a um agente dirigido por interface
Depois disso, o loop do console apenas passa a entrada do usuário para assistant.chat(input).
Teste os prompts de demonstração
O aplicativo imprime alguns prompts iniciais:
What do we know about CHG2145?
Remember that the next shift should verify the checkout retry queue stays below 50.
What should the next shift verify?Tecnologia
Eles são úteis porque exercitam todo o ciclo de memória:
Recuperar uma nota inserida no seed
Armazenar uma nova nota
Recuperar a nota recém-armazenada depois
Dicas e solução de problemas
Este módulo é intencionalmente focado, o que ajuda no aprendizado do padrão. Ainda assim, vale considerar alguns pontos práticos.
Mantenha as instruções da ferramenta explícitas
O prompt do sistema indica ao modelo para armazenar memória somente quando o usuário pedir explicitamente. Isso ajuda a reduzir gravações acidentais. Se você ampliar o prompt sem cuidado, o modelo pode começar a persistir notas de baixo valor.
Trate isto como memória de notas duráveis, não como recuperação de conhecimento completa
Este repositório é melhor para notas operacionais curtas, lembretes e identificadores. Ainda não é um sistema completo de RAG com embeddings, chunking, busca híbrida ou reranqueamento.
Use Oracle Text quando identificadores importarem
Para strings como IDs de incidentes, números de chamados e referências de change request, a recuperação por palavras-chave costuma ser um ponto de partida melhor do que busca semântica. Este exemplo deixa esse trade-off claro.
Valide seu banco de dados e o Docker separadamente
Os testes do projeto são de integração e usam Testcontainers. Se o Docker não estiver disponível, mvn test vai falhar antes mesmo da lógica do repositório rodar. Isso é um problema de ambiente, não necessariamente um bug do app.
Notas podem ser armazenadas e recuperadas pelo repositório
A saída da ferramenta inclui IDs de memória e texto relevante da nota
Comece simples antes de adicionar mais recursos de memória
Um erro comum em projetos de agentes é adicionar de uma vez só: armazenamento vetorial, histórico de conversa, sumarização e políticas de recuperação. Este exemplo sugere uma progressão melhor:
1. Defina um caso de uso concreto de memória
2. Exponha ferramentas explícitas
3. Dê suporte a essas ferramentas com armazenamento durável
4. Valide o comportamento de recuperação
5. Só então considere padrões de memória mais avançados
Continue aprendendo
Se você quer continuar desenvolvendo habilidades em agentes depois deste tutorial, estes recursos da DataCamp são um ótimo próximo passo:
Você viu como criar um agente pequeno, porém útil, com memória usando LangChain4j, Java e Oracle AI Database. A ideia central é simples: dê ao modelo ferramentas explícitas de memória, armazene notas de forma durável como JSON e recupere-as com uma estratégia de busca direta.
Esse design é uma base sólida porque é fácil de entender e de evoluir. Quando o padrão estiver funcionando, você pode adicionar filtros melhores, esquemas de notas mais ricos, escopo por usuário ou até busca vetorial, caso o uso exija.
Se quiser continuar aprendendo sobre design de agentes, o próximo passo é comparar este padrão de memória baseada em ferramentas com frameworks de agentes mais amplos e fluxos de orquestração. Vale explorar como ferramentas explícitas, padrões de recuperação e agentes multiestágio se encaixam em sistemas de IA maiores.
FAQs
Que tipo de memória este tutorial implementa?⌄
Este tutorial implementa memória durável baseada em ferramentas. As notas são armazenadas em uma tabela do banco de dados e recuperadas por chamadas explícitas de ferramentas, em vez de serem anexadas automaticamente à janela de prompt.
Este projeto usa embeddings vetoriais?⌄
Não. Este exemplo propositalmente evita embeddings, busca vetorial e reranqueamento. Ele usa Oracle Text com json_textcontains para pesquisar o conteúdo das notas.
Por que usar ferramentas para memória em vez de manter tudo no histórico do chat?⌄
Memória baseada em ferramentas dá mais controle sobre o que é armazenado, quando é armazenado e como é recuperado. Também funciona melhor para notas duráveis que precisam sobreviver além de uma conversa.
O que eu preciso para rodar o demo ao vivo?⌄
Você precisa de Java 21 ou superior, Maven 3.9 ou superior, acesso ao Oracle AI Database e uma OPENAI_API_KEY no seu shell.
Os testes precisam de Docker? ⌄
Sim. Os testes de integração usam Testcontainers para iniciar o Oracle AI Database Free, então o Docker precisa estar disponível no seu ambiente.
Como Developer Evangelist na Oracle, ajudo desenvolvedores a criar apps modernos — de microsserviços e sistemas orientados a eventos a arquiteturas cloud-native e muito mais. Se você trabalha com ferramentas como Kubernetes, Spring Boot ou Kafka e quer entender onde a Oracle entra nesse ecossistema, é aí que eu atuo.Meu objetivo é compartilhar orientações práticas, mão na massa, para você construir mais rápido, publicar com mais confiança e tirar o máximo das tecnologias de banco de dados da Oracle. Se você usa JSON, event streaming, vector search ou está dando os primeiros passos, estou aqui para deixar tudo mais claro e amigável para desenvolvedores.
Saiba mais sobre os principais tipos de agentes de IA, como eles interagem com os ambientes e como são usados em todos os setores. Entenda o reflexo simples, baseado em modelo, baseado em meta, baseado em utilidade, agentes de aprendizagem e muito mais.
Um tutorial abrangente sobre a criação de agentes LangChain com várias ferramentas para automatizar tarefas em Python usando LLMs e modelos de bate-papo usando OpenAI.
Explore o potencial inexplorado dos modelos de linguagem grandes com o LangChain, uma estrutura Python de código aberto para criar aplicativos avançados de IA.
Aprenda a criar um aplicativo RAG com o Llama 3.1 8B usando Ollama e Langchain, configurando o ambiente, processando documentos, criando embeddings e integrando um retriever.
Uma visão geral abrangente da API Assistants com nosso artigo, que oferece uma análise aprofundada de seus recursos, usos no setor, orientação de configuração e práticas recomendadas para maximizar seu potencial em vários aplicativos de negócios.
Este guia o orienta sobre os conceitos básicos da API ChatGPT, demonstrando seu potencial no processamento de linguagem natural e na comunicação orientada por IA.
Neste tutorial, vamos explorar um pequeno módulo Java que expõe ferramentas personalizadas, salva anotações como JSON no Oracle AI Database e as recupera com busca de texto completo.
Se você está criando agentes de IA, o histórico curto do chat geralmente não é suficiente. Assistentes de verdade precisam de um pouco de memória durável para guardar fatos importantes e recuperá-los depois.
Este tutorial mostra como implementar esse padrão com um módulo Java mínimo. Você vai usar ferramentas do LangChain4j, uma interface simples de agente e o Oracle AI Database como armazenamento. Em vez de adicionar embeddings ou um pipeline completo de recuperação, este exemplo mantém o design propositalmente enxuto: as notas são salvas como documentos JSON e pesquisadas com
Oracle Text.Ao final, você vai entender como o módulo integra:
LangChain4j@ToolJDBCpara armazenamento durável de notasO que é memória baseada em ferramentas no LangChain4j?
LangChain4jpermite expor métodos Java comuns como ferramentas que o modelo pode chamar quando precisa de capacidades externas. Neste módulo, essas capacidades são voltadas à memória:searchMemories(String question)encontra anotações relevantesstoreMemory(String note)grava uma nova nota durávelIsso é diferente do histórico padrão do chat, que guarda mensagens em uma janela de contexto na memória.
Memória persistente baseada em ferramentas decide quando é preciso pesquisar ou armazenar notas, e os dados ficam em um banco de dados.
Esse padrão é útil quando você quer que um agente lembre fatos como anotações de incidentes, lembretes de runbook ou ações de follow-up sem construir um sistema de recuperação maior cedo demais.
A memória persistente baseada em banco pode ser acessada simultaneamente por um ou mais agentes sem disputa de dados.
Com memória baseada em ferramentas, o assistente pode recuperar notas existentes ou salvar novas notas em um banco de dados durável.
Principais recursos do módulo LangChain4j com Oracle AI DB
Este exemplo é pequeno, mas demonstra várias ideias importantes de design de agentes.
Ferramentas personalizadas do LangChain4j
A classe
MemoryToolsexpõe dois métodos anotados com@Tool. Isso significa que oLangChain4jpode disponibilizá-los ao agente sem código adicional de "wrapper".Esse método faz duas coisas úteis: delega a recuperação ao repositório e formata os resultados de um jeito amigável ao modelo, como
[M12] algum texto da nota.Isso facilita o agente citar a saída da ferramenta na resposta final.
Memória durável no Oracle AI Database
As notas ficam em uma tabela
agent_memoriescomo documentos JSON nativos. Cada linha contém:idmemory_doccreated_atO módulo inicializa o schema automaticamente:
Isso mantém o modelo de armazenamento simples, oferecendo dados estruturados e durabilidade gerenciada pelo banco.
Busca por palavras-chave com Oracle Text
O repositório não gera embeddings. Em vez disso, extrai palavras-chave da pergunta do usuário, remove stop words, monta uma expressão do
Oracle TextcomACCUMe pesquisa o conteúdo do documento JSON comjson_textcontains.Isso é especialmente útil para identificadores e termos operacionais como
CHG2145, em que a correspondência exata ou quase exata costuma importar mais do que similaridade semântica.Um fluxo mínimo via console
A classe
Applicationcria o repositório, inicializa o schema, insere algumas notas de exemplo, constrói o modelo de chat e inicia um loop no terminal. Assim, o exemplo é fácil de executar e de adaptar para outro serviço depois.Primeiros passos no seu projeto de memória com LangChain4j
Antes de rodar o módulo, garanta que seu ambiente local atende aos requisitos do projeto.
Pré-requisitos
Você vai precisar de:
OPENAI_API_KEYO projeto Maven depende de:
langchain4jlangchain4j-open-aiojdbc11Testcontainerspara testes de integraçãoExecute o exemplo
Defina sua chave da OpenAI primeiro:
Depois, rode o app a partir do diretório do projeto:
O aplicativo espera exatamente três argumentos:
1. URL
JDBC2. Nome de usuário do banco de dados
3. Senha do banco de dados
Se algo estiver faltando,
Application.main()lança umIllegalArgumentException. SeOPENAI_API_KEYnão estiver definida, lança umIllegalStateException.O que acontece ao iniciar
Quando o app inicia, ele:
1. Cria um
MemoryRepository2. Inicializa o schema do banco
3. Insere três notas de exemplo se a tabela estiver vazia
4. Constrói um
OpenAiChatModel5. Conecta o modelo e as ferramentas no
AiServices6. Inicia um loop de CLI que lê a entrada do usuário até você digitar
exitOu seja, você pode testar a recuperação de memória imediatamente, sem inserir linhas manualmente antes.
Como criar um agente Java com memória usando LangChain4j
Agora vamos percorrer o módulo na mesma ordem em que o aplicativo o utiliza.
Defina a interface do agente
LangChain4jusa uma interface Java para descrever o contrato do agente. Neste projeto, essa interface éMemoryAssistant.A parte importante é a mensagem de sistema. Ela diz ao modelo quando usar cada ferramenta:
Esse é um bom exemplo de política de ferramentas enxuta. O prompt é curto, mas específico o suficiente para orientar a seleção de ferramentas.
Exponha as operações de memória como ferramentas
O agente não fala diretamente com o repositório. Em vez disso, chama a camada
MemoryTools.Aqui está o método de armazenamento:
Isso é propositalmente compacto. Um usuário pode dizer:
Se o modelo seguir corretamente o prompt do sistema, ele chama
storeMemory(), o repositório persiste a nota e a ferramenta retorna algo como:Depois, o usuário pode perguntar:
Nesse ponto, o agente pode chamar
searchMemories()e usar a nota retornada para responder.Crie a camada de repositório
O repositório concentra a maior parte da lógica de memória durável. Ainda é
JDBCpuro, o que deixa o design fácil de inspecionar.Em alto nível, o
MemoryRepositoryé responsável por:Oracle TextO caminho de inserção normaliza e valida o texto da nota antes de armazená-lo:
O documento JSON em si fica assim:
Essa estrutura é simples, mas suficiente para suportar persistência e busca textual.
Entenda a estratégia de busca
A parte mais interessante do repositório é o método
search():Esse método segue um fluxo prático:
1. Tokeniza a pergunta do usuário
2. Converte os tokens para minúsculas
3. Remove stop words como
the,whateremember4. Mantém tokens curtos significativos quando incluem dígitos
5. Monta uma expressão do
Oracle TextcomACCUM6. Pesquisa os dados JSON com
json_textcontainsEsse detalhe de “permitir dígitos” é importante. Ele ajuda termos como
CHG2145a sobreviver na extração de palavras-chave — exatamente o tipo de busca por identificadores que muitos agentes operacionais precisam.O fluxo de busca converte a pergunta em uma expressão de palavras-chave e retorna notas de memória ranqueadas.
A consulta SQL de busca é:
Se a pergunta não gerar boas palavras-chave, o repositório faz fallback para notas recentes. Assim, o agente tem um padrão razoável em vez de retornar uma busca vazia cedo demais.
Conecte tudo no aplicativo
O aplicativo integra as peças com
AiServices.builder():Esse é o padrão completo em um só lugar:
Depois disso, o loop do console apenas passa a entrada do usuário para
assistant.chat(input).Teste os prompts de demonstração
O aplicativo imprime alguns prompts iniciais:
Eles são úteis porque exercitam todo o ciclo de memória:
Dicas e solução de problemas
Este módulo é intencionalmente focado, o que ajuda no aprendizado do padrão. Ainda assim, vale considerar alguns pontos práticos.
Mantenha as instruções da ferramenta explícitas
O prompt do sistema indica ao modelo para armazenar memória somente quando o usuário pedir explicitamente. Isso ajuda a reduzir gravações acidentais. Se você ampliar o prompt sem cuidado, o modelo pode começar a persistir notas de baixo valor.
Trate isto como memória de notas duráveis, não como recuperação de conhecimento completa
Este repositório é melhor para notas operacionais curtas, lembretes e identificadores. Ainda não é um sistema completo de RAG com embeddings, chunking, busca híbrida ou reranqueamento.
Use Oracle Text quando identificadores importarem
Para strings como IDs de incidentes, números de chamados e referências de change request, a recuperação por palavras-chave costuma ser um ponto de partida melhor do que busca semântica. Este exemplo deixa esse trade-off claro.
Valide seu banco de dados e o Docker separadamente
Os testes do projeto são de integração e usam
Testcontainers. Se o Docker não estiver disponível,mvn testvai falhar antes mesmo da lógica do repositório rodar. Isso é um problema de ambiente, não necessariamente um bug do app.Execute os testes com:
Os testes cobrem dois comportamentos importantes:
Comece simples antes de adicionar mais recursos de memória
Um erro comum em projetos de agentes é adicionar de uma vez só: armazenamento vetorial, histórico de conversa, sumarização e políticas de recuperação. Este exemplo sugere uma progressão melhor:
1. Defina um caso de uso concreto de memória
2. Exponha ferramentas explícitas
3. Dê suporte a essas ferramentas com armazenamento durável
4. Valide o comportamento de recuperação
5. Só então considere padrões de memória mais avançados
Continue aprendendo
Se você quer continuar desenvolvendo habilidades em agentes depois deste tutorial, estes recursos da DataCamp são um ótimo próximo passo:
Conclusão
Você viu como criar um agente pequeno, porém útil, com memória usando
LangChain4j, Java e Oracle AI Database. A ideia central é simples: dê ao modelo ferramentas explícitas de memória, armazene notas de forma durável como JSON e recupere-as com uma estratégia de busca direta.Esse design é uma base sólida porque é fácil de entender e de evoluir. Quando o padrão estiver funcionando, você pode adicionar filtros melhores, esquemas de notas mais ricos, escopo por usuário ou até busca vetorial, caso o uso exija.
Se quiser continuar aprendendo sobre design de agentes, o próximo passo é comparar este padrão de memória baseada em ferramentas com frameworks de agentes mais amplos e fluxos de orquestração. Vale explorar como ferramentas explícitas, padrões de recuperação e agentes multiestágio se encaixam em sistemas de IA maiores.