Loading the notebook…
Loading the notebook…
Notebooks · Deep agents · 26
How to give a shipit_agent.Agent and a DeepAgent long-term memory — the kind that remembers facts across sessions, not just within one chat. Three ingredients:
Its imports and arguments are checked against shipit-agent 3.0. The outputs were saved when it was written, for an earlier release.
from pathlib import Path
import sys
ROOT = (
Path.cwd().resolve().parent
if Path.cwd().name == "notebooks"
else Path.cwd().resolve()
)
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from shipit_agent import (
Agent,
AgentMemory,
ConversationMemory,
Entity,
)
from examples.run_multi_tool_agent import build_llm_from_env
from shipit_agent.deep import DeepAgent
from shipit_agent.stores import InMemorySessionStore
llm = build_llm_from_env("bedrock")
def echo_embed(texts):
"""Tiny stand-in for a real embedding function."""
return [[float(len(t)), float(t.count(" "))] + [0.0] * 14 for t in texts]AgentMemory.default(...) gives you all three layers with sensible defaults:
memory = AgentMemory.default(llm=llm, embedding_fn=echo_embed)
print("conversation strategy:", memory.conversation.strategy)
print("knowledge backend :", type(memory.knowledge.vector_store).__name__)
print("entities backend :", type(memory.entities).__name__)conversation strategy: summary knowledge backend : InMemoryVectorStore entities backend : EntityMemory
Pass memory.knowledge as memory_store so the LLM's memory tool reads/writes from it. The runtime auto-registers the memory tool whenever memory_store is set.
agent = Agent.with_builtins(
llm=llm,
memory_store=memory.knowledge,
)
tool_names = sorted({t.name for t in agent.tools})
print("memory tool wired:", "memory" in tool_names)memory tool wired: True
You don't have to wait for the agent to write — you can pre-load facts at any time.
memory.add_fact("user_favourite_colour=teal")
memory.add_fact("user_timezone=Europe/Berlin")
memory.add_fact("user prefers concise answers", metadata={"importance": "high"})
for hit in memory.search_knowledge("what colour does the user like?", top_k=3):
print(f" score={hit.score:.2f} :: {hit.text}")score=0.00 :: user_favourite_colour=teal score=0.00 :: user_timezone=Europe/Berlin score=0.00 :: user prefers concise answers
When the agent needs to track named things, EntityMemory gives you a (name, entity_type, context, metadata) store with keyword search across all fields.
memory.add_entity(
Entity(name="Alice", entity_type="person", context="PM on the growth team")
)
memory.add_entity(
Entity(name="Bob", entity_type="person", context="Eng on the growth team")
)
memory.add_entity(
Entity(
name="Project Atlas",
entity_type="project",
context="Kubernetes migration tracked by Alice",
)
)
print("lookup Alice :", memory.get_entity("Alice"))
print()
print("search growth team:")
for entity in memory.search_entities("growth"):
print(f" · {entity.name} ({entity.entity_type}): {entity.context}")lookup Alice : Entity(name='Alice', entity_type='person', context='PM on the growth team', metadata={})
search growth team:
· Alice (person): PM on the growth team
· Bob (person): Eng on the growth teamConversationMemory keeps message history. Four strategies decide what to keep as history grows: buffer (everything), window (last N), token (within a budget), summary (LLM-summarised).
from shipit_agent.models import Message
window = ConversationMemory(strategy="window", window_size=3)
for i in range(10):
window.add(Message(role="user", content=f"message {i}"))
kept = window.get_messages()
print(f"kept {len(kept)} of 10 messages — last 3:")
for msg in kept:
print(f" · {msg.content}")kept 3 of 10 messages — last 3: · message 7 · message 8 · message 9
DeepAgent accepts the same memory= parameter — and goes one step further: it auto-derives memory_store from memory.knowledge and seeds the inner Agent.history with memory.get_conversation_messages().
deep = DeepAgent.with_builtins(
llm=llm,
memory=memory,
)
inner = deep.agent
print("inner memory_store wired:", inner.memory_store is memory.knowledge)
print("inner history length :", len(inner.history))
tool_names = {t.name for t in inner.tools}
print("memory tool wired :", "memory" in tool_names)inner memory_store wired: False inner history length : 0 memory tool wired : True
Combine memory= (long-term facts) with session_store= (chat history). The agent now remembers BOTH this conversation and facts from past conversations.
session_store = InMemorySessionStore()
deep = DeepAgent.with_builtins(
llm=llm,
memory=memory, # long-term facts (semantic + entities + summary)
session_store=session_store, # chat history persistence
)
chat = deep.chat(session_id="user-42")
chat.send("Remember that I am allergic to gluten.")
memory.add_fact("user_allergy=gluten")
# A second chat handle on the same session id — restored from the session store.
chat2 = deep.chat(session_id="user-42")
history = chat2.history()
print(f"restored {len(history)} messages from session store")
print("semantic search for allergies:")
for hit in memory.search_knowledge("allergy", top_k=2):
print(f" · {hit.text}")restored 5 messages from session store semantic search for allergies: · user_favourite_colour=teal · user_timezone=Europe/Berlin
print("=== conversation messages ===")
for msg in memory.get_conversation_messages()[-5:]:
print(f" {msg.role:9s} {msg.content[:80]}")
print()
print("=== top semantic facts ===")
for hit in memory.search_knowledge("user", top_k=3):
print(f" score={hit.score:.2f} :: {hit.text}")
print()
print("=== entities ===")
for entity in memory.search_entities(""):
print(f" · {entity.name} ({entity.entity_type}): {entity.context}")=== conversation messages === === top semantic facts === score=0.00 :: user_favourite_colour=teal score=0.00 :: user_timezone=Europe/Berlin score=0.00 :: user prefers concise answers === entities === · Alice (person): PM on the growth team · Bob (person): Eng on the growth team · Project Atlas (project): Kubernetes migration tracked by Alice
When the LLM calls the memory tool, you see it as tool_called / tool_completed events in the stream.
for event in chat.stream("What colour do I like?"):
if event.type in ("tool_called", "tool_completed", "run_completed"):
print(f"[{event.type}] {event.message} {event}")[tool_called] Tool called: ask_user AgentEvent(type='tool_called', message='Tool called: ask_user', payload={'arguments': {'question': 'Which colour do you like?', 'context': "We don't have prior information about your colour preferences."}, 'iteration': 1})
[tool_completed] Tool completed: ask_user AgentEvent(type='tool_completed', message='Tool completed: ask_user', payload={'output': '{"kind": "ask_user", "question": "Which colour do you like?", "context": "", "options": []}', 'iteration': 1})[run_completed] Agent run completed AgentEvent(type='run_completed', message='Agent run completed', payload={'output': 'Waiting for your response. What colour do you like?', 'content': 'Waiting for your response. What colour do you like?', 'format': 'markdown', 'usage': {'prompt_tokens': 17244, 'completion_tokens': 151, 'total_tokens': 17395}})| You want… | Pass |
|---|---|
| Remember chat history within one session | session_store=FileSessionStore(...) + agent.chat_session(session_id=...) |
| Remember facts about a user across sessions | memory=AgentMemory.default(llm=llm, embedding_fn=embed) |
| OpenAI-style memory + chat history | Both of the above together |
| Lowest-level memory backend the LLM tool can read/write | memory_store=FileMemoryStore(root=...) |
| DeepAgent that auto-hydrates from prior conversation | DeepAgent(..., memory=AgentMemory.default(...)) |
See: