Hermes Agent
Hermes Agent from Nous Research runs a personal agent in the terminal and across your chats. Its long-term memory is a provider slot, and the Recall provider fills it: before each turn the agent sees what Recall remembers, after each turn Recall learns from the conversation, the built-in MEMORY.md and USER.md writes are mirrored, and the agent has tools to search, store and forget on its own. A correction replaces the old fact, the history stays, and the agent can read memory as of any earlier time.
Why Recall here
A personal agent hears facts that change: a new city, a new job, a preference that
flipped. Hermes keeps its own notes in Markdown, and a search index returns both versions
and lets the model pick. Recall decides at write time. "I moved to Portland" replaces
"Lives in Seattle"; the agent gets the current value with what it replaced, and the old
statement stays readable in the history. Nothing is deleted, so
recall_search with as_of answers what was believed last month,
and recall_history shows when it changed.
By default the memories live in a local database under the Hermes profile, run by
Recall itself, with nothing to configure. Point several profiles or several agents at one
recall serve and they share memory, each under its own key.
Before you start
- Hermes Agent on Python 3.11 or later.
- A model that works facts out of text. The provider picks one from the keys already in
the profile's
.env:anthropic:claude-haiku-5-5withANTHROPIC_API_KEY, elseopenai:gpt-5.4-miniwithOPENAI_API_KEY. A local model works too, asollama:<model>, and then nothing leaves the machine. Without a model, Recall keeps captured text as written: searchable by its words, but nothing replaces anything, and forgetting by description is skipped.
Install the provider
-
From the Hermes plugin catalog, once the entry is merged:
hermes plugins install recall
Until then, put the provider directory into the profile and install its one dependency into the Python environment Hermes runs in:
git clone --depth 1 https://github.com/Polign/polign.git /tmp/polign cp -r /tmp/polign/plugins/hermes ~/.hermes/plugins/recall pip install "polign-recall>=0.24.0"
polign-recallships therecallbinary. On first use with the local database,recalldownloadspolign-server(about 80 MB) and checks it against a SHA-256 built into the binary. Agent startup does not wait for this; the first turns run without memory until the database is up. -
Make Recall the memory provider:
hermes memory setup
Pick recall. The wizard asks for a server URL and key, both blank for the local database, and the extraction model, blank to pick from your keys. Or write it by hand in
~/.hermes/config.yaml:memory: provider: recall
-
Check where memory lives and try it:
hermes memory status hermes chat > I moved to Portland last week, and I edit in vim. > Where do I live?
The second answer comes with a
🧠 Recallline under it, which Hermes prints whenever a provider put memory in front of the turn.
What the agent gets
| Tool | What it does |
|---|---|
recall_search | Memories relevant to a question, each with the date stated and what it replaced. as_of answers as of an earlier time. |
recall_profile | Everything currently believed about the user, newest first, with what each statement replaced. |
recall_remember | Keeps a preference, a fact, a decision or a correction. The result says what it replaced; restating something known changes nothing. |
recall_forget | Stops believing what a description names, such as "my editor". Nothing is deleted, and remembering it again brings it back. |
recall_history | How what is believed about a question changed, statement by statement, oldest first, including things since forgotten. |
Three things happen without a tool call. Before the turn, the provider
asks Recall about the user's message as soon as the turn starts and puts up to eight
answers in front of the prompt in a ## Recall Memory block; the turn waits at
most three seconds for it and goes on without it otherwise. After the turn,
the user and assistant messages go to Recall in the background, one turn at a time, where
the extraction model works out the statements. When the agent writes
MEMORY.md or USER.md, the same text goes to Recall, so the Markdown notes and
Recall agree. Automatic writes are skipped for cron runs and subagents, as Hermes asks of
every provider.
Where memory lives
The first of these that is set wins.
| Setting | Memory lives in |
|---|---|
RECALL_URL and RECALL_API_KEY in the profile's .env, or url from the setup wizard | A recall serve you run, started with -text. The key chooses the namespace, so one server holds memory for many agents without any of them reaching another's records. The extraction model is the server's. |
RECALL_BACKEND and RECALL_BACKEND_URL in .env, with RECALL_BACKEND_KEY when the URL does not carry the credential | A database you chose: local with a directory, polign with http://host:23000, pgvector with postgres://..., mongodb or qdrant. See the backend contract. |
| Nothing | A local database in $HERMES_HOME/recall, run by recall itself. Each Hermes profile has its own. |
The extraction model is RECALL_EXTRACT_MODEL in .env, or
extract_model in $HERMES_HOME/recall.json, which the setup wizard
writes. The value none keeps text as written on purpose. The embedder follows
the model: Anthropic uses the model built into recall, OpenAI uses
text-embedding-3-small, Ollama uses nomic-embed-text.
What works differently from the built-in memory
| Built-in memory | With Recall |
|---|---|
Markdown files in the profile (MEMORY.md, USER.md) | Statements in a database. The files stay, and what the agent writes to them is mirrored into Recall. |
| The whole file in the system prompt | Up to eight memories relevant to the turn, each with what it replaced. The history is kept but hidden unless asked for with as_of or recall_history. |
| One memory per profile | One memory per profile by default. Text mode has one subject, the user, so a gateway serving several people from one profile does not separate them; give each person a profile, or a key of their own on a recall serve. |
| No model needed | An extraction model is needed for a new statement to replace an old one, and for recall_forget. Without one, text is kept as written and found by its words. |
If something goes wrong
| What you see | What to do |
|---|---|
hermes memory status says the provider is unavailable: the polign-recall package is not installed | Run pip install polign-recall in the environment Hermes runs in, then restart Hermes. |
RECALL_URL is set but RECALL_API_KEY is not | A recall serve needs a key. Mint one with recall key create -namespace <name> against the server's database and put it in the profile's .env. |
The first turns show no 🧠 Recall line | The local database is still starting, or downloading polign-server on first use. Check $HERMES_HOME/recall/server.log. |
Recall capture failed ... 5 times; leaving it alone for 120s in hermes logs | Recall did not answer five times in a row. Check the server or the database, and that the extraction model's key is in .env. The provider tries again after two minutes. |
recall_remember answers kept_as_text | No extraction model is set. Set extract_model in hermes memory setup, or put a model key in .env. |
unsupported from recall_forget | The server has no extraction model. Forgetting by description needs one. |
Source & license
The provider is open source under the Apache License 2.0, in github.com/Polign/polign, and uses the polign-recall Python client over Recall's Memory API, version 1. Bug reports and pull requests go there.