GoodMemGoodMem
IntegrationsAgent Frameworks

CAMEL-AI

Expose GoodMem's RAG memory as a CAMEL BaseToolkit so a ChatAgent can store and recall documents.

Stable· Python

Overview

GoodMem is a memory layer for AI agents that handles embedding, vector search, reranking, and LLM-powered answering server-side. This integration packages the GoodMem API as a CAMEL BaseToolkit: drop GoodMemToolkit into a CAMEL ChatAgent and the agent can store and semantically retrieve documents from a GoodMem space alongside its other tools. By default the model sees exactly two tools — goodmem_search and goodmem_remember — while listing, space administration, deletion, and file upload are opt-in constructor settings the developer controls.

Installation

pip install goodmem-camel

The pip package is goodmem-camel; the import name is goodmem_camel. The optional example runner needs OpenAI, installable with pip install goodmem-camel[examples].

Configuration

VariableDescription
GOODMEM_BASE_URLBase URL of your GoodMem server (no /v1 suffix), e.g. https://your-goodmem-server.example.com.
GOODMEM_API_KEYAPI key sent as X-API-Key to authenticate requests.

When both are set, the toolkit needs no connection arguments; the base_url and api_key constructor arguments override them. Everything else is configured on the constructor, notably space_ids (the spaces the toolkit reads from and writes to — the model never chooses a space) and verify_ssl (default True; pass False only for a self-signed dev server).

Quick start

import os

os.environ["GOODMEM_BASE_URL"] = "https://your-goodmem-server.example.com"
os.environ["GOODMEM_API_KEY"] = "gm_xxxxxxxxxxxxxxxxxxxxxxxx"

from camel.agents import ChatAgent
from camel.models import ModelFactory
from camel.types import ModelPlatformType, ModelType

from goodmem_camel import GoodMemToolkit

# One-time setup: pick an embedder and create (or reuse) a space.
setup = GoodMemToolkit()
embedder_id = setup.list_embedders()[0]["embedderId"]
space_id = setup.create_space(name="quickstart", embedder_id=embedder_id)["spaceId"]
setup.close()

# The agent's toolkit is pinned to that space; the model sees only
# goodmem_search and goodmem_remember.
toolkit = GoodMemToolkit(space_ids=[space_id])

agent = ChatAgent(
    system_message=(
        "You are an assistant whose long-term memory lives in GoodMem. "
        "Store facts the user shares, and answer their questions from memory."
    ),
    model=ModelFactory.create(
        model_platform=ModelPlatformType.DEFAULT,
        model_type=ModelType.DEFAULT,
    ),
    tools=toolkit.get_tools(),
)

Local development. The example above uses a TLS-verified production URL. If you are running GoodMem locally with a self-signed certificate, use https://localhost:8080 and disable TLS verification by constructing each toolkit with verify_ssl=False. Keep TLS verification enabled for any deployed server.

Retrieval post-processing

Retrieval post-processing is configured on the GoodMemToolkit constructor, so the developer — never the model — decides what applies. goodmem_search itself takes only query and top_k.

ArgumentTypeDescription
reranker_idUUIDReranker model that reorders matched chunks by relevance. Pass None (not "") for no reranker.
llm_idUUIDGoodMem LLM that generates a grounded answer (abstractReply) alongside the chunks. Pass None (not "") for no LLM. It does not rerank or change scores.
min_scorefloatDrop hits scoring below this value. Applies only to reranker scores, whose scale is provider-dependent (not 0–1); off by default.
metadata_filterdict or expressionServer-side filter every retrieved memory must match: a mapping (an AND of equalities) or an expression built with goodmem_camel.filters.

Every id must be a UUID; anything else — including an empty string — raises GoodMemIdError before any request is made. Each search hit carries chunkId, text, memoryId, spaceId, metadata, and a score oriented so higher is better, with rawScore (exactly what the server sent) and scoreKind ("vector" or "reranker" — the two are not on a common scale) beside it. When a requested reranker fails, the server returns the vector-stage hits (scoreKind: "vector"), the result is marked partial, and statuses carries what the server reported.

Learn more

The full README, examples, and API reference are available on the PyPI package page.