31 KiB
31 KiB
In [1]:
%pip install -q mem0aiNote: you may need to restart the kernel to use updated packages.
In [2]:
import json
import os
import time
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "YOUR_MEM0_API_KEY"
client = MemoryClient()
ADJUSTER_SARAH = "adjuster_sarah_cookbook_demo"
ADJUSTER_MARCUS = "adjuster_marcus_cookbook_demo"
CLAIM_AGENT = "claims_agent_clm48211_cookbook_demo"In [3]:
project_snapshot = client.project.get(fields=["custom_instructions", "agent_custom_instructions"])
print("had custom_instructions:", bool(project_snapshot.get("custom_instructions")))
print("had agent_custom_instructions:", bool(project_snapshot.get("agent_custom_instructions")))had custom_instructions: True had agent_custom_instructions: False
In [4]:
USER_INSTRUCTIONS = """Your Task: Track what a claims adjuster needs remembered about themselves, not about any single claim.
Information to Extract:
1. Drafting and communication style:
- Tone, formatting, and length preferences for letters and summaries
- Rules for how the assistant should write on their behalf
2. Working preferences:
- Coverage lines or claim types they focus on
- How they like updates delivered
Guidelines:
- Store preferences that should carry over to every claim this adjuster works, not just the current one.
Exclude:
- Decisions made on a specific claim (settle vs litigate, reserve changes, subrogation, coverage determinations)
- Policy numbers, coverage limits, or other one-off lookups
- Greetings, small talk, and weather"""
AGENT_INSTRUCTIONS = """Your Task: Track what matters about this specific claim, regardless of which adjuster is working it.
Information to Extract:
1. Claim decisions and reasoning:
- Settle vs litigate calls
- Reserve changes and why
- Subrogation decisions
- Coverage determinations
2. Durable claim facts:
- Cause of loss and other facts that stay true for the life of the claim
Guidelines:
- Store facts that the next adjuster to open this claim needs to see.
Exclude:
- Personal style or communication preferences of whichever adjuster is talking
- One-off lookups that go stale (current weather, a single quoted estimate)
- Greetings and small talk"""
update_response = client.project.update(
custom_instructions=USER_INSTRUCTIONS,
agent_custom_instructions=AGENT_INSTRUCTIONS,
)
print(update_response){'message': 'Updated custom instructions and agent custom instructions'}
In [5]:
def wait_for_event(client, event_id, timeout=90, poll_every=2):
deadline = time.time() + timeout
while time.time() < deadline:
event = client.client.get(f"/v1/event/{event_id}/").json()
if event["status"] in ("SUCCEEDED", "FAILED"):
return event
time.sleep(poll_every)
raise TimeoutError(f"Event {event_id} did not finish in {timeout}s")
def add_and_wait(client, messages, **kwargs):
response = client.add(messages, **kwargs)
event = wait_for_event(client, response["event_id"])
if event["status"] == "FAILED":
raise RuntimeError(f"Add failed: {event.get('error')}")
return event
def summarize(event):
print("status:", event["status"], "| created:", len(event.get("results", [])))
for r in event.get("results", []):
print(" -", r["data"]["memory"])In [6]:
event = add_and_wait(
client,
[
{"role": "user", "content": "What's the building coverage limit on the Meridian Logistics policy for claim CLM-48211?"},
{"role": "assistant", "content": "Checking the policy now. The building coverage limit is $2,400,000 with a $25,000 deductible."},
],
user_id=ADJUSTER_SARAH,
agent_id=CLAIM_AGENT,
)
print(json.dumps(event["results"], indent=2))[
{
"id": "c76bf47b-c5bf-4893-95d5-6ae8c5a4177b",
"data": {
"memory": "The building coverage limit for claim CLM-48211 under the Meridian Logistics policy is $2,400,000 with a $25,000 deductible"
},
"event": "ADD",
"user_id": "adjuster_sarah_cookbook_demo",
"event_end": null,
"event_date": null,
"event_start": null,
"memory_type": null,
"plan_status": null,
"attributed_to": "assistant"
}
]
In [7]:
event = add_and_wait(
client,
[
{"role": "user", "content": "I'm raising the reserve on CLM-48211 to $1.8 million. The structural engineer's report says the warehouse needs a full rebuild, not a repair."},
{"role": "assistant", "content": "Got it. Reserve raised to $1.8 million on CLM-48211 for a full rebuild, per the structural engineer's report. I'll keep that on file for the claim."},
],
user_id=ADJUSTER_SARAH,
agent_id=CLAIM_AGENT,
)
summarize(event)status: SUCCEEDED | created: 2 - Reserve for claim CLM-48211 was increased to $1.8 million to cover a full rebuild, as indicated by the structural engineer's report - The structural engineer's report for claim CLM-48211 states that the warehouse requires a full rebuild rather than a repair
In [8]:
event = add_and_wait(
client,
[
{"role": "user", "content": "Also, for anything you draft for me: no em dashes, and keep coverage position letters to one page."},
{"role": "assistant", "content": "Understood. No em dashes, and coverage letters kept to one page, for everything I draft for you."},
],
user_id=ADJUSTER_SARAH,
agent_id=CLAIM_AGENT,
)
summarize(event)status: SUCCEEDED | created: 1 - User prefers that any drafted documents contain no em dashes and that coverage position letters be limited to one page
In [9]:
event = add_and_wait(
client,
[
{"role": "user", "content": "Thanks. Quick one, what's the weather like in Chicago right now?"},
{"role": "assistant", "content": "It's 72 degrees and clear in Chicago right now."},
],
user_id=ADJUSTER_SARAH,
agent_id=CLAIM_AGENT,
)
summarize(event)status: SUCCEEDED | created: 0
In [10]:
event = add_and_wait(
client,
[
{"role": "user", "content": "I've decided to pursue subrogation against Voss Electrical, the contractor who rewired the warehouse six months ago. The fire marshal's report points to faulty wiring as the ignition source. Also, from now on keep my claim summaries to bullet points, not paragraphs."},
{"role": "assistant", "content": "Noted both. Pursuing subrogation against Voss Electrical based on the fire marshal's faulty-wiring finding, and I'll keep your summaries in bullet points going forward."},
],
user_id=ADJUSTER_SARAH,
agent_id=CLAIM_AGENT,
)
summarize(event)status: SUCCEEDED | created: 2 - User prefers claim summaries to be written as bullet points instead of paragraphs - Assistant noted that subrogation will be pursued against Voss Electrical, with the fire marshal's report identifying faulty wiring as the ignition source
In [11]:
def dump(results, empty_label="(none)"):
if not results:
print(empty_label)
return
for r in results:
print("-", r["memory"])
sarah_all = client.get_all(filters={"user_id": ADJUSTER_SARAH})
print(f"{sarah_all['count']} memories on Sarah's shelf")
dump(sarah_all["results"])2 memories on Sarah's shelf - User prefers claim summaries to be written as bullet points instead of paragraphs - User prefers that any drafted documents contain no em dashes and that coverage position letters be limited to one page
In [12]:
claim_all = client.get_all(filters={"agent_id": CLAIM_AGENT})
print(f"{claim_all['count']} memories on the claim's shelf")
dump(claim_all["results"])4 memories on the claim's shelf - Assistant noted that subrogation will be pursued against Voss Electrical, with the fire marshal's report identifying faulty wiring as the ignition source - The structural engineer's report for claim CLM-48211 states that the warehouse requires a full rebuild rather than a repair - Reserve for claim CLM-48211 was increased to $1.8 million to cover a full rebuild, as indicated by the structural engineer's report - The building coverage limit for claim CLM-48211 under the Meridian Logistics policy is $2,400,000 with a $25,000 deductible
In [13]:
status_results = client.search(
"Draft a status update on claim CLM-48211.",
filters={"OR": [{"user_id": ADJUSTER_SARAH}, {"agent_id": CLAIM_AGENT}]},
)
dump(status_results["results"])- Reserve for claim CLM-48211 was increased to $1.8 million to cover a full rebuild, as indicated by the structural engineer's report - The structural engineer's report for claim CLM-48211 states that the warehouse requires a full rebuild rather than a repair - The building coverage limit for claim CLM-48211 under the Meridian Logistics policy is $2,400,000 with a $25,000 deductible - User prefers that any drafted documents contain no em dashes and that coverage position letters be limited to one page - User prefers claim summaries to be written as bullet points instead of paragraphs - Assistant noted that subrogation will be pursued against Voss Electrical, with the fire marshal's report identifying faulty wiring as the ignition source
In [14]:
marcus_personal = client.get_all(filters={"user_id": ADJUSTER_MARCUS})
print(f"{marcus_personal['count']} memories on Marcus's personal shelf")
dump(marcus_personal["results"])0 memories on Marcus's personal shelf (none)
In [15]:
marcus_view = client.search(
"What's going on with CLM-48211?",
filters={"OR": [{"user_id": ADJUSTER_MARCUS}, {"agent_id": CLAIM_AGENT}]},
)
dump(marcus_view["results"])- Reserve for claim CLM-48211 was increased to $1.8 million to cover a full rebuild, as indicated by the structural engineer's report - The structural engineer's report for claim CLM-48211 states that the warehouse requires a full rebuild rather than a repair - The building coverage limit for claim CLM-48211 under the Meridian Logistics policy is $2,400,000 with a $25,000 deductible - Assistant noted that subrogation will be pursued against Voss Electrical, with the fire marshal's report identifying faulty wiring as the ignition source
In [16]:
sarah_review = client.get_all(filters={"user_id": ADJUSTER_SARAH})
for r in sarah_review["results"]:
print(r["id"], "-", r["memory"])fab356e1-1603-407e-9f99-24a56c08ff6c - User prefers claim summaries to be written as bullet points instead of paragraphs 895f5c47-64bf-44c7-a36f-b37697be5037 - User prefers that any drafted documents contain no em dashes and that coverage position letters be limited to one page
In [17]:
stale = next(r for r in sarah_review["results"] if "one page" in r["memory"].lower() or "letter" in r["memory"].lower())
client.delete(stale["id"])
sarah_after = client.get_all(filters={"user_id": ADJUSTER_SARAH})
dump(sarah_after["results"])- User prefers claim summaries to be written as bullet points instead of paragraphs
In [18]:
client.delete_all(user_id=ADJUSTER_SARAH)
client.delete_all(user_id=ADJUSTER_MARCUS)
client.delete_all(agent_id=CLAIM_AGENT)
print("demo memories deleted")
client.project.update(
custom_instructions=project_snapshot.get("custom_instructions") or "",
agent_custom_instructions=project_snapshot.get("agent_custom_instructions") or "",
)
print("project instructions restored")demo memories deleted
project instructions restored