crewai-goodmem
GoodMem knowledge storage and RAG tools for CrewAI.
GoodMem is a self-hostable RAG service that handles
embedding, chunking, storage and retrieval on the server. This package plugs it
into CrewAI two ways: as a knowledge backend for CrewAI's own Knowledge, and
as tools an agent can call directly.
Install
pip install crewai-goodmem
Python 3.11–3.13, CrewAI 1.15+. Runtime dependencies are crewai and the
official goodmem SDK.
Set GOODMEM_BASE_URL and GOODMEM_API_KEY, or pass base_url/api_key, or
inject a configured Goodmem client.
As a knowledge backend
from crewai import Agent, Crew, Task
from crewai.knowledge import Knowledge
from crewai_goodmem import GoodMemKnowledgeStorage
storage = GoodMemKnowledgeStorage(space_id="<space-id>", reranker_id="<reranker-id>")
knowledge = Knowledge(collection_name="handbook", sources=[], storage=storage)
storage.save(["Refunds over $500 need a manager's approval."])
agent = Agent(
role="Support Lead",
goal="Answer policy questions from the handbook.",
backstory="You cite the passage you relied on.",
knowledge=knowledge,
)
As an agent tool
The search tool takes only a query from the model. Which spaces it searches, how many results it returns, whether it reranks and any metadata filter are set by you, so a model cannot redirect the search mid-run.
from crewai_goodmem import GoodMemSearchTool
search = GoodMemSearchTool(
space_ids=["<space-id>"],
k=5,
reranker_id="<reranker-id>", # optional
metadata_filter={"category": "policy"}, # optional, escaped for you
)
agent = Agent(role="Researcher", goal="Answer from the knowledge base",
backstory="You cite sources.", tools=[search])
Results carry partial and statuses. If part of a search failed — a reranker
was unavailable, one space was unreachable — you get the usable passages and
the fact that they are incomplete. A search that produced nothing usable
returns empty results with partial: true and the statuses, so the model can
tell a failed search from a miss; it is never raised. GoodMemKnowledgeStorage
returns a bare list, so in that case it emits a warning and a log line instead.
Tools
| Tool | Purpose |
|---|---|
GoodMemSearchTool |
Semantic search; the model passes only a query |
GoodMemCreateMemoryTool |
Store text; waits for indexing by default |
GoodMemUploadFileTool |
Store a file from a configured upload_dir (opt-in) |
GoodMemGetMemoryTool |
Fetch a memory with readable content |
GoodMemListMemoriesTool / GoodMemDeleteMemoryTool |
Manage memories |
GoodMemListSpacesTool / GoodMemGetSpaceTool |
Find spaces |
GoodMemCreateSpaceTool / GoodMemUpdateSpaceTool / GoodMemDeleteSpaceTool |
Manage spaces |
GoodMemListEmbeddersTool / GoodMemListRerankersTool |
Discover model IDs |
Space, memory and file tools carry the authority of the configured API key. Give them only to crews that need it.
Waiting for indexing
Searching is not a way to wait for a write. GoodMemCreateMemoryTool waits for
its own memory by default; use wait_for_memories(ids) to wait on specific IDs.
Scores
CrewAI's SearchResult.score is documented as higher-is-better. GoodMem's
vector score is a negative inner product — the best match is the lowest
number (a live capture ranked -0.6154 above -0.3873) — so it is negated to
fit that convention; a reranker score already runs the right way and is passed
through. The untouched server value is kept as metadata["raw_score"], and
metadata["score_kind"] ("vector" or "reranker") names the scale.
Neither scale is 0–1. score_threshold is therefore applied only when a
reranker produced the scores; without one it is ignored with a warning.
Even with a reranker, the scale is model-dependent: on the same documents
Voyage rerank-2.5 scored 0.27..0.93 and Jina jina-reranker-v3 scored
-0.14..0.43. CrewAI's default score_threshold=0.6 keeps the top results on
the first and removes everything on the second, so if a threshold drops every
result the storage warns and names the observed range rather than returning a
silent empty list. Calibrate the threshold for the reranker you use.
Development
uv sync --extra dev
uv run ruff check . && uv run ruff format --check . && uv run mypy src
uv run pytest -m "not e2e" # offline, SDK driven over a mock transport
GOODMEM_BASE_URL=… GOODMEM_API_KEY=… GOODMEM_EMBEDDER_ID=… GOODMEM_RERANKER_ID=… GOODMEM_VERIFY_SSL=false uv run pytest -m e2e
GOODMEM_RERANKER_ID is optional — the reranker tests skip without it.
GOODMEM_VERIFY_SSL=false is for a local server with a self-signed certificate.
Apache-2.0.
Release files for crewai-goodmem 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crewai_goodmem-0.2.0.tar.gz | 35.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crewai_goodmem-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.4 kB
Release files / crewai_goodmem-0.2.0.tar.gz
| Download URL | crewai_goodmem-0.2.0.tar.gz |
|---|---|
| Size | 35.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
401d8acf6e317fb5efe4c09bd38c0a0d96fbdfd87abc1cec1ce52eb4527db011
|
|
BLAKE2b-256 checksum How to use checksums |
135269c29edceca14d19a4b3dd984273e759c8f57136341d8c2d8092cd3ba230
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / crewai_goodmem-0.2.0-py3-none-any.whl
| Download URL | crewai_goodmem-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ae7d787f498229f7bfba6791ca8a93cbbf02cccfa37c402a7fe14be815e7f4c1
|
|
BLAKE2b-256 checksum How to use checksums |
63a11fa246af4b554682ad4a4e48657572f3047baad30c160ea874bd98149f0a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency log