Hermes Agent Skill Authoring — SKILL.md Structure and Best Practices
Author Hermes skills that load fast and behave reliably
Hermes Agent treats skills as the default way to teach repeatable workflows. Official documentation describes them as on-demand knowledge documents aligned with the open agentskills.io shape, loaded through progressive disclosure so the model sees a small index first and only pulls full instructions when a task actually needs them.
Authoring is less about clever wording than about packaging—you are telling the runtime when to load a procedure, what order of steps counts as “done,” and how to tell success from a silent failure. This article stays focused on SKILL.md structure, supporting folders, visibility rules, and the split between secrets and non-secret settings—the details that decide whether a skill shows up in /slash commands, survives a hub install, or quietly disappears on CI.
Hermes sits inside the broader AI Systems: Self-Hosted Assistants, RAG, and Local Infrastructure cluster, where assistants are treated as systems built from inference, retrieval, memory, and tooling rather than as a single chat surface. Install paths, provider wiring, gateway behavior, and the layout of ~/.hermes are all spelled out in the Hermes AI Assistant - Install, Setup, Workflow, and Troubleshooting guide; day-to-day shell ergonomics—hermes skills, profiles, gateway, memory—are easier to scan in the Hermes Agent CLI cheat sheet — commands, flags, and slash shortcuts. In real deployments, skills inherit isolation from profiles (separate config, secrets, memories, and skill trees). Hermes AI Assistant Skills for Real Production Setups argues for treating those profiles—not individual markdown files—as the unit of ownership; keep that in mind when you name skills and decide what belongs in shared external_dirs versus a single profile.

