CrewAI Memory
The native memory backend for CrewAI 1.x: point Memory(storage=...) at MemorySync and your crews get durable, shared, cross-execution memory driven by CrewAI’s own save/recall loop — plus five agent tools and a one-line context helper.
What the integration provides
| Piece | What it does |
|---|---|
MemorySyncStorage | A genuine CrewAI StorageBackend: Memory(storage=MemorySyncStorage(...)) and the crew’s automatic save/recall loop runs against MemorySync instead of local LanceDB files. |
register_memorysync | One-line factory registration, then Memory(storage="memorysync") anywhere in the process. |
| Agent tools | create_memorysync_tools() — five explicit tools (add, search, list, update, delete) that never raise. |
get_crew_context | A prompt-ready recall block for Task descriptions, one line. |
attach_memory_logging | Live logging of CrewAI’s MemorySave/MemoryQuery events for debugging. |
| Concern | Where it lives |
|---|---|
| Crew memory that must survive redeploys and be shared across services | Memory(storage=MemorySyncStorage(...)) — this page. |
| An agent explicitly deciding to store or look something up | The agent tools below. |
| Injecting a user’s history into a task prompt | get_crew_context below. |
Install
pip install crewai-memorysync
Set MEMORYSYNC_API_KEY in the environment, or pass api_key explicitly. Requires crewai 1.x (the unified Memory system) and Python 3.10+. On an older CrewAI the import fails with a sentence naming the fix — never a half-working crew.
The native backend
from crewai import Agent, Crew, Taskfrom crewai.memory import Memoryfrom crewai_memorysync import MemorySyncStoragecrew = Crew(agents=[researcher, writer],tasks=[research_task, write_task],memory=Memory(storage=MemorySyncStorage(user_id="support-crew"),),)crew.kickoff()# Everything the crew remembered is now durable server rows:# it survives redeploys, is shared by every service using this# user_id, and shows up in Memory Explorer.
user_id is the memory owner: one id per crew gives a shared knowledge base; one id per end user gives isolated per-customer memory. Isolation is enforced server-side by the same mechanism that separates customers — never a client-side filter.
Or register it once
from crewai.memory import Memoryfrom crewai_memorysync import register_memorysync# Once at startup:register_memorysync(user_id="support-crew")# Anywhere in the process:memory = Memory(storage="memorysync")
Unknown specs still defer to the built-ins, so registering never breaks storage="lancedb" elsewhere in the process.
What the crew gets back
# You normally never call this yourself — agents recall as they work.# It is shown here so you can verify the loop end to end.matches = memory.recall("what stack does the team use?", depth="shallow")for match in matches:print(match.score, match.record.content, match.record.scope)
CrewAI hands the backend a query *embedding* (it embeds with its own embedder), so scope prefixes, category filters, metadata filters and scores behave exactly like the built-in LanceDB backend — the same 1/(1+distance) score scale, the same ANY-category and ALL-metadata semantics. Records keep their scopes (/agent/researcher), categories, importance, sources and privacy flags through a full round-trip.
Agent memory tools
from crewai import Agentfrom crewai_memorysync import create_memorysync_toolsagent = Agent(role="Personal assistant",goal="Help using what you know about the user",backstory="You remember the user's preferences.",tools=create_memorysync_tools(user_id="customer-7"),)# Untrusted agents: search + list only.create_memorysync_tools(user_id="customer-7", read_only=True)
| Tool | What it does | Failure behaviour |
|---|---|---|
add_memory | Save one durable fact; duplicates answer “already stored”. | Readable error string — never raises. |
search_memory | Semantic search with relevance scores. | Readable error string. |
list_memories | Newest-first listing. | Readable error string. |
update_memory | Change tags/importance. Memory text is immutable. | Readable error string. |
delete_memory | Permanent delete by id, scoped to the configured user. | Readable error string. |
Same names, same behaviour, same response strings as the LangChain tools — an agent moved between frameworks keeps behaving identically, and a tool failure can never abort a task execution.
Context for task descriptions
from crewai import Taskfrom crewai_memorysync import get_crew_contextcontext = get_crew_context("travel preferences", user_id="customer-7")task = Task(description=f"Plan the trip.\nKnown preferences:\n{context}",expected_output="An itinerary honouring every stated preference.",agent=planner,)
Deletion is guarded and honest
storage = MemorySyncStorage(user_id="support-crew")# crew.reset_memories() reaching reset(None) would erase EVERYTHING# this user id owns. Refused by default:storage.reset() # ValueError: ... allow_full_reset ...# Scoped resets always work:storage.reset("/agent/researcher")# Opt in explicitly when a full wipe is really intended:MemorySyncStorage(user_id="support-crew", allow_full_reset=True).reset()
Deletes that remove nothing while matching records exist raise MemorySyncDeleteRefusedError — the common cause is a delete-restricted evaluation key. For a crew handling personal data, a silently unfulfilled erasure would be the worst possible failure, so it is loud by design.
Public API
| Export | Kind | Notes |
|---|---|---|
MemorySyncStorage | StorageBackend | The full protocol: save, search, delete, update, get_record, list_records, scopes, categories, count, reset + async twins. |
register_memorysync / unregister_memorysync | Factory registration | Memory(storage="memorysync") after one call. |
create_memorysync_tools | Tool factory | Five CrewAI BaseTools; read_only=True returns search + list. |
get_crew_context | Helper | Prompt-ready recall block, "" for a new user. |
attach_memory_logging | Observability | Logs MemorySave*/MemoryQuery* events from CrewAI’s event bus. |
MemorySyncDeleteRefusedError | Exception | A delete removed nothing although matches exist. |
Supported versions
| Package | Registry | Requires | Runtime |
|---|---|---|---|
crewai-memorysync 1.0.0 | PyPI | crewai >=1.0 <2 | Python 3.10+ |
The CI suite runs the full protocol-conformance tests — including a real Memory(storage=...) save/recall cycle — against the latest crewai 1.x on every run, so a protocol change in a new CrewAI release fails our pipeline before it can fail your crew.