Causal Reasoning
intermediateAsk 'what if?' and 'why?' to your memories. Engramma builds causal relationships between facts and lets you query them.
Beyond correlation
Most memory systems tell you what is similar. Engramma tells you why things are connected and what would happen if something changed.
This is the difference between "these two facts are related" and "this fact caused that outcome." Engramma builds and maintains a causal graph across your memories, exposed through dedicated /v1/memory/causal/* endpoints.
Three levels of causal queries
Engramma supports three levels of causal reasoning, inspired by Judea Pearl's causal ladder:
Level 1: Association
"What is related to X?"
At this level you ask about the strength and direction of the relationship between two memories. Engramma goes beyond simple similarity — it measures asymmetric causal strength and detects confounders.
import requests
BASE = "https://api.engramma.dev"
HEADERS = {"Authorization": "Bearer <YOUR_KEY>", "Content-Type": "application/json"}
# Level 1: Measure causal strength between two memories
resp = requests.post(
f"{BASE}/v1/memory/causal/strength",
headers=HEADERS,
json={
"text_a": "Memory limits set too low",
"text_b": "OOM crashes during deployment"
}
)
result = resp.json()
print(result)
# {
# "strength_a_to_b": 0.78,
# "strength_b_to_a": 0.12,
# "direction": "a_to_b",
# "observations_a_to_b": 15,
# "observations_b_to_a": 3,
# "confounded": false
# }You can also pass raw embedding vectors instead of text:
resp = requests.post(
f"{BASE}/v1/memory/causal/strength",
headers=HEADERS,
json={
"pattern_a": [0.12, -0.45, ...], # pre-computed embedding
"pattern_b": [0.33, 0.71, ...]
}
)
Level 2: Intervention
"What happens if I do X?"
This goes beyond correlation. The /causal/intervene endpoint reasons about the downstream effects of an action based on stored causal relationships.
import requests
BASE = "https://api.engramma.dev"
HEADERS = {"Authorization": "Bearer <YOUR_KEY>", "Content-Type": "application/json"}
# Level 2: Intervention — predict downstream effects
resp = requests.post(
f"{BASE}/v1/memory/causal/intervene",
headers=HEADERS,
json={
"text": "Increase memory limits to 4GB"
}
)
result = resp.json()
print(result)
# {
# "predicted_effects": [
# {
# "effect_key": [0.33, 0.71, ...],
# "predicted_value": [0.55, -0.12, ...],
# "causal_strength": 0.78
# },
# {
# "effect_key": [0.21, 0.44, ...],
# "predicted_value": [0.60, -0.08, ...],
# "causal_strength": 0.65
# }
# ]
# }You can also intervene using raw embeddings by passing cause_key and cause_value instead of text:
resp = requests.post(
f"{BASE}/v1/memory/causal/intervene",
headers=HEADERS,
json={
"cause_key": [0.12, -0.45, ...],
"cause_value": [0.88, 0.23, ...]
}
)
Level 3: Counterfactual
"Would Y have happened if X hadn't occurred?"
The most powerful level. The /causal/counterfactual endpoint reasons about alternative histories using the causal graph.
import requests
BASE = "https://api.engramma.dev"
HEADERS = {"Authorization": "Bearer <YOUR_KEY>", "Content-Type": "application/json"}
# Level 3: Counterfactual — reason about alternative histories
resp = requests.post(
f"{BASE}/v1/memory/causal/counterfactual",
headers=HEADERS,
json={
"text_cause": "Memory limits set too low",
"text_effect": "PagerDuty alerts fired during deploy",
"text_counterfactual": "Memory limits were already increased to 4GB"
}
)
result = resp.json()
print(result)
# {
# "counterfactual_effect": [0.11, -0.03, ...],
# "computable": true
# }
# computable=true means the causal graph has enough structure
# to reason about this counterfactual. The counterfactual_effect
# embedding represents what the effect would have looked like.When computable is false, it means the causal graph lacks sufficient evidence to reason about the counterfactual. Store more related memories and allow consolidation cycles to run.
How causal links form
You don't need to explicitly tell Engramma which facts are causally related. The engine discovers causal relationships automatically:
- Temporal co-occurrence — Facts stored close in time are candidates for causal links
- Semantic direction — "X causes Y" patterns are detected in stored text
- Retrieval patterns — If querying A frequently leads to accessing B, a link strengthens
- Consolidation — During sleep cycles, weak causal links are pruned and strong ones are reinforced
Causal discovery improves over time. The more memories you store and retrieve, the better the causal graph becomes. This is one reason consolidation cycles matter.
Querying the causal graph
Causal direction
Determine whether A causes B or B causes A, with a confidence score:
import requests
BASE = "https://api.engramma.dev"
HEADERS = {"Authorization": "Bearer <YOUR_KEY>", "Content-Type": "application/json"}
resp = requests.post(
f"{BASE}/v1/memory/causal/direction",
headers=HEADERS,
json={
"text_a": "Code changes without tests",
"text_b": "Deployment failures"
}
)
result = resp.json()
print(result)
# {
# "direction": "a_causes_b",
# "confidence": 0.87,
# "confounded": false,
# "details": {
# "displacement_consistency": 0.92
# }
# }Causal neighbors
Find upstream causes (parents) and downstream effects (children) of a memory:
import requests
BASE = "https://api.engramma.dev"
HEADERS = {"Authorization": "Bearer <YOUR_KEY>", "Content-Type": "application/json"}
resp = requests.post(
f"{BASE}/v1/memory/causal/neighbors",
headers=HEADERS,
json={
"text": "Deployment failures",
"direction": "both",
"min_strength": 0.3
}
)
result = resp.json()
print(result)
# {
# "parents": [
# {"key": [0.44, -0.21, ...], "strength": 0.82},
# {"key": [0.15, 0.67, ...], "strength": 0.76}
# ],
# "children": [
# {"key": [0.33, 0.12, ...], "strength": 0.91},
# {"key": [0.28, -0.55, ...], "strength": 0.65}
# ]
# }
# parents = upstream causes (what leads to deployment failures)
# children = downstream effects (what deployment failures cause)The direction parameter controls which neighbors are returned:
"both"— return both parents and children"parents"— only upstream causes"children"— only downstream effects
Structure discovery
For a broader view of the causal graph, use the structure endpoints:
# Discover the full causal DAG
resp = requests.post(
f"{BASE}/v1/memory/structure/discover",
headers=HEADERS,
json={}
)
# Get the causal graph structure
resp = requests.post(
f"{BASE}/v1/memory/structure/graph",
headers=HEADERS,
json={}
)
Real-world use cases
| Use case | How causal reasoning helps |
|---|---|
| Incident response | Use /causal/neighbors to trace upstream causes of an outage |
| Impact analysis | Use /causal/intervene to predict effects of a proposed change |
| Root cause analysis | Use /causal/direction to confirm whether A truly causes B |
| Decision support | Use /causal/counterfactual to evaluate "what if we had done X?" |
Causal strength
Each causal link has a strength score (0-1) that indicates how reliably A leads to B:
- Strong (> 0.8): Near-certain causal relationship. "Memory exhaustion causes OOM crashes."
- Moderate (0.5-0.8): Likely causal but with exceptions. "Late deployments correlate with incidents."
- Weak (< 0.5): Possible relationship, needs more evidence. May be pruned during consolidation.
The confounded field in responses indicates whether the engine has detected a potential confounder — a third variable that may be causing both A and B. When confounded: true, interpret the causal strength with caution.
Causal links strengthen every time the relationship is observed and weaken when evidence contradicts them. Store contradicting facts to update the causal graph — Engramma handles belief revision automatically.
Limitations
Causal reasoning is powerful but has boundaries:
- Not a knowledge graph — Engramma doesn't store explicit RDF triples. Causal links are learned, not declared.
- Requires evidence — At least 2-3 related facts are needed before causal links form reliably.
- Temporal scope — Very old causal links may weaken if never reinforced (by design — the world changes).
- Correlation risk — Strong correlations may appear as causal links that aren't truly causal. Check the
confoundedfield and use/causal/directionto validate.
Next steps
- Consolidation — How causal links strengthen during sleep cycles
- Explainability — Inspect the reasoning chain behind any result
- Causal Queries Guide — Hands-on tutorial for intervention and counterfactual queries