Hermes Deep Dive: The Developer’s Guide - 2026-09-18
The developer tooling landscape in 2026 has a fragmentation problem. Your AI coding agent lives in one tab, your CI pipeline in another, your observability stack somewhere else, and the glue holding them together is a fragile mess of shell scripts and webhooks. Hermes emerged from this chaos with a deceptively simple premise: what if your agent runtime, your task orchestration, and your deployment pipeline all spoke the same protocol?
This guide covers Hermes from installation through advanced multi-agent workflows, with working code you can run today.
What is Hermes?
Hermes started in late 2024 as an internal tool at a Berlin-based infrastructure company that was tired of rewriting the same “call an LLM, parse the output, do something with it” loop across a dozen microservices. The first public release landed in early 2025, and by mid-2026 it has grown into a full agent orchestration runtime with a plugin ecosystem spanning over 400 community packages.
Core value proposition
Hermes is a local-first, protocol-driven agent runtime. Unlike cloud-hosted agent platforms that lock your workflows into a proprietary dashboard, Hermes runs on your machine or your infrastructure and exposes everything through a typed RPC interface called the Hermes Wire Protocol (HWP).
The pitch is straightforward:
- Deterministic replay. Every agent run is logged as a sequence of typed events. You can replay any run byte-for-byte, which makes debugging non-deterministic LLM behavior tractable.
- Composable skills. Agents are built from small, testable “skills” rather than monolithic prompts. A skill is just a function with a typed signature.
- Transport agnostic. The same agent definition runs over stdio, HTTP, WebSocket, or a message queue without code changes.
What makes it different
The closest comparison points are LangGraph, CrewAI, and the newer entrant Skillsync (which launched on Hacker News this week as a YC W26 company). Skillsync’s thesis is that AI chat sessions should be portable across agents — a genuinely useful idea that Hermes approaches from a different angle. Where Skillsync focuses on session portability at the conversation layer, Hermes treats portability as a property of the runtime protocol. If two Hermes instances speak HWP, they can hand off tasks mid-execution, including full state.
The other differentiator is the replay log. Most agent frameworks give you logs. Hermes gives you a replayable event stream that you can step through, fork, and diff. If you’ve ever spent three hours trying to reproduce a flaky agent failure, you understand why this matters.
🚀 Getting Started
Installation
Hermes ships as a single static binary plus an optional language SDK. The binary is the runtime; the SDK is a thin client.
macOS and Linux (recommended):
# Install the runtime via the official install script
curl -fsSL https://get.hermes.dev/install.sh | sh
# Verify the installation
hermes --version
# Expected output: hermes 0.14.2 (build 2026-09-11, hwp/1.3)
# Install the Python SDK (for scripting)
pip install hermes-sdk==0.14.2
# Or the TypeScript SDK
npm install -g @hermes/sdk@0.14.2
Windows (via winget):
winget install Hermes.Runtime
hermes --version
Docker (for CI environments):
docker pull hermes/runtime:0.14.2-alpine
docker run --rm -v "$PWD:/work" hermes/runtime:0.14.2-alpine hermes run /work/agent.yaml
If you’re on an air-gapped machine, the install script supports an offline mode:
# Download the tarball on a connected machine
curl -fsSL https://get.hermes.dev/releases/hermes-0.14.2-linux-amd64.tar.gz -o hermes.tar.gz
# On the air-gapped machine
tar -xzf hermes.tar.gz
sudo mv hermes /usr/local/bin/
hermes doctor # verifies signatures and dependencies
Configuration
Hermes reads configuration from ~/.hermes/config.toml by default, with per-project overrides in .hermes/config.toml. The precedence order is: environment variables > project config > user config > defaults.
A minimal working config:
# ~/.hermes/config.toml
[runtime]
# Where Hermes stores replay logs and skill caches
data_dir = "~/.hermes/data"
# Max concurrent agent executions
max_workers = 8
# Log level: trace, debug, info, warn, error
log_level = "info"
[providers.openai]
api_key = "${OPENAI_API_KEY}"
default_model = "gpt-5.2-turbo"
timeout_seconds = 120
[providers.anthropic]
api_key = "${ANTHROPIC_API_KEY}"
default_model = "claude-4.5-sonnet"
[providers.local]
# Points at a local llama.cpp or vLLM server
endpoint = "http://localhost:8080/v1"
default_model = "qwen3-32b-instruct"
[wire]
# HWP transport: stdio, http, ws, or nats
transport = "http"
bind = "127.0.0.1:7777"
# Require auth tokens for remote clients
require_auth = true
[telemetry]
# OpenTelemetry-compatible export
enabled = true
endpoint = "http://localhost:4317"
Validate your config before running anything:
hermes config validate
# Output: config OK (3 providers, 1 transport, telemetry enabled)
For secrets, Hermes integrates with the system keyring. On macOS and Linux:
hermes secrets set OPENAI_API_KEY
# Prompts for the value, stores it in the OS keyring
💡 Core Features
Feature 1: Typed Skills
A skill is the atomic unit of work in Hermes. It’s a function with a declared input and output schema, written in YAML or your language of choice. The runtime validates every invocation against the schema, which means malformed LLM outputs fail fast instead of corrupting downstream state.
Here’s a skill that summarizes a GitHub issue thread:
# skills/summarize_issue.yaml
name: summarize_issue
version: 1.0.0
description: Summarizes a GitHub issue and its comments into a structured brief.
input:
type: object
required: [issue_url]
properties:
issue_url:
type: string
format: uri
max_comments:
type: integer
default: 50
output:
type: object
required: [title, summary, action_items]
properties:
title:
type: string
summary:
type: string
maxLength: 500
action_items:
type: array
items:
type: string
steps:
- id: fetch
uses: github.fetch_issue
with:
url: "{{ input.issue_url }}"
max_comments: "{{ input.max_comments }}"
- id: summarize
uses: llm.complete
with:
provider: anthropic
model: claude-4.5-sonnet
prompt: |
Summarize the following GitHub issue thread.
Return JSON matching this schema: {{ output_schema }}
Thread: {{ steps.fetch.output }}
response_format: json
- id: validate
uses: schema.validate
with:
schema: "{{ output_schema }}"
value: "{{ steps.summarize.output }}"
Run it directly from the CLI:
hermes skill run summarize_issue \
--input '{"issue_url": "https://github.com/hermes-dev/hermes/issues/1842"}'
The real-world application here is obvious if you maintain an open-source project: wire this into a GitHub webhook and every new issue gets a structured brief in your triage channel within seconds. The schema validation means a hallucinated action_items field that’s a string instead of an array gets caught at the boundary, not three steps later.
Feature 2: Deterministic Replay
Every Hermes run produces a replay log — a compressed, append-only event stream stored under ~/.hermes/data/replays/. The log captures every skill invocation, every LLM call (including the exact prompt and response), every tool call, and every branch decision.
List recent runs:
hermes replay list --limit 5
# RUN ID SKILL STATUS DURATION STARTED
# 01J8X...A2F summarize_issue success 4.2s 2026-09-18T09:14:22Z
# 01J8X...9C1 triage_pr success 11.8s 2026-09-18T09:11:03Z
# 01J8X...7B4 summarize_issue failed 2.1s 2026-09-18T09:08:47Z
Step through a failed run:
hermes replay inspect 01J8X...7B4 --step
# Step 1/3: fetch
# github.fetch_issue(url=..., max_comments=50)
# -> 200 OK, 47 comments (cached: false)
# Step 2/3: summarize
# llm.complete(provider=anthropic, model=claude-4.5-sonnet)
# -> ERROR: context_length_exceeded (input 214,882 tokens > limit 200,000)
# Step 3/3: validate [SKIPPED]
Fork the run at the failure point and fix it without re-executing the expensive fetch:
hermes replay fork 01J8X...7B4 --at-step 2 --patch '{"max_comments": 20}'
# Forks run, re-executes from step 2 with patched input
# New run: 01J8X...D9E
This is the feature that changes how you develop agents. Instead of guessing why something failed and re-running the whole pipeline, you step through the exact event sequence. The --patch flag lets you test fixes against real captured data.
Feature 3: Multi-Transport Wire Protocol
The Hermes Wire Protocol (HWP) is a typed RPC layer that any Hermes runtime can speak. This is what enables the “hand off tasks mid-execution” capability mentioned earlier.
Start a Hermes runtime as an HTTP server:
hermes serve --transport http --bind 0.0.0.0:7777 --auth-token "$HERMES_TOKEN"
Now any HWP client can invoke skills remotely. Here’s the Python SDK:
from hermes_sdk import Client, TaskHandle
client = Client("http://localhost:7777", token="...")
# Synchronous invocation
result = client.skill("summarize_issue", input={"issue_url": "https://..."})
print(result["summary"])
# Async invocation with streaming events
handle: TaskHandle = client.skill_async(
"triage_pr",
input={"pr_url": "https://github.com/..."},
)
for event in handle.stream():
match event.type:
case "skill.started":
print(f" -> {event.skill_name}")
case "llm.token":
print(event.token, end="", flush=True)
case "skill.completed":
print(f"\nDone in {event.duration_ms}ms")
The real-world application: you can run a lightweight Hermes runtime on a developer laptop and a beefier one on a GPU box, then route skills based on their resource requirements. A local model handles the cheap summarization; the GPU box handles the 70B-parameter reasoning step. The protocol abstracts the transport, so your agent definition doesn’t care.
🛠️ Advanced Workflows
Workflow 1: CI-integrated agent with replay-based debugging
This workflow runs an agent on every pull request, posts a review comment, and captures a replay log you can inspect when the agent misbehaves.
# .github/workflows/hermes-review.yml
name: Hermes PR Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Hermes
run: curl -fsSL https://get.hermes.dev/install.sh | sh
- name: Configure providers
run: |
hermes secrets set OPENAI_API_KEY --value "${{ secrets.OPENAI_API_KEY }}"
hermes secrets set GITHUB_TOKEN --value "${{ secrets.GITHUB_TOKEN }}"
- name: Run review agent
run: |
hermes skill run review_pr \
--input '{"pr_number": ${{ github.event.number }}}' \
--replay-dir ./replays \
--fail-on error
- name: Upload replay log
if: always()
uses: actions/upload-artifact@v4
with:
name: hermes-replay-${{ github.run_id }}
path: ./replays/
retention-days: 30
When a review comes back wrong, download the replay artifact and inspect it locally:
hermes replay inspect ./replays/01J8X...A2F --step --verbose
# Shows the exact diff the agent saw, the prompt it received,
# and the reasoning trace it produced.
The --fail-on error flag makes the CI step fail if the agent hits a runtime error, but not if the agent simply produces an unhelpful review. That distinction matters — you want the pipeline to catch infrastructure failures without blocking on subjective quality.
Workflow 2: Cross-runtime task handoff
This workflow demonstrates HWP’s transport-agnostic handoff. A coordinator agent on a laptop delegates a compute-heavy step to a remote runtime.
# On the GPU box (remote)
hermes serve --transport nats \
--nats-url nats://gpu-box.internal:4222 \
--bind-subject hermes.gpu.tasks \
--register-skills embedding,rerank,long_context_reasoning
# On the laptop (coordinator)
hermes skill run research_pipeline \
--input '{"query": "state of agent runtimes 2026"}' \
--remote nats://nats.internal:4222 \
--remote-subject hermes.gpu.tasks
The coordinator’s research_pipeline skill definition references remote skills by name:
name: research_pipeline
steps:
- id: search
uses: web.search
with:
query: "{{ input.query }}"
max_results: 50
- id: embed
uses: embedding # resolved to remote runtime
with:
texts: "{{ steps.search.output.snippets }}"
- id: rerank
uses: rerank # resolved to remote runtime
with:
query: "{{ input.query }}"
documents: "{{ steps.search.output.snippets }}"
top_k: 10
- id: synthesize
uses: llm.complete
with:
provider: anthropic
model: claude-4.5-sonnet
prompt: |
Synthesize a report from these sources:
{{ steps.rerank.output }}
The key detail: embed and rerank are declared as uses: embedding and uses: rerank with no provider specified. Hermes resolves them against registered remote skills at runtime. If the GPU box goes down, you can register a fallback local implementation without touching the pipeline definition.
📊 Comparison with Alternatives
| Feature | Hermes | LangGraph | CrewAI |
|---|---|---|---|
| Deterministic replay log | ✅ Full event stream with fork/patch | ⚠️ Checkpointing only | ❌ |
| Typed skill schemas | ✅ JSON Schema validation at boundaries | ⚠️ Via Pydantic, optional | ❌ |
| Transport-agnostic RPC | ✅ HWP over stdio/HTTP/WS/NATS | ❌ Python-only | ❌ Python-only |
| Local-first runtime | ✅ Single static binary | ⚠️ Library, no runtime | ⚠️ Library, no runtime |
| Cross-runtime handoff | ✅ Native via HWP | ❌ | ❌ |
| Language SDKs | ✅ Python, TypeScript, Go, Rust | ⚠️ Python, JS (beta) | ⚠️ Python only |
| Plugin ecosystem | ✅ 400+ community skills | ⚠️ ~120 integrations | ⚠️ ~80 tools |
| Learning curve | ⚠️ Moderate (protocol concepts) | ⚠️ Moderate | ✅ Low |
| Self-hostable | ✅ Fully | ✅ Fully | ✅ Fully |
The honest take: LangGraph is more mature for pure-Python graph-based workflows, and CrewAI is faster to prototype with. Hermes wins when you need replay-based debugging, cross-language support, or the ability to distribute agent execution across machines without rewriting your pipeline.
🎯 Pro Tips
1. Use --replay-dir in CI, not the default data directory. The default ~/.hermes/data/replays/ grows unbounded and will eventually fill your CI runner’s disk. Point it at a workspace-relative directory and let your artifact retention policy handle cleanup. A 30-day retention on replays has saved us from more than one “wait, what did the agent actually see?” debugging session.
2. Pin skill versions in production pipelines. Skills are versioned (version: 1.0.0 in the YAML), and uses: summarize_issue resolves to the latest version by default. In production, always pin: uses: summarize_issue@1.0.0. A community skill update that changes output schema can silently break your pipeline otherwise. Hermes will warn you about unpinned skills in hermes doctor, but it won’t block them.
3. Set max_workers conservatively on shared machines. The default is 8, which is fine on a dedicated box but will thrash a shared dev machine when three engineers each run a pipeline. Drop it to 2-3 for local development, and use the hermes serve --max-workers flag to override per-instance rather than editing config files.
4. Leverage hermes replay diff for regression testing. When you change a prompt or a skill definition, run the same input through both versions and diff the replay logs:
hermes replay diff 01J8X...A2F 01J8X...D9E --format unified
# Shows exactly which steps produced different outputs,
# including token-level diffs of LLM responses.
This is the closest thing to unit testing for non-deterministic agents, and it’s criminally underused.
5. Register a local fallback provider. Even if you primarily use cloud providers, configure a local llama.cpp or vLLM endpoint as a fallback. When your primary provider has an outage (and they all do), Hermes can fail over automatically if you set fallback = "local" on the provider config. The output quality drops, but your pipeline keeps running.
🔗 Resources
Official documentation
- Docs:
https://docs.hermes.dev— the HWP spec lives at/spec/hwp-1.3 - Skill registry:
https://hermes.dev/skills— browse and search the 400+ community skills - Release notes:
https://github.com/hermes-dev/hermes/releases
Community
- Discord:
https://discord.gg/hermes-dev— the#replay-debuggingchannel is where the maintainers hang out - GitHub Discussions:
https://github.com/hermes-dev/hermes/discussions - Weekly office hours: Thursdays 16:00 UTC, links posted in Discord
Related tools worth knowing
- Skillsync (YC W26) — complementary to Hermes; Skillsync handles chat session portability across agents, which pairs well with Hermes’s runtime-level portability. Worth watching if you’re building multi-agent systems.
- AutoBot — live voice control for long-running AI work. Not a direct competitor, but the voice-control layer is a natural frontend for Hermes pipelines that run for minutes at a time.
- OpenTelemetry — Hermes exports OTel-compatible traces out of the box; if you already have an observability stack, your agent runs will show up alongside your service traces.
Getting help
hermes doctor— run this first for any installation issuehermes skill lint <file>— validates skill definitions before you run themhermes replay inspect <run-id> --step --verbose— your first stop for debugging
Hermes isn’t trying to be the easiest agent framework to start with — that’s CrewAI’s territory. It’s trying to be the one you don’t have to rip out when your prototype becomes production. The replay log alone justifies the learning curve if you’re shipping agents that matter. Install it, run the summarize_issue skill against a real GitHub thread, and step through the replay. You’ll see what the fuss is about within ten minutes.
Have questions? Join our Discord community or follow us on X.