Short answer: A group is the configuration bundle that maps one use case to one processing path—topics plus a pipeline—so different agents do not share extraction rules or memory pools.
A group holds the topics that decide what gets extracted and the pipeline that decides how raw input becomes stored memories. Most projects start with default; when you outgrow that, named groups keep personalization, continual learning, and product-specific agents from sharing the same rules or pool. Think of a group as the unit of memory configuration, not a folder invented after the fact. Separate groups let Product A and Product B reuse topic names like known_issues while keeping stores and descriptions independent. Pipeline differences are another hard reason to split. Route writes and searches with the group parameter; agents choose the group that matches the product in context. If retrieval mixes facts from different jobs, split groups; if the only problem is kinds of facts inside one job, refine topics instead.
A group in Weaviate Engram is the configuration bundle that maps one use case to one processing path. It holds the topics that decide what gets extracted and the pipeline that decides how raw input becomes stored memories. Most projects start with a single group named default. When you outgrow that, you add named groups so personalization, continual learning, and product-specific agents do not share the same extraction rules or the same memory pool. This chapter explains what a group provides, when the default is enough, when to split, how topic names stay isolated across groups, and how the group parameter routes both writes and searches.
Think of a group as the unit of memory configuration, not as a folder you invent after the fact. Memories still carry their own ids, content, topics, and scopes. The group is the envelope those memories were processed under. Change the group and you change which topic descriptions the pipeline reads and which pipeline steps run. That is why Engram treats one group as one use case.
What does a group actually contain?
After you store a few memories, the natural question is where the extraction rules live. They live on the group. A group gives you a stable identifier for a pipeline configuration, a set of topic definitions, and the pipeline steps that turn string, conversation, or pre-extracted input into committed memories. Topics answer “what should we remember.” The pipeline answers “how should we process it.” The group binds those two answers together so every request that names the group gets the same contract.
That binding matters at request time. When you call client.memories.add or client.memories.search, Engram routes the work through the named group. Omit the parameter and you hit default. Pass another name and you hit that group’s topics and pipeline instead. You do not re-declare topics on every write. You select the bundle that already owns them.
Groups also give topic name isolation. Two groups can each define a topic called user_preferences without colliding. That is useful when separate agents or product lines need the same label with different descriptions or scopes. Isolation between groups is enforced with multi-tenancy under the hood, so memories from one use case do not bleed into another during search.
When is the default group enough?
Knowing what a group holds raises a practical question: do you need more than one? Often you do not. Creating a project provisions a group named default. Templates may seed it with starter topics. The Personalization template, for example, seeds UserKnowledge. For a single agent with one extraction profile, keep writing and searching against default and move on. Extra groups add operational surface area. You should earn them with a real split in use case.
The default path keeps the API quiet. Your add and search calls can omit group entirely and still land in the right place. That is the right starting shape for prototypes, single-product assistants, and any app where one set of topic descriptions covers everything you care about extracting. Grow the topic list inside the group before you invent a second group. Split only when the use cases disagree about what to extract or how to process it.
Scoping still lives on topics, not on the group as a whole. One group can mix user-scoped topics and project-wide topics. A support agent might keep per-user preferences and shared resolution playbooks in the same group if they share one pipeline and one extraction vocabulary. The group boundary is about configuration identity, not about forcing every topic to share the same scope.
When should you create additional groups?
So when does one bundle stop being enough? Create another group when two use cases need different topic definitions or different pipeline configurations. A classic split is personalization versus continual learning. Personalization topics are usually user-scoped. Continual learning topics are often project-wide. They answer different questions for the agent. Searching them together as one mixed pool can confuse retrieval and muddy extraction prompts.
Multi-product teams hit the same fork. Product A and Product B may both want a known_issues topic. They should not share one description or one memory store. Separate groups let each product team tune extraction independently while reusing the same topic names. The agent then searches the group that matches the product in context. That keeps Product A’s known issues out of Product B’s answers without renaming every topic.
Pipeline differences are another hard reason to split. Configurable pipelines are available on enterprise plans. If one use case needs a simple extract-transform-commit path and another needs buffering for daily aggregates, those are different pipeline DAGs. Bundling them as separate groups keeps each run’s behavior predictable. You select the group that owns the DAG you intend to run.
How do you route writes and searches to a named group?
Once you decide to split, the next question is how the client expresses that choice. Engram’s Python SDK takes a group string on both add and search. The same name must be used on both paths if you want writes to be findable later. Hybrid retrieval still works inside a group. Topic filters still narrow within that group. The group parameter is the outer selector.
Here is a clockmaker’s shop assistant that keeps client-facing timing notes separate from shop-wide repair methods. Client notes go to client_timing. Shop methods go to shop_methods. Both groups can define overlapping topic names without colliding. The bench id scopes the personalization side.
import os
from engram import EngramClient, HybridRetrieval
client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])
bench = "escapement-bench-2"
client_run = client.memories.add(
"Bench 2 timed a new Breguet overcoil spring for case 1847. "
"Owner wants the beat error under 0.4 ms before delivery. "
"Do not oil the escape wheel again this visit.",
user_id=bench,
group="client_timing",
)
client.runs.wait(client_run.run_id)
playbook_run = client.memories.add(
"For Swiss lever escapements after a full clean, verify lock before amplitude. "
"If amplitude is low with good lock, check the pallet stone seating before adding oil.",
group="shop_methods",
)
client.runs.wait(playbook_run.run_id)
prefs = client.memories.search(
query="beat error target and oiling notes for case 1847",
user_id=bench,
group="client_timing",
retrieval_config=HybridRetrieval(limit=5),
)
methods = client.memories.search(
query="low amplitude after clean with good lock",
group="shop_methods",
retrieval_config=HybridRetrieval(limit=5),
)
assert any("0.4 ms" in m.content or "1847" in m.content for m in prefs)
assert any("pallet" in m.content.lower() or "lock" in m.content.lower() for m in methods)
Notice the second write omits user_id. That matches a project-wide topic inside shop_methods. The first write requires user_id because those topics are user-scoped. The group name is what keeps the two stores apart. Searching client_timing will not return the pallet-stone playbook, and searching shop_methods will not return the private beat-error target for case 1847.
How should agents choose a group at runtime?
After you can route traffic, the remaining design question is selection logic. Agents should treat the group name as part of the request context, the same way they treat user_id. If the ticket is about a specific customer, search the personalization group with that customer’s id. If the ticket is about how the team resolves a class of problem, search the continual-learning group. Do not merge those result sets blindly unless the prompt explicitly needs both and you can label which memory came from where.
In practice, many apps keep a small map from feature area to group name. A chat path that personalizes replies points at one group. A background job that digests resolved tickets into shared methods points at another. That map is application configuration. Engram stores the groups. Your code decides which name to pass. Keeping the map small reduces the chance of writing to one group and searching another by accident.
When in doubt, start with default and measure confusion. If retrieval regularly mixes facts that belong to different jobs, or if extraction prompts pull the wrong kind of content, that is evidence for a second group. If the only problem is sorting kinds of facts inside one job, add or refine topics instead. Groups are the coarse boundary. Topics are the fine one.
Our next chapter, What are topics in Engram?, goes inside the group to the categories that steer extraction. You will see how topic names, descriptions, scoping, and bounded topics shape what the pipeline keeps and what it ignores.