Hermes Agent

The self-improving AI agent built by Nous Research

github.com/NousResearch/hermes-agent — 9.6k stars — MIT License — v0.3.0

Part 1

ELI5

What is Hermes Agent and why should you care?

What Is Hermes Agent?

Imagine a personal AI assistant that lives on your computer, learns from every conversation, and gets better at helping you over time.

It can...

  • Run commands on your computer
  • Read, write, and fix code
  • Browse the web and do research
  • Send messages on your behalf
  • Schedule tasks to run while you sleep

It remembers...

  • Your name, preferences, and habits
  • How your projects are set up
  • Mistakes it made (so it won't repeat them)
  • Clever solutions it discovered
  • Everything from past conversations

The Secret Sauce: A Learning Loop

Most AI chatbots forget everything when you close the window. Hermes Agent has a closed learning loop:

1. You ask it to do something hard

"Fix the auth bug in my API and deploy it"

2. It figures it out (using tools, trial and error)

Reads code, runs tests, debugs, commits, deploys

3. It saves what it learned as a "skill"

Next time, it already knows the approach

4. It remembers key facts about you

Your deploy workflow, coding style, preferred tools

Talk To It Anywhere

Hermes Agent isn't just a terminal tool. It's one brain, many interfaces:

InterfaceHow It Works
Terminal (CLI)Full TUI, autocomplete, streaming
TelegramChat + voice notes + photos
DiscordServer bot, threads, voice channels
SlackWorkspace integration + threads
WhatsApp / SignalEncrypted messaging
IDE (VS Code, Zed)Editor agent via ACP

One Agent, All Platforms

Same memory, same skills, same personality. Ask it something on Telegram at lunch, pick up where you left off in the terminal at your desk.

Works with any LLM

OpenRouter (200+ models), Anthropic, OpenAI, Nous Portal, custom endpoints. Switch with one command.

Why This Matters

"The agent that grows with you"

Other AI Agents

  • Start from scratch every session
  • Locked to one LLM provider
  • CLI-only or app-only
  • No self-improvement
  • Closed source, subscription model

Hermes Agent

  • Persistent memory + skills across sessions
  • Any LLM via unified provider system
  • CLI + 6 messaging platforms + IDE
  • Autonomous skill creation from experience
  • MIT licensed, runs on a $5 VPS

Part 2

Deep Dive

Architecture, code patterns, and technical details

Repository at a Glance

MetricValue
Stars9,611
Forks1,176
Contributors153+
Commits2,406
LanguagePython (91.6%)
LicenseMIT
Latest Releasev0.3.0 (Mar 17, 2026)
CreatedJuly 22, 2025

Key Directories

agent/        Core agent loop + prompt assembly
tools/        50+ tool implementations
gateway/      Multi-platform messaging
skills/       Skill categories (25+ domains)
cron/         Scheduled job execution
environments/ RL + sandbox backends
hermes_cli/   CLI TUI + commands
honcho_integration/ Cross-session memory
tinker-atropos/    RL training (submodule)

High-Level Architecture

The system is organized around a central AIAgent class that orchestrates everything:

                    Interfaces                        Core                        Backends
               ┌──────────────────┐          ┌──────────────────┐      ┌──────────────────┐
               │  CLI (TUI)        │          │                  │      │  Local shell      │
               │  Telegram         │          │                  │      │  Docker           │
               │  Discord          │──────▶   │   AIAgent        │──▶   │  SSH              │
               │  Slack            │          │   + ToolRegistry │      │  Daytona          │
               │  WhatsApp/Signal  │          │   + MemoryStore  │      │  Singularity      │
               │  IDE (ACP)        │          │   + SkillIndex   │      │  Modal            │
               └──────────────────┘          └──────────────────┘      └──────────────────┘
                                                      │
                                              ┌───────┴────────┐
                                              │  LLM Providers  │
                                              │  OpenRouter     │
                                              │  Anthropic      │
                                              │  OpenAI         │
                                              │  Nous Portal    │
                                              │  Custom         │
                                              └────────────────┘

The Agent Loop: AIAgent

The core loop in run_agent.py drives multi-turn conversations with tool calling:

# Simplified agent loop
while not done:
    # 1. Build system prompt
    system = build_system_prompt(
        identity, memory, skills, context_files
    )

    # 2. Call LLM with tools
    response = call_llm(
        messages, tools, system
    )

    # 3. Execute tool calls (parallel when safe)
    if response.tool_calls:
        results = execute_tools(
            response.tool_calls,
            parallel=is_parallel_safe(calls)
        )
        messages.extend(results)
    else:
        done = True  # Natural stop

    # 4. Compress if needed
    if should_compress(messages):
        messages = compress_context(messages)

Key Design Choices

  • Parallel tool execution when calls are read-only and non-interactive
  • Path-scoped conflict detection prevents parallel writes to the same file
  • Automatic context compression when approaching token limits
  • Provider fallback models on API errors
  • Iteration budget tracking (shared parent/child)
  • Supports streaming callbacks for real-time UI updates

System Prompt Assembly

agent/prompt_builder.py constructs the system prompt from layered sources:

# System prompt layers (in order)

1. Identity
   SOUL.md (custom persona) or
   DEFAULT_AGENT_IDENTITY

2. Platform Hint
   "You are on Telegram..."
   "You are a CLI agent..."

3. Memory Snapshot
   MEMORY.md (agent notes)
   USER.md (user profile)

4. Skills Index
   All available skills by category
   <available_skills> block

5. Context Files (priority order)
   .hermes.md > AGENTS.md >
   CLAUDE.md > .cursorrules

6. Behavioral Guidance
   Memory, session search, skills

Injection Protection

Every context file is scanned before injection:

  • 10+ regex patterns for prompt injection detection
  • Detects "ignore previous instructions", hidden divs, exfil attempts
  • Invisible unicode scanning (zero-width chars, RTL overrides)
  • Blocked content replaced with [BLOCKED: ...] warning

Prefix Cache Preservation

Memory writes update files on disk immediately but do NOT change the system prompt mid-session. The snapshot is frozen at session start to preserve the Anthropic prefix cache.

Memory System: Two Stores

Persistent, bounded, file-backed memory in tools/memory_tool.py:

MEMORY.md (Agent Notes)

  • Environment facts, tool quirks, project conventions
  • 2,200 character limit
  • Actions: add, replace, remove

USER.md (User Profile)

  • Name, role, preferences, communication style
  • 1,375 character limit
  • Same action set

Design Details

  • Entry delimiter: section sign character
  • Atomic writes via temp file + os.replace()
  • File locking with fcntl.flock() for concurrent access
  • Substring matching for replace/remove (no IDs)
  • Security scanning on every write (same patterns as prompt builder)
  • Deduplication on load

Priority rule: User preferences and corrections > environment facts > procedural knowledge. The most valuable memory prevents repeating yourself.

Skills: Procedural Memory

Skills are reusable approaches the agent creates from experience (tools/skill_manager_tool.py):

# Skill directory structure
~/.hermes/skills/
  my-deploy-skill/
    SKILL.md         # YAML frontmatter + instructions
    references/      # Supporting docs
    templates/       # Reusable templates
    scripts/         # Automation scripts
    assets/          # Other files
  data-science/    # Category grouping
    pandas-etl/
      SKILL.md

# SKILL.md frontmatter
---
name: my-deploy-skill
description: Deploy Node.js apps to fly.io
metadata:
  hermes:
    requires_toolsets: [terminal, file]
    fallback_for_tools: [docker]
---
# Step-by-step instructions...

Skill Lifecycle

  • create — Agent writes SKILL.md after solving a hard problem
  • patch — Targeted find-and-replace for quick fixes
  • edit — Full rewrite for major overhauls
  • write_file — Add supporting references
  • delete / remove_file — Clean up

Conditional Activation

  • Skills filtered by OS platform compatibility
  • requires_toolsets — only show if tools available
  • fallback_for_tools — hide if native tool exists
  • All skills security-scanned before activation

25+ Skill Categories

apple, data-science, gaming, github, media, mlops, music, productivity, research, smart-home, software-dev...

Session Search: Cross-Session Recall

SQLite FTS5 full-text search over all past conversations (tools/session_search_tool.py):

How It Works

  • FTS5 queries over stored conversation messages
  • Groups results by session, deduplicates
  • Truncates around matches (100k char windows centered on hits)
  • Sends matched conversations to Gemini Flash for focused summarization
  • Returns structured JSON with session metadata

Search Syntax

  • Keywords joined with OR for broad recall
  • Exact phrase matching with quotes
  • Boolean operators (AND, OR, NOT)
  • Prefix search with asterisk

Why This Matters

Memory stores facts. Session search recovers context. When a user says "remember that deploy issue last week?", the agent searches past transcripts instead of asking the user to repeat themselves.

Delegation Chain Resolution

Parent-session resolution follows delegation chains, so subagent work is searchable from the parent session context.

Tool System: 50+ Tools

Tools are organized into composable toolsets via toolsets.py:

CategoryTools
Terminalterminal, process
Fileread_file, write_file, patch, search_files
Webweb_search, web_extract
Browser11 browser_* tools (CDP)
Visionvision_analyze, image_generate
Memorymemory, session_search
Skillsskills_list, skill_view, skill_manage
Schedulingcronjob (CRUD)
Delegationdelegate_task
Codeexecute_code (Python sandbox)
Advancedmixture_of_agents, clarify, todo

Toolset Composition

# Composite toolsets
"debugging": ["web", "file"]
"safe":      ["web", "vision", "image_gen"]

# Platform toolsets use ALL core tools
"hermes-cli":      _HERMES_CORE_TOOLS
"hermes-telegram": _HERMES_CORE_TOOLS
"hermes-discord":  _HERMES_CORE_TOOLS

# Meta toolset
"hermes-gateway": [all platforms]

Tools self-register via tools/registry.py with schema, handler function, requirement checks, and emoji metadata.

Terminal Backends: Six Environments

tools/terminal_tool.py supports running commands in six different backends:

BackendUse Case
LocalDirect host execution, persistent shell
DockerContainerized with resource limits
SSHRemote host execution with preflight
DaytonaCloud dev environments via API
SingularityHPC/scientific computing containers
ModalServerless cloud sandboxes

Safety Features

  • Tirith pre-exec scanning for dangerous commands
  • Smart approval system that learns safe patterns
  • Secrets redaction in output via redact_sensitive_text()
  • Output truncated to 50k chars (40% head / 60% tail)
  • Background process tracking with status watchers
  • Per-environment idle cleanup (5 min default)
  • Sudo handling via stdin password injection
  • Retry with exponential backoff (3 attempts)

Context Compression

agent/context_compressor.py automatically manages conversation length:

# Context window management

┌─────────────────────────────────┐
│ Protected head (first 3 turns)  │
│   System prompt, initial context │
├─────────────────────────────────┤
│                                 │
│ Compressible middle             │
│   Summarized by auxiliary LLM   │
│   → 2,500 token target summary  │
│                                 │
├─────────────────────────────────┤
│ Protected tail (last 4 turns)   │
│   Recent context, active work   │
└─────────────────────────────────┘

# Trigger: 50% of context limit used

Tool-Call Integrity

  • Never splits tool-call/result pairs at boundaries
  • Removes orphaned tool results
  • Inserts stub results for orphaned calls
  • Maintains valid role alternation

Compression Flow

  • Align boundaries to protect tool groups
  • Generate summary via auxiliary LLM
  • Handle role conflicts (merge into tail)
  • Sanitize and return compressed messages
  • Sync session ID after compression

Subagent Delegation

tools/delegate_tool.py spawns isolated child agents for parallel work:

How It Works

  • Parent agent spawns children with restricted toolsets
  • Up to 3 concurrent children via ThreadPoolExecutor
  • Each child gets a fresh conversation (no parent history)
  • Children cannot delegate further (depth limit = 2)
  • Default 50 iterations per subagent
  • Default toolsets: terminal, file, web

Blocked Tools

  • delegate_task (no recursion)
  • clarify (no user interaction)
  • memory (no shared writes)
  • send_message (no side effects)
  • execute_code (enforce reasoning)
# Example: parallel research
delegate_task(
  tasks=[
    {"goal": "Research React 19 changes"},
    {"goal": "Audit our auth module"},
    {"goal": "Write migration tests"}
  ],
  toolsets=["terminal", "file", "web"]
)

# Returns per-task results:
{
  "results": [
    {"status": "success",
     "summary": "...",
     "api_calls": 12,
     "duration": "45.2s",
     "tool_trace": [...]},
    ...
  ],
  "total_duration": "52.1s"
}

Messaging Gateway

gateway/ provides a unified bridge between messaging platforms and the agent core:

# Gateway architecture

GatewayRunner           # Lifecycle management
  ├── platforms/       # Platform adapters
  │   ├── telegram    # Long-polling + webhook
  │   ├── discord     # Bot + voice channels
  │   ├── slack       # Thread-aware integration
  │   ├── whatsapp    # Bridge protocol
  │   ├── signal      # E2E encrypted
  │   ├── email       # IMAP + SMTP
  │   └── sms         # Plain text (1600 char)
  ├── session.py      # Per-user/group isolation
  ├── delivery.py     # Route responses to platforms
  ├── hooks.py        # Pre/post message processing
  └── stream_consumer.py # Real-time streaming

Key Features

  • Platform-specific prompts adapt output format (no markdown on WhatsApp, etc.)
  • Media file delivery via MEDIA:/path protocol
  • Group session isolation (per-user by default)
  • Unified real-time streaming across all platforms
  • Runs as systemd service (user or system scope)
  • Hardened restart recovery with active run cancellation

The gateway background thread calls cron.tick() every 60 seconds to execute scheduled jobs.

Cron Scheduler: Unattended Automation

cron/scheduler.py runs jobs autonomously on a schedule:

How It Works

  • File-based locking prevents concurrent tick execution
  • Each job spawns a full AIAgent instance
  • Jobs can optionally load skills into their prompt
  • Sessions persisted to SQLite
  • Per-job provider/model overrides
  • Atomic writes for job output

Delivery Targets

Telegram, Discord, Slack, WhatsApp, Signal, Matrix, Mattermost, Home Assistant, DingTalk, Email, SMS

# Natural language cron job
cronjob(
  "Every morning at 8am,
   check my GitHub notifications
   and summarize them",
  schedule="0 8 * * *",
  deliver="telegram"
)

# Silent execution (no delivery)
# Agent responds with [SILENT]
# Output saved locally only

# The cron prompt includes:
# "You are running as a scheduled
#  cron job. There is no user
#  present -- execute fully and
#  autonomously."

Security: Multi-Layer Defense

Security is woven through every layer of the system:

Prompt Injection Defense

  • 10+ regex patterns scan all context files
  • Invisible unicode detection (zero-width, RTL)
  • Blocked content replaced with warnings
  • Memory writes scanned before persistence

Command Approval

  • Tirith pre-exec scanning analyzes terminal commands
  • Pattern-based dangerous command detection
  • Smart approval learns safe patterns over time
  • Full command preview before execution

Skills Guard

  • Three-tier trust model: builtin, trusted, community
  • Static analysis: exfil, injection, destructive, persistence, network, obfuscation
  • Structural validation (file count, size, symlinks, binaries)
  • Optional LLM-based audit for threats regex misses
  • SHA-256 content hashing for integrity

Environment Isolation

  • Provider env vars stripped from subprocesses
  • Docker workspace mount requires explicit opt-in
  • PII redaction when privacy.redact_pii enabled

Skills Guard: Threat Detection

tools/skills_guard.py scans skills across 8 threat categories:

CategoryExamples Detected
Exfiltrationcurl with $TOKEN, cat .env, DNS exfil
InjectionRole hijack, instruction override
Destructiverm -rf /, chmod 777, disk format
PersistenceCron mods, shell rc files, systemd
NetworkReverse shells, tunneling, /dev/tcp
Obfuscationbase64 decode pipes, eval/exec
Privilegesudo, setuid/setgid, sudoers
CredentialsEmbedded API keys, private keys

Install Policy Matrix

# Trust level x Verdict → Action
                safe    caution  dangerous
builtin:      allow   allow    allow
trusted:      allow   allow    block
community:    allow   block    block
agent-made:   allow   allow    block

Verdicts

safe = no findings. caution = high severity matches. dangerous = critical severity findings. LLM audit can only raise severity, never lower it.

Provider System: Any LLM

The centralized provider router supports switching models with zero code changes:

Supported Providers

ProviderNotes
OpenRouter200+ models, primary default
AnthropicNative API + prompt caching
OpenAIGPT-5.x with reasoning support
Nous PortalNous Research's own endpoint
z.ai / GLMChinese model providers
Kimi / MoonshotLong-context models
MiniMaxAnthropic-compatible API
Vercel AI GatewayNew in v0.3.0
Custom endpointsAny OpenAI-compatible URL

Key Capabilities

  • Unified call_llm API abstracts all providers
  • Auto-detection of provider when switching models
  • Anthropic prompt caching for system prompts
  • Adaptive thinking support for reasoning models
  • Provider fallback on API errors
  • Smart model routing via agent/smart_model_routing.py
  • Direct endpoint overrides for vision and subagent calls
  • Per-cron-job provider/model configuration
# Switch models instantly
$ hermes model
# or in chat:
/model anthropic:claude-4-sonnet

Research: RL Training Pipeline

Hermes Agent is designed for model training, not just usage:

Trajectory Generation

  • Batch trajectory generation via batch_runner.py
  • JSON trajectory logging for every conversation
  • Captures tool calls, results, reasoning, and outcomes
  • Trajectory compression via trajectory_compressor.py

Compression Engine

  • Protects first turns (system/human/initial response)
  • Protects last N turns for continuity
  • Compresses middle to fit token budget
  • LLM-generated summaries via OpenRouter
  • HuggingFace tokenizer integration
  • Concurrent processing with semaphore rate limiting

RL Environments

environments/
  agent_loop.py      # HermesAgentLoop
  hermes_base_env.py # Base RL environment
  agentic_opd_env.py # On-Policy Distillation
  web_research_env.py# Web research tasks
  hermes_swe_env/    # SWE-bench environment
  terminal_test_env/ # Terminal testing
  benchmarks/        # Evaluation suites

Agentic OPD (v0.3.0)

On-Policy Distillation environment for training agent policies within the expanded tinker-atropos ecosystem. The agent generates its own training data from real usage.

HermesAgentLoop: The RL Engine

environments/agent_loop.py is a reusable multi-turn engine for RL environments:

class HermesAgentLoop:
    # Works with VLLM, SGLang, OpenRouter,
    # ManagedServer implementations

    def __init__(self, server, tool_schemas,
                 valid_tool_names,
                 max_turns=30,
                 temperature=1.0):
        ...

    async def run(self, messages, handle_fn):
        # Per-turn: API call → parse → execute
        # → track errors → check termination

        # Fallback parsing for raw tool tags
        # when structured calls unavailable

        # Returns AgentResult with:
        #   - messages, turns, reasoning
        #   - tool_errors, natural_stop
        #   - managed_state
        return AgentResult(...)

Design for Training

  • 128-worker thread pool for sync tool calls in async context
  • ToolError dataclass captures turn number, tool name, args, error
  • Special handling for memory/session_search in RL (returns errors, not results)
  • Multi-format reasoning extraction (Anthropic, OpenAI, DeepSeek)
  • Supports dict-formatted tool args from Codex and local backends
  • Task ID isolation for terminal/browser sessions

The agent loop is decoupled from the CLI/gateway infrastructure, allowing it to run in benchmark harnesses and training pipelines independently.

Extensibility: Plugins, MCP, Skills Hub

Three ways to extend Hermes Agent:

1. Plugin Architecture (v0.3.0)

  • Drop Python files into ~/.hermes/plugins/
  • Create custom tools, commands, and hooks
  • No code fork required

2. MCP Integration

  • Model Context Protocol server support
  • Selective tool loading with utility policies
  • Auto-reload when mcp_servers config changes
  • MCP toolsets preserved across config saves

3. Skills Hub

  • agentskills.io for community-shared skills
  • Install via /skills install <name>
  • Security-scanned before activation

New Skills in v0.3.0

SkillDomain
LinearProject management
X/TwitterSocial media (x-cli)
TelephonyTwilio, SMS, AI calls
1PasswordPassword management
NeuroSkillBrain-computer interface
Blender MCP3D modeling
OSS SecurityForensics
Parallel CLIResearch tool
OpenCode CLIDevelopment

Voice Mode + Browser Automation

Voice Mode

  • Push-to-talk in CLI
  • Voice notes on Telegram and Discord
  • Discord voice channels for live conversation
  • Local Whisper transcription via faster-whisper (free)
  • Text-to-speech output via tts_tool.py
  • Configurable STT disable via stt.enabled: false

Browser Automation (CDP)

  • 11 browser tools: navigate, snapshot, click, type, scroll, back, press, close, get_images, vision, console
  • /browser connect attaches to live Chrome via Chrome DevTools Protocol
  • Screenshot-based visual verification
  • Console log access for debugging

Mixture of Agents

The mixture_of_agents tool queries multiple LLMs in parallel and synthesizes their responses. Think "ensemble inference" at the agent level.

Home Assistant

Native smart home control: ha_list_entities, ha_get_state, ha_list_services, ha_call_service. Combine with cron for automated home routines.

Image Generation

image_generate tool creates images on demand. Results delivered natively on messaging platforms (inline photos on Telegram, attachments on Discord/Slack).

v0.3.0 Release Highlights

Released March 17, 2026 — the latest major version:

New in v0.3.0

  • Unified streaming across CLI + all platforms
  • Plugin architecture (~/.hermes/plugins/)
  • Native Anthropic provider with prompt caching
  • Smart approvals that learn safe patterns
  • Persistent shell (state survives tool calls)
  • Agentic OPD for RL training
  • ACP server for IDE integration
  • Vercel AI Gateway provider
  • Voice mode + push-to-talk
  • Browser CDP connection
  • PII redaction
  • Concurrent tool execution

By the Numbers

220+

PRs from @teknium1

50+

Bug fixes

9

New skills

15+

Contributors

Migration from OpenClaw: hermes claw migrate preserves persona, memory, skills, settings, and API keys.

Getting Started

One-Line Install

# Linux, macOS, WSL2
curl -fsSL https://raw.githubusercontent.com/\
NousResearch/hermes-agent/main/\
scripts/install.sh | bash

# Reload shell and start chatting
source ~/.bashrc
hermes

Essential Commands

hermesStart chatting
hermes modelChoose LLM
hermes toolsConfigure tools
hermes gatewayStart messaging bridge
hermes setupFull setup wizard
hermes doctorDiagnose issues

Developer Setup

git clone https://github.com/\
  NousResearch/hermes-agent.git
cd hermes-agent

# Init submodules
git submodule update --init mini-swe-agent

# Setup Python environment
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv venv --python 3.11
source venv/bin/activate
uv pip install -e ".[all,dev]"

# Run tests
python -m pytest tests/ -q

# Optional: RL training
git submodule update --init tinker-atropos
uv pip install -e "./tinker-atropos"

Key Takeaways

  • Self-improving agent with persistent memory, skills, and cross-session search
  • 50+ tools across terminal, file, web, browser, vision, code execution, and more
  • Any LLM via unified provider system (OpenRouter, Anthropic, OpenAI, custom)
  • CLI + 7 messaging platforms + IDE through unified gateway
  • Multi-layer security: injection defense, command approval, skills guard
  • Research-ready: trajectory generation, compression, RL environments
  • MIT licensed, 9.6k stars, 153+ contributors, active development

github.com/NousResearch/hermes-agent

Docs: hermes-agent.nousresearch.com • Skills: agentskills.io • Discord: discord.gg/NousResearch