GoodMemGoodMem
IntegrationsAgent Frameworks

Spring AI

Plug GoodMem's RAG memory into Spring AI as a DocumentRetriever for RAG pipelines, plus agent tools for search, administration, and file uploads.

Stable· Java (Maven/Gradle)

Overview

GoodMem is a retrieval-augmented generation (RAG) memory layer that chunks, embeds, and indexes documents server-side so an agent can pull back the most relevant passages on any question. The Spring AI connector plugs that in three ways: GoodMemDocumentRetriever, a Spring AI DocumentRetriever for RetrievalAugmentationAdvisor and any RAG pipeline that takes one; GoodMemSearchTool, a single @Tool an agent can call with a query; and GoodMemAdminTools plus GoodMemUploadTool for agents that are meant to administer GoodMem — with optional reranking and an LLM-generated answer on retrieval.

Installation

<dependency>
    <groupId>io.github.bashareid</groupId>
    <artifactId>goodmem-spring-ai</artifactId>
    <version>0.3.0</version>
</dependency>

Requires Java 21+ (the GoodMem Java SDK is compiled for 21), Spring AI 1.0.0 (spring-ai-model and spring-ai-rag are provided — your application already has them), and a running GoodMem server. Use 0.2.2 or later; llmId needs 0.3.0. The artifact is published on Maven Central under a personal groupId (io.github.bashareid), which may change.

Configuration

Connection settings are configured in code through GoodMemConnection.builder():

SettingDefaultDescription
baseUrl—Required. Base URL of the GoodMem API server.
apiKey—Required. Sent as the x-api-key header, never in a URL or log.
timeout30sPer-request timeout.
verifySsltruefalse disables certificate checks for this connection only — for a local self-signed server, never production.

You can also hand in an SDK client you configured yourself with GoodMemConnection.of(goodmemClient).

Quick start

import ai.pairsys.goodmem.springai.GoodMemConnection;
import ai.pairsys.goodmem.springai.GoodMemDocumentRetriever;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor;

GoodMemConnection connection = GoodMemConnection.builder()
    .baseUrl(System.getenv("GOODMEM_BASE_URL"))
    .apiKey(System.getenv("GOODMEM_API_KEY"))
    .build();

GoodMemDocumentRetriever retriever = GoodMemDocumentRetriever.builder()
    .connection(connection)
    .spaceId("your-space-uuid")   // the developer decides what is searched
    .topK(5)
    .build();

String answer = ChatClient.builder(chatModel).build()
    .prompt()
    .advisors(RetrievalAugmentationAdvisor.builder().documentRetriever(retriever).build())
    .user("When does payroll run?")
    .call()
    .content();

To let an agent search on demand instead, register new GoodMemSearchTool(retriever) with .tools(...); the model supplies only query and optionally topK, while spaces, filters, the reranker, and the LLM stay with the developer. Incomplete results are reported, never hidden: server-reported problems come back with goodmem_partial=true and the statuses instead of failing the call, and every id argument must be a UUID — anything else is refused before a request is sent.

Local development. The example above assumes a TLS-verified server URL. If you are running GoodMem locally with a self-signed certificate, use https://localhost:8080 and set verifySsl(false) on the connection builder — it disables certificate checks for that connection only. Keep TLS verification enabled for any deployed server.

Retrieval post-processing

GoodMem's retrieval call accepts these optional post-processing parameters (each framework exposes them under its own naming convention):

ParameterRangeDescription
reranker_idUUIDReranker model that reorders matched chunks by relevance.
llm_idUUIDLLM that generates a contextual answer (abstractReply) alongside the chunks.
relevance_threshold0–1Minimum relevance score for a result to be included.
llm_temperature0–2Sampling temperature for the LLM post-processor.
max_resultsintegerMaximum number of results to return.
chronological_resortbooleanRe-sort the final results by creation time instead of relevance.

The Spring AI connector exposes reranking and LLM answers as the developer-set rerankerId and llmId retriever settings, the result count as topK, and metadata filters through GoodMemFilters. It sets no relevance threshold of its own — reranker score ranges are provider-dependent, so apply a threshold with a DocumentPostProcessor only to documents whose goodmem_score_kind is reranker.

Learn more

The full README, examples, and API reference live in the upstream repository: PAIR-Systems-Inc/goodmem-spring-ai.