Hermes Agent 深度实战:当 AI Agent 学会「自我进化」——从闭环学习架构到 70+ 工具链、从 SQLite+FTS5 记忆引擎到 20 平台网关的生产级完全指南(2026)
作者按:2026 年 2 月,Nous Research 放出了一个"养马"神器——Hermes Agent。两个月后 GitHub Star 突破 11 万,连续多周霸榜 GitHub Trending 第一。它到底有什么魔力?本文将从架构设计、记忆系统、技能自进化、多平台网关、工具链集成等维度,带你完整拆解这款"越用越聪明"的开源 AI Agent 框架。全文约 12000 字,建议收藏慢读。
目录
- 为什么我们需要「会学习」的 AI Agent?
- Hermes Agent 是什么?核心差异化能力全景
- 架构深度剖析:从系统概览到目录结构
- 闭环学习引擎:让 Agent 真正「越用越聪明」
- 记忆系统实战:SQLite+FTS5 的三层记忆架构
- 技能系统:从 Skill 生命周期到渐进式加载
- 工具链深度集成:70+ 工具与 6 大终端后端
- 多平台网关:20 个适配器与统一会话路由
- MCP 集成:连接整个 AI 工具生态
- 生产级部署:Docker/Modal/Daytona 无服务器化
- 从 OpenClaw 迁移:一键导入你的 Agent 记忆
- 性能优化:上下文压缩与 Prompt Caching
- 安全机制:命令审批与沙箱隔离
- 完整实战:从安装到部署一个自动化工作流
- 与 OpenClaw 的深度对比:两款「宠物」怎么选?
- 总结与展望:Agent 操作系统的雏形
1. 为什么我们需要「会学习」的 AI Agent?
1.1 传统 AI 助手的「金鱼记忆」之痛
你有没有遇到过这样的场景:
- 你跟 ChatGPT 说"我喜欢用 TypeScript",聊了三个小时后,它又给你生成了 JavaScript 代码
- 你教 Claude "这个项目用 pnpm,不用 npm",新会话它又忘了
- 你花了一下午调好的开发环境配置,下次对话 AI 还是给你推荐默认配置
核心问题:大多数 AI 助手使用的是有限上下文窗口,会话结束后,所有记忆灰飞烟灭。即使用 RAG(检索增强生成)技术,也只是"临时查字典",不是真正的"学习"。
1.2 现有 Agent 框架的三大短板
| 短板 | 具体表现 | 后果 |
|---|---|---|
| 无持久记忆 | 每次会话从零开始 | 重复解释环境、偏好、项目背景 |
| 无自我进化 | 犯过的错下次还犯 | 无法积累经验和最佳实践 |
| 工具扩展难 | 内置工具固定,扩展需改代码 | 无法适应个性化工作流 |
Hermes Agent 的出现,就是要彻底解决这三个问题。
2. Hermes Agent 是什么?核心差异化能力全景
2.1 一句话定义
Hermes Agent 是一个开源的、能自主学习的 AI Agent 框架,核心不是聊天,而是"持久记忆 + 自我进化"。
说白了:
- 你跟它聊得越多,它越懂你
- 它完成的任务越多,积累的技能越多
- 下次遇到类似场景,它直接调用之前的经验,而不是从零开始瞎琢磨
2.2 六大核心差异化能力
2.2.1 技能自学习(Skill Autodidactics)
传统 Agent 完成任务后就忘了。Hermes 不一样:
完成任务 → 识别可复用模式 → 自动生成 Skill 文件 → 存入技能库 → 下次直接调用
触发条件(满足任一即生成 Skill):
- 任务涉及超过 5 次工具调用
- 经过多次尝试才找到可行方案
- 用户显式纠正了 Agent 的方法
生成的 Skill 是标准的 Markdown 文件(兼容 agentskills.io 开放标准),存储在 ~/.hermes/skills/ 目录下。
2.2.2 跨会话持久记忆(Cross-Session Memory)
Hermes 用 SQLite + FTS5 全文索引实现记忆持久化:
-- 消息表:记录所有对话
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
session_id TEXT,
role TEXT, -- 'user' 或 'assistant'
content TEXT,
created_at TIMESTAMP
);
-- FTS5 虚拟表:全文搜索,精确回溯
CREATE VIRTUAL TABLE messages_fts USING fts5(
session_id,
role,
content,
tokenize = 'porter unicode61'
);
三层记忆架构(对应认知科学):
- 情景记忆(Episodic Memory):会话历史 →
messages表 - 语义记忆(Semantic Memory):持久事实 →
MEMORY.md - 程序性记忆(Procedural Memory):技能文件 →
~/.hermes/skills/
2.2.3 多平台网关(Multi-Platform Gateway)
一个 Agent 实例,同时服务 20 个平台:
- 即时通讯:Telegram、Discord、Slack、WhatsApp、Signal、Matrix、飞书、企业微信、钉钉、QQ、微信(第三方桥接)
- 开发工具:VS Code、Zed、JetBrains(通过 ACP 协议)
- 其他:Email、SMS、Home Assistant、Webhook
统一会话路由:无论你从哪个平台发消息,Agent 都能找到正确的上下文。
2.2.4 模型无关(Model Agnostic)
支持 18+ 模型提供商,随时切换无需改代码:
# 交互式切换模型
hermes model
# 或直接指定
hermes model openrouter:anthropic/claude-3.5-sonnet
hermes model openai:gpt-4-turbo
hermes model deepseek:deepseek-chat
hermes model local:ollama/llama3
Nous Portal(官方一站式订阅):
- 300+ 模型任选
- 工具网关(web_search、image_gen、TTS、browser_use)全部打通
- 一条命令配置:
hermes setup --portal
2.2.5 配置隔离与多配置文件(Profile Isolation)
每个"配置文件"(Profile)拥有独立的:
HERMES_HOME目录- 配置文件 (
config.yaml) - 记忆文件 (
MEMORY.md,USER.md) - 会话历史 (SQLite)
- 网关进程
# 创建独立的 work 配置文件
hermes profile create work
# 使用 work 配置文件启动
hermes -p work
# 列出所有配置文件
hermes profile list
典型场景:
default:个人助手work:工作任务(连接企业微信、访问内网工具)research:研究任务(连接学术 API、启用长上下文模型)
2.2.6 工具链深度集成(70+ Tools, 28 Toolsets)
Hermes 内置 70+ 工具,分为 28 个工具集(Toolset):
| 工具集 | 典型工具 | 用途 |
|---|---|---|
terminal | terminal, process_registry | 执行 Shell 命令 |
file | read_file, write_file, patch, search_files | 文件操作 |
web | web_search, web_extract | 联网搜索 |
browser | browser_open, browser_snapshot, browser_click | 浏览器自动化 |
code | execute_code | 沙箱执行代码 |
memory | memory | 管理持久记忆 |
skill | skill_manage, skills_hub | 管理技能 |
mcp | mcp_call, mcp_list | 调用 MCP 服务器 |
cron | cron_add, cron_list | 定时任务 |
delegate | delegate | 派发子 Agent |
工具后端多样化:
- 终端:Local、Docker、SSH、Singularity、Modal、Daytona(6 种)
- 浏览器:Playwright、Browser-Use、Cloud Browser(3 种)
3. 架构深度剖析:从系统概览到目录结构
3.1 系统概览(System Overview)
┌─────────────────────────────────────────────────────────────────────┐
│ Entry Points │
│ │
│ CLI (cli.py) │ Gateway (gateway/run.py) │ ACP (acp_adapter/) │
│ Batch Runner │ API Server │ Python Library │
└──────────┬──────────────┬───────────────────────┬───────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ AIAgent (run_agent.py) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Prompt │ │ Provider │ │ Tool │ │
│ │ Builder │ │ Resolution │ │ Dispatch │ │
│ │ (prompt_ │ │ (runtime_ │ │ (model_ │ │
│ │ builder.py) │ │ provider.py)│ │ tools.py) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ │
│ │ Compression │ │ 3 API Modes │ │ Tool Registry│ │
│ │ & Caching │ │ chat_compl. │ │ (registry.py)│ │
│ │ │ │ codex_resp. │ │ 70+ tools │ │
│ │ │ │ anthropic │ │ 28 toolsets │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────┴─────────────────┴─────────────────┴───────────────────────┘
│ │
▼ ▼
┌───────────────────┐ ┌──────────────────────┐
│ Session Storage │ │ Tool Backends │
│ (SQLite + FTS5) │ │ Terminal (6 backends) │
│ hermes_state.py │ │ Browser (3 backends) │
│ gateway/session. │ │ Web (4 backends) │
│ py │ │ MCP (dynamic) │
└───────────────────┘ │ File, Vision, etc. │
└──────────────────────┘
3.2 数据流(Data Flow)
3.2.1 CLI 会话流程
User input
↓
HermesCLI.process_input()
↓
AIAgent.run_conversation()
↓
prompt_builder.build_system_prompt()
↓
runtime_provider.resolve_runtime_provider()
↓
API call (chat_completions / codex_responses / anthropic_messages)
↓
tool_calls?
↓ Yes
model_tools.handle_function_call()
↓
loop (继续调用 LLM)
↓ No
final response → display → save to SessionDB
3.2.2 网关消息流程
Platform event (e.g., Telegram message)
↓
Adapter.on_message() → MessageEvent
↓
GatewayRunner._handle_message()
↓
authorize user
↓
resolve session key
↓
create AIAgent with session history
↓
AIAgent.run_conversation()
↓
deliver response back through adapter
3.2.3 定时任务流程
Scheduler tick
↓
load due jobs from jobs.json
↓
create fresh AIAgent (no history)
↓
inject attached skills as context
↓
run job prompt
↓
deliver response to target platform
↓
update job state and next_run
3.3 目录结构详解
hermes-agent/
├── run_agent.py # AIAgent — 核心对话循环(大文件)
├── cli.py # HermesCLI — 交互式终端 UI(大文件)
├── model_tools.py # 工具发现、Schema 收集、分发
├── toolsets.py # 工具分组和平台预设
├── hermes_state.py # SQLite 会话/状态数据库(含 FTS5)
├── hermes_constants.py # HERMES_HOME、profile-aware 路径
├── batch_runner.py # 批量轨迹生成
│
├── agent/ # Agent 内部模块
│ ├── prompt_builder.py # 系统提示词组装
│ ├── context_engine.py # ContextEngine ABC(可插拔)
│ ├── context_compressor.py # 默认引擎——有损摘要
│ ├── prompt_caching.py # Anthropic Prompt Caching
│ ├── auxiliary_client.py # 辅助 LLM(视觉、摘要)
│ ├── model_metadata.py # 模型上下文长度、Token 估算
│ ├── models_dev.py # models.dev 注册表集成
│ ├── anthropic_adapter.py # Anthropic Messages API 格式转换
│ ├── display.py # KawaiiSpinner、工具预览格式化
│ ├── skill_commands.py # Skill 斜杠命令
│ ├── memory_manager.py # 记忆管理器编排
│ ├── memory_provider.py # 记忆提供商 ABC
│ └── trajectory.py # 轨迹保存助手
│
├── hermes_cli/ # CLI 子命令和设置
│ ├── main.py # 入口点——所有 `hermes` 子命令(大文件)
│ ├── config.py # DEFAULT_CONFIG、OPTIONAL_ENV_VARS、迁移
│ ├── commands.py # COMMAND_REGISTRY——中央斜杠命令定义
│ ├── auth.py # PROVIDER_REGISTRY、凭证解析
│ ├── runtime_provider.py # Provider → api_mode + credentials
│ ├── models.py # 模型目录、提供商模型列表
│ ├── model_switch.py # /model 命令逻辑(CLI + 网关共享)
│ ├── setup.py # 交互式设置向导(大文件)
│ ├── skin_engine.py # CLI 主题引擎
│ ├── skills_config.py # hermes skills——按平台启用/禁用
│ ├── skills_hub.py # /skills 斜杠命令
│ ├── tools_config.py # hermes tools——按平台启用/禁用
│ ├── plugins.py # PluginManager——发现、加载、钩子
│ ├── callbacks.py # 终端回调(clarify、sudo、approval)
│ └── gateway.py # hermes gateway start/stop
│
├── tools/ # 工具实现(每个工具一个文件)
│ ├── registry.py # 中央工具注册表
│ ├── approval.py # 危险命令检测
│ ├── terminal_tool.py # 终端编排
│ ├── process_registry.py # 后台进程管理
│ ├── file_tools.py # read_file, write_file, patch, search_files
│ ├── web_tools.py # web_search, web_extract
│ ├── browser_tool.py # 10 个浏览器自动化工具
│ ├── code_execution_tool.py # execute_code 沙箱
│ ├── delegate_tool.py # 子 Agent 委派
│ ├── mcp_tool.py # MCP 客户端(大文件)
│ ├── credential_files.py # 基于文件的凭证传递
│ ├── env_passthrough.py # 沙箱的 env var 传递
│ ├── ansi_strip.py # ANSI 转义序列剥离
│ └── environments/ # 终端后端(local, docker, ssh, modal, daytona, singularity)
│
├── gateway/ # 消息平台网关
│ ├── run.py # GatewayRunner——消息分发(大文件)
│ ├── session.py # SessionStore——会话持久化
│ ├── delivery.py # 出站消息投递
│ ├── pairing.py # DM 配对授权
│ ├── hooks.py # 钩子发现和生命周期事件
│ ├── mirror.py # 跨会话消息镜像
│ ├── status.py # Token 锁、profile-scoped 进程跟踪
│ ├── builtin_hooks/ # 始终注册的钩子(目前无)
│ └── platforms/ # 20 个适配器
│ ├── telegram.py
│ ├── discord.py
│ ├── slack.py
│ ├── whatsapp.py
│ ├── signal.py
│ ├── matrix.py
│ ├── mattermost.py
│ ├── email.py
│ ├── sms.py
│ ├── dingtalk.py
│ ├── feishu.py
│ ├── wecom.py
│ ├── wecom_callback.py
│ ├── weixin.py # 微信(需第三方桥接)
│ ├── bluebubbles.py
│ ├── qqbot.py
│ ├── homeassistant.py
│ ├── webhook.py
│ ├── api_server.py
│ └── yuanbao.py
│
├── acp_adapter/ # ACP 服务器(VS Code / Zed / JetBrains)
├── cron/ # 调度器(jobs.py, scheduler.py)
├── plugins/memory/ # 记忆提供商插件
├── plugins/context_engine/ # 上下文引擎插件
├── skills/ # 内置技能(始终可用)
├── optional-skills/ # 官方可选技能(需显式安装)
├── website/ # Docusaurus 文档站点
└── tests/ # Pytest 套件(~25,000 个测试,~1,250 个文件)
3.4 设计原则(Design Principles)
| 原则 | 实践中的含义 |
|---|---|
| Prompt 稳定性 | 系统提示词在会话期间不变化。除显式用户操作(/model)外,无缓存破坏突变。 |
| 可观察执行 | 每次工具调用都通过回调对用户可见。CLI(spinner)和网关(聊天消息)中的进度更新。 |
| 可中断 | API 调用和工具执行可以在飞行中被用户中断(Ctrl+C 或 /stop)。 |
| 平台无关核心 | 一个 AIAgent 类服务 CLI、网关、ACP、批处理和 API 服务器。平台差异存在于入口点,而非 Agent。 |
| 松耦合 | 可选子系统(MCP、插件、记忆提供商、RL 环境)使用注册表模式和 check_fn 门控,而非硬依赖。 |
| 配置文件隔离 | 每个配置文件(hermes -p )拥有自己的 HERMES_HOME、配置、记忆、会话和网关 PID。多个配置文件可以同时运行。 |
4. 闭环学习引擎:让 Agent 真正「越用越聪明」
4.1 什么是闭环学习(Closed Learning Loop)?
传统 Agent 的工作模式是开环的:
接收任务 → 执行 → 返回结果 → 结束(经验丢失)
Hermes Agent 引入了闭环学习:
接收任务 → 执行 → 识别可复用模式 → 生成/更新 Skill → 存储到技能库 → 下次直接调用
↑ ↓
└───────────┘
失败时自动修正
4.2 闭环学习的五个环节
根据官方文档和代码分析,Hermes 的闭环学习包含以下五个环节:
4.2.1 策划记忆(Curated Memory)
触发时机:任务完成后
执行逻辑:
- Agent 判断什么值得记住(环境事实、用户偏好、踩过的坑)
- 调用
memory工具,将关键信息写入MEMORY.md或USER.md
代码示例(Agent 内部决策):
# 伪代码:Agent 完成任务后的记忆策划逻辑
def after_task_review(task_result, conversation_history):
# 1. 提取关键信息
key_facts = extract_key_facts(task_result, conversation_history)
# 2. 判断是否需要记忆
for fact in key_facts:
if is_important(fact) and not already_known(fact):
# 3. 调用 memory 工具
memory(action="add", target="memory", content=fact)
4.2.2 创建技能(Skill Creation)
触发条件(满足任一):
- 任务涉及超过 5 次工具调用
- 经过多次尝试才找到可行方案
- 用户显式纠正了 Agent 的方法
生成内容:标准的 SKILL.md 文件
文件结构:
---
name: fix-docker-network-issue
description: 修复 Docker 容器网络不通的问题
version: 1.0.0
metadata:
hermes:
tags: [docker, networking, troubleshooting]
category: devops
---
# Fix Docker Network Issue
## When to Use
当容器无法访问外网,或容器之间无法通信时。
## Procedure
1. 检查 Docker 网络:`docker network ls`
2. 检查容器网络配置:`docker inspect <container> | jq '.[0].NetworkSettings'`
3. 如果是 bridge 网络问题,重启 Docker:`sudo systemctl restart docker`
4. 如果是 DNS 问题,配置 Daemon:`/etc/docker/daemon.json`
## Pitfalls
- 不要随意删除默认 bridge 网络
- 重启 Docker 会中断所有容器
## Verification
`docker run --rm alpine ping -c 3 8.8.8.8`
4.2.3 技能自改进(Skill Self-Improvement)
触发时机:现有 Skill 执行失败时
执行逻辑:
- Agent 检测到 Skill 的执行步骤无效(工具调用失败、返回错误结果)
- 尝试替代方案,找到可行路径
- 调用
skill_manage工具,用patch或edit动作更新 Skill
代码示例(Skill 自改进):
# Agent 发现现有 Skill 的某个步骤失效了
# 旧步骤:Docker 重启命令是 `systemctl restart docker`
# 新环境:使用的是 `service docker restart`
# Agent 调用 skill_manage 工具
skill_manage(
action="patch",
name="fix-docker-network-issue",
old_string="重启 Docker:`sudo systemctl restart docker`",
new_string="重启 Docker:\n- Systemd: `sudo systemctl restart docker`\n- SysV: `sudo service docker restart`\n- macOS: `open -a Docker`"
)
4.2.4 FTS5 召回(FTS5 Recall)
作用:按需检索历史对话
实现:
- 所有会话消息存储在 SQLite 的
messages表 - 创建 FTS5 虚拟表
messages_fts - Agent 使用
session_search工具进行全文搜索
搜索示例:
# Agent 需要回忆"上次是怎么配置 Nginx 反向代理的?"
session_search(
mode="full_text",
pattern="Nginx 反向代理配置",
scope="messages",
sort="recency"
)
4.2.5 用户建模(User Modeling)
实现方式:集成 Honcho 方言式建模
作用:
- 从用户行为推断偏好(例如:用户总是拒绝某个工具的输出格式)
- 动态调整 Agent 的回应风格
配置:
# ~/.hermes/config.yaml
memory:
provider: honcho # 使用 Honcho 进行用户建模
4.3 write_approval 门控:防止「学歪了」
如果担心 Agent 自己乱改 Skill 或记忆,可以开启 write_approval:
# ~/.hermes/config.yaml
skills:
write_approval: true # 技能写入需人工审批
memory:
write_approval: true # 记忆写入需人工审批
开启后:
- Agent 的技能写入会被暂存到
~/.hermes/pending/skills/ - 记忆写入会被暂存到
~/.hermes/pending/memory/ - 用户通过以下命令审批:
/skills pending # 列出待审批的技能写入 /skills diff <id> # 查看完整 diff /skills approve <id> # 批准 /skills reject <id> # 拒绝 /memory pending # 列出待审批的记忆写入 /memory approve <id> # 批准 /memory reject <id> # 拒绝
5. 记忆系统实战:SQLite+FTS5 的三层记忆架构
5.1 记忆系统的三大组件
| 组件 | 文件位置 | 用途 | 字符限制 |
|---|---|---|---|
| MEMORY.md | ~/.hermes/memories/MEMORY.md | Agent 的个人笔记(环境事实、约定、经验教训) | 2,200 字符(~800 tokens) |
| USER.md | ~/.hermes/memories/USER.md | 用户档案(偏好、沟通风格、期望) | 1,375 字符(~500 tokens) |
| SessionDB | ~/.hermes/state.db (SQLite) | 所有会话历史的全文索引 | 无限制 |
5.2 MEMORY.md 详解
5.2.1 内容格式
User runs macOS 14 Sonoma, uses Homebrew, has Docker Desktop and Podman. Shell: zsh with oh-my-zsh.
§
Project ~/code/api uses Go 1.22, sqlc for DB queries, chi router. Run tests with 'make test'. CI via GitHub Actions.
§
The staging server (10.0.1.50) needs SSH port 2222, not 22. Key is at ~/.ssh/staging_ed25519.
§
User prefers TypeScript over JavaScript. Always use `pnpm` instead of `npm`.
格式说明:
- 每个条目用
§分隔 - 条目可以是多行的
- 系统提示词中会自动显示使用百分比和字符计数
5.2.2 系统提示词中的注入
在每次会话开始时,记忆内容会被冻结快照并注入系统提示词:
═══════════════════════════════════════════════
MEMORY (your personal notes) [67% — 1,474/2,200 chars]
═══════════════════════════════════════════════
User runs macOS 14 Sonoma, uses Homebrew...
§
Project ~/code/api uses Go 1.22...
§
...
关键点:
- 冻结快照模式:系统提示词在会话期间不变,以保留 LLM 的前缀缓存
- 更改下次生效:Agent 在会话期间添加/删除记忆条目,更改会立即持久化到磁盘,但要到下次会话开始时才会出现在系统提示词中
5.3 USER.md 详解
5.3.1 应该记录什么?
| 记录 | 跳过 |
|---|---|
| 用户的名字、角色、时区 | 琐碎/模糊的信息("用户问过 Python") |
| 沟通偏好(简洁 vs 详细、格式偏好) | 容易重新发现的事实("Python 3.12 支持 f-string 嵌套") |
| 讨厌的事和要避免的事 | 原始数据转储(大代码块、日志文件) |
| 工作流习惯 | 会话特定的临时信息 |
| 技术熟练度 | 已经在上下文文件中的信息(SOUL.md、AGENTS.md) |
5.3.2 好的记忆条目示例
# 好的:打包多个相关事实
User runs macOS 14 Sonoma, uses Homebrew, has Docker Desktop and Podman. Shell: zsh with oh-my-zsh. Editor: VS Code with Vim keybindings.
# 好的:具体、可操作的约定
Project ~/code/api uses Go 1.22, sqlc for DB queries, chi router. Run tests with 'make test'. CI via GitHub Actions.
# 好的:带上下文的经验教训
The staging server (10.0.1.50) needs SSH port 2222, not 22. Key is at ~/.ssh/staging_ed25519.
# 坏的:太模糊
User has a project.
# 坏的:太啰嗦
On January 5th, 2026, the user asked me to look at their project which is located at ~/code/api. I discovered it uses Go version 1.22 and...
5.4 SessionDB:FTS5 全文搜索
5.4.1 数据库 Schema
-- 消息表
CREATE TABLE messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
role TEXT NOT NULL CHECK(role IN ('user', 'assistant', 'system')),
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- FTS5 虚拟表(用于全文搜索)
CREATE VIRTUAL TABLE messages_fts USING fts5(
session_id,
role,
content,
content='messages',
content_rowid='id'
);
-- 触发器:自动同步 FTS5 索引
CREATE TRIGGER messages_ai AFTER INSERT ON messages BEGIN
INSERT INTO messages_fts(rowid, session_id, role, content)
VALUES (new.id, new.session_id, new.role, new.content);
END;
CREATE TRIGGER messages_ad AFTER DELETE ON messages BEGIN
INSERT INTO messages_fts(messages_fts, rowid, session_id, role, content)
VALUES ('delete', old.id, old.session_id, old.role, old.content);
END;
CREATE TRIGGER messages_au AFTER UPDATE ON messages BEGIN
INSERT INTO messages_fts(messages_fts, rowid, session_id, role, content)
VALUES ('delete', old.id, old.session_id, old.role, old.content);
INSERT INTO messages_fts(rowid, session_id, role, content)
VALUES (new.id, new.session_id, new.role, new.content);
END;
5.4.2 使用 session_search 工具
Agent 通过 session_search 工具搜索历史对话:
三种调用形状:
发现(Discovery):搜索相关消息
session_search( mode="full_text", pattern="Docker 网络配置", scope="messages", sort="recency", limit=10 )滚动(Scroll):浏览特定会话
session_search( mode="scroll", conversationId=12345, offset=0, limit=50 )浏览(Browse):查看特定消息的上下文
session_search( mode="browse", messageId=67890, context=5 # 前后各 5 条消息 )
5.5 容量管理
5.5.1 容量限制
| 存储 | 限制 | 典型条目数 |
|---|---|---|
| MEMORY.md | 2,200 字符 | 8-15 条 |
| USER.md | 1,375 字符 | 5-10 条 |
5.5.2 存满时怎么办?
当你尝试添加会导致超出限制的条目时,工具会返回错误:
{
"success": false,
"error": "Memory at 2,100/2,200 chars. Adding this entry (250 chars) would exceed the limit. Consolidate now: use 'replace' to merge overlapping entries into shorter ones or 'remove' stale or less important entries (see current_entries below), then retry this add — all in this turn.",
"current_entries": ["..."],
"usage": "2,100/2,200"
}
Agent 应该然后:
- 读取当前条目(在错误响应中显示)
- 识别可以删除或合并的条目
- 使用
replace将相关条目合并为更短的版本 - 然后添加新条目
最佳实践:当记忆使用率超过 80% 时(在系统提示词标题中可见),在添加新条目之前先合并条目。
6. 技能系统:从 Skill 生命周期到渐进式加载
6.1 Skill 的生命周期
创建(create)
↓
加载(load)→ 使用(use)
↓
更新(patch/edit)← 发现更好方法
↓
删除(delete)→ 过时/无效
6.2 Skill 的存储位置
所有技能住在 ~/.hermes/skills/——主目录和事实来源。
~/.hermes/skills/
├── mlops/ # 分类目录
│ ├── axolotl/
│ │ ├── SKILL.md # 主要指令(必需)
│ │ ├── references/ # 额外文档
│ │ ├── templates/ # 输出格式
│ │ ├── scripts/ # 从技能可调用的辅助脚本
│ │ └── assets/ # 补充文件
│ └── vllm/
│ └── SKILL.md
├── devops/
│ └── deploy-k8s/ # Agent 创建的技能
│ ├── SKILL.md
│ └── references/
├── .hub/ # Skills Hub 状态
│ ├── lock.json
│ ├── quarantine/
│ └── audit.log
└── .bundled_manifest # 跟踪内置技能的播种
6.3 SKILL.md 格式详解
---
name: my-skill
description: Brief description of what this skill does
version: 1.0.0
platforms: [macos, linux] # 可选——限制到特定 OS 平台
metadata:
hermes:
tags: [python, automation]
category: devops
fallback_for_toolsets: [web] # 可选——条件激活(见下文)
requires_toolsets: [terminal] # 可选——条件激活(见下文)
config: # 可选——config.yaml 设置
- key: my.setting
description: "What this controls"
default: "value"
prompt: "Prompt for setup"
---
# Skill Title
## When to Use
Trigger conditions for this skill.
## Procedure
1. Step one
2. Step two
## Pitfalls
- Known failure modes and fixes
## Verification
How to confirm it worked.
6.3.1 平台特定技能
技能可以使用 platforms 字段限制自己到特定操作系统:
| 值 | 匹配 |
|---|---|
macos | macOS (Darwin) |
linux | Linux |
windows | Windows |
platforms: [macos] # 仅 macOS(例如 iMessage、Apple Reminders、FindMy)
platforms: [macos, linux] # macOS 和 Linux
设置后,技能会自动从不兼容平台上的系统提示词、skills_list() 和斜杠命令中隐藏。
6.3.2 条件激活(Fallback Skills)
技能可以根据当前会话中可用的工具自动显示或隐藏。
metadata:
hermes:
fallback_for_toolsets: [web] # 仅当这些工具集不可用时显示
requires_toolsets: [terminal] # 仅当这些工具集可用时显示
fallback_for_tools: [web_search] # 仅当这些特定工具不可用时显示
requires_tools: [terminal] # 仅当这些特定工具可用时显示
示例:内置的 duckduckgo-search 技能使用 fallback_for_toolsets: [web]。当你设置了 FIRECRAWL_API_KEY 时,web 工具集可用,Agent 使用 web_search——DuckDuckGo 技能保持隐藏。如果 API 密钥缺失,web 工具集不可用,DuckDuckGo 技能自动出现作为后备。
6.4 渐进式加载(Progressive Disclosure)
技能使用 Token 高效的加载模式:
Level 0: skills_list() → [{name, description, category}, ...] (~3k tokens)
Level 1: skill_view(name) → Full content + metadata (varies)
Level 2: skill_view(name, path) → Specific reference file (varies)
Agent 只在真正需要时才加载完整的技能内容。
6.5 使用技能
每个安装的技能自动作为斜杠命令可用:
# 在 CLI 或任何消息平台:
/gif-search funny cats
/axolotl help me fine-tune Llama 3 on my dataset
/github-pr-workflow create a PR for the auth refactor
/plan design a rollout for migrating our auth provider
# 只是技能名称加载它并让 Agent 询问你需要什么:
/excalidraw
你也可以通过自然对话与技能交互:
hermes chat --toolsets skills -q "What skills do you have?"
hermes chat --toolsets skills -q "Show me the axolotl skill"
6.6 技能包(Skill Bundles)
技能包是将多个技能分组在单个斜杠命令下的微型 YAML 文件。
6.6.1 快速示例
# 为后端功能工作创建包
hermes bundles create backend-dev \
--skill github-code-review \
--skill test-driven-development \
--skill github-pr-workflow \
-d "Backend feature work — review, test, PR workflow"
然后在 CLI 或任何网关平台中:
/backend-dev refactor the auth middleware
Agent 一次性加载所有三个技能到一条用户消息中。
6.6.2 YAML Schema
包住在 ~/.hermes/skill-bundles/<slug>.yaml 中,看起来像这样:
name: backend-dev
description: Backend feature work — review, test, PR workflow.
skills:
- github-code-review
- test-driven-development
- github-pr-workflow
instruction: |
Always start by writing failing tests, then implement.
Open the PR through the standard workflow with co-author tags.
6.7 Agent 管理的技能(skill_manage 工具)
Agent 可以通过 skill_manage 工具创建、更新和删除自己的技能。
6.7.1 何时 Agent 创建技能?
- 成功完成复杂任务(5+ 工具调用)后
- 当它遇到错误 or 死胡同并找到可行路径时
- 当用户纠正它的方法时
- 当它发现非平凡的工作流时
6.7.2 动作
| 动作 | 用途 | 关键参数 |
|---|---|---|
create | 从零开始创建新技能 | name, content (完整 SKILL.md), optional category |
patch | 针对性修复(首选) | name, old_string, new_string |
edit | 重大结构重写 | name, content (完整 SKILL.md 替换) |
delete | 完全删除技能 | name |
write_file | 添加/更新支持文件 | name, file_path, file_content |
remove_file | 删除支持文件 | name, file_path |
提示:patch 动作是更新的首选——它比 edit 更 Token 高效,因为只有更改的文本出现在工具调用中。
7. 工具链深度集成:70+ 工具与 6 大终端后端
7.1 工具注册表(Tool Registry)
中央工具注册表在 tools/registry.py 中,在导入时自注册。
7.1.1 注册流程
tools/registry.py (无依赖——被所有工具文件导入)
↑
tools/*.py (每个在导入时调用 registry.register())
↑
model_tools.py (导入 tools/registry + 触发工具发现)
↑
run_agent.py, cli.py, batch_runner.py, environments/
这意味着工具注册发生在导入时,在任何 Agent 实例创建之前。任何带有顶层 registry.register() 调用的 tools/*.py 文件都会被自动发现——无需手动导入列表。
7.1.2 工具 Schema 收集
# model_tools.py
def collect_tool_schemas():
"""收集所有注册工具的 JSON Schema。"""
schemas = []
for tool_name, tool_info in registry.get_all_tools().items():
schema = {
"type": "function",
"function": {
"name": tool_name,
"description": tool_info["description"],
"parameters": tool_info["parameters_schema"]
}
}
schemas.append(schema)
return schemas
7.2 六大终端后端详解
Hermes 的终端工具(terminal)支持 6 种后端:
| 后端 | 用途 | 配置示例 |
|---|---|---|
| Local | 本地 Shell 执行 | terminal: local |
| Docker | 在容器中执行 | terminal: docker, docker_image: alpine:latest |
| SSH | 在远程服务器执行 | terminal: ssh, ssh_host: user@server |
| Singularity | HPC 环境(科学计算) | terminal: singularity |
| Modal | 无服务器云函数 | terminal: modal, 需配置 Modal Token |
| Daytona | 无服务器开发环境 | terminal: daytona, 需配置 Daytona URL |
7.2.1 Modal 后端实战
Modal 是一个无服务器平台,可以按需运行 Python 函数。
配置:
# 安装 Modal
pip install modal
# 认证
modal setup
# 在 ~/.hermes/config.yaml 中启用
tools:
terminal:
backend: modal
modal:
image: "python:3.11"
timeout: 300
gpu: "T4" # 可选
代码示例(Agent 内部):
# Agent 接收到任务:"训练一个 PyTorch 模型"
# 它决定使用 Modal 后端执行训练脚本
terminal(
command="""
cd /workspace
pip install torch torchvision
python train.py --epochs 10 --lr 0.001
""",
backend="modal",
workdir="/workspace"
)
优势:
- 成本极低:空闲时不计费
- 自动扩展:可以并行运行多个训练任务
- GPU 支持:按需分配 T4、A10G、A100
7.2.2 Daytona 后端实战
Daytona 是一个开发环境管理平台,可以创建临时的、无服务器的开发环境。
配置:
# 安装 Daytona CLI
curl -fsSL https://download.daytona.io/install.sh | bash
# 在 ~/.hermes/config.yaml 中启用
tools:
terminal:
backend: daytona
daytona:
target: "https://daytona.example.com"
api_key: "your-api-key"
使用场景:
- 需要隔离环境测试代码
- 需要临时环境运行 CI/CD 任务
- 需要并行运行多个开发任务
7.3 工具分发流程
LLM 返回 tool_calls
↓
AIAgent.run_conversation()
↓
model_tools.handle_function_call(tool_calls)
↓
registry.dispatch(tool_name, tool_args)
↓
tools/terminal_tool.py: terminal(tool_args)
↓
environments/local.py: execute_locally(command)
↓
返回结果 → LLM → 最终响应
8. 多平台网关:20 个适配器与统一会话路由
8.1 网关架构概览
┌─────────────────────────────────────────────────────────┐
│ GatewayRunner (gateway/run.py) │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Platform Adapters (20 adapters) │ │
│ │ telegram, discord, slack, whatsapp, signal, │ │
│ │ matrix, mattermost, email, sms, dingtalk, │ │
│ │ feishu, wecom, weixin, bluebubbles, qqbot, │ │
│ │ homeassistant, webhook, api_server, yuanbao │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ Session Store (SQLite) │ │
│ │ 统一会话路由、跨平台消息镜像 │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ User Authorization │ │
│ │ Allowlists + DM Pairing │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ Hook System │ │
│ │ 生命周期钩子、消息过滤、响应修改 │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ AIAgent (run_agent.py) │
└─────────────────────────────────────────────────────────┘
8.2 统一会话路由
问题:用户从 Telegram 发消息,然后切换到 Discord 继续对话,Agent 如何找到正确的上下文?
解决方案:SessionStore 使用统一的会话键(Session Key)
# gateway/session.py
class SessionStore:
def resolve_session_key(self, platform, user_id, chat_id=None):
"""
解析统一的会话键。
规则:
- 如果用户在多个平台上,使用 user_id 作为统一键
- 如果群聊,使用 chat_id 作为键
"""
if chat_id:
# 群聊:每个群聊独立会话
return f"group:{chat_id}"
else:
# 私聊:跨平台统一会话
return f"user:{user_id}"
8.3 DM 配对授权(DM Pairing)
场景:你希望通过 Telegram 与 Agent 私聊,但不希望陌生人也能使用。
解决方案:DM Pairing
# 在 CLI 中启用 DM Pairing
hermes config set gateway.platforms.telegram.dm_pairing true
# 配对流程:
# 1. 用户首次发送 /start
# 2. Agent 回复:"请提供配对码"
# 3. 用户在 CLI 中运行:hermes pair telegram <code>
# 4. Agent 记录该用户为"已授权"
8.4 钩子系统(Hook System)
网关支持生命周期钩子,允许在消息处理的关键节点插入自定义逻辑。
钩子类型:
on_message_received:消息接收后、处理前on_before_agent_call:Agent 调用前on_after_agent_response:Agent 响应后、投递前on_message_sent:消息投递后
示例:消息过滤钩子
# ~/.hermes/plugins/filter_hook.py
def on_message_received(event):
"""过滤包含敏感词的消息。"""
sensitive_words = ["密码", "token", "secret"]
for word in sensitive_words:
if word in event.content:
event.blocked = True
event.response = "消息包含敏感词,已屏蔽。"
return event
return event
9. MCP 集成:连接整个 AI 工具生态
9.1 什么是 MCP?
MCP(Model Context Protocol) 是 Anthropic 推出的开放协议,用于连接 AI 模型与外部工具/数据源。
核心价值:
- 标准化:统一的工具接口,无需为每个工具写适配器
- 可扩展:任何实现 MCP 服务器的工具都可以被 Hermes 调用
- 生态丰富:已有数百个 MCP 服务器(Playwright、GitHub、Postgres、Google Maps...)
9.2 Hermes 的 MCP 集成架构
Hermes Agent
↓
mcp_tool.py (MCP 客户端)
↓
MCP Server (例如:playwright-mcp)
↓
外部工具(例如:浏览器)
9.3 配置 MCP 服务器
9.3.1 方式一:通过配置文件
# ~/.hermes/config.yaml
mcp:
servers:
- name: playwright
transport: stdio
command: "npx @playwright/mcp-server"
env:
DEBUG: "pw:api"
- name: github
transport: http
url: "https://mcp.github.com"
auth_token: "${GITHUB_TOKEN}"
- name: postgres
transport: stdio
command: "mcp-server-postgres"
args:
- "--connection-string"
- "postgresql://user:pass@localhost:5432/mydb"
9.3.2 方式二:通过自然语言
用户:帮我添加一个 MCP 服务器,连接我的 GitHub 仓库
Agent:
1. 调用 mcp_add 工具
2. 配置 GitHub MCP 服务器
3. 测试连接
4. 确认添加成功
9.4 使用 MCP 工具
配置完成后,MCP 服务器的工具会自动出现在 Hermes 的工具列表中。
示例:使用 Playwright MCP 截图网页
用户:帮我截图 https://example.com 的首页
Agent:
1. 调用 mcp_call 工具
2. 指定服务器:playwright
3. 指定工具:page_screenshot
4. 传递参数:{"url": "https://example.com"}
5. 返回截图路径
6. 显示截图
10. 生产级部署:Docker/Modal/Daytona 无服务器化
10.1 为什么需要无服务器化?
传统部署的问题:
- 成本高:VPS 7×24 运行,即使空闲也计费
- 维护难:需要手动更新依赖、处理崩溃
- 扩展差:流量高峰时无法自动扩展
无服务器化的优势:
- 成本极低:空闲时不计费
- 自动扩展:可以同时运行数百个实例
- 零维护:平台负责底层基础设施
10.2 Docker 后端部署
10.2.1 使用 Docker Compose
# docker-compose.yml
version: '3.8'
services:
hermes:
build: .
volumes:
- ~/.hermes:/root/.hermes
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY
command: ["hermes", "gateway", "start"]
redis:
image: redis:alpine
ports:
- "6379:6379"
10.2.2 构建 Docker 镜像
# Dockerfile
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
ENV PATH="/root/.hermes/bin:${PATH}"
WORKDIR /root/.hermes
CMD ["hermes", "gateway", "start"]
10.3 Modal 后端部署
10.3.1 编写 Modal 函数
# modal_deploy.py
import modal
app = modal.App("hermes-agent")
image = (
modal.Image.debian_slim()
.apt_install("git", "curl")
.run_commands(
"curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash"
)
)
@app.function(
image=image,
secrets=[modal.Secret.from_name("openai-api-key")],
timeout=300,
keep_warm=1 # 保持一个实例热身,减少冷启动
)
def run_hermes_task(prompt: str):
import subprocess
result = subprocess.run(
["hermes", "chat", "-q", prompt],
capture_output=True,
text=True
)
return result.stdout
10.3.2 部署到 Modal
# 部署
modal deploy modal_deploy.py
# 调用
modal run modal_deploy.py::run_hermes_task --prompt "帮我分析这个日志"
10.4 Daytona 后端部署
10.4.1 创建 Daytona 开发环境
# 安装 Daytona CLI
curl -fsSL https://download.daytona.io/install.sh | bash
# 创建开发环境
daytona create hermes-agent \
--image python:3.11 \
--env OPENAI_API_KEY=${OPENAI_API_KEY}
# 在开发环境中执行命令
daytona exec hermes-agent -- hermes gateway start
10.4.2 配置 Hermes 使用 Daytona 后端
# ~/.hermes/config.yaml
tools:
terminal:
backend: daytona
daytona:
target: "https://daytona.example.com"
api_key: "${DAYTONA_API_KEY}"
default_environment: "hermes-agent"
11. 从 OpenClaw 迁移:一键导入你的 Agent 记忆
11.1 为什么需要从 OpenClaw 迁移?
OpenClaw 是另一款流行的 AI Agent 框架(是的,就是那只"龙虾"🦞)。如果你之前是 OpenClaw 用户,现在想切换到 Hermes,不用担心——Hermes 提供了一键迁移工具。
11.2 迁移内容
| 迁移内容 | 说明 |
|---|---|
SOUL.md | 人格文件 |
MEMORY.md | 记忆条目 |
USER.md | 用户档案 |
| Skills | 用户创建的技能 → ~/.hermes/skills/openclaw-imports/ |
| Command allowlist | 命令审批模式 |
| Messaging settings | 平台配置、授权用户、工作目录 |
| API keys | 白名单凭证(Telegram、OpenRouter、OpenAI、Anthropic、ElevenLabs) |
| TTS assets | 工作区音频文件 |
| Workspace instructions | AGENTS.md(使用 --workspace-target) |
11.3 迁移流程
11.3.1 首次设置时自动迁移
在安装过程中,设置向导(hermes setup)会自动检测 ~/.openclaw 并在配置开始前提供迁移。
11.3.2 安装后随时迁移
hermes claw migrate # 交互式迁移(完整预设)
hermes claw migrate --dry-run # 预览会迁移什么
hermes claw migrate --preset user-data # 迁移不含密钥
hermes claw migrate --overwrite # 覆盖现有冲突
11.4 迁移示例
# 预览迁移
hermes claw migrate --dry-run
# 输出:
# Would import:
# - SOUL.md → ~/.hermes/memories/SOUL.md
# - MEMORY.md → ~/.hermes/memories/MEMORY.md
# - USER.md → ~/.hermes/memories/USER.md
# - 3 skills → ~/.hermes/skills/openclaw-imports/
# - API keys: TELEGRAM_BOT_TOKEN, OPENROUTER_API_KEY
#
# Skip with --preset user-data to exclude API keys.
# 执行迁移
hermes claw migrate
# 输出:
# Importing SOUL.md...
# Importing MEMORY.md...
# Importing USER.md...
# Importing 3 skills...
# Importing API keys...
# Migration complete!
12. 性能优化:上下文压缩与 Prompt Caching
12.1 问题:上下文窗口有限
即使是最先进的 LLM,上下文窗口也是有限的:
- Claude 3.5 Sonnet:200K tokens
- GPT-4 Turbo:128K tokens
- Llama 3:8K tokens
当会话历史超过上下文窗口时怎么办?
12.2 解决方案一:上下文压缩(Context Compression)
Hermes 使用 context_compressor.py 对中间对话轮次进行摘要。
12.2.1 压缩策略
原始会话历史:
[System Prompt] + [Message 1] + [Message 2] + ... + [Message N]
压缩后:
[System Prompt] + [Summary of Messages 1~K] + [Message K+1] + ... + [Message N]
12.2.2 压缩算法
# context_compressor.py (伪代码)
def compress_history(messages, max_tokens=200000):
"""压缩会话历史到指定 token 数。"""
current_tokens = count_tokens(messages)
if current_tokens <= max_tokens:
return messages # 无需压缩
# 步骤1:识别可压缩的区域(中间的消息)
system_prompt = messages[0]
recent_messages = messages[-10:] # 保留最近 10 条消息
middle_messages = messages[1:-10]
# 步骤2:使用辅助 LLM 摘要中间消息
summary = summarize_with_llm(middle_messages)
# 步骤3:替换
compressed_messages = [system_prompt, summary] + recent_messages
return compressed_messages
12.3 解决方案二:Prompt Caching(Anthropic)
Anthropic 提供了 Prompt Caching 功能,可以缓存系统提示词,避免每次请求都重新计算。
12.3.1 工作原理
传统方式:
Request 1: [System Prompt] + [Message 1] → LLM 计算 → Response 1
Request 2: [System Prompt] + [Message 1] + [Message 2] → LLM 重新计算 → Response 2
↑
重复计算,浪费 Token
Prompt Caching:
Request 1: [System Prompt] + [Message 1] → LLM 计算 + 缓存 → Response 1
Request 2: [Cache Key] + [Message 2] → LLM 使用缓存 → Response 2
↑
使用缓存,节省 Token
12.3.2 Hermes 中的实现
# prompt_caching.py
def apply_prompt_caching(messages):
"""为系统提示词应用 Anthropic 缓存断点。"""
system_prompt = messages[0]["content"]
# 将系统提示词分块,并添加缓存控制标记
chunks = chunk_system_prompt(system_prompt)
cached_chunks = []
for i, chunk in enumerate(chunks):
if i == len(chunks) - 1:
# 最后一块:设置 cache_control = "ephemeral"
cached_chunks.append({
"type": "text",
"text": chunk,
"cache_control": {"type": "ephemeral"}
})
else:
cached_chunks.append({
"type": "text",
"text": chunk
})
messages[0]["content"] = cached_chunks
return messages
12.4 Token 消耗对比
| 场景 | 无优化 | 上下文压缩 | Prompt Caching |
|---|---|---|---|
| 长会话(50 轮) | 180K tokens | 90K tokens | 60K tokens |
| 短会话(10 轮) | 40K tokens | 40K tokens | 15K tokens |
| 成本节省 | - | ~50% | ~70% |
13. 安全机制:命令审批与沙箱隔离
13.1 命令审批(Command Approval)
13.1.1 为什么需要命令审批?
场景:Agent 执行危险命令(例如:rm -rf /、DROP DATABASE)
解决方案:命令审批模式
13.1.2 配置命令审批
# ~/.hermes/config.yaml
security:
command_approval:
mode: allowlist # off | allowlist | full
# 允许执行的命令模式(正则表达式)
allowlist:
- "^ls"
- "^cat"
- "^grep"
- "^git status"
- "^git diff"
# 始终需要审批的命令模式
always_approve:
- "^rm"
- "^sudo"
- "^docker rm"
- "^DROP"
- "^DELETE"
13.1.3 审批流程
Agent 调用 terminal 工具
↓
检测到命令匹配 always_approve 模式
↓
暂停执行,发送审批请求给用户
↓
用户在 CLI 或消息平台中审批
↓
批准 → 执行命令
拒绝 → 返回错误给 Agent
示例(Telegram 中审批):
Agent:
⚠️ 需要审批命令:
sudo systemctl restart nginx
是否批准?回复 /approve 或 /reject
用户:/approve
Agent:执行命令,返回结果。
13.2 沙箱隔离(Sandbox Isolation)
13.2.1 为什么需要沙箱?
场景:Agent 执行不受信任的代码(例如:用户要求"运行这个脚本")
解决方案:在沙箱中执行
13.2.2 Docker 沙箱
# ~/.hermes/config.yaml
tools:
code_execution:
backend: docker
docker:
image: "python:3.11-slim"
memory_limit: "512m"
cpu_limit: 1.0
timeout: 30 # 秒
network: "none" # 禁用网络
13.2.3 代码示例
# Agent 接收到任务:"运行这段 Python 代码"
# 使用 code_execution 工具
code_execution(
code="""
import os
print("Hello, Sandbox!")
print("CWD:", os.getcwd())
""",
backend="docker",
config={
"image": "python:3.11-slim",
"memory_limit": "512m",
"network": "none"
}
)
# 输出:
# Hello, Sandbox!
# CWD: /workspace
14. 完整实战:从安装到部署一个自动化工作流
14.1 场景:每日自动抓取 Hacker News 热门文章并摘要
需求:
- 每天早上 9:00,自动抓取 Hacker News 热门文章(前 10 条)
- 用 LLM 生成摘要
- 发送到 Telegram
14.2 步骤一:安装 Hermes Agent
# Linux / macOS / WSL2
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
# 安装后刷新 shell
source ~/.bashrc # 或 source ~/.zshrc
# 验证安装
hermes --version
14.3 步骤二:配置模型和平台
# 交互式配置
hermes setup
# 选择提供商:OpenRouter
# 选择模型:anthropic/claude-3.5-sonnet
# 配置 Telegram Bot Token(从 @BotFather 获取)
14.4 步骤三:创建定时任务
# 方式一:通过 CLI 创建
hermes cron add \
--name "HN Daily Summary" \
--schedule "0 9 * * *" \
--prompt "抓取 Hacker News 热门文章(前 10 条),生成摘要,并发送到 Telegram" \
--deliver-to telegram
# 方式二:通过自然语言创建
hermes chat -q "帮我创建一个定时任务:每天早上 9 点抓取 Hacker News 热门文章并摘要,发送到 Telegram"
# Agent 会自动调用 cron_add 工具
14.5 步骤四:编写 Skill(可选但推荐)
为了让 Agent 更好地完成任务,可以创建一个 Skill:
# 让 Agent 创建 Skill
hermes chat -q "帮我创建一个 Skill,用于抓取 Hacker News 热门文章并生成摘要"
# Agent 会调用 skill_manage 工具
skill_manage(
action="create",
name="hn-daily-summary",
content="""
---
name: hn-daily-summary
description: 抓取 Hacker News 热门文章并生成摘要
version: 1.0.0
---
# HN Daily Summary
## When to Use
需要每日自动抓取 Hacker News 热门文章时。
## Procedure
1. 调用 web_search 工具,搜索 "Hacker News top stories API"
2. 使用 web_extract 工具,提取 https://hacker-news.firebaseio.com/v0/topstories.json
3. 获取前 10 条故事的 ID
4. 对于每个 ID,获取详情:https://hacker-news.firebaseio.com/v0/item/{id}.json
5. 提取标题、URL、评分
6. 使用 LLM 生成摘要
7. 格式化为 Markdown
8. 发送到 Telegram(使用 deliver 工具)
## Pitfalls
- HN API 有速率限制,请勿频繁请求
- 如果某篇文章无法访问,跳过并继续
## Verification
检查 Telegram 是否收到消息。
"""
)
14.6 步骤五:测试和运行
# 手动触发任务
hermes cron run "HN Daily Summary"
# 查看任务状态
hermes cron list
# 查看执行日志
hermes cron logs "HN Daily Summary"
15. 与 OpenClaw 的深度对比:两款「宠物」怎么选?
15.1 定位对比
| 维度 | Hermes Agent | OpenClaw |
|---|---|---|
| 核心差异化 | 自我进化 + 持久记忆 | 跨平台 + 易用性 |
| 学习模式 | 自主创建 Skill | 依赖用户配置 |
| 记忆系统 | SQLite + FTS5 + MEMORY.md | MEMORY.md + 简单搜索 |
| 平台支持 | 20 个平台适配器 | 15 个平台适配器 |
| 工具数量 | 70+ 工具,28 工具集 | 40+ 工具,15 工具集 |
| 终端后端 | 6 种(含 Modal、Daytona) | 3 种(Local、Docker、SSH) |
| MCP 支持 | 完整支持(动态调用) | 基础支持 |
| 闭环学习 | ✅ 原生支持 | ❌ 不支持 |
| 无服务器部署 | ✅ Modal、Daytona | ❌ 不支持 |
15.2 适用场景
选择 Hermes Agent,如果你:
- 希望 Agent 能够自我学习和进化
- 需要深度的持久记忆(跨会话、可搜索)
- 需要无服务器部署(降低成本)
- 需要丰富的工具链(70+ 工具)
- 是技术深度用户,愿意花时间配置
选择 OpenClaw,如果你:
- 希望开箱即用,配置简单
- 不需要 Agent 自我学习
- 主要在单一平台使用(例如:本地 CLI)
- 是普通用户,希望"能用就行"
15.3 迁移路径
如果你现在是 OpenClaw 用户,想尝试 Hermes:
# 一键迁移
hermes claw migrate
# 迁移后,两个工具可以同时运行
# - OpenClaw:处理简单任务
# - Hermes Agent:处理复杂任务、需要记忆的任务
16. 总结与展望:Agent 操作系统的雏形
16.1 Hermes Agent 的技术创新
- 闭环学习:首次在开源 Agent 框架中实现真正的"自我进化"
- 三层记忆架构:情景记忆 + 语义记忆 + 程序性记忆,覆盖认知科学的三大记忆类型
- 渐进式技能加载:Token 高效的技能系统,避免上下文窗口浪费
- 无服务器化:Modal、Daytona 集成,让 Agent 部署成本降到几乎为零
- 统一网关:20 个平台适配器,真正实现"一个 Agent,处处可用"
16.2 Agent 操作系统的雏形
Hermes Agent 的架构设计,已经具备了操作系统的雏形:
| 操作系统组件 | Hermes Agent 对应 |
|---|---|
| 进程管理 | Agent 会话管理 |
| 文件系统 | Skills、Memory、SessionDB |
| 设备驱动 | 工具后端(终端、浏览器、MCP) |
| 网络协议 | 平台适配器(Telegram、Discord...) |
| 安全模块 | 命令审批、沙箱隔离 |
| 调度器 | Cron 定时任务 |
未来展望:
- Agent 应用商店:类似 iOS App Store,用户可以直接安装"Agent 应用"(即 Skill 包)
- Agent 间通信:多个 Agent 可以协同工作,形成"Agent 集群"
- ** Agent 操作系统标准**:Hermes Agent 可能成为 Agent 操作系统的参考实现
16.3 最后的思考
Hermes Agent 的出现,标志着 AI Agent 从"工具"到"伙伴"的质变。
它不再是一个被动执行命令的聊天机器人,而是一个能够主动学习、持续进化、记住你偏好的真正伙伴。
如果你还没有尝试过 Hermes Agent,现在就是最好的时机。相信我,一旦你体验过"越用越聪明"的 Agent,你再也回不去传统的"金鱼记忆"助手了。
参考资源
- 官方 GitHub:https://github.com/NousResearch/hermes-agent
- 官方文档:https://hermes-agent.nousresearch.com/docs/
- Discord 社区:https://discord.gg/NousResearch
- Skills Hub:https://agentskills.io
- Nous Research:https://nousresearch.com
全文完。希望这篇深度实战指南能帮助你理解和使用 Hermes Agent。如果你有任何问题或建议,欢迎在评论区留言讨论!
Disclaimer:本文所有技术细节均来自公开文档和代码分析,如有错误欢迎指正。Hermes Agent 是 Nous Research 的注册商标。