Skip to content

Hermes

A Python agent from Nous Research. The proposition: long-running, self-improving, resource-constrained local agent. pyproject plus flake.nix support macOS, Linux, and Termux (Android).

维度 CodexClaude CodeOpenClawHermes
Entry `hermes` main binary (CLI)`hermes_cli/` sub-command dispatch`mcp_serve.py` MCP server entry`hermes_state.py` global state
Core `agent/` turn loop + insights + memory_manager`gateway/` model gateway`model_tools.py` tool table`acp_adapter/` ACP protocol
Memory `tools/memory_tool.py` MEMORY.md (2200 char) + USER.md (1375 char)4 actions: add / replace / remove / readFrozen snapshot injected into system prompt`_MEMORY_THREAT_PATTERNS` 11-rule scan
Security `tools/tirith_security.py` subprocess scannerExit code is the verdict, not the LLM`agent/redact.py` 30+ vendor prefix redactioncosign + SHA-256 double-check on the tirith binary
Cron `cron/` croniter implementation`~/.hermes/cron/jobs.json` persistence`ONESHOT_GRACE_SECONDS = 120``_CRON_THREAT_PATTERNS` 10-rule scan
Observability & cost `agent/insights.py` inspired by Claude Code`agent/usage_pricing.py` 5-source priority`CanonicalUsage` + `PricingEntry`Local markdown reports
Hermes trades character limits, subprocess isolation, and explicit scans for predictability.
  1. Engineering restraint is the signature. Two markdown files store all long-term memory. The 2200 plus 1375 character cap forces the model to prioritize.
  2. Frozen snapshot preserves prefix cache. Memory snapshots into the system prompt at session load. Mid-session writes only touch disk. The next session picks them up; the prefix cache survives.
  3. tirith security out-of-process. Content-level security scanning runs in a separate Python binary. The main process reads exit code 0, 1, or 2. fail_open is the default; the agent always runs.
  4. 30+ vendor prefix redaction. agent/redact.py covers sk-, ghp_, AKIA, xox, AIza, gAAAA, and other mainstream key prefixes. Configuration is snapshot at import time to defeat mid-runtime tampering.
  5. Cross-platform down to Android. The most complete reference for running a Python agent under Termux. constraints-termux.txt pins dependencies installable on Android.
  1. Weak retrieval. No FTS5, no vector index, no temporal decay. When MEMORY.md fills up, only the model itself can prioritize.
  2. No Phase 2 consolidation. All memory writes go through the in-turn memory tool.
  3. tirith is an out-of-band install. In restricted environments where cosign or tirith won’t install, falling back to fail_open is effectively no scan.
  4. No GUI or TUI. Pure CLI plus MCP. IDE integration is on you.
  1. Character limit instead of token limit. Predictable across models, tokenizer-independent. MEMORY.md’s 2200-char design drops into any agent.
  2. Frozen snapshot injection (tools/memory_tool.py). Mid-session writes only land on disk; the next session reloads. The simplest way to keep memory fresh without burning prefix cache.
  3. tirith subprocess plus exit-code verdict. Delegate content-level security scanning to a separate process. The main process reads three exit codes.
  4. _MEMORY_THREAT_PATTERNS 11 rules plus 10 invisible-unicode codepoints. Scan before write. Covers prompt injection, role hijack, exfil_curl, read_secrets, and ssh_backdoor.
  5. agent/redact.py 30+ prefixes plus import-time snapshot. Redaction config snapshots at import time, so it cannot be mutated mid-runtime.