cookbook · Decider 1 · Agent memory with Mem0
Decide what an agent should remember, before Mem0 stores it
Mem0 gives an agent long-term memory, and every message you add runs Mem0's extraction. Most chat turns hold nothing worth keeping: thanks, small talk, a one-off question. This recipe asks Decider 1 one choice question per message (what does it contain?) and only sends preferences, facts, events and instructions to Mem0, tagged with their kind as metadata. Mem0 still does the extraction, merging and search. meraGPT and Mem0 work better together: Decider 1 makes the quick, cheap call on every turn, and Mem0's model only runs on the turns that carry something to remember.
The conversation
Each message went through the recipe once. p(keep) is the probability on the four kinds we keep.
| message | Decider 1 | p(keep) | sent to Mem0 |
|---|---|---|---|
| I'm vegetarian, and I can't stand coriander. | preference | 0.96 | yes |
| Can you check the weather in Lisbon? | request | 0.44 | no |
| My daughter's birthday is on 12 March. | event | 0.96 | yes |
| Thanks, that's all for today! | small_talk | 0.23 | no |
| Please keep restaurant suggestions under 40 euros a head. | preference | 0.78 | yes |
| What's 15% of 80? | request | 0.27 | no |
| We moved to Berlin last month. | fact | 0.97 | yes |
| lol ok | small_talk | 0.48 | no |
Request
POST /v1/systemone, documented in the Decider 1 reference.
curl https://meragpt.com/v1/systemone \
-H "Authorization: Bearer $MERAGPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "decider-1",
"state": {
"message": "I'\''m vegetarian, and I can'\''t stand coriander."
},
"questions": {
"kind": {
"type": "choice",
"instructions": "What does this message from the user contain?",
"criteria": {
"preference": "Something the user likes, dislikes or habitually does.",
"fact": "A lasting fact about the user'\''s life or situation.",
"event": "Something in the user'\''s life that happened or will happen at a particular time.",
"instruction": "How the user wants the assistant to behave from now on.",
"request": "A one-off question or task, with nothing to remember about the user.",
"small_talk": "Greetings, thanks or chit-chat."
}
}
}
}'What came back
The real output from running this recipe, unedited.
{
"answers": {
"kind": {
"type": "choice",
"choice": "preference",
"confidence": 0.8591,
"probabilities": {
"preference": 0.8591,
"fact": 0.0485,
"event": 0.0218,
"instruction": 0.0352,
"request": 0.0218,
"small_talk": 0.0135
}
}
}
}What Mem0 stored
The user's memories after the conversation, as Mem0's extraction wrote them.
- User follows a vegetarian diet and cannot tolerate the taste of coriander (kind: preference)
- User's daughter has a birthday on 12 March (kind: event)
- User prefers restaurant suggestions to cost under 40 euros per person (kind: preference)
- User moved to Berlin around September 2026 (kind: fact)
Python
import os
import requests
from mem0 import MemoryClient
API = "https://meragpt.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['MERAGPT_API_KEY']}"}
mem0 = MemoryClient() # reads MEM0_API_KEY
KEEP = {"preference", "fact", "event", "instruction"}
TRIAGE = {
"kind": {
"type": "choice",
"instructions": "What does this message from the user contain?",
"criteria": {
"preference": "Something the user likes, dislikes or habitually does.",
"fact": "A lasting fact about the user's life or situation.",
"event": "Something in the user's life that happened or will happen at a particular time.",
"instruction": "How the user wants the assistant to behave from now on.",
"request": "A one-off question or task, with nothing to remember about the user.",
"small_talk": "Greetings, thanks or chit-chat.",
},
}
}
def remember(user_id: str, message: str) -> dict:
kind = requests.post(f"{API}/systemone", headers=HEADERS, json={
"model": "decider-1",
"state": {"message": message},
"questions": TRIAGE,
}).json()["answers"]["kind"]
if kind["choice"] in KEEP:
mem0.add([{"role": "user", "content": message}], user_id=user_id, metadata={"kind": kind["choice"]})
return kind
for message in [
"I'm vegetarian, and I can't stand coriander.",
"Thanks, that's all for today!",
]:
kind = remember("user-123", message)
print(kind["choice"], kind["confidence"], message)
TypeScript
import MemoryClient from "mem0ai";
const API = "https://meragpt.com/v1";
const headers = {
Authorization: `Bearer ${process.env.MERAGPT_API_KEY}`,
"Content-Type": "application/json",
};
const mem0 = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
const KEEP = new Set(["preference", "fact", "event", "instruction"]);
const TRIAGE = {
kind: {
type: "choice",
instructions: "What does this message from the user contain?",
criteria: {
preference: "Something the user likes, dislikes or habitually does.",
fact: "A lasting fact about the user's life or situation.",
event: "Something in the user's life that happened or will happen at a particular time.",
instruction: "How the user wants the assistant to behave from now on.",
request: "A one-off question or task, with nothing to remember about the user.",
small_talk: "Greetings, thanks or chit-chat.",
},
},
};
async function remember(userId: string, message: string) {
const r = await fetch(`${API}/systemone`, {
method: "POST",
headers,
body: JSON.stringify({ model: "decider-1", state: { message }, questions: TRIAGE }),
}).then((res) => res.json());
const kind = r.answers.kind;
if (KEEP.has(kind.choice)) {
await mem0.add([{ role: "user", content: message }], { userId, metadata: { kind: kind.choice } });
}
return kind;
}
for (const m of ["I'm vegetarian, and I can't stand coriander.", "Thanks, that's all for today!"]) {
const k = await remember("user-123", m);
console.log(k.choice, k.confidence, m);
}
When to trust it
Gate on the choice, not on one probability. In our run every message worth keeping put 0.78 to 0.97 on the four kinds you keep, and every one-off request or bit of small talk put 0.23 to 0.48 there; 'lol ok' was the closest call, at 0.48. The kind label itself is softer: an instruction about budgets was labelled a preference, and in another run a peanut allergy was too, so use the kind for filtering and display, not as a fact. Asking the same thing as a yes/no question ('is this worth remembering?') did not separate the messages at all, so keep it a choice. We also tried having Decider 1 compare a new message with stored memories (is it a repeat, does it replace an old fact?) and it was not reliable yet, which is why this recipe leaves merging to Mem0.
Try it without code in the playground, or see more Decider 1 recipes: route a support email in one call, act only when the model is sure, flag a phishing email, drop retrieved passages that do not help, hold a reply that promises money, pick an agent's first tool, ask many questions in one call.