Summary
Proposes adding a cookbook recipe for persistent, cross-session memory using Dakera — a self-hosted, decay-weighted vector memory server.
The problem: Instructor is stateless between calls
Every client.create() call starts fresh. Applications that need cross-session memory must implement their own retrieval and injection logic. There's currently no memory example in the Instructor cookbook.
The integration
Instructor's hook system (client.on("completion:kwargs") / client.on("completion:response")) is the ideal native integration point — observed in the existing Langfuse tracing integration.
DakeraMemoryHook uses the same pattern:
import instructor
from examples.persistent_memory_dakera.dakera_memory import DakeraMemory, DakeraMemoryHook
client = instructor.from_provider("openai/gpt-4o-mini")
mem = DakeraMemory(base_url="http://localhost:3300", api_key="demo", agent_id="user-123")
hook = DakeraMemoryHook(mem)
hook.attach(client) # 3 lines for persistent memory
class Reply(BaseModel):
text: str
# Session 1
reply = client.create(messages=[{"role": "user", "content": "My name is Alex."}], response_model=Reply)
# Session 2 (new process — memories recalled from Dakera automatically)
reply = client.create(messages=[{"role": "user", "content": "What is my name?"}], response_model=Reply)
# reply.text → "Your name is Alex."
How it hooks in
completion:kwargs → searches Dakera for the top-K most relevant memories for the current prompt → prepends a system message with the recalled context
completion:response → stores the user prompt + model reply in Dakera after the call
Dakera errors are silently swallowed (non-fatal) — the hook never crashes an LLM call.
Structured extraction variant
The hook also works naturally with structured extraction pipelines:
class UserProfile(BaseModel):
name: str
preferences: list[str]
profile = client.create(
messages=[{"role": "user", "content": "I'm Alex, I love Python and Rust."}],
response_model=UserProfile,
)
# profile.name, profile.preferences are structured — and the conversation is persisted
What the PR adds
examples/persistent_memory_dakera/dakera_memory.py — integration helper (DakeraMemory, AsyncDakeraMemory, DakeraMemoryHook, build_context_messages)
examples/persistent_memory_dakera/run.py — four runnable scenarios
examples/persistent_memory_dakera/test_dakera_memory.py — 31 tests, all passing (fully mocked with unittest.mock, no live server needed)
docs/examples/persistent_memory_dakera.md — cookbook page
mkdocs.yml — one line added under Cookbook: alongside "Tracing with Langfuse"
Dakera
- Docker:
docker run -p 3300:3300 -e DAKERA_API_KEY=demo ghcr.io/dakera-ai/dakera:latest
- REST API:
POST /v1/memory/store, /v1/memory/search, /v1/memory/forget
- Server-side embedding (no local model needed)
- Decay-weighted importance (memories fade unless accessed)
Summary
Proposes adding a cookbook recipe for persistent, cross-session memory using Dakera — a self-hosted, decay-weighted vector memory server.
The problem: Instructor is stateless between calls
Every
client.create()call starts fresh. Applications that need cross-session memory must implement their own retrieval and injection logic. There's currently no memory example in the Instructor cookbook.The integration
Instructor's hook system (
client.on("completion:kwargs")/client.on("completion:response")) is the ideal native integration point — observed in the existing Langfuse tracing integration.DakeraMemoryHookuses the same pattern:How it hooks in
completion:kwargs→ searches Dakera for the top-K most relevant memories for the current prompt → prepends a system message with the recalled contextcompletion:response→ stores the user prompt + model reply in Dakera after the callDakera errors are silently swallowed (non-fatal) — the hook never crashes an LLM call.
Structured extraction variant
The hook also works naturally with structured extraction pipelines:
What the PR adds
examples/persistent_memory_dakera/dakera_memory.py— integration helper (DakeraMemory,AsyncDakeraMemory,DakeraMemoryHook,build_context_messages)examples/persistent_memory_dakera/run.py— four runnable scenariosexamples/persistent_memory_dakera/test_dakera_memory.py— 31 tests, all passing (fully mocked withunittest.mock, no live server needed)docs/examples/persistent_memory_dakera.md— cookbook pagemkdocs.yml— one line added underCookbook:alongside "Tracing with Langfuse"Dakera
docker run -p 3300:3300 -e DAKERA_API_KEY=demo ghcr.io/dakera-ai/dakera:latestPOST /v1/memory/store,/v1/memory/search,/v1/memory/forget