NucliaMemory
NucliaMemory is a high-level SDK component that turns any Nuclia Knowledge Box into a personalised, multi-session memory store. It lets you:
- Organise knowledge into resources (discrete memory domains backed by KB resources).
- Attach entries (annotated observations, decisions, or notes) to resources on behalf of specific sessions.
- Automatically extract distilled facts and a knowledge graph from each entry via a background data-augmentation task.
- Recall grounded, personalised answers for any session without mixing up other sessions' context.
All examples assume you have authenticated and set a default Knowledge Box.
Core Concepts
| Concept | Description |
|---|---|
| Resource | A named memory domain stored as a KB resource. It can contain reference documents (policy text, guidelines, etc.) and collects the entries of all sessions. |
| Entry | A timestamped text entry belonging to a resource. It records any content to be remembered. For example, decisions, observations, or conversation transcripts. It may also contain optional reasoning, context messages, and structured metadata. |
| Fact | A short, distilled statement automatically extracted from an entry by the Memory data augmentation task. Facts act as a compressed, searchable index of entries. |
| Graph | An entity–relation graph extracted from both the resource's reference content and a session's entries, giving a personalised knowledge graph view. |
| Global entry | An entry not tied to any specific resource. Stored under a per-session resource. Useful for cross-resource or agent-level memory. |
Initializing Memory
Before using NucliaMemory you must call initialize() once per Knowledge Box. This registers the background task that extracts facts and knowledge graphs from new entries.
from nuclia.sdk.memory import NucliaMemory
memory = NucliaMemory()
memory.initialize()
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
rules | list[str] | None | None | Custom rules for the fact-extraction task (e.g. formatting constraints, additional context, restrictions). |
graph_extraction | bool | None | True | Whether to extract a knowledge graph from the generated facts. |
entity_defs | list[EntityDefinition] | None | None | Custom entity type definitions for the graph extractor. |
examples | list[GraphExtractionExample] | None | None | Few-shot examples to guide graph extraction. |
llm_config | LLMConfig | None | None | Override the LLM used for extraction. |
overwrite | bool | False | If True, replace an existing task configuration with the new one. |
from nuclia_models.worker.proto import LLMConfig
from nuclia.sdk.memory import NucliaMemory
memory = NucliaMemory()
memory.initialize(
rules=[
"Facts must be self-contained and reference the employee ID where available.",
"Do not include personal opinions — only verifiable actions and decisions.",
],
graph_extraction=True,
llm_config=LLMConfig(generative_model="claude-4-6-sonnet")
overwrite=False,
)
CLI
nuclia memory initialize
nuclia memory initialize --rules='["Facts must be objective."]' --graph_extraction=true
Managing Resources
Create a resource
Resources are the named memory domains. Create one before writing entries to it.
resource_id = memory.create_resource(
title="Vacation Policy",
slug="vacation-policy", # optional; auto-generated from title if omitted
summary="Rules governing PTO.", # optional
texts={"policy": "...full policy text..."}, # optional reference documents
)
You can also attach remote URLs or local files as reference content:
memory.create_resource(
title="Employee Handbook",
urls={"handbook": "https://example.com/handbook.pdf"},
)
memory.create_resource(
title="Onboarding Guide",
file_paths={"guide": "/path/to/onboarding.pdf"},
)
Raises ResourceAlreadyExistsError if the slug already exists.
CLI
nuclia memory create_resource --title="Vacation Policy" --slug=vacation-policy
Get a resource
from nuclia.sdk.memory import NucliaMemory, ResourceNotFoundError
memory = NucliaMemory()
try:
resource = memory.get_resource(resource="vacation-policy")
print(resource.id, resource.title, resource.status)
except ResourceNotFoundError:
print("Resource not found")
Resource fields:
| Field | Type | Description |
|---|---|---|
id | str | UUID of the resource. |
slug | str | URL-friendly identifier. |
title | str | Human-readable title. |
summary | str | None | Short description. |
status | str | Processing status ("processed", "pending", "error", …). |
CLI
nuclia memory get_resource --resource=vacation-policy
List resources
page = memory.list_resources(query="policy", page=0, size=10)
print(f"Total resources: {page.total}")
for resource in page.items:
print(f" {resource.slug}: {resource.title}")
ResourcePage fields: items, total, has_more.
CLI
nuclia memory list_resources
nuclia memory list_resources --query=policy --page=0 --size=10
Update a resource
memory.update_resource(
"vacation-policy",
title="PTO & Vacation Policy",
texts={"policy": "...updated text..."},
)
CLI
nuclia memory update_resource vacation-policy --title="PTO & Vacation Policy"
Delete a resource
memory.delete_resource("vacation-policy", confirm=True)
⚠️
confirm=Trueis required. This permanently deletes the resource and all its entries.
CLI
nuclia memory delete_resource vacation-policy --confirm=true
List sessions per resource
Returns the list of session IDs that have at least one entry in a given resource. This is useful for serverless or stateless workloads where you don't keep a local registry of which sessions exist.
sessions = memory.list_sessions(resource="vacation-policy")
print(sessions)
# ["alice-hr", "bob-hr"]
List all sessions with global entries
Omit resource to get every session that has created at least one global (cross-resource) entry:
sessions = memory.list_sessions()
print(sessions)
# ["agent-session-abc123", "agent-session-xyz789", ...]
This call paginates through the KB catalog automatically, so it works correctly even when there are a large number of sessions.
Note: A session ID will only appear in the result if the corresponding field or resource still exists. Users whose entries were fully deleted via
forget_entries()will not be listed.
Error handling
ResourceNotFoundError is raised if the given resource does not exist:
from nuclia.sdk.memory import NucliaMemory, ResourceNotFoundError
memory = NucliaMemory()
try:
sessions = memory.list_sessions(resource="non-existent-resource")
except ResourceNotFoundError:
print("Resource does not exist.")
Async
sessions = await memory.list_sessions(resource="vacation-policy")
sessions = await memory.list_sessions() # global entries
CLI
nuclia memory list_sessions --resource=vacation-policy
nuclia memory list_sessions
Writing Entries
remember() writes a timestamped entry for a session on a resource. The background task automatically distils a fact and updates the knowledge graph.
Resource-scoped entry
from nuclia.sdk.memory import EntryContextMessage, NucliaMemory
memory = NucliaMemory()
memory.remember(
text="Approved carry-over exception for Maria (EMP-1042). "
"She could not use 8 vacation days due to a Q4 product launch.",
resource="vacation-policy",
session_id="alice-hr",
entry_id="alice-entry-001", # optional; random ID used if omitted
reasoning="Business-critical event justified the exception.",
context=[
EntryContextMessage(
author="Maria (employee)",
text="I had 8 days remaining but the Q4 launch prevented me from taking them.",
),
EntryContextMessage(
author="Maria's manager",
text="Confirmed — Maria's presence was essential during the entire Q4 period.",
),
],
metadata={
"employee_id": "EMP-1042",
"department": "Engineering",
"decision": "approved",
"days_requested": 8,
},
)
Raises EntryAlreadyExistsError if an entry with the same entry_id already exists for this session and resource.
Global entry (not tied to a resource)
Omit resource to write a cross-resource or agent-level entry. Each session gets their own dedicated resource for global entries.
memory.remember(
text="User prefers concise, bullet-point answers.",
session_id="agent-session-abc123",
)
CLI
nuclia memory remember \
--text="Approved carry-over for Maria (EMP-1042)" \
--resource=vacation-policy \
--session_id=alice-hr \
--entry_id=alice-entry-001
EntryContextMessage fields
| Field | Type | Description |
|---|---|---|
author | str | Name or role of the message author. |
text | str | Message content. |
Reading Entries and Facts
List entries
Iterate over all entries written in a session for a resource:
for entry in memory.entries(resource="vacation-policy", session_id="alice-hr"):
print(f"[{entry.id}] {entry.timestamp}: {entry.content.text}")
List global entries (omit resource):
for entry in memory.entries(session_id="agent-session-abc123"):
print(entry.content.text)
Pass recent_first=False to get oldest entries first.
Entry fields:
| Field | Type | Description |
|---|---|---|
id | str | Entry identifier. |
timestamp | datetime | UTC creation time. |
content | EntryContent | Structured content: text, reasoning, context, metadata. |
CLI
nuclia memory entries --resource=vacation-policy --session_id=alice-hr
nuclia memory entries --session_id=agent-session-abc123
List extracted facts
After the background task runs, each entry is distilled into one or more short facts:
for fact in memory.facts(resource="vacation-policy", session_id="alice-hr"):
ts = fact.timestamp.strftime("%Y-%m-%d %H:%M")
print(f"[{ts}] {fact.content.text}")
if fact.content.related_entry_ids:
print(f" ← from entries: {fact.content.related_entry_ids}")
Fact fields:
| Field | Type | Description |
|---|---|---|
id | str | Fact identifier. |
timestamp | datetime | UTC extraction time. |
content | FactContent | text, reasoning, related_entry_ids. |
CLI
nuclia memory facts --resource=vacation-policy --session_id=alice-hr
Query the knowledge graph
Retrieve entity –relation paths extracted from the resource content and a session's entries:
edges = memory.graph(resource="vacation-policy", session_id="alice-hr")
for edge in edges:
print(
f"{edge.source.value!r} --{edge.relation.label}--> {edge.destination.value!r}"
)
CLI
nuclia memory graph --resource=vacation-policy --session_id=alice-hr
Querying Memory
Semantic retrieval (recall)
Returns a ranked list of relevant context blocks without generating an answer. Useful when you want to feed context into your own LLM pipeline.
blocks = memory.recall(
question="Has anyone ever approved a carry-over exception?",
resource="vacation-policy",
session_id="alice-hr",
top_k=10,
)
for block in blocks:
print(f"[score={block.score:.3f}] {block.text[:120]}")
Returns: list[RelevantContextBlock]
| Field | Type | Description |
|---|---|---|
id | str | Paragraph identifier. |
text | str | Text of the retrieved block. |
score | float | Relevance score. |
CLI
nuclia memory recall \
--question="Has anyone approved a carry-over exception?" \
--resource=vacation-policy \
--session_id=alice-hr
Generative answer (ask)
Returns a grounded, personalised answer generated by an LLM over the resource and session's facts. This is the primary entry point for building memory-powered assistants.
Internally it builds a request to the /ask endpoint with a filter to only retrieve memories relevant to the provided session and resource
from nuclia.sdk.memory import NucliaMemory
memory = NucliaMemory()
result = memory.ask(
query="Have I ever approved a carry-over exception?",
resource="vacation-policy",
session_id="alice-hr",
)
print(result.answer)
for key, block in result.citations.items():
print(f" [{key}] (score={block.score:.3f}) {block.text[:80]}")
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
query | str | — | Natural-language question. |
resource | str | — | Resource ID or slug to scope the answer to. |
session_id | str | None | None | User whose entries and facts are used for personalisation. |
context | list[ChatContextMessage] | None | None | Prior conversation messages (oldest first) to include as extra context. |
include_global_facts | bool | False | Also include this sessions's global (cross-resource) facts in the context. |
extra_context | list[str] | None | None | Additional free-text snippets to inject into the prompt. |
custom_prompt | CustomPrompt | None | None | Override system, user, and/or rephrase prompt templates. |
ask_request_overrides | dict | None | None | Low-level overrides for the underlying AskRequest. |
Returns: AskResult
| Field | Type | Description |
|---|---|---|
answer | str | Generated answer text. |
citations | dict[str, RelevantContextBlock] | Footnote-keyed map of source paragraphs used in the answer. |
Using a custom prompt
from nucliadb_models.search import CustomPrompt
result = memory.ask(
query="Have I approved any carry-over exceptions this year?",
resource="vacation-policy",
session_id="alice-hr",
custom_prompt=CustomPrompt(
system=(
"You are an HR assistant helping {user_name} recall their own past decisions. "
"All entries in the context were made BY {user_name}. "
"Answer in the second person ('You approved…')."
),
user=(
"Context:\n\n{context}\n\n"
"Answer this question on behalf of {user_name}: {question}"
),
),
)
Maintaining conversation history
Pass previous exchanges to maintain dialogue context across turns:
from nucliadb_models.search import ChatContextMessage
history = [
ChatContextMessage(author="user", text="Tell me about Maria's vacation exception."),
ChatContextMessage(author="assistant", text="Alice approved 8 days for Maria in Q4."),
]
result = memory.ask(
query="What was the reasoning behind that decision?",
resource="vacation-policy",
session_id="alice-hr",
context=history,
)
CLI
nuclia memory ask \
--query="Have I approved a carry-over exception?" \
--resource=vacation-policy \
--session_id=alice-hr
Forgetting
Delete a single entry
Deletes one entry and any facts derived solely from it.
memory.forget_entry(session_id="alice-hr", entry_id="alice-entry-001", resource="vacation-policy")
Omit resource to delete from global entries.
CLI
nuclia memory forget_entry --session_id=alice-hr --entry_id=alice-entry-001 --resource=vacation-policy
Delete all entries for a session on a resource
Deletes all entries in scope and also deletes the corresponding facts for that same scope.
memory.forget_entries(session_id="alice-hr", resource="vacation-policy")
CLI
nuclia memory forget_entries --session_id=alice-hr --resource=vacation-policy
Delete a single fact
memory.forget_fact(session_id="alice-hr", fact_id="fact-xyz", resource="vacation-policy")
CLI
nuclia memory forget_fact --session_id=alice-hr --fact_id=fact-xyz --resource=vacation-policy
Delete all facts for a session on a resource
memory.forget_facts(session_id="alice-hr", resource="vacation-policy")