Skip to main content
Go to documentation:
⌘U
Weaviate Database

Develop AI applications using Weaviate's APIs and tools

Deploy

Deploy, configure, and maintain Weaviate Database

Query Agent

Run agentic search over your Weaviate Cloud collections

Weaviate Cloud

Manage and scale Weaviate in the cloud

Engram

Persistent memory for LLM agents and applications

Additional resources

Integrations
Contributor guide
Events & Workshops
Weaviate Academy

Need help?

Weaviate LogoAsk AI Assistant⌘K
Community Forum

Store memories

Engram supports three content types for storing memories. Each content type is a different entrypoint into the same pipeline.

All examples below use a connected client

See Connect to Engram for how to instantiate one.

import os
from engram import EngramClient

client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])

String content

Send raw text and let Engram extract structured memories from it.

run = client.memories.add(
"The user prefers dark mode and works primarily in Python. They are building a RAG application.",
user_id=test_user_id,
group="default",
)

print(run.run_id)
print(run.status)

The pipeline extracts individual facts from the text (e.g. "prefers dark mode", "works in Python") and stores them as separate memories.

Conversation content

Send multi-turn messages and let Engram extract memories from the dialogue. You can send new messages as they happen — there is no need to wait until a conversation is finished.

run = client.memories.add(
[
{"role": "user", "content": "I just moved to Berlin and I am looking for a good coffee shop."},
{"role": "assistant", "content": "Welcome to Berlin! Here are some popular coffee shops in the city..."},
{"role": "user", "content": "I prefer specialty coffee, not chains."},
],
user_id=test_user_id,
group="default",
)

print(run.run_id)
print(run.status)

The pipeline reads the messages and extracts relevant facts (e.g. "lives in Berlin", "prefers specialty coffee").

Pre-extracted content

If you've already extracted structured content, send it directly. This bypasses the LLM extraction step, but the content still passes through the transform and commit pipeline stages.

run = client.memories.add(
PreExtractedInput(items=[
PreExtractedItem(content="User prefers dark mode", topic="UserKnowledge"),
PreExtractedItem(content="User works in Python", topic="UserKnowledge"),
]),
user_id=test_user_id,
group="default",
)

print(run.run_id)
print(run.status)

Response

All three content types return the same response format:

{
"run_id": "run-uuid",
"status": "running"
}

A successful response means the pipeline has started, not that the memories have been committed. In most cases you don't need to do anything else, since memories become available once the pipeline finishes. If you have a specific reason to confirm completion, you can use the run_id to check the pipeline status.

Optional parameters

ParameterTypeDescription
user_idstringScope the memory to a specific user. Required if the target topic is user-scoped.
propertiesobject<string, string>Custom scope properties (e.g. {"conversation_id": "abc-123"}). Must include every key any target topic is scoped by.
groupstringMemory group name (defaults to default)
rootstringPipeline root name (for advanced pipeline configurations)
info

Which parameters are required depends on the topic's scoping configuration, not the content type. If a topic is user-scoped, you must include user_id. If a topic is scoped by a custom property (e.g. conversation_id), pass it in properties. These scoping parameters apply equally to all three content types.

Questions and feedback

If you have any questions or feedback, let us know in the user forum.