En este tutorial, recorreremos un pequeño módulo de Java que expone herramientas personalizadas, guarda notas como JSON en Oracle AI Database y las recupera con búsqueda de texto completo.
Si estás creando agentes de IA, el historial de chat de corto plazo suele no ser suficiente. Los asistentes reales a menudo necesitan una pequeña cantidad de memoria duradera para guardar hechos importantes y recuperarlos más tarde.
Este tutorial muestra cómo implantar ese patrón con un módulo mínimo en Java. Usarás LangChain4j tools, una interfaz de agente sencilla y Oracle AI Database como almacén subyacente. En lugar de añadir embeddings o una canalización completa de retrieval, este ejemplo mantiene el diseño deliberadamente pequeño: las notas se guardan como documentos JSON y se buscan con Oracle Text.
Al final, entenderás cómo el módulo conecta:
Una interfaz de agente LangChain4j
Dos métodos personalizados con @Tool
Un repositorio JDBC para almacenamiento duradero de notas
Una aplicación de consola que enlaza todo el flujo
¿Qué es la memoria basada en herramientas en LangChain4j?
LangChain4j te permite exponer métodos Java ordinarios como herramientas que un modelo puede llamar cuando necesita capacidades externas. En este módulo, esas capacidades están orientadas a la memoria:
searchMemories(String question) encuentra notas guardadas relevantes
storeMemory(String note) escribe una nueva nota duradera
Esto es distinto del historial estándar de chat que almacena mensajes en una ventana de contexto en memoria.
Este patrón es útil cuando quieres que un agente recuerde hechos como notas de incidencias, recordatorios de runbooks o acciones de seguimiento sin construir demasiado pronto un sistema de retrieval más grande.
La memoria persistente respaldada por base de datos también puede ser accedida en paralelo por uno o más agentes sin contención de datos.
La memoria basada en herramientas permite que el asistente recupere notas existentes o guarde nuevas notas en una base de datos duradera.
Funciones clave del módulo LangChain4j y Oracle AI DB
Este ejemplo es pequeño, pero demuestra varias ideas importantes de diseño de agentes.
Herramientas personalizadas de LangChain4j
La clase MemoryTools expone dos métodos anotados con @Tool. Eso significa que LangChain4j puede ponerlos a disposición del agente sin código envoltorio adicional.
// 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();}Con la tecnología de
Este método hace dos cosas útiles. Delegar la recuperación al repositorio y dar formato a los resultados de forma que el modelo los entienda, por ejemplo [M12] some note text.
Así, la salida de la herramienta es fácil de citar por el agente en su respuesta final.
Memoria duradera en Oracle AI Database
Las notas se almacenan en una tabla agent_memories como documentos JSON nativos. Cada fila contiene:
Una columna de identidad id
Una columna JSON llamada memory_doc
Una marca de tiempo created_at
El módulo inicializa el esquema automáticamente:
-- 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)Con la tecnología de
Esto mantiene el modelo de almacenamiento simple y, aun así, te da datos estructurados y durabilidad gestionada por la base de datos.
Búsqueda por palabras clave con Oracle Text
El repositorio no genera embeddings. En su lugar, extrae palabras clave de la pregunta del usuario, elimina stop words, construye una expresión de Oracle Text con ACCUM y busca el contenido del documento JSON con json_textcontains.
Esto resulta especialmente útil para identificadores y términos operativos como CHG2145, donde el ajuste exacto o casi exacto de tokens suele importar más que la similitud semántica.
Un flujo mínimo por consola
La clase Application crea el repositorio, inicializa el esquema, precarga algunas notas, construye el modelo de chat y arranca un bucle en terminal. Así el ejemplo es fácil de ejecutar y de adaptar a otro servicio más adelante.
Primeros pasos con tu proyecto de memoria en LangChain4j
Antes de ejecutar el módulo, asegúrate de que tu entorno local cumple los requisitos del proyecto.
Requisitos previos
Necesitas:
Java 21 o superior
Maven 3.9 o superior
Oracle AI Database Free en local o remoto
Una variable de entorno OPENAI_API_KEY
El proyecto Maven depende de:
langchain4j
langchain4j-open-ai
ojdbc11
JUnit y Testcontainers para pruebas de integración
Ejecuta el ejemplo
Primero, define tu clave de API de OpenAI:
# Set the API key used by the chat model.exportOPENAI_API_KEY=<your key>Con la tecnología de
Después, ejecuta la app desde el directorio del proyecto:
# Compile and run the sample with the database connection details.
mvn compile exec:java \-Dexec.args="jdbc:oracle:thin:@localhost:1521/freepdb1 testuser testpwd"Con la tecnología de
La aplicación espera exactamente tres argumentos:
1. URL JDBC
2. Nombre de usuario de la base de datos
3. Contraseña de la base de datos
Si faltan, Application.main() lanza un IllegalArgumentException. Si falta OPENAI_API_KEY, lanza un IllegalStateException.
Qué ocurre al iniciar
Cuando la app arranca:
1. Crea un MemoryRepository
2. Inicializa el esquema de base de datos
3. Precaega tres notas de ejemplo si la tabla está vacía
4. Construye un OpenAiChatModel
5. Conecta el modelo y las herramientas en AiServices
6. Inicia un bucle CLI que lee entradas hasta que escribes exit
Esto te permite probar la recuperación de memoria de inmediato sin insertar filas a mano primero.
Cómo crear un agente Java con memoria en LangChain4j
Ahora recorramos el módulo en el mismo orden en que lo usa la aplicación.
Define la interfaz del agente
LangChain4j usa una interfaz de Java para describir el contrato del agente. En este proyecto, esa interfaz es 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);}Con la tecnología de
Lo importante es el mensaje del sistema. Indica al modelo cuándo usar cada herramienta:
Buscar cuando notas anteriores puedan ayudar
Guardar cuando el usuario pida explícitamente que se recuerde algo
Es un buen ejemplo de política de herramientas ligera. El prompt es breve, pero lo bastante específico para guiar la selección de herramientas.
Expón las operaciones de memoria como herramientas
El agente no habla directamente con el repositorio. En su lugar, llama a la capa MemoryTools.
Este es el método de almacenamiento:
// 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 +".";}Con la tecnología de
Esto es intencionadamente compacto. Un usuario podría decir:
Remember that the next shift should verify the checkout retry queue stays below 50.Con la tecnología de
Si el modelo sigue correctamente el prompt del sistema, llamará a storeMemory(), el repositorio persistirá la nota y la herramienta devolverá algo como:
En ese momento, el agente puede llamar a searchMemories() y usar la nota devuelta para responder.
Crea la capa de repositorio
El repositorio es donde vive la mayor parte de la lógica de memoria duradera. Sigue siendo JDBC puro, lo que facilita inspeccionar el diseño.
A alto nivel, MemoryRepository se encarga de:
Creación del esquema
Precarga opcional
Inserción de notas
Extracción de palabras clave
Búsqueda con Oracle Text
Recuperación alternativa de notas recientes cuando no hay palabras clave útiles
La ruta de inserción normaliza y valida el texto de la nota antes de almacenarlo:
// 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);}}Con la tecnología de
El propio documento JSON tiene este aspecto:
{"noteText":"Runbook note: use section 3 to validate checkout recovery after a rollback.","createdAt":"2026-04-27T17:00:00Z"}Con la tecnología de
La estructura es simple, pero suficiente para soportar persistencia y búsqueda de texto.
Entiende la estrategia de búsqueda
La parte más interesante del repositorio es el 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);}Con la tecnología de
Este método sigue un flujo práctico:
1. Tokeniza la pregunta del usuario
2. Pasa los tokens a minúsculas
3. Elimina stop words como the, what y remember
4. Conserva tokens cortos significativos cuando incluyan dígitos
5. Construye una expresión de Oracle Text con ACCUM
6. Busca en los datos JSON con json_textcontains
Ese detalle de “se permiten dígitos” es importante. Ayuda a que términos como CHG2145 sobrevivan a la extracción de palabras clave, justo el tipo de búsquedas con identificadores que muchos agentes operativos necesitan.
El flujo de búsqueda convierte una pregunta en una expresión de palabras clave y devuelve notas ordenadas por relevancia.
La consulta SQL de búsqueda es:
-- 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 ONLYCon la tecnología de
Si la pregunta no produce palabras clave útiles, el repositorio recurre a notas recientes. Eso da al agente un valor por defecto razonable en lugar de devolver demasiado pronto una búsqueda vacía.
Conecta todo en la aplicación
La aplicación une las piezas con 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();Con la tecnología de
Este es el patrón completo en un solo lugar:
Construir un modelo de chat
Exponer métodos como herramientas
Vincular esas herramientas a un agente guiado por interfaz
Después de eso, el bucle de consola simplemente pasa la entrada del usuario a assistant.chat(input).
Prueba los prompts de demo
La aplicación imprime algunos prompts de inicio:
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?Con la tecnología de
Estos prompts son útiles porque ejercitan todo el ciclo de memoria:
Recuperar una nota precargada existente
Guardar una nota nueva
Recuperar más tarde la nota recién guardada
Consejos y resolución de problemas
Este módulo es deliberadamente acotado, lo que es una ventaja cuando aprendes el patrón. Aun así, conviene tener presentes algunos detalles prácticos.
Mantén las instrucciones de la herramienta explícitas
El prompt del sistema indica al modelo que solo guarde memoria cuando el usuario lo pida explícitamente. Eso ayuda a reducir escrituras accidentales. Si amplías el prompt sin cuidado, el modelo puede empezar a persistir notas de poco valor.
Trátalo como memoria de notas duraderas, no como retrieval de conocimiento completo
Este repositorio es ideal para notas operativas cortas, recordatorios e identificadores. Aún no es un sistema completo de generación aumentada con recuperación con embeddings, particionado, búsqueda híbrida o reordenamiento.
Usa Oracle Text cuando los identificadores importen
Para cadenas como IDs de incidencias, números de tickets y referencias de solicitudes de cambio, la recuperación orientada a palabras clave suele ser un mejor punto de partida que la búsqueda semántica. Este ejemplo refleja claramente ese compromiso.
Valida por separado tu base de datos y la configuración de Docker
Las pruebas del proyecto son de integración y se ejecutan con Testcontainers. Si Docker no está disponible, mvn test fallará antes de que se ejecute la lógica del repositorio. Eso es un problema de entorno, no necesariamente un bug de la aplicación.
Las pruebas cubren dos comportamientos importantes:
Las notas se pueden guardar y recuperar a través del repositorio
La salida de las herramientas incluye IDs de memoria y texto relevante de la nota
Empieza simple antes de añadir más funciones de memoria
Un error común en proyectos de agentes es añadir almacenamiento vectorial, historial de conversación, resumen y políticas de retrieval todo a la vez. Este ejemplo propone una mejor secuencia:
1. Define un caso de uso concreto de memoria
2. Expón herramientas explícitas
3. Respalda esas herramientas con almacenamiento duradero
4. Verifica el comportamiento de recuperación
5. Solo entonces valora patrones de memoria más avanzados
Sigue aprendiendo
Si quieres seguir desarrollando habilidades con agentes después de este tutorial, estos recursos de DataCamp son un buen siguiente paso:
Ya has visto cómo crear un agente pequeño pero útil con memoria usando LangChain4j, Java y Oracle AI Database. La idea principal es sencilla: dale al modelo herramientas de memoria explícitas, guarda las notas de forma duradera como JSON y recupéralas con una estrategia de búsqueda directa.
Este diseño es una base sólida porque es fácil de entender y de ampliar. Una vez que este patrón funcione, podrás añadir mejor filtrado, esquemas de notas más ricos, ámbito por usuario o incluso búsqueda vectorial si el caso de uso lo requiere.
Si quieres seguir aprendiendo sobre diseño de agentes, un buen siguiente paso es comparar este patrón de memoria basada en herramientas con frameworks de agentes más amplios y flujos de orquestación. En particular, merece la pena explorar cómo encajan las herramientas explícitas, los patrones de retrieval y los agentes multi‑paso en sistemas de IA más grandes.
FAQs
¿Qué tipo de memoria implementa este tutorial?⌄
Este tutorial implementa memoria duradera basada en herramientas. Las notas se guardan en una tabla de base de datos y se recuperan mediante llamadas explícitas a herramientas, en lugar de adjuntarse automáticamente a la ventana de prompt.
¿Este proyecto usa embeddings vectoriales?⌄
No. Este ejemplo evita a propósito embeddings, búsqueda vectorial y reranking. Usa Oracle Text con json_textcontains para buscar en el contenido de las notas.
¿Por qué usar herramientas para la memoria en lugar de mantener todo en el historial del chat?⌄
La memoria basada en herramientas te da más control sobre qué se guarda, cuándo se guarda y cómo se recupera. Además, funciona mejor para notas duraderas que deben sobrevivir más allá de una sola conversación.
¿Qué necesito para ejecutar la demo en vivo?⌄
Necesitas Java 21 o superior, Maven 3.9 o superior, acceso a Oracle AI Database y una OPENAI_API_KEY en tu shell.
¿Las pruebas necesitan Docker? ⌄
Sí. Las pruebas de integración usan Testcontainers para arrancar Oracle AI Database Free, por lo que Docker debe estar disponible en tu entorno.
Como Developer Evangelist en Oracle, ayudo a desarrolladores a crear aplicaciones modernas: microservicios, sistemas orientados a eventos, arquitecturas cloud‑native y mucho más. Si trabajas con herramientas como Kubernetes, Spring Boot o Kafka y te preguntas cómo encaja Oracle en ese mundo, ahí entro yo.Mi objetivo es compartir guías prácticas y accionables que te permitan desarrollar más rápido, publicar con más seguridad y exprimir al máximo la tecnología de bases de datos de Oracle. Si trabajas con JSON, event streaming, vector search o simplemente estás empezando, estoy aquí para aclarar el camino y hacerlo todo más accesible para desarrolladores.
Aprende a utilizar modelos de IA generativa para crear un editor de imágenes, un chatbot similar a ChatGPT con pocos recursos y una aplicación clasificadora de aprobación de préstamos y a automatizar interacciones PDF y un asistente de voz con GPT.
Un tutorial completo sobre la construcción de agentes LangChain multiherramienta para automatizar tareas en Python utilizando LLMs y modelos de chat utilizando OpenAI.
Aprende a crear una aplicación RAG con Llama 3.1 8B utilizando Ollama y Langchain, configurando el entorno, procesando documentos, creando incrustaciones e integrando un recuperador.
Explore el potencial sin explotar de los grandes modelos lingüísticos con LangChain, un marco Python de código abierto para crear aplicaciones avanzadas de IA.
Aprende a afinar los LLM en conjuntos de datos personalizados, evaluar el rendimiento y exportar y servir modelos sin problemas utilizando el marco de trabajo de bajo/ningún código de LLaMA-Factory.
Una guía completa para afinar un modelo FLAN-T5 para una tarea de respuesta a preguntas utilizando la biblioteca de transformadores, y ejecutando la inferencia optmizada en un escenario del mundo real.
En este tutorial, recorreremos un pequeño módulo de Java que expone herramientas personalizadas, guarda notas como JSON en Oracle AI Database y las recupera con búsqueda de texto completo.
Si estás creando agentes de IA, el historial de chat de corto plazo suele no ser suficiente. Los asistentes reales a menudo necesitan una pequeña cantidad de memoria duradera para guardar hechos importantes y recuperarlos más tarde.
Este tutorial muestra cómo implantar ese patrón con un módulo mínimo en Java. Usarás LangChain4j tools, una interfaz de agente sencilla y Oracle AI Database como almacén subyacente. En lugar de añadir embeddings o una canalización completa de retrieval, este ejemplo mantiene el diseño deliberadamente pequeño: las notas se guardan como documentos JSON y se buscan con
Oracle Text.Al final, entenderás cómo el módulo conecta:
LangChain4j@ToolJDBCpara almacenamiento duradero de notas¿Qué es la memoria basada en herramientas en LangChain4j?
LangChain4jte permite exponer métodos Java ordinarios como herramientas que un modelo puede llamar cuando necesita capacidades externas. En este módulo, esas capacidades están orientadas a la memoria:searchMemories(String question)encuentra notas guardadas relevantesstoreMemory(String note)escribe una nueva nota duraderaEsto es distinto del historial estándar de chat que almacena mensajes en una ventana de contexto en memoria.
La memoria persistente basada en herramientas decide cuándo necesita buscar o guardar notas, y los datos subyacentes viven en una base de datos.
Este patrón es útil cuando quieres que un agente recuerde hechos como notas de incidencias, recordatorios de runbooks o acciones de seguimiento sin construir demasiado pronto un sistema de retrieval más grande.
La memoria persistente respaldada por base de datos también puede ser accedida en paralelo por uno o más agentes sin contención de datos.
La memoria basada en herramientas permite que el asistente recupere notas existentes o guarde nuevas notas en una base de datos duradera.
Funciones clave del módulo LangChain4j y Oracle AI DB
Este ejemplo es pequeño, pero demuestra varias ideas importantes de diseño de agentes.
Herramientas personalizadas de LangChain4j
La clase
MemoryToolsexpone dos métodos anotados con@Tool. Eso significa queLangChain4jpuede ponerlos a disposición del agente sin código envoltorio adicional.Este método hace dos cosas útiles. Delegar la recuperación al repositorio y dar formato a los resultados de forma que el modelo los entienda, por ejemplo
[M12] some note text.Así, la salida de la herramienta es fácil de citar por el agente en su respuesta final.
Memoria duradera en Oracle AI Database
Las notas se almacenan en una tabla
agent_memoriescomo documentos JSON nativos. Cada fila contiene:idmemory_doccreated_atEl módulo inicializa el esquema automáticamente:
Esto mantiene el modelo de almacenamiento simple y, aun así, te da datos estructurados y durabilidad gestionada por la base de datos.
Búsqueda por palabras clave con Oracle Text
El repositorio no genera embeddings. En su lugar, extrae palabras clave de la pregunta del usuario, elimina stop words, construye una expresión de
Oracle TextconACCUMy busca el contenido del documento JSON conjson_textcontains.Esto resulta especialmente útil para identificadores y términos operativos como
CHG2145, donde el ajuste exacto o casi exacto de tokens suele importar más que la similitud semántica.Un flujo mínimo por consola
La clase
Applicationcrea el repositorio, inicializa el esquema, precarga algunas notas, construye el modelo de chat y arranca un bucle en terminal. Así el ejemplo es fácil de ejecutar y de adaptar a otro servicio más adelante.Primeros pasos con tu proyecto de memoria en LangChain4j
Antes de ejecutar el módulo, asegúrate de que tu entorno local cumple los requisitos del proyecto.
Requisitos previos
Necesitas:
OPENAI_API_KEYEl proyecto Maven depende de:
langchain4jlangchain4j-open-aiojdbc11Testcontainerspara pruebas de integraciónEjecuta el ejemplo
Primero, define tu clave de API de OpenAI:
Después, ejecuta la app desde el directorio del proyecto:
La aplicación espera exactamente tres argumentos:
1. URL
JDBC2. Nombre de usuario de la base de datos
3. Contraseña de la base de datos
Si faltan,
Application.main()lanza unIllegalArgumentException. Si faltaOPENAI_API_KEY, lanza unIllegalStateException.Qué ocurre al iniciar
Cuando la app arranca:
1. Crea un
MemoryRepository2. Inicializa el esquema de base de datos
3. Precaega tres notas de ejemplo si la tabla está vacía
4. Construye un
OpenAiChatModel5. Conecta el modelo y las herramientas en
AiServices6. Inicia un bucle CLI que lee entradas hasta que escribes
exitEsto te permite probar la recuperación de memoria de inmediato sin insertar filas a mano primero.
Cómo crear un agente Java con memoria en LangChain4j
Ahora recorramos el módulo en el mismo orden en que lo usa la aplicación.
Define la interfaz del agente
LangChain4jusa una interfaz de Java para describir el contrato del agente. En este proyecto, esa interfaz esMemoryAssistant.Lo importante es el mensaje del sistema. Indica al modelo cuándo usar cada herramienta:
Es un buen ejemplo de política de herramientas ligera. El prompt es breve, pero lo bastante específico para guiar la selección de herramientas.
Expón las operaciones de memoria como herramientas
El agente no habla directamente con el repositorio. En su lugar, llama a la capa
MemoryTools.Este es el método de almacenamiento:
Esto es intencionadamente compacto. Un usuario podría decir:
Si el modelo sigue correctamente el prompt del sistema, llamará a
storeMemory(), el repositorio persistirá la nota y la herramienta devolverá algo como:Más tarde, el usuario puede preguntar:
En ese momento, el agente puede llamar a
searchMemories()y usar la nota devuelta para responder.Crea la capa de repositorio
El repositorio es donde vive la mayor parte de la lógica de memoria duradera. Sigue siendo
JDBCpuro, lo que facilita inspeccionar el diseño.A alto nivel,
MemoryRepositoryse encarga de:Oracle TextLa ruta de inserción normaliza y valida el texto de la nota antes de almacenarlo:
El propio documento JSON tiene este aspecto:
La estructura es simple, pero suficiente para soportar persistencia y búsqueda de texto.
Entiende la estrategia de búsqueda
La parte más interesante del repositorio es el método
search():Este método sigue un flujo práctico:
1. Tokeniza la pregunta del usuario
2. Pasa los tokens a minúsculas
3. Elimina stop words como
the,whatyremember4. Conserva tokens cortos significativos cuando incluyan dígitos
5. Construye una expresión de
Oracle TextconACCUM6. Busca en los datos JSON con
json_textcontainsEse detalle de “se permiten dígitos” es importante. Ayuda a que términos como
CHG2145sobrevivan a la extracción de palabras clave, justo el tipo de búsquedas con identificadores que muchos agentes operativos necesitan.El flujo de búsqueda convierte una pregunta en una expresión de palabras clave y devuelve notas ordenadas por relevancia.
La consulta SQL de búsqueda es:
Si la pregunta no produce palabras clave útiles, el repositorio recurre a notas recientes. Eso da al agente un valor por defecto razonable en lugar de devolver demasiado pronto una búsqueda vacía.
Conecta todo en la aplicación
La aplicación une las piezas con
AiServices.builder():Este es el patrón completo en un solo lugar:
Después de eso, el bucle de consola simplemente pasa la entrada del usuario a
assistant.chat(input).Prueba los prompts de demo
La aplicación imprime algunos prompts de inicio:
Estos prompts son útiles porque ejercitan todo el ciclo de memoria:
Consejos y resolución de problemas
Este módulo es deliberadamente acotado, lo que es una ventaja cuando aprendes el patrón. Aun así, conviene tener presentes algunos detalles prácticos.
Mantén las instrucciones de la herramienta explícitas
El prompt del sistema indica al modelo que solo guarde memoria cuando el usuario lo pida explícitamente. Eso ayuda a reducir escrituras accidentales. Si amplías el prompt sin cuidado, el modelo puede empezar a persistir notas de poco valor.
Trátalo como memoria de notas duraderas, no como retrieval de conocimiento completo
Este repositorio es ideal para notas operativas cortas, recordatorios e identificadores. Aún no es un sistema completo de generación aumentada con recuperación con embeddings, particionado, búsqueda híbrida o reordenamiento.
Usa Oracle Text cuando los identificadores importen
Para cadenas como IDs de incidencias, números de tickets y referencias de solicitudes de cambio, la recuperación orientada a palabras clave suele ser un mejor punto de partida que la búsqueda semántica. Este ejemplo refleja claramente ese compromiso.
Valida por separado tu base de datos y la configuración de Docker
Las pruebas del proyecto son de integración y se ejecutan con
Testcontainers. Si Docker no está disponible,mvn testfallará antes de que se ejecute la lógica del repositorio. Eso es un problema de entorno, no necesariamente un bug de la aplicación.Ejecuta las pruebas con:
Las pruebas cubren dos comportamientos importantes:
Empieza simple antes de añadir más funciones de memoria
Un error común en proyectos de agentes es añadir almacenamiento vectorial, historial de conversación, resumen y políticas de retrieval todo a la vez. Este ejemplo propone una mejor secuencia:
1. Define un caso de uso concreto de memoria
2. Expón herramientas explícitas
3. Respalda esas herramientas con almacenamiento duradero
4. Verifica el comportamiento de recuperación
5. Solo entonces valora patrones de memoria más avanzados
Sigue aprendiendo
Si quieres seguir desarrollando habilidades con agentes después de este tutorial, estos recursos de DataCamp son un buen siguiente paso:
Conclusión
Ya has visto cómo crear un agente pequeño pero útil con memoria usando
LangChain4j, Java y Oracle AI Database. La idea principal es sencilla: dale al modelo herramientas de memoria explícitas, guarda las notas de forma duradera como JSON y recupéralas con una estrategia de búsqueda directa.Este diseño es una base sólida porque es fácil de entender y de ampliar. Una vez que este patrón funcione, podrás añadir mejor filtrado, esquemas de notas más ricos, ámbito por usuario o incluso búsqueda vectorial si el caso de uso lo requiere.
Si quieres seguir aprendiendo sobre diseño de agentes, un buen siguiente paso es comparar este patrón de memoria basada en herramientas con frameworks de agentes más amplios y flujos de orquestación. En particular, merece la pena explorar cómo encajan las herramientas explícitas, los patrones de retrieval y los agentes multi‑paso en sistemas de IA más grandes.