Skip to content

Building Reusable Skills

This module covers the memory architecture and procedural self-improvement of Nous Research's Hermes Agent , a real, actively-maintained open-source project (github.com/NousResearch/hermes-agent) with persistent memory and a skill system the agent builds up over time.

Note on this rewrite: an earlier version of this module described a fictional PostgreSQL/pgvector memory store and a Docker-compiled Python skill pipeline. Neither matches how Hermes Agent actually works. This version is grounded in the real docs: memory is file-based (Markdown + SQLite), and skills are markdown instruction files the agent writes for itself, not compiled code.

Owl mascot

What you'll learn

  • How Hermes Agent's frozen-snapshot memory keeps prefix caching cheap
  • Full-text (not vector) session search via SQLite FTS5
  • Writing a real, reusable SKILL.md the agent can invoke later

How it works

Traditional agents are constrained by static, hardcoded tools. Hermes Agent's approach to self-evolution is procedural, not code-generation: when it works through a non-trivial task, it can write down the reusable procedure as a skill , a markdown instruction file, for its future self.

A. Memory Architecture: Frozen Snapshot, Not Live Retrieval

Hermes stores memory as two Markdown files under ~/.hermes/memories/, not a database:

  • MEMORY.md (≈2,200 characters / ~800 tokens): environment facts, project conventions, tool workarounds, and task logs, the agent's own notes.
  • USER.md (≈1,375 characters / ~500 tokens): identity details, communication preferences, and the user's technical skill level.

At session start, both files are loaded and rendered into the system prompt as a frozen block , unchanged for the rest of the conversation, specifically to preserve LLM prefix caching (re-computing a changing prefix on every turn is the expensive path; see Prompting & Context Engineering for why that matters). Everything else, full conversation history across all past sessions, lives in SQLite (~/.hermes/state.db) with FTS5 full-text indexing, reachable through the session_search tool. Note this is full-text search, not semantic/vector search: session_search returns exact message matches, no embedding similarity, no LLM summarization.

B. Skill Storage & Format

Skills are Markdown files with YAML frontmatter, stored in ~/.hermes/skills/ (the source of truth) , the same SKILL.md pattern used by OpenClaw (see Exposing Agents to Users). A skill is procedural memory: instructions for a task the agent has already solved once, not a compiled function.


Options & when to use each

StrategyExtensibilityExecution SafetyLatencyError RecoveryPrimary Production Bottleneck
Static ToolsLow (requires redeploy)Very HighUltra-LowN/A (fixed logic)Rigid limits during novel edge-case tasks
Code InterpreterHigh (ad-hoc run)LowModerateLowArbitrary code execution needs a real sandbox boundary
Markdown Skill Files (Hermes/OpenClaw pattern)HighHigh (no new code path, reuses existing tools)Low (no compile step)Moderate (agent must judge relevance correctly)A skill's instructions go stale as the underlying tools/APIs change
External API PluginsModerateHighModerateLowDynamic API payload formatting changes

Markdown-file skills trade the theoretical ceiling of "the agent writes arbitrary new code" for a much smaller, auditable surface: a skill can only ever compose tools that already exist and are already sandboxed. That's a safety win over a code-generation approach, at the cost of not being able to genuinely add new capabilities the agent doesn't already have a tool for.


Build it

A. Install and First Run

To install the Hermes Agent platform on your machine, execute the appropriate setup curl command for your operating system and initialize the shell environment:

bash
# Linux/macOS/WSL2/Android (Termux)
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash

# Windows PowerShell
iex (irm https://hermes-agent.nousresearch.com/install.ps1)

source ~/.bashrc
hermes

The installer handles its own dependencies (Python 3.11, Node.js v22, ripgrep, ffmpeg) , no separate conda/uv environment needed. Per-user installs land in ~/.hermes/ (data/config) and ~/.local/bin/hermes (binary).

B. Configure Provider & Tools

After installation, run the onboarding commands to link your account to the Tool Gateway portal, select a generative model, and configure system integrations:

bash
hermes setup --portal   # recommended: one subscription, 300+ models + Tool Gateway
hermes model            # choose your LLM provider directly, if not using --portal
hermes tools             # enable/disable individual tools

C. Requesting a Skill

Skills aren't hand-written up front, you ask the agent to solve a task, and once it's done something non-trivial and reusable, you can have it capture that as a skill:

text
hermes> Write a script that reports CPU and RAM load, and save this as a reusable skill called 'system-load'.

The agent uses its skill_manage tool to write ~/.hermes/skills/system-load/SKILL.md:

markdown
---
name: system-load
description: Reports current CPU and RAM load percentages.
metadata:
  hermes:
    tags: [system, monitoring]
---
# System Load Check

## When to Use
The user asks for current CPU or RAM utilization.

## Procedure
Run `top -bn1 | head -5` and `free -h`, then summarize the CPU and RAM
percentages in one sentence.

## Verification
Confirm the reported percentages are within 0-100%.

Invoke it later via slash command or natural language:

text
hermes> /system-load

or chain skills together: /system-load /some-other-skill do a full health check.


What goes wrong

| Mistake | How you notice it | The fix | | :--- | :--- | :--- | :--- | | Skill Not Picked Up | Agent doesn't follow the new skill's procedure. | Malformed YAML frontmatter, or the skill file watcher missed the change mid-session. | Validate frontmatter; start a new session to force a fresh skill-list load. | | Stale Frozen Memory | Agent references outdated environment facts mid-conversation. | MEMORY.md/USER.md are loaded once at session start and deliberately not re-read until the next session (prefix-caching tradeoff). | Update memory explicitly, then start a new session, don't expect a mid-session memory edit to take effect immediately. | | session_search Misses Relevant Context | Agent can't recall a past conversation you know exists. | FTS5 is full-text/keyword search, not semantic, a paraphrased query with no shared keywords won't match. | Search with the actual terms/phrasing used in the original conversation, not a paraphrase. | | Tool Call Blocked by Approval Mode | Command execution pauses for manual confirmation, or is rejected outright. | approvals.mode is manual, or the command hits the hardline blocklist (irreversible operations like rm -rf /) that no config setting can override. | Check approvals.mode; irreversible-command blocks are intentional and not meant to be bypassed. |


Confirm it worked

To verify your agent's memory and skill system:

  1. Confirm the install and check diagnostics:
    bash
    hermes doctor
  2. Inspect what's loaded into a fresh session's context: Start hermes and ask it directly: "What's in your current memory?" , it should paraphrase the contents of MEMORY.md/USER.md, since both are already in its frozen system-prompt block.
  3. Confirm a skill was actually written to disk:
    bash
    cat ~/.hermes/skills/system-load/SKILL.md
    Confirm the frontmatter (name, description) and body ("When to Use," "Procedure," "Verification") match what you asked for.
  4. Confirm reuse on a fresh session: restart hermes, then run /system-load immediately, it should execute without re-deriving the CPU/RAM-check logic from scratch, since the skill now persists across sessions.

Next: Multi-Agent Workflows & State Management , coordinating more than one agent, each with its own skills and memory, on a single task.