Hermes Agent Learning Loop & Skills
TL;DR
- Hermes writes a reusable skill document every time it completes a multi-step task with confidence ≥ 0.7
- Skills are Markdown files with structured frontmatter: inspectable, editable, and importable from OpenClaw ClawHub
- On repeated workflows, skill-assisted Hermes runs 40–60% faster than cold-start Hermes in measured tests
- You can guide the learning loop by seeding it with example tasks and adjusting the confidence threshold
This guide assumes Hermes is already running via the Docker Compose stack. If it isn't, start there.
What the learning loop actually does
Every Hermes session runs the same agentic loop: plan → execute → reflect → synthesise. The learning loop is a post-synthesis step that runs only when certain conditions are met.
Task completed
↓
Self-reflection: did the output meet the goal? (confidence score 0.0–1.0)
↓ confidence < 0.7
Task logged as low-confidence; no skill written.
↓ confidence ≥ 0.7
Check: was this task type solved successfully in the last 10 similar tasks?
↓ yes (duplicate)
Skip — skill already exists.
↓ no (novel or improved)
Distil: extract steps, tool calls, decision points from working memory
↓
Generalise: rewrite as a reusable procedure
↓
Self-test: run a synthetic variant of the original task using only the skill document
↓ self-test fails
Discard skill; log for review.
↓ self-test passes
Write skill document to /data/skills/<slug>.md
Index in semantic memory (pgvector embedding)
The self-test is what separates Hermes's skill library from a simple log of past prompts. Hermes doesn't write a skill if it can't prove the skill generalises to at least one variant of the original task.
The SKILL.md format
Skills are Markdown files with YAML frontmatter. The format is compatible with OpenClaw ClawHub's SKILL.md standard, so skills can be exported and imported between systems.
---
name: weekly-crm-sales-summary
version: 1.0.0
intent: "Fetch the week's CRM activity, calculate deal velocity, compare to the prior week, and flag accounts where engagement dropped more than 20%."
tools:
- http-get
- sql-query
- text-analysis
confidence_threshold: 0.7
created: 2026-05-01T09:14:23Z
last_used: 2026-05-01T09:14:23Z
use_count: 1
author: hermes-learning-loop
tags: [crm, reporting, sales]
---
# weekly-crm-sales-summary
## Intent
Fetch the week's CRM activity, calculate deal velocity, compare to the prior week, and flag accounts where engagement dropped more than 20%.
## Steps
1. Query the CRM API for all deals updated in the past 7 days.
- Endpoint: `GET /api/v1/deals?updated_after={iso_date}`
- Required fields: `id`, `name`, `stage`, `owner`, `last_activity_at`, `value`
- Handle pagination with `?page={n}` until `has_more: false`.
2. Fetch the equivalent data for the prior week (days 8–14).
3. Calculate deal velocity for both weeks:
- Velocity = (deals advancing stage) / (total active deals)
- Group by sales owner.
4. Identify accounts where engagement dropped > 20%:
- Engagement proxy: `last_activity_at` recency delta between weeks.
- Flag threshold: engagement this week < 80% of engagement prior week.
5. Format output as a structured report:
- Summary table: owner, this-week velocity, prior-week velocity, delta.
- Flag list: account name, owner, engagement delta, recommended action.
## Decision points
- If the CRM API returns 429 (rate limit): wait 60 seconds and retry once.
- If a deal has no `last_activity_at`: treat as zero engagement — do not omit.
- If the dataset is empty (no deals updated): return "No CRM activity this week" rather than computing division by zero.
## Example output (abbreviated)
| Owner | This week | Prior week | Delta |
|---|---|---|---|
| Alice | 0.38 | 0.31 | +22% |
| Bob | 0.21 | 0.29 | −28% |
Flagged accounts (engagement drop > 20%):
- Acme Corp (Bob): −31% — last activity 9 days ago. Recommend outreach.
The frontmatter intent field is what pgvector indexes. When a future task arrives, Hermes computes the embedding of the task description and retrieves skill documents whose intent embedding is within a configurable cosine distance threshold (HERMES_SKILL_RETRIEVAL_THRESHOLD, default 0.85).
Hands-on example: training Hermes on a repeated workflow
The fastest way to build a useful skill library is to run real workflows (the ones you actually need) for the first two or three weeks. Here's a concrete walkthrough using the CRM sales summary example.
Step 1: Run the task cold
Give Hermes a task it has no skill document for:
Prepare the weekly sales summary from the CRM, compare it to last week, and flag any accounts that dropped more than 20%.
On the first run (cold), Hermes works through the task from scratch. It will:
- Discover the CRM API schema (usually one or two exploratory calls).
- Construct the queries.
- Calculate the metrics.
- Format the report.
- Reflect on whether the output is correct.
A cold run for this task takes approximately 4–7 minutes on a remote LLM API (Claude Opus 4.7 via the Anthropic endpoint), depending on CRM dataset size.
After completion, check whether a skill document was written:
docker compose exec hermes ls /data/skills/
# weekly-crm-sales-summary-v1.md ← created if confidence ≥ 0.7
If no file appears, check the logs:
docker compose logs hermes --tail 50 | grep -E 'Skill|confidence|threshold'
A low-confidence output usually means the CRM API returned unexpected data or the task was ambiguous. Refine the task description and re-run.
Step 2: Inspect the skill document
docker compose exec hermes cat /data/skills/weekly-crm-sales-summary-v1.md
Read the generated steps carefully. The learning loop is good at capturing successful tool call sequences but can be overly specific about values (e.g., hardcoding a specific date range instead of deriving it dynamically). Common edits worth making:
- Generalise date references. Replace any hardcoded
2026-04-28withtoday - 7 daysor{last_week_start}so the skill stays valid next week. - Broaden the intent field. If the generated intent is "Prepare CRM sales summary for the week of April 28", change it to "Prepare a weekly CRM sales summary comparing current vs prior week activity." The broader the intent, the wider the retrieval net.
- Check the decision points section. The loop extracts decision points from cases where Hermes branched during execution. If the task ran without encountering the rate-limit path, that decision point won't be in the skill. Add it manually if you know it matters.
Edit the skill in place:
docker compose exec hermes vi /data/skills/weekly-crm-sales-summary-v1.md
After editing, re-index the skill so pgvector picks up the updated intent embedding:
docker compose exec hermes hermes skills reindex weekly-crm-sales-summary-v1
Step 3: Measure the speedup on subsequent runs
Run the same task a second time (Hermes will retrieve the skill document from semantic memory):
# Time the cold run: ~4–7 min
# Time the skill-assisted run: ~1.5–2.5 min
In our test run on 2026-05-01 (local Docker, 4 vCPU / 16 GB, Claude Opus 4.7 as the LLM backend):
| Run | Task | Time |
|---|---|---|
| Cold (no skill) | Weekly CRM sales summary | 6m 14s |
| Skill-assisted (v1) | Weekly CRM sales summary | 2m 07s |
| Skill-assisted (v2, after edit) | Weekly CRM sales summary | 1m 49s |
The speedup comes from Hermes skipping the API discovery phase and most of the planning phase. The skill document provides the proven procedure directly, so Hermes only runs the execution and reflection steps.
The v2 improvement (1m 49s vs 2m 07s) came from broadening the intent field, which let Hermes retrieve the skill with higher confidence rather than partially replanning.
Skill retrieval in practice
When a task arrives, Hermes runs skill retrieval before starting the planning phase:
New task: "Generate the weekly sales report for the team"
↓
Embed task description
↓
Query pgvector: cosine similarity against all skill intents
↓
Retrieve skills above threshold (default: 0.85 cosine similarity)
↓
Inject retrieved skills into the planning context as "known procedures"
↓
Plan executes: preferring known procedures over exploratory calls
You can see which skills were retrieved for a task in the Hermes logs:
docker compose logs hermes --tail 100 | grep 'Retrieved skill'
# [2026-05-01 09:14:23] Retrieved skill: weekly-crm-sales-summary-v1 (similarity: 0.92)
# [2026-05-01 09:14:23] Retrieved skill: crm-api-auth-pattern (similarity: 0.87)
If a relevant skill isn't being retrieved, the similarity score is likely below the threshold. Two fixes:
- Edit the skill's intent to be closer to how you actually phrase the task.
- Lower the retrieval threshold slightly:
HERMES_SKILL_RETRIEVAL_THRESHOLD=0.80in.env. The trade-off is more false positives: Hermes retrieves skills that don't quite match and spends time deciding they don't apply.
Managing the skill library
List all skills
docker compose exec hermes hermes skills list
Output:
weekly-crm-sales-summary-v1 used 14× last used: 2026-05-01 confidence: 0.91
crm-api-auth-pattern used 8× last used: 2026-04-29 confidence: 0.88
github-pr-summary used 3× last used: 2026-04-27 confidence: 0.74
Audit stale skills
Skills that haven't been used in 30 days are likely stale:
docker compose exec hermes hermes skills audit --stale-after 30d
# weekly-github-digest: last used 45 days ago — consider deleting
Delete a skill
docker compose exec hermes hermes skills delete weekly-github-digest
Deleting a skill doesn't affect episodic or semantic memory. It only removes the skill document from /data/skills/ and its vector index entry. Hermes will regenerate a fresh skill document the next time it successfully completes a task of that type.
Export skills
Skills are plain Markdown files. Back them up alongside your volumes:
docker compose exec hermes tar -czf /backup/skills-$(date +%Y-%m-%d).tar.gz /data/skills/
docker cp hermes:/backup/skills-2026-05-01.tar.gz ./
The restic backup configured in the Docker Compose stack already includes /data/skills/ in the nightly run, so no additional backup configuration is needed.
Import OpenClaw ClawHub skills
Hermes can import skills in SKILL.md format from ClawHub. The import process adds the skill's intent to the vector index and makes it available for retrieval:
# Download a ClawHub skill
curl -O https://clawhub.dev/skills/@clawhub/linear/SKILL.md
# Import into Hermes
docker compose exec -T hermes hermes skills import < SKILL.md
Not all ClawHub skills are compatible. Hermes doesn't implement ClawHub's platform-specific tool types (WhatsApp, Telegram, etc.). Skills that rely only on HTTP, SQL, code execution, and file operations import cleanly.
Configuring the learning loop
The learning loop has three tuneable parameters, set in .env:
| Variable | Default | Effect |
|---|---|---|
HERMES_LEARNING_LOOP_ENABLED | true | Disable entirely for a pure-execution mode |
HERMES_LEARNING_LOOP_CONFIDENCE_THRESHOLD | 0.7 | Minimum confidence to write a skill. Lower = more skills, lower quality |
HERMES_SKILL_RETRIEVAL_THRESHOLD | 0.85 | Cosine similarity cutoff for skill retrieval. Lower = broader retrieval |
Raising the confidence threshold (e.g., 0.80) produces a smaller, higher-quality skill library. Hermes writes fewer skills but each one is more reliable. Use this in production when you care about reproducibility over coverage.
Lowering the confidence threshold (e.g., 0.60) produces a broader skill library. Hermes writes skills for tasks it's less certain about. This is useful during an initial training period, but it can introduce noisy or partially-correct procedures. Monitor skill quality carefully at lower thresholds.
Disabling the learning loop makes Hermes behave more like a conventional agent: every task runs from scratch. Useful for one-shot tasks where you don't want to pollute the skill library with domain-specific procedures that won't generalise.
Seeding the skill library before first use
If you know which workflows Hermes will run repeatedly, seed the library by running each workflow once as soon as the stack is up. The seeding run trains Hermes on your specific data, tools, and naming conventions before any production load.
A seeding session for a sales team might look like:
# Run 1: CRM weekly summary (Monday)
Prepare the weekly sales summary from the CRM. The CRM is Twenty CRM running at crm.internal. Compare this week to last week and flag accounts with >20% engagement drop.
# Run 2: GitHub PR digest (Monday)
List all PRs merged last week across the repos in the github.com/myorg organisation. Include: title, author, review count, lines changed. Format as a Slack-friendly digest.
# Run 3: Invoice status check (Tuesday)
Check which invoices in the billing system are more than 14 days overdue. Include the customer name, amount, and the last contact date from the CRM.
After each run, inspect the skill document, edit the intent to generalise, and re-index. By the end of a seeding week, Hermes typically has 8–15 high-quality skills covering the team's recurring workflows. From that point, the skill-assisted runs are fast enough that the agent feels more like a fast script than a cold LLM call.
Comparing skill-assisted Hermes to OpenClaw on the same task
OpenClaw and Hermes solve the same task differently:
| OpenClaw (with a matching ClawHub skill) | Hermes (with a learned skill) | |
|---|---|---|
| First run | Fast if skill exists; slow if not | Always slow (no pre-existing skill) |
| Subsequent runs | Consistent speed (skill is static) | Faster than first run; speed compounds as skill is refined |
| Skill authoring | Manual (you write the SKILL.md) | Automatic (Hermes writes it from experience) |
| Skill quality | As good as the author | Depends on task success and confidence |
| Cross-session memory | No (per-session only) | Yes (episodic + semantic memory) |
For workflows your team runs every week, the operational answer is usually: run Hermes for the first few weeks to build the skill library, then evaluate whether the skill quality is high enough to switch to a static OpenClaw skill for production stability. The skill documents Hermes generates are valid SKILL.md files, so exporting them to ClawHub is a single hermes skills export command.
For novel tasks that happen once, OpenClaw with a matching ClawHub community skill is often faster than Hermes, because Hermes still pays the full cold-start cost while OpenClaw can install a battle-tested community skill in under a minute.
Monitoring skill quality over time
Skill quality degrades when the target systems change (API updates, schema changes, new authentication requirements). Signs of degradation:
- Hermes retrieves a skill but then deviates from it mid-execution (visible in logs as
Overriding skill step N: API response unexpected). - Task confidence scores trend downward across runs.
- You notice the skill-assisted run taking longer than before, because Hermes is spending time reconciling the skill's steps with a changed environment.
Run a weekly audit:
docker compose exec hermes hermes skills audit --show-confidence-trend
Output:
weekly-crm-sales-summary-v1
Last 5 runs: 0.91, 0.89, 0.85, 0.79, 0.72 ← declining trend
Recommendation: re-run cold to regenerate skill
A declining confidence trend usually means either the target system changed or the skill's steps are subtly wrong in a way that Hermes is compensating for rather than fixing. Delete the skill and run the task cold to produce a fresh document.
What Hermes does not learn
The learning loop has explicit scope limits (as of v0.12.0):
- User preferences about output format: Hermes remembers these in episodic memory, not skills. Preferences (e.g., "always use bullet points", "always include an executive summary") are recalled from the episodic store, not written into skill documents.
- Authentication credentials: never written to skill documents. Credentials flow through the environment variables and are retrieved from the secrets store at runtime.
- Tasks that failed: the learning loop only writes on success with confidence ≥ 0.7. A failed task contributes to episodic memory (Hermes "remembers" it tried and failed) but not to skills.
- One-shot tasks: single-message, single-step completions don't trigger the learning loop. The loop activates only for tasks that required a planning phase (≥ 2 steps with tool calls).
A seeding week of running real workflows produces a useful library of 8–15 skills. After that, the library grows organically as Hermes encounters new task types. Most teams see meaningful time savings (40%+ on repeated tasks) within 2 weeks of regular use.
Yes. Mount the same hermes_skills volume from both instances, or copy skill files between instances with `docker cp`. Both instances write skills to /data/skills/. If they run concurrent tasks of the same type, they may produce duplicate skills (same intent, slightly different steps). Run `hermes skills deduplicate` to merge duplicates by highest use_count.
Skill documents are plain Markdown files on the hermes_skills volume. They survive upgrades as long as you don't run `docker compose down -v`. After upgrading, the vector index is rebuilt automatically on first startup from the existing skill files. This can take 1–2 minutes if you have a large skill library.
Yes. Drop a SKILL.md-format file into /data/skills/ and run `hermes skills reindex <filename>`. Hermes will start retrieving it for matching tasks. The quality of manually authored skills depends entirely on how well you write the `intent` field: the more natural-language the description, the better the retrieval.
Yes, with one caveat: the self-test phase (where Hermes validates the skill on a synthetic task variant) uses the same LLM as the main task. With a 7B local model, self-tests are less reliable than with Claude Opus 4.7, because the smaller model is more likely to pass a skill that has subtle errors. Consider raising HERMES_LEARNING_LOOP_CONFIDENCE_THRESHOLD to 0.80 when using local 7B models.
Common mistakes and fixes
Learning loop completes tasks but never writes skill documents.
The loop only writes a skill document when confidence ≥ 0.7. Check logs: `docker compose logs hermes --tail 100 | grep 'Skill write threshold'`. If you see 'threshold not met', the task is either failing mid-loop or producing low-confidence outputs. Break the task into smaller, more specific steps. High-confidence completions on sub-tasks compound into higher-confidence skill documents.
Skill documents exist in /data/skills/ but Hermes doesn't retrieve them on repeated tasks.
Skill retrieval depends on semantic similarity between the new task and the skill's frontmatter `intent` field. If the intent is too narrow, it won't match. Inspect the skill: `docker compose exec hermes cat /data/skills/<skill-slug>.md`. If the intent is task-specific rather than general, edit the frontmatter `intent` field to a more abstract description of the task class.
Skill documents accumulate outdated steps after the target API changes.
Run `docker compose exec hermes hermes skills audit` to find skills with >30-day-old last-use dates. Delete stale skills and let Hermes relearn: `docker compose exec hermes hermes skills delete <skill-slug>`. The next time Hermes encounters the task type, it will produce a fresh skill document reflecting the current API.



