How to Implement Customer Memory with Privacy
Before You Start
Determine which privacy regulations apply to your customers. If you serve EU residents, GDPR applies regardless of where your company is located. If you serve California residents, CCPA applies. Most other jurisdictions have similar data protection laws with varying specifics. The controls in this guide satisfy the strictest common requirements across these regulations, so implementing all five steps provides broad compliance coverage.
Step-by-Step Implementation
Not everything a customer says in a support conversation should be stored in memory. Data minimization, a core GDPR principle, requires you to store only what is necessary for the purpose of improving service quality. Create an explicit classification that defines what goes into memory and what gets discarded after the conversation ends.
MEMORY_CLASSIFICATION = {
"store": {
"product_preferences": "Which features the customer uses",
"technical_environment": "Tech stack and infrastructure",
"communication_preferences": "How they prefer to interact",
"issue_history": "Summary of past issues and resolutions",
"account_context": "Plan type, usage patterns"
},
"exclude": {
"payment_details": "Credit card numbers, bank accounts",
"passwords_credentials": "Any authentication secrets",
"personal_identifiers": "SSN, government IDs, dates of birth",
"health_information": "Medical conditions, treatments",
"off_topic_personal": "Family details, political views",
"raw_transcripts": "Full conversation text (store summaries)"
}
}Implement the exclusion list as a pre-storage filter that scans memory content before it is written. Use pattern matching for structured data (credit card numbers, SSNs) and content classification for unstructured data (personal opinions, health information). The filter should err on the side of excluding rather than storing, because data that is never stored cannot be leaked, requested for deletion, or create compliance exposure.
Before storing customer memories, obtain consent that meets regulatory requirements. The consent must be informed (the customer understands what is being stored and why), specific (consent covers the specific purposes you intend to use memory for), freely given (the customer can decline without losing access to support), and recorded (you can demonstrate when and how consent was obtained).
def check_memory_consent(customer_id):
consent = get_consent_record(customer_id)
if consent is None:
# First interaction, request consent
return request_consent(customer_id)
if consent['status'] == 'granted':
return True
if consent['status'] == 'declined':
return False # Do not store memories
if consent['status'] == 'partial':
return consent['allowed_categories']
def request_consent(customer_id):
# Present consent notice during first interaction
notice = (
"I can remember details from our conversations to "
"provide better support in the future, like your "
"technical setup and past issues. You can change "
"this preference or delete stored information any "
"time. Would you like me to remember our interactions?"
)
return present_consent_choice(customer_id, notice)Store consent records separately from customer memories so that deleting a customer's memories does not delete the record of their consent (or refusal). You need to prove what consent was given even after the data it authorized has been deleted. Update the consent timestamp whenever the customer modifies their preferences, and periodically re-confirm consent for customers who have not interacted in more than 12 months.
Every stored memory should have a time-to-live (TTL) that determines when it expires. Retention limits serve two purposes: they enforce the data minimization principle by removing data that is no longer necessary, and they reduce the risk surface by limiting how much historical data exists at any point. Different memory categories may have different retention periods based on their utility and sensitivity.
RETENTION_POLICIES = {
"episodic": {
"ttl_days": 180,
"description": "Specific interaction records"
},
"semantic": {
"ttl_days": 365,
"description": "Factual customer knowledge"
},
"preference": {
"ttl_days": 365,
"description": "Communication and product preferences"
},
"consolidated": {
"ttl_days": 730,
"description": "Merged summaries from consolidation"
}
}
def store_with_retention(memory, category):
policy = RETENTION_POLICIES[category]
memory['metadata']['expires_at'] = (
datetime.now() + timedelta(days=policy['ttl_days'])
).isoformat()
memory_api.store(memory)Run an expiration job daily that identifies and deletes memories past their TTL. The expiration process must be the same as a customer deletion request: remove the content, the embeddings, the graph connections, and any cached references. Expired memories should not linger in backup systems or replicas beyond your backup retention period.
Customers must be able to see what the AI remembers about them and delete any or all of it. This satisfies the right to access and right to erasure under GDPR, and similar rights under CCPA and other regulations. Build a self-service interface, either in your customer portal or through the support bot itself, that lets customers view their memory profile, delete specific memories, and delete their entire memory profile.
# Customer-facing memory management endpoint
@app.route('/api/customer/memories', methods=['GET'])
def list_customer_memories(customer_id):
memories = memory_api.recall(
query="*",
filter={"customer_id": customer_id},
limit=100
)
return sanitize_for_display(memories)
@app.route('/api/customer/memories/', methods=['DELETE'])
def delete_customer_memory(customer_id, memory_id):
memory = memory_api.get(memory_id)
if memory['metadata']['customer_id'] != customer_id:
return error(403, "Not your memory")
memory_api.forget(memory_id)
audit_log.record("customer_deletion", customer_id, memory_id)
return success("Memory deleted")
@app.route('/api/customer/memories/all', methods=['DELETE'])
def delete_all_customer_memories(customer_id):
memory_api.forget_all(filter={"customer_id": customer_id})
audit_log.record("full_erasure", customer_id)
return success("All memories deleted") The display format matters. Show customers their memories in plain language, not raw JSON or technical metadata. If a memory says "Customer uses Python 3.11 with FastAPI on AWS ECS," display it as "We remember that you use Python 3.11 with FastAPI on AWS." Customers should be able to understand what the AI knows about them without technical expertise.
When a customer requests deletion, the erasure must be complete. This means removing the memory text content, the vector embedding generated from that content, any knowledge graph nodes and edges that reference the memory, any cached retrieval results that include the memory, and any consolidated memories that incorporated the deleted memory's content. Partial deletion, where the text is removed but the embedding remains searchable, does not satisfy GDPR requirements.
def complete_erasure(customer_id, memory_id=None):
if memory_id:
memories_to_delete = [memory_api.get(memory_id)]
else:
memories_to_delete = memory_api.list_all(
filter={"customer_id": customer_id}
)
for memory in memories_to_delete:
# Remove vector embedding from index
vector_store.delete(memory['embedding_id'])
# Remove knowledge graph connections
graph.delete_edges_for(memory['id'])
graph.cleanup_orphan_nodes(customer_id)
# Remove from memory store
memory_api.delete(memory['id'])
# Invalidate any cached results containing this memory
cache.invalidate_containing(memory['id'])
# Log the erasure (but not the deleted content)
audit_log.record("erasure_complete", customer_id,
count=len(memories_to_delete))Test the completeness of erasure by attempting to retrieve the deleted memory through every access path: direct ID lookup, vector similarity search, graph traversal, and keyword search. If any path returns the deleted memory or information derived from it, the erasure is incomplete. This testing should be part of your compliance verification process, not just your development testing.
Handling Edge Cases
Customers who decline memory consent still deserve good support. Your system must function without memory, falling back to stateless operation for customers who opt out. Do not penalize customers who decline memory by providing noticeably worse service. The quality difference should come from convenience (not having to repeat context), not from the AI being unable to help.
When a customer who previously consented withdraws consent, treat it as a full deletion request. Delete all stored memories and stop storing new ones. Do not retain memories in a "suspended" state hoping the customer will re-consent. Withdrawn consent means the data should no longer exist.
Build customer memory that respects privacy by design. Adaptive Recall includes consent tracking, retention policies, and complete erasure out of the box.
Get Started Free