This guide walks you through installing Mnemosyne, setting up the supervisor, and running your first memory session.
Installation
Add mnemosyne to your dependencies in mix.exs:
def deps do
[
{:mnemosyne, github: "edlontech/mnemosyne"}
]
endThen fetch and compile:
mix deps.get
mix compile
Setting Up the Supervisor
Mnemosyne runs under its own supervision tree. Add it to your application's supervisor in lib/my_app/application.ex:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
{Mnemosyne.Supervisor,
config: %Mnemosyne.Config{
llm: %{model: "gpt-4o-mini", opts: %{}},
embedding: %{model: "text-embedding-3-small", opts: %{}}
},
llm: MyApp.LLMAdapter,
embedding: MyApp.EmbeddingAdapter}
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
endThe supervisor requires three things:
- config - A
Mnemosyne.Configstruct with LLM and embedding model settings - llm - A module implementing the
Mnemosyne.LLMbehaviour - embedding - A module implementing the
Mnemosyne.Embeddingbehaviour
If you're using Sycophant, you can use the built-in adapters:
{Mnemosyne.Supervisor,
config: %Mnemosyne.Config{
llm: %{model: "gpt-4o-mini", opts: %{}},
embedding: %{model: "text-embedding-3-small", opts: %{}}
},
llm: Mnemosyne.Adapters.SycophantLLM,
embedding: Mnemosyne.Adapters.SycophantEmbedding}Opening a Repository
All graph operations are scoped to a repository. A repository is an isolated knowledge graph with its own storage backend.
{:ok, _pid} = Mnemosyne.open_repo("my-project",
backend: {Mnemosyne.GraphBackends.InMemory, []})For persistent storage across restarts, use the DETS persistence layer:
{:ok, _pid} = Mnemosyne.open_repo("my-project",
backend: {Mnemosyne.GraphBackends.InMemory,
persistence: {Mnemosyne.GraphBackends.Persistence.DETS, path: "priv/memory/my-project.dets"}})Running a Session
Sessions are the write interface. A session collects observation-action pairs, groups them into trajectories, and extracts knowledge using LLM calls.
# Start a session tied to a repo
{:ok, session_id} = Mnemosyne.start_session("Help user plan a trip", repo: "my-project")
# Feed in observations and actions
:ok = Mnemosyne.append(session_id, "User wants to visit Tokyo", "Asking about travel dates")
:ok = Mnemosyne.append(session_id, "User says next March for 2 weeks", "Suggesting itinerary")
# Close the episode and commit extracted knowledge
:ok = Mnemosyne.close_and_commit(session_id)close_and_commit/1 is a convenience that closes the episode, waits for LLM extraction to finish, and commits the resulting knowledge graph changeset.
Recalling Memories
Once knowledge is committed, query it with recall/3:
{:ok, %{candidates: candidates}} = Mnemosyne.recall("my-project", "What are the user's travel preferences?")The result contains candidates partitioned by node type (:semantic, :procedural, :episodic, etc.), each scored by relevance.
If you have an active session, use recall_in_context/4 to augment the query with the session's current state:
{:ok, memories} = Mnemosyne.recall_in_context("my-project", session_id, "What did we discuss?")Cleaning Up
# Close a repo when done
:ok = Mnemosyne.close_repo("my-project")
# List open repos
Mnemosyne.list_repos()Next Steps
- Core Concepts - understand episodes, trajectories, and the three memory types
- Sessions and Episodes - session lifecycle in detail
- Extraction Profiles - domain-specific extraction tuning
- Retrieval and Recall - how recall works and how to tune it
- Custom Adapters - writing your own LLM and embedding adapters