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.

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.