Module 01: Overview & Mental Model
π― What You'll Learn
- The big picture: what Hermes Agent actually is
- High-level architecture diagram
- Key components and their responsibilities
- How data flows through the system
- Where to find things in the codebase
1.1 What is Hermes Agent?
Hermes is a tool-using AI agent that can:
- Chat with you naturally (CLI or messaging apps)
- Execute tools (terminal, files, web, browser, etc.)
- Remember past conversations and learn from experience
- Run autonomously on schedules or in the background
- Delegate work to subagents for parallel processing
Key Design Principles
- Model-agnostic β Use any LLM provider (OpenRouter, Nous Portal, local, etc.)
- Platform-agnostic β Same agent, multiple interfaces (CLI, Telegram, Discord...)
- Self-improving β Creates and refines skills from experience
- Persistent β Remembers across sessions via SQLite + memory system
- Research-ready β Batch processing, trajectory logging, RL environments
1.2 High-Level Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER INTERFACES β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β CLI β β Telegram β β Discord β β Slack... β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β
βββββββββΌβββββββββββββΌβββββββββββββΌβββββββββββββΌβββββββββββββββ
β β β β
ββββββββββββββ΄ββββββ¬βββββββ΄βββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β GATEWAY LAYER β
β (gateway/run.py) β
β - Message routing β
β - Platform adapters β
β - Session management β
ββββββββββββββ¬βββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β AGENT CORE β
β (run_agent.py) β
β - Conversation loop β
β - Tool orchestration β
β - Context building β
ββββββββββββββ¬βββββββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββ
β β β
βββββββββΌβββββββββ ββββββββΌββββββββ ββββββββββΌβββββββββ
β TOOL LAYER β β MEMORY LAYERβ β SKILLS LAYER β
β (tools/*.py) β β(hermes_state.β β (optional-skillsβ
β - terminal β β py) β β + ~/.hermes/ β
β - files β β - sessions β β skills/) β
β - web β β - memories β β - skill defs β
β - browser β β - search β β - templates β
ββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
1.3 Core Components Deep Dive
Gateway Layer (gateway/)
Purpose: Bridge between messaging platforms and the agent core.
| File | Responsibility |
|---|---|
run.py (255KB!) | Main gateway loop, message dispatch, slash commands |
session.py | SessionStore β persists conversations to SQLite |
platforms/ | Telegram, Discord, Slack adapters |
config.py | Gateway configuration |
Key Concept: The gateway runs as a separate process from the CLI. It polls for incoming messages and dispatches them to the agent.
Agent Core (run_agent.py, model_tools.py)
Purpose: The brain β manages conversations and tool execution.
| File | Responsibility |
|---|---|
run_agent.py | AIAgent class, conversation loop |
model_tools.py | Tool discovery, function call handling |
cli.py | Interactive CLI (separate from gateway) |
Key Concept: The agent loop is synchronous: receive message β build context β call LLM β execute tools β repeat.
Tools Layer (tools/)
Purpose: Implementations of all callable functions.
tools/
βββ registry.py # Central tool registry (schemas + dispatch)
βββ terminal_tool.py # Shell command execution
βββ file_tools.py # Read/write/search/patch files
βββ web_tools.py # Web search + extraction
βββ browser_tool.py # Browser automation (Browserbase)
βββ delegate_tool.py # Spawn subagents
βββ mcp_tool.py # MCP client (~1050 lines)
βββ ... (20+ more)
Key Concept: All tools register themselves with registry.register() at import time. The registry builds the schema sent to the LLM.
Memory Layer (hermes_state.py)
Purpose: Persistent storage for sessions, memories, and search.
| Feature | Implementation |
|---|---|
| Sessions | SQLite with FTS5 full-text search |
| Memories | Key-value store in ~/.hermes/memories/ |
| User profile | JSON in ~/.hermes/config.yaml |
Skills Layer (optional-skills/, ~/.hermes/skills/)
Purpose: Procedural memory β reusable workflows.
skill/
βββ SKILL.md # Instructions (YAML frontmatter + markdown)
βββ references/ # Supporting docs
βββ templates/ # Reusable templates
βββ scripts/ # Helper Python scripts
Key Concept: Skills are loaded as user messages, not system prompts β preserves prompt caching.
1.4 Data Flow: A Typical Turn
Let's trace what happens when you send a message:
Step 1: Message Arrival (Gateway)
# gateway/run.py - Main loop
while True:
messages = platform.poll() # Telegram, Discord, etc.
for msg in messages:
session = session_store.get(msg.chat_id)
response = agent.chat(msg.text, session.context)
platform.send(response)
Step 2: Context Building (Agent Core)
# run_agent.py - AIAgent.run_conversation()
messages = [
{"role": "system", "content": system_prompt},
*session.history, # Past conversation
{"role": "user", "content": new_message}
]
tool_schemas = registry.get_available_tools() # From enabled toolsets
Step 3: LLM Call (Model Tools)
# model_tools.py
response = client.chat.completions.create(
model="anthropic/claude-opus-4.6",
messages=messages,
tools=tool_schemas
)
Step 4: Tool Execution (Registry)
# model_tools.py - handle_function_call()
if response.tool_calls:
for tool_call in response.tool_calls:
result = registry.dispatch(tool_call.name, tool_call.args)
messages.append({"role": "tool", "content": result})
Step 5: Response (Back to Gateway)
# Agent returns final text β Gateway sends to platform
platform.send(final_response)
session_store.save(history + [user_msg, assistant_msg])
1.5 File Dependency Chain
From the AGENTS.md documentation:
tools/registry.py (no deps β imported by all tool files)
β
tools/*.py (each calls registry.register() at import time)
β
model_tools.py (imports tools/registry + triggers tool discovery)
β
run_agent.py, cli.py, batch_runner.py, environments/
Why this matters: If you add a new tool:
- Create
tools/my_tool.pywithregistry.register() - Add import in
model_tools.py_discover_tools() - Add to toolset in
toolsets.py
1.6 Key Files to Explore First
| File | Lines | What It Does |
|---|---|---|
run_agent.py | ~800 | Core agent loop |
model_tools.py | ~500 | Tool orchestration |
tools/registry.py | ~300 | Tool registration + dispatch |
gateway/run.py | ~2500 | Gateway main loop (large but readable) |
hermes_cli/commands.py | ~770 | Slash command registry |
hermes_state.py | ~950 | Session storage + search |
1.7 Hands-On Exercise
Exercise 1: Trace the Code
- Open
~/git/nous-hermes-agent/run_agent.py - Find the
AIAgent.run_conversation()method (around line 150) - Read through the main while loop β identify where:
- The LLM is called
- Tool results are appended to messages
- The final response is returned
Exercise 2: Find Your Session
# Look at your current session file
cat ~/.hermes/sessions/session_20260322_124359_6b542f4e.json | head -50
What fields do you see? What does session_key mean?
Exercise 3: List Available Tools
# In your Telegram chat, try:
/tools list
# Or in CLI:
cd ~/git/nous-hermes-agent
source venv/bin/activate
hermes
tools list
How many tools are enabled? What toolsets do they belong to?
1.8 Common Questions
Q: Why is gateway/run.py so large (255KB)?
A: It contains the main loop, all platform adapters, slash command handling, and delivery logic β essentially the entire messaging interface.
Q: What's the difference between CLI and gateway?
A: CLI (hermes_cli/main.py) is for interactive terminal use. Gateway (gateway/run.py) runs as a background service polling messaging platforms.
Q: How does the agent "know" which tools to offer the LLM?
A: model_tools.py builds tool schemas from the registry based on enabled toolsets in config.
Q: Where do skills come from?
A: Built-in skills are in optional-skills/. User-installed skills go in ~/.hermes/skills/.
β Module 1 Checklist
- Understand the high-level architecture
- Know where key components live in the codebase
- Trace a message through the system (gateway β agent β tools β response)
- Complete all three exercises