Hermes Agent does not retrain its model. It learns by writing text: two small memory files (MEMORY.md and USER.md) that load into every new session, Markdown skills it creates and patches with its skill_manage tool, and a full text index of past sessions it can search. A background review re-reads each conversation and decides what to save, and a curator prunes old skills.
All of those writes are on by default and ungated by default. The rest of this post walks through each mechanism from the Hermes documentation and source code, shows what a good agent-written skill looks like, lists every gate with its default value, and gives a step by step setup for a learning loop you can review and roll back. Every version, config key and default below was checked against the Hermes Agent repository on 23 October 2026, when the latest stable release was v0.22.5.
Key takeaways
- No weights change. Hermes Agent "learns" by editing files on disk:
~/.hermes/memories/MEMORY.md(2,200 character cap),~/.hermes/memories/USER.md(1,375 character cap) and skills under~/.hermes/skills/. The model stays whatever model you configured. - Memory is a frozen snapshot. It loads into the system prompt at session start and does not change mid-session. A full store returns an error; nothing is silently dropped or auto-compacted.
- Skills are procedural memory. The agent writes them with
skill_manage(create,patch,delete,write_file,remove_file). A targetedpatchis the preferred update. - A background review runs after turns and replays the conversation in a forked agent that can write memory and skills. It is on by default (
auxiliary.background_review.enabled: true). - The curator prunes, it does not delete. Unused agent-created skills go stale after 14 days and are archived after 30. LLM consolidation is off by default.
- Session search is a database query, not memory. Every session lives in
~/.hermes/state.dbwith SQLite FTS5; the docs say thesession_searchtool makes no LLM calls. - The gates exist but start open.
memory.write_approval,skills.write_approvalandskills.guard_agent_createdall default tofalse. Turning the first two on stages every write for your approval. - Everything is auditable. Skill mutations land in an append-only ledger with per-file SHA-256 hashes, and
hermes curator rollback <entry-id>undoes a single change.
The learning loop at a glance
Hermes Agent is Nous Research's open source agent (MIT licence, repository created 22 July 2025, public launch listed on nousresearch.com/releases as 25 February 2026). Its README describes "a closed learning loop": agent-curated memory with periodic nudges, autonomous skill creation after complex tasks, skills that improve during use, FTS5 session search, optional user modelling through Honcho, and compatibility with the agentskills.io standard.
Here is every moving part in one table.
| Mechanism | Where it lives | Who writes it | Loaded when | Default gate | How you see it |
|---|---|---|---|---|---|
| Agent notes | ~/.hermes/memories/MEMORY.md | memory tool, target memory | Session start, frozen | None (memory.write_approval: false) | cat the file, /journey |
| User profile | ~/.hermes/memories/USER.md | memory tool, target user | Session start, frozen | None | cat the file, /journey |
| Skills | ~/.hermes/skills/<category>/<name>/SKILL.md plus support files | skill_manage, /learn, background review, curator | Index in system prompt; body on demand | None (skills.write_approval: false) | /skills, /journey, ledger |
| Session history | ~/.hermes/state.db (SQLite, FTS5) | Hermes itself, every message | On demand via session_search | Not applicable | hermes sessions list |
| Background review | Forked agent after a turn | Writes memory and skills | After turns | On (auxiliary.background_review.enabled: true) | Chat line, agent.log |
| Curator | Background maintenance pass | Archives, optionally consolidates | Every 7 days when idle 2 hours | On, prune only | hermes curator status |
Version timeline for the learning features
Hermes ships several releases a week, so the exact release that introduced each behaviour matters when you read older guides. Dates below come from the GitHub release pages and releases feed and from nousresearch.com, fetched on 23 October 2026. Where a date comes from a blog post rather than a release, the table says so.
| Date | Version or event | What changed for learning | Source |
|---|---|---|---|
| 22 Jul 2025 | Repository created | Project begins (pre-public) | GitHub repository metadata |
| 25 Feb 2026 | Public launch | Listed as "An autonomous agent that lives on your server, remembers what it learns, and gets more capable the longer it runs" | nousresearch.com/releases |
| 12 Mar 2026 | v0.2.0 (tag v2026.3.12) | "First tagged release since v0.1.0" | GitHub release page |
| 1 Jul 2026 | v0.18.0 "Judgment" (tag v2026.7.1) | /learn and /journey added; release notes say they "turned self-improvement into something you can see and steer" | GitHub release page |
| 2 to 4 Sep 2026 | Nous refactor run | 1,393 subagent refactor of the Hermes codebase, PR merged 4 September | Nous Research blog (self-reported) |
| 3 Sep 2026 | Two CVE records published | Neither concerns the learning loop; see the FAQ | CVE.org |
| 23 Oct 2026 | v0.22.5 | Latest stable release at time of writing | GitHub releases feed |
Docs quoted here are the main branch versions of 23 October 2026; older releases may lack some keys, so check hermes --version against the docs for your version.
What are MEMORY.md and USER.md?
Hermes keeps two plain text files under ~/.hermes/memories/. The memory feature page describes them like this:
| File | Purpose | Character cap | Rough token size |
|---|---|---|---|
MEMORY.md | The agent's own notes: environment facts, project conventions, tool quirks, lessons learned, completed work | 2,200 | About 800 tokens |
USER.md | Your profile: name, role, timezone, communication preferences, pet peeves, skill level | 1,375 | About 500 tokens |
Both caps are configurable as memory.memory_char_limit and memory.user_char_limit. Entries are separated by a section sign, and each store renders into the system prompt with a header showing its usage, for example a percentage and a "1,474/2,200 chars" count, so the model can see how close it is to the cap.
The frozen snapshot
At the start of every session, Hermes reads both files and injects them into the system prompt as a frozen block. The docs are explicit that this snapshot "never changes mid-session": a memory the agent writes at 10:00 is saved to disk immediately but is not visible to the model in that same session. It appears the next time a session starts. The reason given is performance: a stable system prompt keeps the provider's prompt cache warm.
This has two practical consequences.
- Learning needs session boundaries. On messaging platforms a chat is one continuous session that survives restarts, so fresh memories stay invisible until you run
/new. The docs recommend/newat natural breaks such as a finished task or the start of a day. - A poisoned entry also waits for the next session. The same frozen snapshot that keeps the cache warm means a bad memory written today shapes every session from tomorrow on, until someone removes it. That is the defender's reason to review memory writes rather than only watch the live chat.
The memory tool: add, patch, remove
The agent edits memory with a single memory tool. Every call names a target (memory or user) and carries one or more operations:
adda new entry.patchone span inside an existing entry, usingold_textto find the span andcontentas its replacement.removean entry, matched by a unique substring.
There is no read action, because the content is already in the system prompt. There is also no replace action any more. The docs say models misused it as find and swap and wiped other facts in multi-fact entries. Exact duplicate entries are rejected quietly with a "no duplicate added" message.
What happens when memory is full
Memory does not auto-compact. When an add would push a store over its cap, the tool fails with a structured error that states the current usage, the size of the new entry, how many characters over the limit it would be, and the current entries. The agent is then expected to issue one batch that removes or shortens stale entries and adds the new one; the cap is checked only on the batch result. The docs recommend consolidating once a store passes 80 percent, for example merging three "project uses X" entries into one.
Two agent processes must not share one Hermes home: the docs warn they "will compound each other's entries into state neither of them (nor you) authored." Give each agent its own profile (hermes -p work).
When does the agent decide to write a skill?
Skills are Hermes's procedural memory: longer instructions for a class of task, loaded only when relevant. The skills feature page says the system prompt asks the agent to record a non-trivial workflow with skill_manage, and lists what that covers in practice:
- It worked out a multi-step workflow worth repeating.
- It hit errors or dead ends and found the working path.
- The user corrected its approach.
In the current source (agent/prompt_builder.py on main, read 23 October 2026), the wording is short. The guidance block says "When you work out a non-trivial workflow, record it with skill_manage for future reuse." The skills index section adds that after difficult or iterative tasks the agent should offer to save a skill, and that if a skill it loaded "was missing steps, had wrong commands, or needed pitfalls you discovered" it should update it before finishing. A code comment in the same file records that an older, longer phrasing of this instruction was reworded after it caused provider errors, which is a useful reminder that these prompts are tuned empirically and change between releases.
Two periodic nudges back the prompt up. The example configuration in the repository (cli-config.yaml.example) sets:
memory:
nudge_interval: 10 # remind the agent to consider saving memories every 10 user turns (0 = off)
skills:
creation_nudge_interval: 15 # remind the agent to consider saving a skill every 15 tool-calling iterations (0 = off)
The background review, covered below, is the third path. It looks at the whole conversation after a turn and is told to be "ACTIVE": its prompt says most sessions should produce at least one skill update.
What a good agent-written SKILL.md looks like
A Hermes skill is a directory with a SKILL.md file and optional references/, templates/, scripts/, examples/ and assets/ folders. The frontmatter follows the agentskills.io specification, which requires a name (up to 64 characters, lowercase letters, digits and single hyphens, matching the directory name) and a description (up to 1,024 characters, saying what the skill does and when to use it). Hermes adds optional fields under metadata.hermes such as tags, category, platform restrictions and conditional activation.
The body Hermes expects has four sections: When to Use, Procedure, Pitfalls and Verification. The house standard for /learn output adds a description of 60 characters or fewer.
The docs and the background review prompt are unusually specific about quality. A skill should capture "lessons, not logs":
- Procedure first, in the order the steps are done, with the commands and decision points that work.
- A pitfall is a general rule plus one clause of why, attached to the step it affects, stated once.
- No PR or issue numbers, dates, ticket IDs or quoted chat as content.
- Always-on rules belong in
SKILL.md;references/holds a few topical files that get extended, never one file per session. - Do not restate what is already loaded every turn, such as the repository's
AGENTS.mdor tool schemas. - Fix a wrong sentence in place rather than appending "UPDATE: actually".
Here is an illustrative skill in that shape. It is our own example, not one shipped with Hermes.
---
name: postgres-migration-check
description: Run and verify a Postgres schema migration safely
version: 1.0.0
metadata:
hermes:
tags: [postgres, migrations]
category: devops
---
# Postgres migration check
## When to Use
Before applying any schema migration to the staging or production database.
## Procedure
1. Confirm the target: `psql "$DATABASE_URL" -c 'select current_database();'`
2. Take a schema-only dump first: `pg_dump --schema-only "$DATABASE_URL" > pre_migration.sql`
3. Run the migration tool in dry-run mode and read the planned statements.
4. Apply the migration.
5. Run the project test suite against staging.
## Pitfalls
- Check for long-running transactions before step 4; an ALTER TABLE waits on their locks and blocks every writer behind it.
- Never run step 4 from a shell that still points at production after a staging test; re-run step 1 every time.
## Verification
`psql "$DATABASE_URL" -c '\d+ <table>'` shows the new columns, and the test suite passes.
The advisory linter
skill_manage lints creates, SKILL.md patches and references/ writes against three rules: incident-log-shape (a body dense with PR or issue numbers), references-sprawl (more than 60 reference files) and oversized-body (a body past about 24,000 characters). The docs say they warn and never block a write, so treat them as hygiene, not a security control.
How does skill_manage work?
skill_manage is the single tool the agent uses to change its own skills. The actions, from the skills feature page:
| Action | Use for | Key parameters |
|---|---|---|
create | New skill from scratch | name, content (the whole SKILL.md), optional category |
patch | Targeted fix (preferred) | name, old_string, new_string |
patch with content | Full structural rewrite (edit is the legacy alias) | name, content |
delete | Remove a skill | name |
write_file | Add or update a support file | name, file_path, file_content |
remove_file | Remove a support file | name, file_path |
Why a targeted patch is preferred
The docs give the token reason: only the changed text is sent. Two more reasons matter for security.
- A small diff is reviewable. With
skills.write_approvalon, you approve from a gist and a unified diff; three changed lines are easy to read, a full rewrite is not. - A small diff cannot quietly drop content. A whole-file rewrite can lose a pitfall, a verification step or a warning without anyone noticing. A patch changes only the span it names.
The tool is also strict about shape. Each action has its own text slot (content, new_string or file_content). An operation that carries another action's slot is rejected before any operation in the batch is applied, so a malformed batch fails as a whole rather than half applying.
Read before write, and what pinning protects
The background review prompt says skill_manage enforces a read-before-write rule during review: before the review patches an existing SKILL.md or overwrites an existing support file, it must load that exact file with skill_view in the same review. Content quoted earlier in the conversation does not count. Creating a new skill or adding a new support file needs no prior read.
Pinning is narrower than many readers expect. The curator page says pinning protects a skill from deletion: the curator skips it and skill_manage refuses delete. But "Patches and edits still go through, so the agent can improve a pinned skill's content." The review prompt says the same thing from the other side: hand-written, installed, bundled and pinned skills are "all yours to improve." If you want a skill the agent cannot change, pinning is not enough. You need skills.write_approval: true, a read-only file, or a skill directory the agent does not own (see project-local skills below).
What do the background review and the curator do?
These are the two parts of the loop that run without you asking.
The background review
The module docstring in agent/background_review.py describes it plainly: after a turn, the agent "may spawn a daemon thread that replays the conversation snapshot in a forked AIAgent and asks 'should any skill/memory be saved or updated?'". The fork inherits the parent's provider, model, credentials and cached system prompt so it can reuse the prompt cache. The main conversation is never touched.
The review has three prompts (memory only, skills only and combined). From the source, the skill review looks for four signals:
- The user corrected your style, tone, format or verbosity.
- The user corrected your workflow or the order of steps.
- A non-trivial technique, fix, workaround or debugging path emerged.
- A skill loaded in this session turned out to be wrong, incomplete or outdated.
It then prefers, in order: patch a skill that was loaded in this session, patch an existing class-level umbrella skill, add a support file under an existing skill, and only then create a new class-level skill. It is told never to delete a skill and to leave overlap to the curator.
The prompt also lists what not to save, which is good practice for any agent memory:
- Environment-dependent failures such as missing binaries or unconfigured credentials.
- Negative claims about tools ("X does not work"), which "harden into refusals the agent cites against itself for months."
- Transient errors that resolved during the session.
- One-off task narratives.
- Unresolved failures written up as if they were a working method.
The memory review routes each fact to one store: who you are goes to USER.md, facts about the environment go to MEMORY.md, never both.
The review runs with a tool whitelist: memory, skill management and read-only file tools by default. extra_tools can add named tools the parent already has; the default list is empty.
Configuration keys, all under auxiliary.background_review (the docs warn that a top-level background_review: block is not read):
| Key | Default | What it does |
|---|---|---|
enabled | true | false stops automatic post-turn forks; manual /refine still works |
provider, model | auto (main chat model) | Route the review to another model; the docs report about 3 to 5 times lower cost in their own testing |
max_input_tokens | Unset: 75 percent of the review model's context window, capped at 600,000 | Caps the total replayed input tokens for one review |
extra_tools | Empty list | Opt in additional tools by name |
Every review's token use is recorded in session_model_usage with task='background_review', and a completion line goes to agent.log.
In gateway chats, display.memory_notifications (default on) prints a short line such as "Skill 'foo' patched"; verbose adds a preview; off hides the line, but the docs stress the review "still runs and still writes."
The curator
The curator is a background maintenance pass for agent-created skills only. It is triggered by an inactivity check rather than cron. With the defaults, it runs when at least 7 days (interval_hours: 168) have passed since its last run and the agent has been idle for 2 hours (min_idle_hours: 2).
A run has two phases:
- Automatic transitions, no LLM. Skills unused for 14 days (
stale_after_days) become stale; skills unused for 30 days (archive_after_days) move to~/.hermes/skills/.archive/. Pinned skills and skills referenced by cron jobs are skipped. - LLM consolidation, off by default. With
curator.consolidate: true, a forked agent surveys agent-created skills and can keep, patch, merge them into umbrella skills, or archive them.
The curator "never auto-deletes"; the worst outcome is archival, which hermes curator restore undoes. Hub-installed skills are always off limits. Bundled skills are archived only if you opt in with curator.prune_builtins: true.
One detail surprises people. "Agent-created" has a narrow meaning. The curator docs say only the background review fork sets the agent-created marker. Skills the foreground agent creates during a conversation, including with /learn, are recorded as created_by: learn and the curator leaves them alone. Run hermes curator status to see the managed and unmanaged counts.
Before a consolidation pass, Hermes snapshots ~/.hermes/skills/ as a tar.gz under .curator_backups/ (two kept by default).
The ledger
Every skill mutation, whoever makes it, appends one line to ~/.hermes/skills/.curator_ledger.jsonl. Each entry records the actor (curator, agent or user), the action, evidence such as the triggering session id, and before and after manifests with a SHA-256 hash per file. File contents are stored by hash under ~/.hermes/.curator_backups/blobs/. That is enough to answer "who changed this skill, when, and from what session", and to undo one change. The ledger is "telemetry, never a gate": if writing an entry fails, the mutation still happens. It is capped at 5 MB by default (skills.ledger_max_bytes), after which old entries can be dropped, so copy it somewhere durable for a long audit trail.
Seeing and steering it: /learn, /journey and /refine
Hermes v0.18.0 (1 July 2026) added two commands aimed at making the loop visible.
/learnturns something you point at into a skill: a local directory, a URL, the workflow you just walked through, pasted notes, or a whole book or docs corpus. Large sources become "knowledge-base skills" with a leanSKILL.md, an index, and one distilled file per chapter or topic underreferences/. The docs say the distillation "never reproduces passages of the source text."/learnhas no tool of its own: it builds a prompt and the agent saves the result withskill_manage, soskills.write_approvalapplies./journey(alsohermes journey,hermes learningorhermes memory-graph) shows a timeline of saved skills and memory entries. A skill appears once it has a learning signal: created by/learnor a foregroundskill_managecreate, created by the background review, or used at least once. You can prune and correct from it:hermes journey list,hermes journey edit <node>, andhermes journey delete <node>, which archives skills (restorable) and removes memory chunks.
How does session search complement memory?
Memory holds the few facts that should always be in context. Session search is for everything else. All CLI and messaging sessions are stored in ~/.hermes/state.db, a SQLite database in WAL mode with three key tables: sessions (metadata), messages (full history including tool calls) and messages_fts, an FTS5 virtual table. SQLite's own documentation describes FTS5 as "an SQLite virtual table module that provides full-text search functionality", with built-in bm25(), highlight() and snippet() functions for ranking and excerpts.
The session_search tool has four calling shapes, chosen by which arguments are set:
| Shape | Arguments | Returns | Typical time (docs) |
|---|---|---|---|
| Discovery | query | Top sessions by FTS5 rank, deduplicated by lineage; the top hit gets bookends and about five messages either side | Tens of milliseconds |
| Scroll | session_id, around_message_id, window | A window of messages around an anchor | 1 to 2 ms |
| Read | session_id | The whole session, or a bounded head and tail | Not stated |
| Browse | No arguments | Recent sessions, newest first | Not stated |
Queries use standard FTS5 syntax (keywords, quoted phrases, OR, NOT, prefixes such as deploy*).
The agent is prompted to use it when "the user references something from a past conversation or you suspect relevant prior context exists", with typical triggers such as "we did this before", "last time" or "as I mentioned".
A disagreement in the sources. The README's feature table, read on 23 October 2026, still says "FTS5 session search with LLM summarization for cross-session recall." The current sessions and memory pages say the opposite: the tool "makes no LLM calls and returns views of actual messages from the DB rather than generating summaries." We describe the behaviour from the feature pages, which are more specific and more recently edited, and flag the README line as likely out of date.
Two notes follow from "everything is stored":
- Retention. Auto-prune is off by default. When on, ended sessions inactive for
sessions.retention_days(default 90) are removed at startup. - Backups hold everything.
hermes sessions exportwrites every stored row, including compacted turns and messages removed by rewind or edit. Use--redactto strip API keys and tokens, and prefer--format mdorhtmlwhen sharing a conversation.
What is user modelling in Hermes, and what personal data is stored?
"User modelling" in Hermes has two layers, and it helps to keep them apart.
The built-in layer is USER.md. The memory docs list what belongs there: name, role, timezone, communication preferences, things to avoid, workflow habits and technical skill level. The background review's routing block is broader: USER.md is for "who the user is: persona, preferences, communication and work style, personal details they revealed, and expectations." By default the agent saves to it "proactively" and you do not need to ask.
The optional layer is an external memory provider. The README highlights "Honcho dialectic user modeling." The current Honcho docs page says Honcho is now a catalog plugin maintained by Plastic Labs, installed with hermes plugins install honcho and configured with memory.provider: honcho. Honcho's README describes it as "memory infrastructure for building stateful agents", available managed or self-hosted. Per the Hermes docs, after conversation turns (every 2 turns by default, dialecticCadence) Honcho "analyzes the exchange and derives insights about the user's preferences, habits, and goals", which accumulate server-side as conclusions, a user representation and a peer card. External providers run alongside the built-in files rather than replacing them.
What personal data can end up stored, by location:
| Store | What it can contain | Where it lives |
|---|---|---|
| USER.md | Profile facts the agent decided to keep, including personal details you mentioned | Your machine, ~/.hermes/memories/ |
| MEMORY.md | Paths, hosts, project names, completed work with dates | Your machine |
| state.db | Every message, tool call and tool output from every session | Your machine |
| Skills | Your preferences embedded in procedures, by design | Your machine, ~/.hermes/skills/ |
| External provider | Derived conclusions and representations of you | The provider's server, or your self-hosted one |
| Model provider | Everything sent in prompts, including the memory snapshot | Your configured LLM provider, under its terms |
On a shared host or a gateway several people message, treat ~/.hermes as personal data, and give each person their own profile.
What scanning and gating exist on memory and skill writes?
This is the part most readers come for. The table lists every control we found in the docs, with its default on 23 October 2026.
| Control | Applies to | Default | What it does |
|---|---|---|---|
| Memory content scan | Every memory write | Always on | Blocks entries matching prompt injection, credential exfiltration or SSH backdoor patterns, or containing invisible Unicode |
memory.write_approval | Memory writes, foreground and background | false | When true, CLI writes prompt inline and all other writes (gateway, scripts, background review) are staged for /memory pending |
skills.write_approval | Every skill_manage write | false | When true, every create, patch, delete, write_file and remove_file is staged under ~/.hermes/pending/skills/ for /skills pending, diff, approve, reject |
skills.guard_agent_created | Agent skill writes | false | Content scanner for dangerous keyword patterns; flagged writes become an approval prompt. Turned off by default because legitimate workflows touching ~/.ssh/ or API key variables tripped it too often |
skill_manage linter | Creates, SKILL.md patches, references writes | Always on | Advisory only; never blocks |
| Pinning | Delete only | Off per skill | Blocks curator archival and agent delete; does not block patches |
| Project skill trust | Repo .hermes/skills, .agents/skills | Not trusted | Skills load only after hermes skills trust; dangerous ones are quarantined at scan time and rescanned when content changes |
| Skills Hub install scan | Hub, GitHub and URL installs | Always on | Scans the quarantined bundle; records source URL, content hash, scanner version and findings in skills/.hub/lock.json; --force cannot override a "dangerous" verdict |
| Context file scan | AGENTS.md, SOUL.md and similar | Always on | Heuristic checks for injection, hidden comments, secret reads, exfiltration and invisible Unicode |
| Background review | Post-turn learning | On | Disable with auxiliary.background_review.enabled: false |
| Curator | Agent-created skills | On, prune only | Consolidation opt-in; never deletes |
| Ledger | All skill mutations | On | Telemetry, not a gate; 5 MB cap by default |
Three observations from reading these together.
Scanning is pattern based. The security docs say of the context file scanner that its patterns "are heuristics, not semantic intent detection." The memory scan and the agent-created skill guard are described in the same terms. A carefully worded instruction that contains no obvious pattern can pass. See our post on the limits of static scanners for AI agent skills.
The approval gates are the strong control, and they are off by default. With both write_approval keys on, nothing the agent learns reaches disk without a human yes. The docs themselves recommend this for "small models that misjudge what they learned, secure environments, or just wanting eyes on the self-improvement loop."
The background review stages some changes even with the gate off. The memory docs note that a staged patch or remove from the background review records the full entry it targets, that "the background review stages these even with the gate off", and that approval is refused if the target changed after staging.
Step by step: a learning loop you can review and roll back
This walkthrough keeps Hermes's learning on but puts a human and version control in the loop. It assumes a working install (hermes setup and hermes doctor pass). Commands are from the Hermes docs; the git steps are standard git.
Step 1: back up the current state
Before changing anything, take copies. Several later steps change or delete agent state.
# Snapshot everything Hermes has learned so far
hermes curator backup --reason "before-learning-review-setup"
tar czf ~/hermes-learning-backup-$(date +%Y%m%d).tgz \
~/.hermes/memories ~/.hermes/skills ~/.hermes/config.yaml
# Export sessions with secrets redacted
hermes sessions export ~/hermes-sessions-$(date +%Y%m%d).jsonl --redact
Step 2: turn on the approval gates and the content guard
Edit ~/.hermes/config.yaml:
memory:
write_approval: true # stage or prompt every memory write
skills:
write_approval: true # stage every skill write under ~/.hermes/pending/skills/
guard_agent_created: true # pattern scan on agent skill writes
project_discovery: true # keep repo skills discoverable, but untrusted until you trust them
display:
memory_notifications: verbose # show a preview of each learned change in gateway chats
curator:
enabled: true
consolidate: false # keep LLM consolidation off until you trust the review
backup:
enabled: true
keep: 5 # keep more snapshots than the default of 2
auxiliary:
background_review:
enabled: true
max_input_tokens: 48000 # cap the cost of one review
extra_tools: [] # no extra tools for the unattended review
You can also toggle the gates at runtime with /memory approval on and /skills approval on, which persist the setting.
Step 3: put the skills directory under git
The curator ledger records hashes, but a git history gives you diffs, blame and an off-machine copy.
cd ~/.hermes/skills
git init
printf '.curator_backups/\n.hub/quarantine/\n' > .gitignore
git add -A
git commit -m "Baseline: skills before review gating"
Push it to a private repository you control. Do not commit ~/.hermes/.env or anything under ~/.hermes that holds credentials.
Step 4: review staged writes as part of your routine
At the end of a working session, or when a notification appears:
/memory pending
/memory approve <id>
/memory reject <id>
/skills pending
/skills diff <id>
/skills approve <id>
/skills reject <id>
Read the full diff on the CLI or in ~/.hermes/pending/skills/<id>.json; the docs note diff output is truncated in chat bubbles. What to look for in a skill diff:
- New commands that fetch from the network, pipe to a shell, or touch credentials, SSH keys or cloud metadata.
- New
scripts/files. A script is code, and it will run with the agent's permissions. - Instructions that widen scope ("always", "for every task", "regardless of") or tell the agent to skip a check.
- Preferences that look like they came from a web page or file rather than from you.
After approving, commit:
cd ~/.hermes/skills && git add -A && git commit -m "Approved skill changes $(date +%F)"
Step 5: audit with the ledger and the journey
hermes curator status
hermes curator ledger --limit 50
hermes curator ledger --skill postgres-migration-check
hermes journey list
Step 6: undo a bad change
Warning: the commands below change agent state. Take a fresh backup first.
hermes curator backup --reason "before-rollback"
cp -a ~/.hermes/memories ~/.hermes/memories.bak-$(date +%Y%m%d%H%M)
Then undo exactly one skill mutation from the ledger, or restore a whole snapshot:
hermes curator rollback <entry-id> # restore one mutation's before-state
hermes curator rollback --list # list whole-tree snapshots
hermes curator rollback --id <ts> # restore a specific snapshot (takes a pre-rollback snapshot first)
For a bad memory entry, use hermes journey delete <node> (memory chunks are removed, not archived) or edit the file directly in $EDITOR with hermes journey edit <node>. Start a new session afterwards so the corrected snapshot loads.
Step 7: keep repo skills under code review
For procedures a team shares, put them in the repository's .hermes/skills/ or .agents/skills/ directory, review them through pull requests, and trust the repository explicitly:
cd ~/code/myproject
hermes skills trust
The curator never modifies project skills and new agent-created skills never land there, so the only way they change is through your normal review process.
How does this map to the research it borrows from?
Hermes does not cite papers in its docs, so this mapping is ours. The three papers below are the clearest ancestors of its design, read from their arXiv abstracts on 23 October 2026.
| Paper | arXiv ID, first version | What changes as the agent "learns" | Evaluator | Result in the authors' own terms |
|---|---|---|---|---|
| Voyager: An Open-Ended Embodied Agent with Large Language Models (Wang et al.) | 2305.16291, 25 May 2023 | An ever-growing library of executable code skills, plus an automatic curriculum; no fine-tuning | The Minecraft environment, execution errors and a self-verification step | 3.3x more unique items, 2.3x longer distances, tech tree milestones up to 15.3x faster than prior methods, and reuse of the skill library in a new world |
| Reflexion: Language Agents with Verbal Reinforcement Learning (Shinn et al.) | 2303.11366, 20 Mar 2023 | Verbal reflections stored in an episodic memory buffer; "not by updating weights" | Task feedback signals (scalar or free text, external or self-generated) | 91 percent pass@1 on HumanEval, and gains over a baseline agent on decision-making, coding and reasoning tasks |
| MemGPT: Towards LLMs as Operating Systems (Packer et al.) | 2310.08560, 12 Oct 2023 | Memory moved between a small in-context tier and larger external tiers, managed by the model | Document analysis beyond the context window, and multi-session chat | Agents that "remember, reflect, and evolve dynamically through long-term interactions" in multi-session chat |
The parallels:
- Skills are Voyager's skill library, in Markdown. Voyager grew a library of code skills retrieved by description; Hermes stores SKILL.md procedures retrieved through a description index, loading full bodies only on demand.
- Pitfalls and the background review are Reflexion-style reflection. Reflexion turns feedback into written lessons that shape the next attempt. Hermes's review turns corrections and dead ends into pitfalls attached to a procedure.
- Memory plus session search is a two-tier memory hierarchy, like MemGPT. A small, always-loaded tier (MEMORY.md and USER.md) and a large tier fetched on demand (
state.db).
What is different matters as much:
- No benchmark, no ground truth. Voyager had Minecraft and Reflexion had unit tests to say whether a lesson was right. Hermes's evaluator is the conversation: a user correction or the agent's own judgment that a path worked. The review prompt tries hard to avoid saving unverified methods, but nothing outside the model checks a skill before it is used.
- The library persists across real work and real users. Research agents reset between experiments. A Hermes skill written in March can shape a deployment in October.
- Skills can carry scripts. Voyager's skills were code run inside a game. A Hermes skill's
scripts/folder runs on your machine or in your sandbox, with whatever access the terminal backend allows.
None of the three papers studied adversarial inputs to a persistent skill library or memory, and Hermes has not published an evaluation of its learning loop's accuracy. Our post on agent memory poisoning and memory hardening covers the research that does.
What did Nous report from "Refactoring Hermes with 1,393 agents"?
In a September 2026 post on the Nous Research blog, Teknium describes asking his everyday Hermes agent to clean up the Hermes codebase. Everything in this section is self-reported by Nous; we have not reproduced it.
What the post reports:
- The run started on 2 September 2026, lasted about nineteen active hours, dispatched 1,393 subagents and reached 218 running at once. The PR merged on 4 September after a restart, a continuation session and two rounds of community review.
- Non-test Python source fell by 34.4 percent, from 1,063,826 lines to 698,363. Files over 5,000 lines fell from 37 to 6; functions over 300 lines from 192 to 2; the largest gateway file from 34,847 lines to 5,512.
- The estimated model cost was about $19,300 for the main run, or roughly $25,000 with follow-up sessions, excluding human review time. The post compares this with a staffing estimate of $150,000 to $1.8 million for manual work.
- A simulated lookup of 4,000 symbols returned on average 993 tokens instead of 2,218.
What it says about learning: the author's hermes-agent-dev skill "grew out of my everyday work on the repository." When a procedure was worked out or a mistake corrected, Hermes saved the lesson automatically; by the time of the refactor the skill carried instructions on preparing a PR, shortcuts to avoid and how to verify a change. The author shares the skill with other engineers, whose agents install and adapt it.
What the post itself flags as limits, to its credit:
- Reviewers caught real regressions the tests missed: public names removed because they had no callers inside the repository, and an automated rewrite that changed exception handling at roughly 65 sites. Further fixes followed after merge.
- The lookup numbers are "lookup costs; we didn't measure agents completing engineering tasks." The median lookup actually returned more tokens.
- Splitting files increased module count and import dependencies, and some entry points took longer to import.
How to read self-reported results
- Ask what was measured. Line counts and lookup tokens were; ease of future changes was not.
- Ask who measured it. The product team, on its own codebase, with its most experienced user.
- Separate the learning claim from the scale claim. The post shows a long-lived skill carrying a maintainer's procedures into a large job. It does not show how much of the result came from the skill rather than the model, the orchestration or human review.
- Notice the supply chain lesson. A skill shared across a team is a shared dependency and deserves the same review and versioning as code.
Threats to the learning loop, and the matching controls
Every learning mechanism is a place where untrusted content can become a persistent instruction. OWASP's description of indirect prompt injection is the starting point: content from "external sources, such as websites or files" can alter a model's behaviour. A learning loop adds persistence: the altered behaviour can be written down and replayed in later sessions.
| Threat | Mechanism in Hermes | Built-in control | Default | What to add |
|---|---|---|---|---|
| A web page or file nudges the agent to save a false "preference" | Foreground or background memory write | Memory content scan | On | memory.write_approval: true; review USER.md weekly |
| A learned skill gains a risky command or script | skill_manage patch or write_file | Advisory linter; optional guard | Guard off | skills.write_approval: true, guard_agent_created: true, git diffs, review new scripts/ |
| A cloned repository ships hostile project skills | Project-local skills | Trust prompt plus scan-time quarantine | Untrusted until trusted | Trust only repos you review; keep project skills in PR review |
| A third-party skill is installed with hidden behaviour | Skills Hub, GitHub or URL install | Install scan, lock file with hashes, quarantine | On | Prefer reviewed sources; pin and diff updates |
| A bad lesson spreads through a shared team skill | Skill shared across engineers | None specific | Not applicable | Treat shared skills as code: repo, review, signed commits |
| Sensitive data accumulates in history | state.db, exports | --redact on export | Auto-prune off | Retention policy, disk encryption, redacted exports |
| Silent learning on a messaging gateway | Background review | Chat notification | on | verbose notifications; staged writes |
Two related posts go deeper: AI agent memory security risks and whether an AI agent skill file can give shell access.
Where Safeguard fits, honestly
Safeguard does not scan, govern or monitor Hermes Agent, and Hermes is not a Safeguard integration or partner. The honest connection is narrower. A learning agent produces software artifacts: skills with scripts, code it writes into your repositories, and packages it installs while working. Those artifacts flow into codebases and container images like any other code. Safeguard generates and analyses SBOMs (SPDX and CycloneDX) for repositories and images, matches components against vulnerability data, applies policies and gates in CI, and supports attestation and signing (SLSA, Sigstore, in-toto). That is useful for whatever an agent changes in your projects, whichever agent it is. It does not review memory entries or skill prose, and it makes no claim to detect malicious skills.
Common mistakes
- Assuming "learning" means training. Nothing in this loop changes model weights. If you switch models, the memory and skills come with you; so do any mistakes in them.
- Leaving both
write_approvalkeys at their defaults on a shared or unattended agent. On a gateway or cron host, the background review writes without anyone watching. - Treating
display.memory_notifications: offas "learning off". It only hides the chat line. Useauxiliary.background_review.enabled: falseto stop automatic reviews. - Thinking a pin freezes a skill. Pinning blocks deletion and archival, not patches.
- Never running
/newon messaging platforms. Fresh memories stay invisible and the loop barely runs. - Pointing two agents at one Hermes home. Their memories compound into state nobody wrote.
- Approving skill writes from the one-line gist alone. Read the full diff, especially for new
scripts/files.
FAQ
How does Hermes Agent learn?
It writes text, not weights. It saves short facts to MEMORY.md and USER.md, writes and patches Markdown skills with skill_manage, and searches past sessions in a SQLite FTS5 database. A background review re-reads conversations to decide what to save, and a curator archives skills that go unused.
Does Hermes Agent train or fine-tune its own model?
No. The learning loop changes files under ~/.hermes. The model is whichever provider and model you configured. Nous Research does train the separate Hermes model family, but that is a different product from the agent's learning loop.
What happens when Hermes Agent memory is full?
The write fails with an error that shows current usage and entries. The agent must remove or shorten entries and add the new one in a single batch. Memory never auto-compacts or silently drops entries. You can raise the caps with memory.memory_char_limit and memory.user_char_limit, at a token cost in every prompt.
How do I stop Hermes Agent from saving skills without asking?
Set skills.write_approval: true in ~/.hermes/config.yaml or run /skills approval on. Every skill write is then staged for /skills pending, /skills diff, /skills approve or /skills reject. Do the same for memory with memory.write_approval: true.
Can I turn off the Hermes Agent background review?
Yes. Set auxiliary.background_review.enabled: false. You can still run a review by hand with /refine. You can also lower its frequency through memory.nudge_interval and skills.creation_nudge_interval, or route it to a cheaper model.
Is Hermes Agent's memory safe from prompt injection?
Memory writes are scanned for injection, exfiltration and SSH backdoor patterns and for invisible Unicode, but the scanning is pattern based. The stronger control is human approval of writes, plus regular review of USER.md, MEMORY.md and skill diffs.
How do I undo something Hermes Agent learned?
For skills, use hermes curator rollback <entry-id> to undo one ledgered change or hermes curator rollback --id <ts> to restore a snapshot. For memory, use hermes journey delete <node> or edit the file. Back up first, and start a new session afterwards.
What is the difference between Hermes Agent and the Hermes models?
Hermes Agent is Nous Research's open source agent software, which runs on many model providers. The Hermes models are Nous Research's open-weight language models. You can use the agent without the models and the models without the agent.
Has Hermes Agent had security vulnerabilities?
Two CVE records were published on 3 September 2026: CVE-2026-71963, an OS command execution issue through git configuration in a repository, affecting 0.18.2 through 0.21.0, and CVE-2026-85105, a session authorization bypass reported against 0.18.0. Neither is in the learning loop. We cover them in our posts on CVE-2026-71963 and CVE-2026-85105.
Fix it without waiting for upstream
A learning agent does more than remember: it installs packages, writes scripts into skills and edits code in your repositories, and all of that becomes part of the software you ship. The agent's own dependency tree, plugins and skill scripts are open source components that receive CVEs like any other, so the patching gap below applies to them too.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The Safeguard MCP server can be one of the tools an AI assistant uses, so supply chain questions get answered from real SBOM and vulnerability data rather than from the model's memory. This demo shows adding Safeguard from Claude's connector directory, signing in with OAuth and choosing which tools Claude may call. The same per-tool choice is the principle this post argues for in an agent's learning loop: decide up front what an assistant is allowed to touch.
Click through it at your own pace, or open it full screen.
The Safeguard CLI is an assistant that edits code and runs commands, and it asks before each command. In this session it fixes a lodash CVE: it reads the finding and advisory, edits package.json, runs npm install and npm test with approval, and pushes nothing. Approve-before-write is the same pattern as Hermes's write_approval gates, applied to dependency fixes.
Click through it at your own pace, or open it full screen.
If your agents run on your own hardware, scanning should too. This demo sets up the Safeguard runner on your own machine, approves it with a device code and scans from the terminal, which suits a repository an agent has just changed or a skills repository you version with git.
Click through it at your own pace, or open it full screen.
To try it on your own code, download Safeguard or read the CLI documentation.
Quick check
A Hermes agent saves a new memory during a session. When does the model first see it in its system prompt?
At the start of the next session. Memory is injected as a frozen snapshot at session start; writes go to disk immediately but do not change the running session's system prompt.
You pinned a skill. Can the agent's background review still change it?
Yes. Pinning blocks deletion and curator archival, but patches and edits still go through. To require approval for every change, set skills.write_approval: true.
Sources
- NousResearch/hermes-agent repository and README
- Hermes Agent docs: Persistent Memory
- Hermes Agent docs: Skills System
- Hermes Agent docs: Curator
- Hermes Agent docs: Sessions
- Hermes Agent docs: Configuration
- Hermes Agent docs: Honcho Memory
- Hermes Agent docs: Security
- Hermes Agent source: agent/prompt_builder.py
- Hermes Agent source: agent/background_review.py
- Hermes Agent example configuration: cli-config.yaml.example
- Hermes Agent v0.18.0 release notes
- Hermes Agent v0.2.0 release notes
- Hermes Agent releases
- Nous Research: Releases
- Nous Research blog: Refactoring Hermes with 1,393 agents
- Agent Skills specification
- Honcho README (Plastic Labs)
- SQLite FTS5 Extension
- arXiv 2305.16291: Voyager
- arXiv 2303.11366: Reflexion
- arXiv 2310.08560: MemGPT
- OWASP GenAI Security Project: LLM01 Prompt Injection
- CVE.org: CVE-2026-71963
- CVE.org: CVE-2026-85105
Last reviewed: 23 October 2026. Hermes Agent ships several releases a week; check the docs for your installed version before relying on any default or config key above.