Same Skeleton, Opposite Souls: Hermes vs Claude Code
If you stripped the names off the architecture diagrams of Hermes Agent and Claude Code, you'd think they were the same project. Same agentic loop. Same tool registry. Same markdown memory files on disk. Same hooks system. Same MCP integration.
But they're built for completely opposite purposes. And the difference comes down to one question: what is memory for?
This post compares the shared architecture and the critical design split between these two agents. It's not a feature checklist or a "which is better" verdict — because that's the wrong question. One is a precision instrument you pick up for a task. The other is a resident that's always on.
Quick Primer: How AI Agents Work#
Before comparing these two, four concepts you need:
- System prompt — Hidden instructions the agent reads before every conversation. Think of it as the agent's "job description" that it re-reads at the start of every interaction.
- Tools — Functions the AI can call: read a file, run a terminal command, search the web. The AI doesn't do things directly; it asks the system to execute tools on its behalf.
- Context window — The total amount of text the AI can "see" at once. Everything — system prompt, conversation history, tool results — must fit inside this window.
- Tokens cost money — Every word sent to and from the AI has real cost. This is why both agents obsess over efficiency.
Everything in this post is either putting stuff into the context window, or trying to keep stuff out of it.
The Shared Skeleton#
Let's start with why these look identical.
The Agentic Loop#
Both agents run the same core loop:
Hermes implements this in conversation_loop.py (up to 90 iterations). Claude Code implements it in QueryEngine.ts + queryLoop() (a multi-turn state machine). Both loop until the LLM decides it's done — no more tool calls to make. Both have iteration caps to prevent runaway behavior. Both support interrupt/cancellation mid-loop. Both batch parallel-safe tools for concurrent execution.
Here's what one cycle looks like concretely:
User: "Fix the bug in auth.ts"
Iteration 1: LLM calls
Read("auth.ts")→ sees error on line 42 Iteration 2: LLM callsEdit("auth.ts", fix)→ file updated Iteration 3: LLM callsBash("npm test")→ tests pass Iteration 4: LLM responds "Fixed!" → loop ends
This is the universal pattern. Every agentic system — Cursor, Codex, custom agents — uses this same skeleton. It's think → act → observe, repeated.
Tool Registry with Progressive Disclosure#
Both have ~40 built-in tools registered in a central registry. And both face the same scaling problem: each tool has a schema (a description of what it does, what arguments it takes). Forty tool schemas stuffed into the context window every turn means thousands of tokens wasted, even if the model only uses 2-3 tools.
Both solve it identically — let the model discover tools on demand:
- Tell the LLM which tools exist (just the names — cheap)
- LLM calls a "search" tool when it needs one
- System returns the full schema for just that tool
- Only discovered tools get full schemas in subsequent turns
Hermes uses three bridge tools: tool_search (keyword search), tool_describe (get full schema), tool_call (invoke a deferred tool). It activates automatically when deferred tools would consume more than 10% of context.
Claude Code uses a ToolSearch tool that returns special tool_reference blocks the API expands into full schemas. Discovered tools persist even after conversation summaries.
Here's the flow:
Turn 1: Model sees "Core tools available: Read, Edit, Bash, Grep, WebFetch..." (names only — ~200 tokens) Turn 2: Model calls
ToolSearch("database")→ gets full schema forquery_dbTurn 3+:query_dbschema stays loaded alongside core tools
When two independent teams converge on the same solution, that's a signal. Progressive disclosure isn't clever engineering trivia — it's the only way to scale tool count without bankrupting the context window.
Markdown Memory on Disk#
Both persist memory as plain markdown files on the filesystem:
- Hermes:
~/.hermes/memories/MEMORY.md+USER.md - Claude Code:
~/.claude/projects/<project>/memory/directory with aMEMORY.mdindex and topic files
(Claude Code also has CLAUDE.md, but that's project instructions you write and check into the repo — shared with the team, more like a README for the agent. The auto memory system is the memory/ directory, where Claude writes notes for itself.)
Both load memory into context at the start of every session. Both allow the agent to read/write memory via tool calls. Both use structured formats. Both cap memory size to prevent unbounded growth.
Same idea. Markdown files. On disk. Loaded into context. No vector database. No embeddings. Just files.
It looks like they copied each other's homework. But how they use this memory — that's where everything splits.
Hooks, Plugins, and MCP#
Both are extensible via the same mechanisms:
Lifecycle hooks — Both fire events before and after tool execution, allowing external code to block, approve, or modify behavior. Think middleware in a web server.
Plugin/skill systems — Both support user-installed extensions that add new tools and behaviors.
MCP (Model Context Protocol) — A standard protocol that lets agents plug in external tools. Think of it like USB for AI: a Postgres MCP server gives both agents database access. A Slack MCP server gives both messaging. The agent doesn't care how the tool is implemented; MCP standardizes the interface.
Sub-agents — Both can spawn isolated child agents for parallel workstreams. Hermes calls it delegate_task. Claude Code calls it Agent (with optional worktree isolation — a separate copy of the code so agents don't conflict).
At this point, you should be thinking: these are the same thing with different logos. And architecturally, you'd be right.
The Pivot: Memory Philosophy#
Everything above is plumbing. The real design decision isn't how to build an agent — it's: what role does memory play?
Claude Code: Memory as Influence#
Claude Code's design principle: each session is essentially fresh. Memory exists, but it's background influence — not the driver.
The system prompt explicitly tells the model: "Memory records can become stale. Before acting on memory, verify against current state." Semantic recall selects at most 5 relevant memories per turn — a light touch. The model is expected to reason from the actual code in front of it: git status, file reads, grep results. Memory is never enforced; it can be wrong, and the system knows it.
Why is this right for coding?
- Code changes constantly. A memory from last week about "the auth module" might be completely wrong after a refactor.
- You want the model reading
auth.tsright now, not recalling what it looked like three days ago. - Coding is high-precision work. Stale assumptions = wrong code = bugs.
- Fresh eyes on each session is a feature, not a bug.
Here's what memory-as-influence looks like in practice:
Monday: You refactor the auth module from class-based to functional. Claude Code helps, session ends. Background extraction saves a memory: "Auth module uses functional pattern with composable middleware."
Thursday: You open a new session: "Add rate limiting to the auth flow." Claude Code recalls that memory — but doesn't trust it blindly. First thing it does:
Read("lib/auth.ts")to verify the current structure. Only then does it write code that fits.What if someone refactored it back to classes on Wednesday? Claude Code would see that in the file and adapt. The memory is a hint about where to look, not a fact about what's there.
Claude Code also obsesses over keeping the current session alive as long as possible. It has 5 increasingly expensive compaction strategies — from "delete old tool results" (free) up to "summarize everything with an LLM call" (expensive, last resort). The logic: the files you've read and errors you've hit today are worth more than any cross-session memory.
The analogy: Claude Code is like a brilliant contractor. Every time you hire them, they show up fresh, read the blueprints, look at what's actually built, and do excellent work. They might remember your preferences from last time, but they trust the blueprints over their memory.
Hermes: Memory as the Whole Point#
Hermes takes the opposite stance. It's a daemon — a background process that never truly resets. Memory isn't supplementary; it's the product. The agent gets measurably better at you the longer it runs.
The killer feature is the Closed Learning Loop:
- Observe — Every 10 tool-calling iterations, a background thread analyzes what just happened
- Extract — Decides what should be persisted as a reusable "skill" (not just a fact — a procedure)
- Load — Next session, skill index is in the system prompt. The LLM decides which to activate.
- Improve — Agent patches existing skills mid-session via 9-strategy fuzzy matching
- Curate — Unused skills auto-archive after 90 days. Active skills evolve.
The distinction between what these two systems save is revealing:
- Claude Code saves facts: "user prefers TypeScript", "project uses Prisma"
- Hermes saves procedures: reusable multi-step playbooks with references, templates, and verification scripts
A Hermes skill looks like this on disk:
~/.hermes/skills/python-debugging/
├── SKILL.md (instructions that evolve over time)
├── references/ (knowledge banks, API docs)
├── templates/ (starter files)
└── scripts/ (verification scripts)
And here's what skill evolution looks like across sessions:
Session 1: You ask Hermes to deploy your app. It figures it out from scratch. Background review fires: "User deploys to Railway via
railway up. Save this." → Createsdeployment/SKILL.mdwith the procedure.Session 5: You deploy again. Hermes loads the skill, follows the procedure, succeeds faster. Mid-session it notices: "Oh, they run
npm run buildfirst now." → Patches the skill with the new step.Session 20: The skill now includes error handling, rollback steps, and a pre-deploy checklist — all accumulated from real usage, with no manual maintenance.
Beyond skills, Hermes has session_search — full-text search over ALL past conversation history (SQLite with FTS5 indexing). No LLM call needed. Two weeks ago you debugged a weird Docker networking issue. You don't remember the fix. Hermes does — it can keyword-search across every session you've ever had and pull up the exact exchange.
Why this is right for a personal daemon: Hermes runs on 20+ platforms (Telegram, Discord, Slack, desktop). It handles scheduling, research, and conversations — not just coding. Your preferences, workflows, and recurring tasks are stable. Getting better at predicting what you need is the value proposition. Always-on means always-accumulating.
Both tools have scheduling too — but the difference is revealing. Hermes has a built-in cron system that delivers results to wherever you are (Telegram, Slack, Discord) because it's a multi-platform daemon. Claude Code has /loop (run a prompt repeatedly while the session stays open) — it operates within a single session rather than across platforms.
Both can do things on a schedule. But one delivers results to your phone at 6am; the other runs within the session you're working in.
The analogy: Hermes is like a personal assistant who's been with you for years. They know your schedule, your preferences, how you like things done. They don't re-read your manual every morning — they are the manual.
Why This Split is Inevitable#
These aren't just different product decisions. They reflect a fundamental tension in agent design:
- Coding needs fresh reasoning — the source of truth is the code, right now
- Personal assistance needs accumulated knowledge — the source of truth is patterns over time
- You can't optimize for both simultaneously
What happens when you get this wrong?
- A coding agent that over-trusts memory → suggests refactors based on stale architecture → introduces bugs
- A personal daemon that distrusts memory → asks you the same questions every session → never improves
This is why "which is better" is the wrong question. They're optimized for opposite ends of a real tradeoff. The right question is: what are you trying to do?
The Complementary Workflow#
The architecture supports running both together:
Hermes as the persistent layer: always on, accumulating context, handling scheduling, delivering across platforms. Claude Code as the precision layer: deep coding sessions with fresh eyes on the actual codebase. Hermes can shell out to Claude Code via its terminal tool when coding work is needed.
Here's what that looks like:
Morning: Hermes's cron job summarizes overnight GitHub notifications, pings you on Telegram: "3 PRs need review, 1 CI failure on the auth service."
You reply: "Fix the CI failure."
Hermes delegates: Spawns Claude Code via shell. Claude Code opens the project fresh, reads the failing test, reads the code, fixes the bug, pushes.
Hermes reports back: "Fixed. Missing env var in test config. PR #247 pushed."
Evening: Hermes's skill for "CI triage" now includes the pattern "check env vars in test config" — it learned from the interaction.
Think of it like a chief of staff who knows everything about you and your priorities, delegating to a specialist surgeon who needs fresh focus and zero stale assumptions for each operation.
Summary#
Side-by-side comparison
| Aspect | Claude Code | Hermes |
|---|---|---|
| Purpose | Coding specialist — precision instrument | Personal daemon — always-on resident |
| Memory philosophy | Memory as influence (verify before trusting) | Memory as product (accumulate and evolve) |
| What it saves | Facts: preferences, project context | Procedures: multi-step playbooks with templates |
| Session model | Fresh each time, current session is king | Never resets, skills evolve across sessions |
| Scheduling | /loop — runs within a session | Built-in cron — delivers across platforms |
| Platforms | Terminal, IDE, Web | 20+ platforms (Telegram, Discord, Slack, desktop...) |
| LLM providers | Anthropic (deep optimization) | 34+ providers (resilience + choice) |
| Extensibility | MCP, hooks, skills, sub-agents | MCP, hooks, plugins, sub-agents |
| Cross-session recall | Semantic recall (≤5 memories/turn) | Full-text search over all past sessions |
What Developers Can Learn#
If you're building your own agent, these two systems offer converging evidence on what works:
The agentic loop is solved. Every agent uses think → act → observe. Don't reinvent it. Focus on what goes into the loop: your tools, your context strategy, your memory.
Progressive disclosure is mandatory at scale. If you have more than 10 tools, don't send all their schemas every turn. Let the model discover them. Both agents converged on this independently.
Decide your memory philosophy early. Is your agent a tool the user picks up (memory = soft suggestions)? Or a presence that accumulates (memory = evolving procedures)? This shapes your entire architecture. Trying to do both makes both worse.
Don't change your system prompt mid-session. If you do, you invalidate the LLM's prompt cache — the provider caches the beginning of your prompt and skips re-processing it on repeated calls. Changing the prompt busts that cache, making every subsequent call slower and more expensive. Both agents learned this and freeze their system prompt at session start.
Markdown files on disk are fine for memory. Both world-class agents use plain files. No vector database, no embeddings. Simple files with structure scale to real production.
MCP is the extensibility standard. If you want third-party tools to plug into your agent, use the Model Context Protocol. It's what both adopted. Building a custom plugin API from scratch is reinventing the wheel.
Provider lock-in trades flexibility for depth. Claude Code commits to Anthropic and gets prompt caching, tool_reference expansion, and cache editing that generic agents can't access. Hermes stays provider-agnostic (34+ providers) and gets resilience plus user choice. Neither is wrong — but you have to pick.
Safety scales with power. Claude Code has 5 permission layers because it has filesystem write access on developer machines. Hermes takes a different approach — it can isolate execution in Docker containers or remote environments. Match your safety architecture to your blast radius.
The Meta-Lesson#
The hardest decision in agent design isn't technical. It's philosophical:
What is your agent's relationship to time?
Is it a tool you pick up fresh each time — trusting the environment over memory, optimizing for precision on the task at hand? Or is it a presence that accumulates and improves — trusting memory over the environment, optimizing for personalization over time?
Every architectural decision flows from that answer. Same skeleton. Opposite souls.
The future isn't one agent that does everything. It's a stack — persistent layers that know you, specialist layers that do the work. Hermes and Claude Code aren't competitors. They're two layers of the same stack.