Skill or tool?
Official guidance is blunt. Use a skill when the capability is mostly prose instructions plus shell commands and tools Hermes already exposes—wrapping a CLI, driving git, calling curl, or using web_extract for structured fetches. Use a tool when you need tight integration for API keys and auth flows, deterministic binary handling, streaming, or Python that must execute the same way every time.
That boundary matters in practice because skills ship without changing agent code, while tools carry review and release overhead. Most teams benefit from starting with a skill, then promoting only the brittle core to a tool once the failure modes are obvious (auth refresh loops, binary parsers, strict idempotency).
Procedures versus curated memory
Skills answer how to run a workflow; Hermes’ bounded core memory answers what has already been agreed about the user and the project. A skill loads when the task matches its description; MEMORY.md and USER.md stay in the prompt as a small, curated fact layer. The two mechanisms stack rather than compete, and the full picture of snapshots, limits, and external providers is laid out in Hermes Agent Memory System: How Persistent AI Memory Actually Works.
Anatomy of a skill directory
On disk, every skill is a folder under ~/.hermes/skills/, often nested under a category such as devops/ or research/. Hermes expects SKILL.md at the leaf; everything else is optional structure you add when the instructions would otherwise sprawl. The usual pattern is references/ for long tables or vendor docs, templates/ for output skeletons, scripts/ for deterministic helpers, and assets/ for static files the agent should not re-fetch.
That layout mirrors how progressive disclosure works in practice: the agent can stay at the main file until it truly needs a deep appendix. Keeping “happy path” prose in SKILL.md and pushing rarely used detail into references/ is one of the cheapest ways to protect token budgets.
Hermes can also merge in external skill directories via skills.external_dirs in config.yaml. Those paths are scanned for discovery, but the agent still writes through skill_manage into the primary ~/.hermes/skills/ tree. Local names shadow external ones, so if you “fix” a shared skill in your home directory, teammates pulling the same external repo will not see your edit until they remove or rename the local copy—a common source of “it works on my machine” confusion.
SKILL.md frontmatter that survives review
The body of SKILL.md is Markdown; the opening block must be valid YAML between --- delimiters. Real skills accumulate long fenced examples, so the small habits from Markdown Code Blocks: Complete Guide with Syntax, Languages & Examples—consistent language tags, readable excerpts, tight fences—keep large files maintainable for humans and slightly easier for the model to scan.
Required fields are name and description. The name becomes the slash route and index key; it stays lowercase with hyphens and must respect the documented length cap. The description is the only prose many sessions ever pay for at level zero, so it should read like a search result or router string (“when backups look stale, verify latest archive and checksum”), not the first paragraph of a blog post.
Optional top-level keys such as version, author, and license help hub packaging and audits. The platforms list (macos, linux, windows) is sharper than it looks—when set, Hermes omits the skill entirely on non-matching hosts, which is why a skill that “works on my Mac” can vanish in Linux CI with no error message beyond a shorter skill list.
Hermes-specific knobs live under metadata.hermes: tags, related_skills, and the conditional visibility fields in the next section. required_environment_variables declares secrets that should land in .env and pass into sandboxes; required_credential_files covers OAuth token files and other on-disk credentials that must mount into Docker or Modal; metadata.hermes.config declares non-secret preferences stored under skills.config in config.yaml.
Official docs stress size discipline for a reason. Trim the description to its budget, front-load the procedure, and push historical notes or giant option matrices into references/ so a partial skill_view still gives the agent something actionable.
Below is a minimal SKILL.md you can drop into ~/.hermes/skills/devops/backup-check/SKILL.md (or any category folder) and iterate from there.
---
name: backup-check
description: Verify nightly backup archives exist, are non-empty, and pass a quick checksum spot-check on the latest file.
version: 1.0.0
metadata:
hermes:
tags: [devops, backups, shell]
requires_toolsets: [terminal]
config:
- key: backup_check.archive_dir
description: Absolute path to the directory that holds backup archives
default: "/var/backups"
prompt: Backup archive directory (absolute path)
---
# Backup archive spot-check
## When to use
Use when the user asks to confirm backups ran, to audit the latest archive on disk, or to catch empty or stale backup files before a restore drill.
## Quick reference
- Latest archive directory is configured under `skills.config.backup_check.archive_dir` (set via `hermes config migrate` if declared in metadata).
- Default check uses `ls` by mtime and `test -s` for non-empty files.
## Procedure
1. Resolve the archive directory from skill config or ask the user once if unset.
2. List the most recently modified file matching the expected pattern (for example `*.tar.zst`).
3. Confirm the file exists, is non-empty, and record its path and size for the reply.
4. If a checksum file exists beside the archive, verify it with the documented tool (for example `sha256sum -c`).
## Pitfalls
- Empty files can still have a recent mtime if a failed job touched the path; always check size.
- Relative paths break when the terminal cwd is not the backup host; use absolute paths in config.
## Verification
The user should see the latest archive path, byte size, and either a checksum OK line or an explicit note that no `.sha256` sidecar was found.
Progressive disclosure in practice
Progressive disclosure is the difference between a skill library that feels snappy and one that burns thousands of tokens before the first user message. Hermes walks three conceptual steps: a compact catalog (names and short descriptions), the full SKILL.md when the task matches, and—only if needed—a slice of a reference file via skill_view paths. Assume level zero is all the model will read until it explicitly commits; every sentence in the description and the first screen of body text should help routing, not storytelling.
A practical outline that survives partial loads is When to use (triggers in plain language), Quick reference (commands, env vars, file paths), Procedure (ordered steps the agent should not improvise away), Pitfalls (known failure modes), and Verification (what “green” looks like). Narrative history, vendor changelog dumps, and twenty-row option tables belong in references/ with stable headings so the agent can pull a single section.
When a skill activates, Hermes can rewrite ${HERMES_SKILL_DIR} and ${HERMES_SESSION_ID} in the body so shell lines point at the installed folder without hand-built paths. Optional inline shell snippets (!cmd``) can inject fresh context (current branch, disk free space), but they execute on the host and stay disabled unless skills.inline_shell is on—treat that flag as a trust boundary for the whole skill source, not a convenience toggle.
Conditional activation and prompt hygiene
Skills can show or hide based on which toolsets or tools exist in the current session. requires_toolsets / requires_tools gate a skill behind capabilities that must be present; fallback_for_toolsets / fallback_for_tools surface a cheaper or local path when a premium integration is absent—the DuckDuckGo fallback when a paid web search API is not configured is the canonical example.
These predicates directly shape prompt noise. An overly strict requires_* rule hides a skill from newcomers who have not finished hermes tools setup yet; an overly loose fallback_for_* rule duplicates half your library whenever someone omits an API key. The useful middle ground is to name real prerequisites, test with hermes chat --toolsets skills, and toggle keys or toolsets on purpose while watching whether the skill list breathes the way you expect.
Secrets, config, and credential files
Secrets should be declared in required_environment_variables. Hermes can prompt when a skill loads in the local CLI, persist values in .env, and pass them into terminal and execute_code sandboxes without streaming the raw secret back into the model transcript. Remote chat surfaces refuse to collect keys inline and instead point people at hermes setup or manual .env edits—author your skill text so it matches that behavior (tell users that a key is required, not *to paste it into Telegram).
Non-secret preferences—default paths, org names, feature toggles—belong in metadata.hermes.config. Values resolve into skills.config inside config.yaml, show up in hermes config show, and arrive in the skill message as resolved facts so the model does not need to open your config file mid-task.
File-shaped credentials (OAuth token JSON, service account keys) map to required_credential_files. When those files exist, Hermes can bind-mount them into Docker or sync them into Modal jobs; declaring them upfront avoids the classic “script works locally, dies in sandbox” gap.
Supporting scripts and dependencies
The upstream guide pushes authors toward boring dependencies: stdlib Python, curl, and Hermes’ own tools (web_extract, read_file, terminal). That is less about purity than about reproducibility—every extra pip install is another silent failure when the agent runs in a clean container.
When JSON or XML parsing is fiddly, a short script under scripts/ plus a ${HERMES_SKILL_DIR} path beats asking the model to re-derive parsers each run. If you truly need a package, state the install command in Procedure, repeat the failure symptom in Pitfalls, and give a Verification command that fails loudly when the dependency is missing.
Publishing, hub installs, and trust
Community skills move through the Skills Hub and the other discovery paths the user guide lists—official optional skills, GitHub slugs, skills.sh entries, .well-known indexes, and raw SKILL.md URLs. Installs are scanned for obvious exfiltration, injection, and destructive patterns; trust tiers run from builtin through community, and some findings only clear with --force while the worst cases stay blocked entirely.
The SKILL.md file shape is not Hermes-specific; IDE-centric assistants use the same progressive-loading idea with different discovery and triggers. Claude Skills and SKILL.md for Developers: VS Code, JetBrains, Cursor is a useful contrast read—frontmatter discipline and “load only when relevant” carry over, even when the installer and slash-command wiring differ.
Org-wide rollouts usually pair a private tap or shared Git repo with external_dirs for read-only sharing, while keeping the agent-writable copy under each profile when skill_manage is allowed to mutate skills in place.
Troubleshooting and optimization
When a skill misbehaves, walk this checklist before rewriting prose.
- Visibility — Confirm
platforms,requires_*, andfallback_for_*predicates. A skill that “works on my Mac” but not in Linux CI is often a platform guard. - Name collisions — Duplicate names across local and external directories follow local precedence. Rename or namespace aggressively.
- Discovery layout — A misplaced
SKILL.mdor wrong category folder can drop the skill from indexing entirely. - Token load — If sessions feel slow, shorten level-zero descriptions, move depth into
references/, and deduplicate giant tables. - Agent edits — Hermes can create, patch, or delete skills via
skill_manage. Treat valuable skills like code: review diffs, export snapshots, and reset bundled skills deliberately when upgrades drift.
A tight regression loop beats rereading the whole file: hermes chat --toolsets skills -q "Use the <skill> workflow to <concrete task>" should show the agent pulling the right disclosure level before it freestyles. If it never invokes skill_view, your When to use text or description probably does not match how people phrase requests.
Official references stay authoritative for behavior changes—the Skills System user guide for runtime semantics, Creating Skills for author-facing rules, the Bundled Skills Catalog for copy-paste examples, and the agentskills.io specification for the shared file format Hermes aligns with.