作者:PySuper | 来源:zhengxingtao.com
上一篇 #48 讲了 Hermes Agent 的自进化原理,部署部分点到为止。这篇是纯运维向——你拿到一台裸机,照着做,30 分钟后 Hermes 就在跑,并且能从 Telegram/Discord 跟你对话。所有脚本都可直接复制运行,不含省略号。
目录
部署前规划
方案一:Docker 一键部署(推荐)
方案二:pip/uv 安装部署
方案三:云服务器一键部署
多渠道接入配置
模型配置
自进化系统配置
执行后端配置
生产加固
一键部署脚本(完整版)
与 OpenClaw 联合部署方案
常见问题排查
1. 部署前规划
1.1 硬件需求
Hermes Agent 的资源消耗跟 OpenClaw 有本质区别——Hermes 重存储,因为 Skill、记忆、会话摘要都在本地持久化。选配置时磁盘比 CPU 更关键。
表格
据《How to Set Up Hermes Agent》(https://hermes-agent.ai/blog/hermes-agent-setup-guide),Hetzner CX22(2 vCPU / 4GB RAM)约 EUR4/月,是性价比最高的入门选择。
1.2 操作系统支持
plaintext
┌─────────────────────────────────────────────────────┐
│ Hermes Agent OS 支持矩阵 │
├─────────────┬───────────┬───────────┬───────────────┤
│ OS │ 安装脚本 │ Docker │ 备注 │
├─────────────┼───────────┼───────────┼───────────────┤
│ Ubuntu 22.04│ ✅ │ ✅ │ 官方推荐 │
│ Debian 12 │ ✅ │ ✅ │ 稳定 │
│ macOS │ ✅ │ ✅ │ Intel/Apple │
│ WSL2 │ ✅ │ ✅ │ Win11 必须 │
│ Termux │ ✅ │ ❌ │ 精简版 │
│ Windows 原生│ ❌ │ ❌ │ 不支持 │
│ NixOS │ ✅ │ ✅ │ Nix flake │
└─────────────┴───────────┴───────────┴───────────────┘
1.3 与 OpenClaw 的部署差异
Hermes 和 OpenClaw 都能跑在 2C4G 上,但资源侧重完全不同:
plaintext
┌──────────────────────────────────────────────────────────────┐
│ 资源消耗对比(同等工作负载) │
│ │
│ OpenClaw Hermes Agent │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ CPU: ★★★★☆ │ │ CPU: ★★★☆☆ │ │
│ │ 内存: ★★★☆☆ │ │ 内存: ★★★☆☆ │ │
│ │ 磁盘: ★★☆☆☆ │ │ 磁盘: ★★★★★ │ │
│ │ 网络: ★★★★★ │ │ 网络: ★★★☆☆ │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ OpenClaw 重 API 调用(常驻 Claude Opus) │
│ Hermes 重本地存储(Skill 文件 + FTS5 索引 + 记忆) │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 磁盘空间增长预估(6个月日常使用) │ │
│ │ │ │
│ │ OpenClaw: ~500MB (配置+日志) │ │
│ │ Hermes: ~2-5GB (Skill+记忆+会话索引) │ │
│ │ Ollama: +4-40GB (每个模型 4-40GB) │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
关键差异:
存储:Hermes 的 Skill 文件(
~/.hermes/skills/)、FTS5 会话索引(sessions.db)、记忆文件(MEMORY.md/USER.md/SOUL.md)会持续增长。OpenClaw 的配置基本不增长。模型灵活性:Hermes 支持 19+ 提供商(含本地 Ollama、vLLM),OpenClaw 主要依赖 Anthropic。这意味着 Hermes 可以跑在便宜的模型上,日成本更低。
网关开销:Hermes 的 Gateway 进程同时处理所有平台消息,内存占用比 OpenClaw 的轻量 CLI 更大。
1.4 模型选择:云 API vs 本地
表格
据社区共识,Kimi K2.5 约0.03/M token——日常使用选这两款不会肉疼。
2. 方案一:Docker 一键部署(推荐)
Docker 是最省心的方案:环境隔离、升级方便、数据持久化有保障。生产环境优先选这个。
2.1 完整 docker-compose.yml
yaml
# docker-compose.yml — Hermes Agent 生产部署
# 用法: HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d
#
# 安全提示:
# - Dashboard 默认绑定 127.0.0.1,不对外暴露
# - API Server 默认关闭,需手动开启并设置密钥
# - .env 文件权限必须 600
version: "3.8"
services:
# ── Hermes Agent 主服务 ──────────────────────────────────
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: ["gateway", "run"]
ports:
- "8642:8642" # Gateway API
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_UID=${HERMES_UID:-10000}
- HERMES_GID=${HERMES_GID:-10000}
# API Server(默认关闭,生产环境按需开启)
# - API_SERVER_HOST=0.0.0.0
# - API_SERVER_KEY=${API_SERVER_KEY}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
depends_on:
redis:
condition: service_healthy
networks:
- hermes-net
# ── Redis 记忆后端 ──────────────────────────────────────
redis:
image: redis:7-alpine
container_name: hermes-redis
restart: unless-stopped
command: >
redis-server
--appendonly yes
--appendfsync everysec
--maxmemory 1gb
--maxmemory-policy allkeys-lru
--requirepass ${REDIS_PASSWORD:-}
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
deploy:
resources:
limits:
memory: 1536M
cpus: "0.5"
networks:
- hermes-net
# ── Dashboard Web UI ───────────────────────────────────
dashboard:
image: nousresearch/hermes-agent:latest
container_name: hermes-dashboard
restart: unless-stopped
command: ["dashboard", "--host", "127.0.0.1", "--no-open"]
ports:
- "9119:9119"
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_UID=${HERMES_UID:-10000}
- HERMES_GID=${HERMES_GID:-10000}
- GATEWAY_HEALTH_URL=http://hermes:8642
depends_on:
- hermes
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
networks:
- hermes-net
# ── PostgreSQL(可选:生产级记忆后端)──────────────────
postgres:
image: postgres:16-alpine
container_name: hermes-postgres
restart: unless-stopped
environment:
POSTGRES_DB: hermes
POSTGRES_USER: hermes
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-hermes_local_dev}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hermes"]
interval: 10s
timeout: 5s
retries: 3
deploy:
resources:
limits:
memory: 1G
cpus: "0.5"
networks:
- hermes-net
# ── Ollama(可选:本地模型推理)────────────────────────
ollama:
image: ollama/ollama:latest
container_name: hermes-ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
deploy:
resources:
limits:
memory: 16G
cpus: "4.0"
# GPU 支持(NVIDIA)
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
networks:
- hermes-net
volumes:
redis_data:
postgres_data:
ollama_data:
networks:
hermes-net:
driver: bridge
2.2 环境变量详解
创建 .env 文件:
bash
# ── LLM 提供商(至少填一个)──────────────────────────────
# OpenRouter(推荐:200+ 模型切换)
OPENROUTER_API_KEY=sk-or-v1-your-key-here
# 或 Anthropic 直连
# ANTHROPIC_API_KEY=sk-ant-api03-your-key
# 或 DeepSeek
# DEEPSEEK_API_KEY=sk-your-deepseek-key
# ── Redis 密码(生产必须设置)────────────────────────────
REDIS_PASSWORD=
# ── PostgreSQL 密码 ──────────────────────────────────────
POSTGRES_PASSWORD=your-strong-password-here
# ── API Server 密钥(开启 API 时必须设置)─────────────────
# API_SERVER_KEY=your-api-server-key
# ── Docker UID/GID(文件权限映射)────────────────────────
HERMES_UID=1000
HERMES_GID=1000
# ── 消息网关(按需填写)──────────────────────────────────
# TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
# DISCORD_BOT_TOKEN=your-discord-token
# SLACK_BOT_TOKEN=xoxb-your-slack-token
# ── 可选工具密钥 ─────────────────────────────────────────
# FIRECRAWL_API_KEY=fc-your-key
# FAL_KEY=your-fal-key
安全提醒:.env 文件权限必须收紧:
bash
chmod 600 .env
2.3 数据持久化策略
plaintext
┌──────────────────────────────────────────────────────────────┐
│ Hermes 数据持久化架构 │
│ │
│ 宿主机 ~/.hermes/ 容器内 /opt/data/ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ .env │ ◀────▶ │ .env │ │
│ │ config.yaml │ ◀────▶ │ config.yaml │ │
│ │ SOUL.md │ ◀────▶ │ memories/SOUL.md│ │
│ │ memories/ │ ◀────▶ │ memories/ │ │
│ │ MEMORY.md │ │ MEMORY.md │ │
│ │ USER.md │ │ USER.md │ │
│ │ skills/ │ ◀────▶ │ skills/ │ │
│ │ deploy-k8s/ │ │ deploy-k8s/ │ │
│ │ nginx-ssl/ │ │ nginx-ssl/ │ │
│ │ sessions/ │ ◀────▶ │ sessions/ │ │
│ │ cron/ │ ◀────▶ │ cron/ │ │
│ │ logs/ │ ◀────▶ │ logs/ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ Docker Named Volumes: │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ redis_data │ │ postgres_data│ │ ollama_data │ │
│ │ 会话缓存 │ │ 结构化记忆 │ │ 模型文件 │ │
│ │ (1GB limit) │ │ (生产推荐) │ │ (4-40GB/模型)│ │
│ └───────────────┘ └──────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
关键原则:容器可以删,镜像可以升级,但 ~/.hermes/ 目录和 Named Volumes 绝不能丢。所有状态都在这里。
2.4 一键启动/停止/重启
bash
# ── 启动所有服务 ─────────────────────────────────────────
docker compose up -d
# ── 查看状态 ─────────────────────────────────────────────
docker compose ps
# ── 查看日志 ─────────────────────────────────────────────
docker compose logs hermes --tail 50 -f
# ── 健康检查 ─────────────────────────────────────────────
curl http://localhost:8642/health
# 预期返回: {"status":"ok"}
# ── 重启(升级后)────────────────────────────────────────
docker compose pull
docker compose up -d
# ── 停止所有服务 ─────────────────────────────────────────
docker compose down
# ── 停止并清理(数据卷保留)──────────────────────────────
docker compose down --remove-orphans
# ── 完全清理(⚠️ 含数据卷,慎用!)───────────────────────
docker compose down -v
2.5 Docker 安全加固
据 Hermes Agent 官方 Docker 文档(https://hermes-agent.nousresearch.com/docs/user-guide/docker),最高隔离级别的运行方式:
bash
docker run -d --name hermes \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges \
--tmpfs /tmp:size=100m \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
2.6 多 Profile 部署
Hermes 支持多 Profile(不同 SOUL、Skill、记忆、凭证),Docker 下的推荐做法是一个容器一个 Profile:
yaml
# docker-compose.yml — 多 Profile 示例
services:
hermes-work:
image: nousresearch/hermes-agent:latest
container_name: hermes-work
restart: unless-stopped
command: ["gateway", "run"]
ports:
- "8642:8642"
volumes:
- ~/.hermes-work:/opt/data
hermes-personal:
image: nousresearch/hermes-agent:latest
container_name: hermes-personal
restart: unless-stopped
command: ["gateway", "run"]
ports:
- "8643:8642"
volumes:
- ~/.hermes-personal:/opt/data
每个 Profile 独立容器、独立端口、独立数据——不会串台。
3. 方案二:pip/uv 安装部署
适合不想用 Docker 的场景:macOS 开发环境、已有多台 VPS 的老运维、或需要深度定制。
3.1 Python 环境准备
Hermes 需要 Python 3.11+。推荐用 uv 管理,它比 pip 快 10-100 倍:
bash
# ── 安装 uv ──────────────────────────────────────────────
curl -LsSf https://astral.sh/uv/install.sh | sh
# ── 验证 ─────────────────────────────────────────────────
uv --version
# ── 如果坚持用 pip ──────────────────────────────────────
python3 --version # 需要 3.11+
3.2 一键安装脚本
据 Hermes Agent 安装文档(https://hermes-agent.ac.cn/docs/getting-started/installation),官方安装脚本最省心:
bash
# 官方一键安装(处理 Python + uv + 依赖 + PATH)
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
# 安装选项
curl -fsSL ... | bash -s -- --skip-setup # 跳过设置向导
curl -fsSL ... | bash -s -- --no-venv # 不创建虚拟环境
curl -fsSL ... | bash -s -- --branch dev # 安装开发分支
curl -fsSL ... | bash -s -- --dir /opt/hermes # 指定安装目录
3.3 手动安装(完全控制)
bash
# ── 克隆仓库 ─────────────────────────────────────────────
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
# ── 创建虚拟环境 ─────────────────────────────────────────
uv venv venv --python 3.11
# ── 安装依赖 ─────────────────────────────────────────────
export VIRTUAL_ENV="$(pwd)/venv"
# 完整安装(含所有消息平台 + 语音 + Cron)
uv pip install -e ".[all]"
# 最小安装(仅核心 Agent)
# uv pip install -e "."
# 按需安装
# uv pip install -e ".[messaging]" # Telegram/Discord/Slack
# uv pip install -e ".[cron]" # 定时任务
# uv pip install -e ".[mcp]" # MCP 集成
# uv pip install -e ".[voice]" # 语音(不支持 Termux)
# ── 可选子模块 ───────────────────────────────────────────
# uv pip install -e "./tinker-atropos" # RL 训练后端
# ── Node.js 依赖(可选:浏览器自动化 + WhatsApp)─────────
# npm install
# ── 创建配置目录 ─────────────────────────────────────────
mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}
# ── 复制默认配置 ─────────────────────────────────────────
cp cli-config.yaml.example ~/.hermes/config.yaml
# ── 创建 .env ────────────────────────────────────────────
touch ~/.hermes/.env
# ── 添加到 PATH ──────────────────────────────────────────
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# ── 验证安装 ─────────────────────────────────────────────
hermes doctor
3.4 配置文件 config.yaml 详解
Hermes 的核心配置文件是 ~/.hermes/config.yaml,据官方示例配置(https://github.com/NousResearch/hermes-agent/blob/main/cli-config.yaml.example)整理:
yaml
# =============================================================================
# ~/.hermes/config.yaml — Hermes Agent 完整配置
# =============================================================================
# ── 模型配置 ─────────────────────────────────────────────
model:
# 默认模型(provider:model 格式或纯模型名)
default: "anthropic/claude-sonnet-4-6"
# 推理提供商
# auto | openrouter | nous | anthropic | openai-codex | copilot |
# zai | kimi-coding | minimax | minimax-cn | deepseek | custom
provider: "auto"
# API 基础 URL(custom 提供商必填)
base_url: "https://openrouter.ai/api/v1"
# 上下文长度(一般不设,Hermes 自动检测)
# context_length: 131072
# 输出 token 上限(一般不设,用模型原生上限)
# max_tokens: 8192
# ── 备用模型(主模型挂了自动切换)─────────────────────────
fallback_model:
provider: openrouter
model: anthropic/claude-sonnet-4
# ── 终端执行后端 ─────────────────────────────────────────
terminal:
# local | docker | ssh | modal | daytona | vercel_sandbox | singularity
backend: "local"
cwd: "."
timeout: 180
env_passthrough: [] # 传递到沙箱的环境变量名列表
# Docker 后端配置
# docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
# docker_mount_cwd_to_workspace: false
# docker_forward_env:
# - GITHUB_TOKEN
# docker_volumes:
# - "/host/path:/container/path"
# SSH 后端配置
# ssh_host: "your-server.com"
# ssh_user: "root"
# ssh_port: 22
# ssh_key_path: "~/.ssh/id_rsa"
# Modal 后端配置
# modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"
# Daytona 后端配置
# daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
# container_cpu: 1
# container_memory: 5120
# container_disk: 10240
# container_persistent: true
# ── Agent 行为 ──────────────────────────────────────────
agent:
max_turns: 90 # 每次对话最大工具调用轮次
reasoning_effort: "medium" # none | low | minimal | medium | high | xhigh
# ── 记忆系统 ─────────────────────────────────────────────
memory:
memory_enabled: true # 启用 MEMORY.md
user_profile_enabled: true # 启用 USER.md
memory_char_limit: 2200 # MEMORY.md 最大字符数
user_char_limit: 1375 # USER.md 最大字符数
# ── 上下文压缩 ──────────────────────────────────────────
compression:
enabled: true
threshold: 0.50 # 上下文占用超过 50% 时触发压缩
summary_model: "google/gemini-3-flash-preview" # 压缩用的便宜模型
# ── 审批模式 ─────────────────────────────────────────────
approvals:
mode: "manual" # manual(手动确认)| smart(AI 判断)| off(全自动)
# ── 工具集 ───────────────────────────────────────────────
toolsets:
- all
# ── 显示设置 ─────────────────────────────────────────────
display:
skin: "default" # default | ares | mono | slate | poseidon
tool_progress: "all" # off | new | all | verbose
compact: false
show_reasoning: false
streaming: false
# ── 辅助模型(各子任务可用不同模型省钱)─────────────────
auxiliary:
# 视觉分析
vision:
provider: "auto"
model: ""
timeout: 120
# 网页摘要
web_extract:
provider: "auto"
model: ""
timeout: 360
# 危险命令审批
approval:
provider: "auto"
model: ""
timeout: 30
# 会话搜索
session_search:
provider: "auto"
model: ""
timeout: 30
max_concurrency: 3
# ── MCP 服务器 ──────────────────────────────────────────
# mcp:
# servers:
# - name: my-tools
# command: npx my-mcp-server
# - name: github
# command: npx
# args: ["-y", "@modelcontextprotocol/server-github"]
# env:
# GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
# ── 提供商超时配置(可选)──────────────────────────────
# providers:
# ollama-local:
# request_timeout_seconds: 300
# stale_timeout_seconds: 900
# anthropic:
# request_timeout_seconds: 30
3.5 Systemd 服务配置
bash
# ── 创建 systemd 服务文件 ────────────────────────────────
sudo tee /etc/systemd/system/hermes-agent.service << 'EOF'
[Unit]
Description=Hermes Agent Gateway
After=network.target redis.service
Requires=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/hermes-agent
ExecStart=/home/ubuntu/hermes-agent/venv/bin/hermes gateway run
Restart=always
RestartSec=10
Environment=HERMES_HOME=/home/ubuntu/.hermes
# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/ubuntu/.hermes
[Install]
WantedBy=multi-user.target
EOF
# ── 启用并启动 ──────────────────────────────────────────
sudo systemctl daemon-reload
sudo systemctl enable hermes-agent
sudo systemctl start hermes-agent
# ── 查看状态 ─────────────────────────────────────────────
sudo systemctl status hermes-agent
# ── 查看日志 ─────────────────────────────────────────────
journalctl -u hermes-agent -f
3.6 日志轮转
bash
# ── 创建 logrotate 配置 ─────────────────────────────────
sudo tee /etc/logrotate.d/hermes-agent << 'EOF'
/home/ubuntu/.hermes/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
EOF
# ── 验证配置 ─────────────────────────────────────────────
sudo logrotate -d /etc/logrotate.d/hermes-agent
4. 方案三:云服务器一键部署
4.1 云平台选择
表格
据腾讯云 Techpedia(https://www.tencentcloud.com/techpedia/144037),腾讯云 Lighthouse 是首个提供 Hermes Agent 官方应用镜像的云平台,90 秒从零到运行。
4.2 腾讯云 Lighthouse 一键部署
登录腾讯云控制台 → 搜索「Lighthouse」
创建实例 → 应用镜像 → AI Agent → Hermes Agent
选择 2C4G 或更高配置
完成购买,等待 90 秒
模板预装内容:
Ubuntu 22.04 LTS
Python 3.11 + 全部 Hermes 依赖
Redis 持久化配置
Nginx 反向代理
systemd 服务 + 防火墙规则
4.3 VPS 5 美元/月方案(Hetzner)
Hetzner CX22 是目前性价比最高的选择——2 vCPU、4GB RAM,仅 EUR4/月:
bash
# ── SSH 登录 ─────────────────────────────────────────────
ssh root@your-hetzner-ip
# ── 更新系统 ─────────────────────────────────────────────
apt update && apt upgrade -y
# ── 安装依赖 ─────────────────────────────────────────────
apt install -y \
python3.11 python3.11-venv python3-pip \
redis-server git curl nginx \
build-essential libssl-dev libffi-dev
# ── 运行 Hermes 安装脚本 ────────────────────────────────
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
# ── 配置 API Key ─────────────────────────────────────────
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env
# ── 启动 ─────────────────────────────────────────────────
hermes gateway install
hermes gateway start
# ── 验证 ─────────────────────────────────────────────────
curl http://localhost:8642/health
4.4 Modal 无服务器部署
据 Hermes Agent 配置文档(https://hermes-agent.nousresearch.com/docs/user-guide/configuration),Modal 后端适合临时任务和弹性计算:
yaml
# ~/.hermes/config.yaml
terminal:
backend: modal
modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"
需要设置 Modal 凭证:
bash
pip install modal
modal token new # 浏览器 OAuth 登录
4.5 Daytona 云开发环境
Daytona 适合需要持久化云开发环境的场景:
yaml
# ~/.hermes/config.yaml
terminal:
backend: daytona
daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
container_cpu: 2
container_memory: 4096
container_disk: 10240
container_persistent: true
bash
# 设置 Daytona API Key
export DAYTONA_API_KEY=your-daytona-key
5. 多渠道接入配置
据 Hermes Agent 消息网关文档(https://hermes-agent.nousresearch.com/docs/user-guide/messaging),Gateway 是一个单进程,同时连接所有已配置平台:
plaintext
┌──────────────────────────────────────────────────────────────┐
│ Hermes Gateway 架构 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Telegram │ │ Discord │ │ Slack │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │ WhatsApp │ │ Signal │ │ Email │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │ DingTalk │ │ Feishu │ │ WeCom │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ Gateway 进程 │ │
│ │ (单进程多平台) │ │
│ │ │ │
│ │ ┌─ Session Store ─┐ │ │
│ │ │ per chat 状态 │ │ │
│ │ └─────────────────┘ │ │
│ │ ┌─ Cron Scheduler ─┐ │ │
│ │ │ 每 60s 检查 │ │ │
│ │ └─────────────────┘ │ │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ AIAgent 核心 │ │
│ │ (run_agent.py) │ │
│ └───────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
5.1 Telegram Bot 接入(完整步骤)
bash
# 第 1 步:创建 Bot
# 在 Telegram 中找 @BotFather
# /newbot → 输入名称 → 输入用户名 → 获得 Token
# 第 2 步:配置 Hermes
hermes gateway setup telegram
# 或手动配置:
hermes config set TELEGRAM_BOT_TOKEN "123456:ABC-DEF..."
# 第 3 步:启动网关
hermes gateway start
# 第 4 步:验证
# 在 Telegram 中给你的 Bot 发消息,应该能收到回复
可选:限制哪些用户可以使用 Bot:
bash
# 在 ~/.hermes/.env 中添加
TELEGRAM_ALLOWED_USERS=12345678,87654321
5.2 Discord Bot 接入
bash
# 第 1 步:创建 Discord Application
# https://discord.com/developers/applications → New Application
# Bot → Add Bot → 复制 Token
# OAuth2 → URL Generator → bot scope → 勾选权限
# 第 2 步:配置 Hermes
hermes gateway config --platform discord
# 或:
hermes config set DISCORD_BOT_TOKEN "your-discord-token"
# 第 3 步:启动网关
hermes gateway start
社区技巧:用 Discord 的频道做 Agent 上下文隔离——每个频道一个项目,避免上下文串台。
5.3 Slack 接入
bash
# 第 1 步:创建 Slack App
# https://api.slack.com/apps → Create New App
# Bot Token Scopes: chat:write, channels:history, groups:history
# Install to Workspace → 复制 Bot Token (xoxb-...)
# 第 2 步:启用 Socket Mode
# Basic Information → Socket Mode → Enable
# 生成 App-Level Token (xapp-...)
# 第 3 步:配置 Hermes
hermes config set SLACK_BOT_TOKEN "xoxb-your-token"
hermes config set SLACK_APP_TOKEN "xapp-your-app-token"
# 第 4 步:启动网关
hermes gateway start
5.4 CLI 模式(终端直接用)
不需要任何网关配置,直接在终端使用:
bash
# 交互式 REPL
hermes
# 单次查询
hermes chat -q "帮我检查 nginx 配置"
# 指定模型
hermes chat --provider openrouter --model anthropic/claude-sonnet-4
# 使用配置文件
hermes chat --config ~/.hermes/config.yaml
5.5 平台功能对比
表格
5.6 消息网关常用命令速查
bash
hermes gateway # 前台运行
hermes gateway setup # 交互式配置所有平台
hermes gateway install # 安装为系统服务(Linux)/ launchd(macOS)
hermes gateway start # 启动服务
hermes gateway stop # 停止服务
hermes gateway status # 查看服务状态
聊天内命令:
表格
6. 模型配置
6.1 Nous Portal(官方推荐)
Nous Portal 是 Hermes 自己的推理端点,通过 OAuth 认证:
bash
# 首次登录(浏览器 OAuth)
hermes model
# 选择 "Nous Portal" → 浏览器自动打开 → 授权
# 设置默认模型
hermes model nous:hermes-3
# 或在 config.yaml 中:
# model:
# provider: "nous"
# default: "hermes-3"
6.2 OpenRouter(200+ 模型切换)
OpenRouter 是最灵活的选择,一个 API Key 访问 200+ 模型:
bash
# 设置 API Key
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env
# 自动选择最便宜的模型
hermes model openrouter:auto
# 指定模型
hermes model openrouter:anthropic/claude-sonnet-4
hermes model openrouter:deepseek/deepseek-v4
hermes model openrouter:moonshotai/kimi-k2.5
# 在 config.yaml 中:
# model:
# provider: "openrouter"
# default: "anthropic/claude-sonnet-4"
# base_url: "https://openrouter.ai/api/v1"
OpenRouter 提供商路由控制(省钱利器):
yaml
# config.yaml
provider_routing:
sort: "throughput" # price | throughput | latency
# only: ["anthropic", "google"] # 只用这些提供商
# ignore: ["deepinfra"] # 排除这些提供商
6.3 Anthropic Claude 原生 OAuth PKCE
据 Hermes Agent 中文文档(https://hermes-agent.lzw.me/docs/integrations/providers),Anthropic 支持三种认证方式:
bash
# 方式 1:API Key(按 token 计费)
export ANTHROPIC_API_KEY=sk-ant-api03-your-key
hermes chat --provider anthropic --model claude-sonnet-4-6
# 方式 2:OAuth(推荐,复用 Claude Pro/Max 订阅)
hermes model
# 选择 "Anthropic" → OAuth 浏览器登录
# Hermes 自动使用 Claude Code 的凭据存储(如果已有)
# Token 保存在 ~/.hermes/auth.json,自动刷新
# 方式 3:手动 setup-token(回退方案)
export ANTHROPIC_TOKEN=your-setup-token
hermes chat --provider anthropic
在 config.yaml 中永久设置:
yaml
model:
provider: "anthropic"
default: "claude-sonnet-4-6"
--provider claude 和 --provider claude-code 是 --provider anthropic 的别名。
6.4 OpenAI GPT 系列
bash
# API Key
echo 'OPENAI_API_KEY=sk-your-key' >> ~/.hermes/.env
# ChatGPT 订阅用户(OAuth,无需 API Key)
hermes model
# 选择 "OpenAI Codex" → 浏览器 OAuth
# 指定模型
hermes model openai:gpt-4o
6.5 本地 Ollama
bash
# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 拉取模型
ollama pull qwen3:14b
ollama pull llama3.1:8b
# 配置 Hermes
hermes model
# 选择 "Custom endpoint"
# API base URL: http://localhost:11434/v1
# API key: ollama(随便填,本地不需要)
# 或在 config.yaml 中:
# model:
# provider: "custom"
# default: "qwen3:14b"
# base_url: "http://localhost:11434/v1"
6.6 DeepSeek
bash
# 设置 API Key
echo 'DEEPSEEK_API_KEY=sk-your-deepseek-key' >> ~/.hermes/.env
# 使用
hermes model deepseek:deepseek-v4
6.7 模型回退和负载均衡
当主模型挂了(限流、宕机、认证失败),Hermes 自动切换到备用模型:
yaml
# config.yaml
fallback_model:
provider: openrouter
model: anthropic/claude-sonnet-4
API Key 池化管理(多 Key 轮换,防限流):
bash
# 添加第二个 OpenRouter Key
hermes auth add openrouter --api-key sk-or-v1-your-second-key
# 添加 Anthropic OAuth 凭证
hermes auth add anthropic --type oauth # 浏览器登录
# 查看所有凭证池
hermes auth list
# 交互式管理
hermes auth
据 Hermes Agent 官方认证文档,凭证池支持四种轮换策略:round_robin(轮询)、least_used(最久未用优先)、fill_first(先用完一个)、random(随机)。
7. 自进化系统配置
这是 Hermes 区别于所有其他 Agent 的核心——让它真正"越用越聪明"。
7.1 Skill 生成触发条件配置
据 Hermes Agent 源码解析(https://juejin.cn/post/7638806086187614234),Skill 创建的触发条件定义在 skill_manage 工具的 schema 中:
plaintext
┌──────────────────────────────────────────────────────────────┐
│ Skill 创建触发条件 │
│ │
│ 自动创建(满足任一): │
│ ┌──────────────────────────────────────────────┐ │
│ │ ✅ 工具调用超过 5 次(复杂任务) │ │
│ │ ✅ 踩过坑并成功修复 │ │
│ │ ✅ 用户纠正了做法 │ │
│ │ ✅ 发现了非显而易见的工作流 │ │
│ │ ✅ 用户主动要求记住 │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ 自动修补(Skill 已存在但需要更新): │
│ ┌──────────────────────────────────────────────┐ │
│ │ ✅ 步骤有遗漏(Pitfalls 追加) │ │
│ │ ✅ OS 特定故障需要补充 │ │
│ │ ✅ 新发现的边界条件 │ │
│ │ ✅ 用户纠正了 Skill 中的做法 │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ 不创建(简单任务): │
│ ┌──────────────────────────────────────────────┐ │
│ │ ❌ 工具调用 ≤ 5 次的一次性任务 │ │
│ │ ❌ 纯查询类(不需要执行步骤) │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
配置 Skill 创建频率(Nudge 间隔):
yaml
# config.yaml
skills:
# 每多少次工具调用后触发 Skill 审查(默认 10)
creation_nudge_interval: 10
# 两层索引(v2,减少 Token 消耗)
index_v2: false # 实验性功能,默认关闭
# Token 预算(index_v2 开启时生效,默认 2000)
index_token_budget: 2000
7.2 Signal-Based Nudge(信号驱动提示)
据 Hermes Agent PR #21841(https://github.com/NousResearch/hermes-agent/pull/21841),v0.11+ 引入了基于信号的 Skill 创建提示,比固定计数器更智能:
yaml
# config.yaml
skills:
nudge_signals:
enabled: false # 实验性,默认关闭
# S1: 重复工具模式(同一参数签名出现 N 次触发)
repeated_pattern_threshold: 3
# S2: 新 CLI 命令(30天内未出现过的外部命令)
novel_cli_window_days: 30
# S3: 用户明确暗示("记住"、"下次"、"以后"、"记一下")
# 内置关键词,无需配置
# S4: 重复错误修复(同一错误出现 N 次后修复触发)
error_repeat_threshold: 2
7.3 Skill Curator 自动维护设置
Skill Curator 在后台定期审查 Skill 库,评分和修剪:
bash
# 查看所有 Skill
hermes skills list
# 查看特定 Skill 详情
hermes skills view deploy-k8s
# 手动触发 Skill 审查
hermes skills review
# 删除低质量 Skill
hermes skills delete deprecated-skill
系统提示词中有一句关键约束:"Skills that aren't maintained become liabilities"——通过提示词给 Agent 灌输维护责任感。
7.4 Nudge Engine 提醒策略
Nudge Engine 维护两个独立计数器:
plaintext
┌──────────────────────────────────────────────────────────────┐
│ Nudge Engine 双计数器机制 │
│ │
│ ┌───────────────────────────────┐ │
│ │ Memory Nudge │ │
│ │ 触发间隔: 10 个用户回合 │ │
│ │ 计数方式: 按用户回合计 │ │
│ │ 作用: 审查 MEMORY.md/USER.md │ │
│ │ 重置: Agent 主动写入记忆时 │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Skill Nudge │ │
│ │ 触发间隔: 10 次工具迭代 │ ← 可通过 config 调整 │
│ │ 计数方式: 按工具迭代计 │ │
│ │ 作用: 审查是否需要创建/修补 │ │
│ │ 重置: Agent 主动操作 Skill 时 │ │
│ └───────────────────────────────┘ │
│ │
│ Nudge 触发 → fork 后台 Agent 审查 → 不打扰用户 │
│ 审查完成 → 结果写回记忆/Skill → 下次对话生效 │
└──────────────────────────────────────────────────────────────┘
7.5 SOUL.md 初始化和进化
SOUL.md 定义了 Agent 的身份——性格、专长、沟通风格。位置:~/.hermes/memories/SOUL.md
方式 1:让 Hermes 自己写
plaintext
你: 请定义你自己的身份和性格
Hermes: (自动生成 SOUL.md)
方式 2:Token 压缩 DSL(省 Token)
markdown
# Agent Identity
Core:SelfImprove,CompoundLearning
AGENT_LOOP={CheckCtx,MapTools,Execute,Verify}
LEARN_LOOP={Observe,Pattern,Skill,Memory}
MEMORY_SYS={Short:ctx,Long:facts,Episodic:skills}
## Personality
Direct+Concise | TechFoc:Python,DevOps,AI/ML
## Rules
AlwaysVerify b4 destructive | EditOverCreate | AskIfAmbiguous
方式 3:明确人格定义
markdown
# Hermes Agent Identity
## Personality
- Direct and concise — avoid hedging
- Technical competence in: Python, DevOps, AI/ML
- Slightly informal but professional
## Response Style
- Lead with the answer, then explain
- Use code blocks liberally
- Numbered steps for procedures
## Behavioral Rules
- Always verify before destructive operations
- Prefer editing existing files over creating new
- Ask clarifying questions when ambiguous
关键原则:SOUL.md 越短越好。社区推荐压缩到 500-1000 字符——每个 session 都要注入系统提示词,太长烧 Token。
Hermes 可以通过 memory_manage 工具修改自己的 SOUL.md,实现人格进化。
7.6 记忆后端选择
表格
Redis 配置:
bash
# 安装 Redis
sudo apt install redis-server -y
# 持久化配置
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG SET maxmemory 2gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE
# 启动
sudo systemctl enable redis-server
sudo systemctl start redis-server
7.7 FTS5 全文搜索配置
Hermes 的情景记忆使用 SQLite FTS5 做全文搜索,无需额外配置——自动创建在 ~/.hermes/sessions/sessions.db:
bash
# 验证 FTS5 索引
sqlite3 ~/.hermes/sessions/sessions.db ".schema"
# 搜索历史会话
hermes session search "部署 nginx"
8. 执行后端配置
据 Hermes Agent 配置文档(https://hermes-agent.nousresearch.com/docs/user-guide/configuration),Hermes 支持 7 种执行后端:
plaintext
┌──────────────────────────────────────────────────────────────┐
│ 执行后端架构 │
│ │
│ ┌──────────────┐ │
│ │ Hermes Agent │ │
│ │ (命令调度) │ │
│ └──────┬───────┘ │
│ │ │
│ ├──────── local ──── 本机直接执行 │
│ │ 零隔离,开发环境用 │
│ │ │
│ ├──────── docker ──── Docker 容器 │
│ │ 完全隔离,CI/CD 用 │
│ │ │
│ ├──────── ssh ─────── SSH 远程服务器 │
│ │ 网络隔离,远端强算力 │
│ │ │
│ ├──────── modal ──── Modal 云沙箱 │
│ │ 弹性计算,临时任务 │
│ │ │
│ ├──────── daytona ── Daytona 云开发环境 │
│ │ 持久化云环境,团队协作 │
│ │ │
│ ├──────── vercel ─── Vercel Sandbox │
│ │ microVM,快照持久化 │
│ │ │
│ └──────── singularity ─ Singularity/Apptainer │
│ HPC 集群,共享机器 │
└──────────────────────────────────────────────────────────────┘
8.1 本地终端执行
默认后端,零配置:
yaml
# config.yaml
terminal:
backend: "local"
cwd: "."
timeout: 180
8.2 Docker 沙箱隔离
yaml
# config.yaml
terminal:
backend: "docker"
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
timeout: 300
docker_mount_cwd_to_workspace: false
docker_forward_env:
- GITHUB_TOKEN
- NPM_TOKEN
docker_volumes:
- "/host/path:/container/path"
Hermes 自动 bind-mount Skills 目录和凭证文件到容器内(只读)。
8.3 SSH 远程执行
yaml
# config.yaml
terminal:
backend: "ssh"
ssh_host: "your-server.com"
ssh_user: "root"
ssh_port: 22
# ssh_key_path: "~/.ssh/id_rsa" # 或用 ssh-agent
cwd: "/root"
timeout: 300
persistent_shell: true # 保持 Shell 状态跨命令
Skills 和凭证文件通过 rsync 自动同步到远端。
8.4 Modal 无服务器
yaml
# config.yaml
terminal:
backend: "modal"
modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"
bash
# 认证
pip install modal
modal token new
8.5 Daytona 云开发环境
yaml
# config.yaml
terminal:
backend: "daytona"
daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
container_cpu: 2
container_memory: 4096 # MB → 转为 GiB
container_disk: 10240 # MB → 转为 GiB,最大 10GiB
container_persistent: true # 停止而非删除
Daytona 磁盘上限 10GiB,超出会被 cap 并警告。Sandbox 名称遵循 hermes-{task_id} 模式。
9. 生产加固
9.1 安全
API Key 管理
plaintext
┌──────────────────────────────────────────────────────────────┐
│ API Key 管理最佳实践 │
│ │
│ ❌ 错误做法: │
│ · 直接写在 config.yaml 里 │
│ · 提交 .env 到 Git │
│ · 多人共享同一个 Key │
│ │
│ ✅ 正确做法: │
│ · .env 文件 + chmod 600 │
│ · 生产环境用 Secret Manager / K8s Secret │
│ · 多 Key 池化轮换(hermes auth add) │
│ · 定期轮换高权限 Token │
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ 凭证自动发现优先级: │ │
│ │ 1. ~/.hermes/.env 环境变量 │ │
│ │ 2. ~/.hermes/auth.json OAuth 令牌 │ │
│ │ 3. ~/.claude/.credentials.json │ │
│ │ 4. config.yaml 中的 api_key 字段 │ │
│ │ 5. hermes auth add 手动添加 │ │
│ └───────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Docker 隔离
bash
# 最高隔离级别
docker run -d --name hermes \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges \
--tmpfs /tmp:size=100m \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
VPS 基础加固
bash
# SSH 密钥登录(禁用密码)
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
# UFW 防火墙
ufw allow OpenSSH
ufw allow 8642/tcp # Hermes Gateway(生产环境限制 IP)
ufw enable
# 限制 8642 端口只允许特定 IP
ufw allow from YOUR_IP to any port 8642
Tirith 安全模块
Hermes 内置 Tirith 安全模块,自动拦截:
混淆的 Shell 管道模式
记忆写入中的 Prompt 注入
凭证泄露模式
工具输入中的不可见 Unicode
yaml
# config.yaml
approvals:
mode: "manual" # manual | smart | off
注意:Tirith 可能过于激进。如果它拦截了你需要运行的命令,解决方法是在分屏终端中手动执行,而不是通过 Hermes。
9.2 备份
自动备份脚本
bash
#!/bin/bash
# hermes-backup.sh — Hermes Agent 自动备份脚本
# 使用方法: chmod +x hermes-backup.sh && ./hermes-backup.sh
set -euo pipefail
# ── 配置 ─────────────────────────────────────────────────
HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
BACKUP_DIR="${BACKUP_DIR:-$HOME/hermes-backups}"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/hermes-backup-$TIMESTAMP.tar.gz"
# ── 创建备份目录 ─────────────────────────────────────────
mkdir -p "$BACKUP_DIR"
# ── 检查 Hermes 是否在运行 ──────────────────────────────
if docker ps | grep -q hermes; then
echo "[INFO] 检测到 Docker 模式,暂停容器确保数据一致性..."
docker compose pause hermes 2>/dev/null || true
sleep 2
fi
# ── 执行备份 ─────────────────────────────────────────────
echo "[INFO] 开始备份 $HERMES_HOME ..."
tar -czf "$BACKUP_FILE" \
--exclude="*.log" \
--exclude="image_cache" \
--exclude="audio_cache" \
--exclude="whatsapp/session" \
-C "$(dirname "$HERMES_HOME")" \
"$(basename "$HERMES_HOME")"
BACKUP_SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)
echo "[INFO] 备份完成: $BACKUP_FILE ($BACKUP_SIZE)"
# ── 恢复容器 ─────────────────────────────────────────────
if docker ps -a | grep -q hermes; then
docker compose unpause hermes 2>/dev/null || true
fi
# ── 清理旧备份 ───────────────────────────────────────────
DELETED=$(find "$BACKUP_DIR" -name "hermes-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete -print | wc -l)
echo "[INFO] 清理 $DELETED 个超过 $RETENTION_DAYS 天的旧备份"
# ── 可选:上传到 S3 ─────────────────────────────────────
# aws s3 cp "$BACKUP_FILE" s3://your-bucket/hermes-backups/
# echo "[INFO] 已上传到 S3"
设置定时备份:
bash
# 每天凌晨 3 点自动备份
(crontab -l 2>/dev/null; echo "0 3 * * * $HOME/hermes-backup.sh >> $HOME/hermes-backups/backup.log 2>&1") | crontab -
9.3 监控
健康检查
bash
# 基础健康检查
curl http://localhost:8642/health
# {"status":"ok"}
# 详细健康检查
curl http://localhost:8642/health/detailed
# Docker 内健康检查
docker compose exec hermes curl -s http://localhost:8642/health
Prometheus 指标
Hermes Agent 的 Rust 版(hermes-agent-rs)内置 OpenTelemetry + Prometheus 指标暴露。Python 版需要手动集成:
yaml
# config.yaml — 如果使用 hermes-agent-rs
# 指标默认暴露在 /metrics 端点
对于 Python 版,用 Prometheus Blackbox Exporter 探测 /health:
yaml
# prometheus.yml
scrape_configs:
- job_name: 'hermes-health'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- http://localhost:8642/health
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
日志收集
bash
# Hermes 内置日志
hermes logs
hermes logs gateway --since 10m
hermes logs errors --tail 100
# Docker 日志
docker compose logs hermes --tail 100 -f
# Systemd 日志
journalctl -u hermes-agent -f --since "10 minutes ago"
生产环境推荐用 Fluent Bit / Vector 收集 ~/.hermes/logs/*.log,对 LLM 调用链路可启用 Langfuse 做可观测。
9.4 成本控制
模型调用统计
bash
# 查看当前使用的模型
hermes model
# 查看凭证池状态
hermes auth list
预算限制
OpenRouter 支持设置使用限额:
bash
# 在 OpenRouter 控制台设置月度限额
# https://openrouter.ai/settings/limits
Kimi K2.5 社区建议:添加余额并设置限额,防止 API Key 泄露导致巨额账单。
省钱策略
plaintext
┌──────────────────────────────────────────────────────────────┐
│ 省钱策略矩阵 │
│ │
│ 策略 │ 日成本 │ 质量 │ 延迟 │
│ ───────────────────────────────────────────────────────── │
│ 全用 Opus │ $50+ │ 极优 │ 低 │
│ Opus + Kimi 混用 │ $10-20 │ 优 │ 中 │
│ 全用 DeepSeek V4 │ $2-5 │ 良 │ 中 │
│ 本地 Ollama │ 电费 │ 中 │ 高 │
│ OpenRouter auto │ $5-15 │ 良-优 │ 中 │
│ │
│ 进阶省钱: │
│ · 主模型用便宜的,辅助模型(vision等)用更便宜的 │
│ · 压缩模型用 gemini-flash(几乎免费) │
│ · 设置 fallback_model 防主模型限流时浪费重试 Token │
│ · 多 Key 池化轮换避免触发 rate limit │
└──────────────────────────────────────────────────────────────┘
yaml
# config.yaml — 省钱配置示例
model:
default: "deepseek/deepseek-v4"
provider: "openrouter"
fallback_model:
provider: openrouter
model: "anthropic/claude-sonnet-4"
# 便宜的压缩模型
compression:
summary_model: "google/gemini-3-flash-preview"
# 便宜的辅助模型
auxiliary:
vision:
model: "openai/gpt-4o-mini"
web_extract:
model: "google/gemini-3-flash-preview"
session_search:
model: "deepseek/deepseek-v4"
max_concurrency: 2
10. 一键部署脚本(完整版)
这个脚本从裸机到 Hermes 运行,全程交互式引导。支持 Ubuntu/Debian/macOS。
bash
#!/usr/bin/env bash
# =============================================================================
# hermes-setup.sh — Hermes Agent 一键部署脚本
# 版本: 1.0.0
# 兼容: Ubuntu 20.04+, Debian 12+, macOS (Intel/Apple Silicon)
#
# 使用方法:
# chmod +x hermes-setup.sh && ./hermes-setup.sh
#
# 或远程执行:
# curl -fsSL https://your-host/hermes-setup.sh | bash
# =============================================================================
set -euo pipefail
# ── 颜色定义 ─────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# ── 辅助函数 ─────────────────────────────────────────────
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ── 确认函数 ─────────────────────────────────────────────
confirm() {
local prompt="$1"
local default="${2:-n}"
local yn
if [[ "$default" == "y" ]]; then
read -rp "$prompt [Y/n] " yn
yn="${yn:-Y}"
else
read -rp "$prompt [y/N] " yn
yn="${yn:-N}"
fi
[[ "$yn" =~ ^[Yy] ]]
}
# ── 选择函数 ─────────────────────────────────────────────
select_option() {
local prompt="$1"
shift
local options=("$@")
echo -e "${BLUE}$prompt${NC}"
for i in "${!options[@]}"; do
echo " $((i+1))) ${options[$i]}"
done
local choice
read -rp "请选择 [1-${#options[@]}]: " choice
choice=$((choice - 1))
if [[ $choice -ge 0 && $choice -lt ${#options[@]} ]]; then
echo "${options[$choice]}"
else
echo "${options[0]}"
fi
}
# =============================================================================
# 第 1 步: 检测系统环境
# =============================================================================
info "=== 第 1 步: 检测系统环境 ==="
# 检测操作系统
OS="$(uname -s)"
case "$OS" in
Linux)
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS_NAME="$NAME"
OS_VERSION="$VERSION_ID"
else
OS_NAME="Linux"
OS_VERSION="unknown"
fi
;;
Darwin)
OS_NAME="macOS"
OS_VERSION="$(sw_vers -productVersion)"
;;
*)
error "不支持的操作系统: $OS。请使用 Linux 或 macOS。"
;;
esac
ok "操作系统: $OS_NAME $OS_VERSION"
# 检测架构
ARCH="$(uname -m)"
ok "CPU 架构: $ARCH"
# 检测内存
if [[ "$OS" == "Darwin" ]]; then
TOTAL_MEM=$(( $(sysctl -n hw.memsize) / 1024 / 1024 / 1024 ))
else
TOTAL_MEM=$(( $(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 / 1024 ))
fi
ok "内存: ${TOTAL_MEM}GB"
if [[ $TOTAL_MEM -lt 3 ]]; then
warn "内存不足 4GB,Hermes 可能运行不稳定"
fi
# 检测磁盘空间
DISK_AVAIL=$(df -h ~ | awk 'NR==2 {print $4}')
ok "可用磁盘: $DISK_AVAIL"
# =============================================================================
# 第 2 步: 安装依赖
# =============================================================================
info "=== 第 2 步: 安装依赖 ==="
# 检测 Git
if ! command -v git &>/dev/null; then
warn "未检测到 Git,正在安装..."
if [[ "$OS" == "Darwin" ]]; then
xcode-select --install 2>/dev/null || true
else
sudo apt update && sudo apt install -y git
fi
fi
ok "Git: $(git --version)"
# 检测 Docker
USE_DOCKER=false
if command -v docker &>/dev/null; then
ok "Docker: $(docker --version)"
if confirm "检测到 Docker,是否使用 Docker 部署?" "y"; then
USE_DOCKER=true
fi
else
if confirm "是否安装 Docker 并使用 Docker 部署?" "y"; then
info "正在安装 Docker..."
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# 激活 Docker 组(当前 session)
newgrp docker 2>/dev/null || true
USE_DOCKER=true
ok "Docker 安装完成"
fi
fi
# 检测 Docker Compose
if [[ "$USE_DOCKER" == "true" ]]; then
if docker compose version &>/dev/null; then
ok "Docker Compose: $(docker compose version)"
else
warn "Docker Compose 未安装,尝试安装..."
sudo apt install -y docker-compose-plugin 2>/dev/null || \
mkdir -p ~/.docker/cli-plugins && \
curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \
-o ~/.docker/cli-plugins/docker-compose && \
chmod +x ~/.docker/cli-plugins/docker-compose
fi
fi
# 非 Docker 模式:安装 Python + uv
if [[ "$USE_DOCKER" == "false" ]]; then
# 安装 uv
if ! command -v uv &>/dev/null; then
info "正在安装 uv(Python 包管理器)..."
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
fi
ok "uv: $(uv --version)"
# 检测 Python
PYTHON_CMD=""
for cmd in python3.11 python3.12 python3 python; do
if command -v "$cmd" &>/dev/null; then
PY_VER=$($cmd -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
if [[ "$(echo "$PY_VER >= 3.11" | bc -l)" -eq 1 ]]; then
PYTHON_CMD="$cmd"
break
fi
fi
done
if [[ -z "$PYTHON_CMD" ]]; then
info "未找到 Python 3.11+,uv 会自动下载..."
else
ok "Python: $($PYTHON_CMD --version)"
fi
# 安装 Redis(Linux)
if [[ "$OS" == "Linux" ]]; then
if ! command -v redis-server &>/dev/null; then
if confirm "是否安装 Redis(推荐用于记忆后端)?" "y"; then
sudo apt install -y redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-server
# 配置持久化
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG SET maxmemory 512mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE
ok "Redis 安装并配置完成"
fi
else
ok "Redis: $(redis-server --version | head -1)"
fi
fi
fi
# =============================================================================
# 第 3 步: 交互式选择
# =============================================================================
info "=== 第 3 步: 交互式配置 ==="
# 选择消息渠道
CHANNEL=$(select_option "选择消息渠道(可多选,稍后配置)" \
"Telegram" "Discord" "Slack" "仅 CLI(不接入消息平台)")
info "已选择渠道: $CHANNEL"
# 选择模型提供商
MODEL_PROVIDER=$(select_option "选择模型提供商" \
"OpenRouter(推荐:200+ 模型)" \
"DeepSeek(最便宜)" \
"Anthropic Claude(高质量)" \
"OpenAI GPT(企业级)" \
"本地 Ollama(免费离线)" \
"Kimi/Moonshot(长上下文)")
case "$MODEL_PROVIDER" in
OpenRouter*)
PROVIDER="openrouter"
read -rp "请输入 OpenRouter API Key (sk-or-v1-...): " API_KEY
DEFAULT_MODEL="anthropic/claude-sonnet-4"
BASE_URL="https://openrouter.ai/api/v1"
;;
DeepSeek*)
PROVIDER="deepseek"
read -rp "请输入 DeepSeek API Key: " API_KEY
DEFAULT_MODEL="deepseek-v4"
BASE_URL="https://api.deepseek.com/v1"
;;
Anthropic*)
PROVIDER="anthropic"
read -rp "请输入 Anthropic API Key (sk-ant-...): " API_KEY
DEFAULT_MODEL="claude-sonnet-4-6"
BASE_URL="https://api.anthropic.com"
;;
OpenAI*)
PROVIDER="openai"
read -rp "请输入 OpenAI API Key (sk-...): " API_KEY
DEFAULT_MODEL="gpt-4o"
BASE_URL="https://api.openai.com/v1"
;;
*Ollama*)
PROVIDER="custom"
API_KEY="ollama"
DEFAULT_MODEL="qwen3:14b"
BASE_URL="http://localhost:11434/v1"
# 检查 Ollama 是否运行
if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
warn "Ollama 未运行。请先安装并启动 Ollama:"
echo " curl -fsSL https://ollama.com/install.sh | sh"
echo " ollama pull qwen3:14b"
fi
;;
Kimi*)
PROVIDER="kimi-coding"
read -rp "请输入 Kimi API Key: " API_KEY
DEFAULT_MODEL="kimi-k2.5"
BASE_URL="https://api.moonshot.cn/v1"
;;
esac
# 选择记忆后端
MEMORY_BACKEND=$(select_option "选择记忆后端" \
"SQLite(默认,零配置)" \
"Redis(高性能)" \
"PostgreSQL(生产级)")
case "$MEMORY_BACKEND" in
SQLite*) MEM_BACKEND="sqlite" ;;
Redis*) MEM_BACKEND="redis" ;;
PostgreSQL*) MEM_BACKEND="postgres" ;;
esac
# 选择执行后端
EXEC_BACKEND=$(select_option "选择执行后端" \
"本地终端(默认)" \
"Docker 沙箱(隔离)" \
"SSH 远程(远端服务器)")
case "$EXEC_BACKEND" in
本地*) TERM_BACKEND="local" ;;
Docker*) TERM_BACKEND="docker" ;;
SSH*) TERM_BACKEND="ssh"
read -rp "SSH 主机: " SSH_HOST
read -rp "SSH 用户 [root]: " SSH_USER
SSH_USER="${SSH_USER:-root}"
read -rp "SSH 端口 [22]: " SSH_PORT
SSH_PORT="${SSH_PORT:-22}"
;;
esac
# =============================================================================
# 第 4 步: 生成配置文件
# =============================================================================
info "=== 第 4 步: 生成配置文件 ==="
HERMES_HOME="$HOME/.hermes"
mkdir -p "$HERMES_HOME"/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}
# ── 生成 .env ──────────────────────────────────────────
ENV_FILE="$HERMES_HOME/.env"
cat > "$ENV_FILE" << ENVEOF
# ── Hermes Agent 环境变量 ──────────────────────────────
# 自动生成于 $(date -Iseconds)
# LLM 提供商
ENVEOF
case "$PROVIDER" in
openrouter) echo "OPENROUTER_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
deepseek) echo "DEEPSEEK_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
anthropic) echo "ANTHROPIC_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
openai) echo "OPENAI_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
kimi-coding) echo "KIMI_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
esac
# 消息渠道 Token
case "$CHANNEL" in
Telegram)
read -rp "请输入 Telegram Bot Token: " TG_TOKEN
echo "TELEGRAM_BOT_TOKEN=$TG_TOKEN" >> "$ENV_FILE"
;;
Discord)
read -rp "请输入 Discord Bot Token: " DC_TOKEN
echo "DISCORD_BOT_TOKEN=$DC_TOKEN" >> "$ENV_FILE"
;;
Slack)
read -rp "请输入 Slack Bot Token (xoxb-...): " SL_TOKEN
echo "SLACK_BOT_TOKEN=$SL_TOKEN" >> "$ENV_FILE"
;;
esac
chmod 600 "$ENV_FILE"
ok ".env 文件已生成: $ENV_FILE"
# ── 生成 config.yaml ──────────────────────────────────
CONFIG_FILE="$HERMES_HOME/config.yaml"
cat > "$CONFIG_FILE" << CONFEOF
# =============================================================================
# ~/.hermes/config.yaml — Hermes Agent 配置
# 自动生成于 $(date -Iseconds)
# =============================================================================
# ── 模型 ─────────────────────────────────────────────
model:
default: "$DEFAULT_MODEL"
provider: "$PROVIDER"
base_url: "$BASE_URL"
# ── 备用模型 ─────────────────────────────────────────
fallback_model:
provider: "openrouter"
model: "anthropic/claude-sonnet-4"
# ── 终端执行后端 ─────────────────────────────────────
terminal:
backend: "$TERM_BACKEND"
cwd: "."
timeout: 180
CONFEOF
# 追加终端后端配置
case "$TERM_BACKEND" in
docker)
cat >> "$CONFIG_FILE" << 'CONFEOF'
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
CONFEOF
;;
ssh)
cat >> "$CONFIG_FILE" << CONFEOF
ssh_host: "$SSH_HOST"
ssh_user: "$SSH_USER"
ssh_port: $SSH_PORT
persistent_shell: true
CONFEOF
;;
esac
cat >> "$CONFIG_FILE" << 'CONFEOF'
# ── Agent 行为 ───────────────────────────────────────
agent:
max_turns: 90
reasoning_effort: "medium"
# ── 记忆 ─────────────────────────────────────────────
memory:
memory_enabled: true
user_profile_enabled: true
memory_char_limit: 2200
user_char_limit: 1375
# ── 上下文压缩 ───────────────────────────────────────
compression:
enabled: true
threshold: 0.50
summary_model: "google/gemini-3-flash-preview"
# ── 审批模式 ─────────────────────────────────────────
approvals:
mode: "manual"
# ── 工具集 ───────────────────────────────────────────
toolsets:
- all
# ── 显示 ─────────────────────────────────────────────
display:
skin: "default"
tool_progress: "all"
compact: false
CONFEOF
ok "config.yaml 已生成: $CONFIG_FILE"
# ── 生成 docker-compose.yml(Docker 模式)───────────
if [[ "$USE_DOCKER" == "true" ]]; then
COMPOSE_FILE="$HOME/hermes-docker/docker-compose.yml"
mkdir -p "$HOME/hermes-docker"
# Docker 模式的 .env
cat > "$HOME/hermes-docker/.env" << DOCKERENVEOF
HERMES_UID=$(id -u)
HERMES_GID=$(id -g)
OPENROUTER_API_KEY=${API_KEY:-}
POSTGRES_PASSWORD=$(openssl rand -hex 16)
DOCKERENVEOF
chmod 600 "$HOME/hermes-docker/.env"
cat > "$COMPOSE_FILE" << 'COMPOSEEOF'
version: "3.8"
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: ["gateway", "run"]
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_UID=${HERMES_UID:-10000}
- HERMES_GID=${HERMES_GID:-10000}
deploy:
resources:
limits:
memory: 4G
depends_on:
redis:
condition: service_healthy
networks:
- hermes-net
redis:
image: redis:7-alpine
container_name: hermes-redis
restart: unless-stopped
command: >
redis-server
--appendonly yes
--appendfsync everysec
--maxmemory 512mb
--maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- hermes-net
dashboard:
image: nousresearch/hermes-agent:latest
container_name: hermes-dashboard
restart: unless-stopped
command: ["dashboard", "--host", "127.0.0.1", "--no-open"]
ports:
- "9119:9119"
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_UID=${HERMES_UID:-10000}
- HERMES_GID=${HERMES_GID:-10000}
depends_on:
- hermes
networks:
- hermes-net
volumes:
redis_data:
networks:
hermes-net:
driver: bridge
COMPOSEEOF
ok "docker-compose.yml 已生成: $COMPOSE_FILE"
fi
# =============================================================================
# 第 6 步: 初始化数据库
# =============================================================================
info "=== 第 6 步: 初始化 ==="
if [[ "$USE_DOCKER" == "false" ]]; then
# 克隆 Hermes Agent
HERMES_SRC="$HOME/.hermes/hermes-agent"
if [[ ! -d "$HERMES_SRC" ]]; then
info "正在克隆 Hermes Agent 仓库..."
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git "$HERMES_SRC"
fi
# 创建虚拟环境并安装
cd "$HERMES_SRC"
uv venv venv --python 3.11
export VIRTUAL_ENV="$(pwd)/venv"
uv pip install -e ".[all]"
# 添加到 PATH
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# 确保 PATH 包含 ~/.local/bin
if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
fi
# 初始化
hermes doctor || true
ok "Hermes Agent 安装完成"
fi
# =============================================================================
# 第 7 步: 启动
# =============================================================================
info "=== 第 7 步: 启动 Hermes Agent ==="
if [[ "$USE_DOCKER" == "true" ]]; then
cd "$HOME/hermes-docker"
docker compose pull
docker compose up -d
info "等待服务启动..."
sleep 10
else
# 安装为 systemd 服务
if [[ "$OS" == "Linux" ]]; then
if confirm "是否安装为 systemd 服务(开机自启)?" "y"; then
sudo tee /etc/systemd/system/hermes-agent.service << SYSEOF
[Unit]
Description=Hermes Agent Gateway
After=network.target redis.service
Requires=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$HERMES_SRC
ExecStart=$HERMES_SRC/venv/bin/hermes gateway run
Restart=always
RestartSec=10
Environment=HERMES_HOME=$HERMES_HOME
[Install]
WantedBy=multi-user.target
SYSEOF
sudo systemctl daemon-reload
sudo systemctl enable hermes-agent
sudo systemctl start hermes-agent
ok "systemd 服务已安装并启动"
fi
fi
# macOS launchd
if [[ "$OS" == "Darwin" ]]; then
hermes gateway install
hermes gateway start
fi
fi
# =============================================================================
# 第 8 步: 可选 Nginx + SSL
# =============================================================================
if [[ "$OS" == "Linux" ]]; then
if confirm "是否配置 Nginx 反向代理 + SSL(Let's Encrypt)?" "n"; then
read -rp "请输入域名(如 hermes.yourdomain.com): " DOMAIN
sudo apt install -y nginx certbot python3-certbot-nginx
sudo tee /etc/nginx/sites-available/hermes << NGINXEOF
server {
listen 80;
server_name $DOMAIN;
location / {
proxy_pass http://127.0.0.1:8642;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
}
}
NGINXEOF
sudo ln -sf /etc/nginx/sites-available/hermes /etc/nginx/sites-enabled/hermes
sudo nginx -t && sudo systemctl reload nginx
# SSL
sudo certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "admin@$DOMAIN"
ok "Nginx + SSL 配置完成: https://$DOMAIN"
fi
fi
# =============================================================================
# 第 9 步: 健康检查和验证
# =============================================================================
info "=== 第 9 步: 健康检查 ==="
MAX_RETRIES=10
RETRY=0
HEALTH_OK=false
while [[ $RETRY -lt $MAX_RETRIES ]]; do
RETRY=$((RETRY + 1))
if curl -sf http://localhost:8642/health >/dev/null 2>&1; then
HEALTH_OK=true
break
fi
info "等待 Hermes 启动... ($RETRY/$MAX_RETRIES)"
sleep 3
done
if [[ "$HEALTH_OK" == "true" ]]; then
ok "Hermes Agent 健康检查通过!"
else
warn "健康检查未通过,请手动检查:"
warn " docker compose logs hermes --tail 50"
warn " 或: journalctl -u hermes-agent --since '5 minutes ago'"
fi
# =============================================================================
# 输出访问地址和管理命令
# =============================================================================
echo ""
echo "============================================================"
echo -e "${GREEN} Hermes Agent 部署完成!${NC}"
echo "============================================================"
echo ""
echo " 📍 访问地址:"
echo " API: http://localhost:8642"
echo " 健康检查: http://localhost:8642/health"
if [[ "$USE_DOCKER" == "true" ]]; then
echo " Dashboard: http://localhost:9119"
fi
echo ""
echo " 🔧 管理命令:"
if [[ "$USE_DOCKER" == "true" ]]; then
echo " 启动: cd ~/hermes-docker && docker compose up -d"
echo " 停止: cd ~/hermes-docker && docker compose down"
echo " 日志: cd ~/hermes-docker && docker compose logs -f hermes"
echo " 升级: cd ~/hermes-docker && docker compose pull && docker compose up -d"
else
echo " 启动: sudo systemctl start hermes-agent"
echo " 停止: sudo systemctl stop hermes-agent"
echo " 状态: sudo systemctl status hermes-agent"
echo " 日志: journalctl -u hermes-agent -f"
echo " CLI: hermes"
echo " 模型: hermes model"
fi
echo ""
echo " 📱 消息网关:"
echo " 配置: hermes gateway setup"
echo " 启动: hermes gateway start"
echo " 状态: hermes gateway status"
echo ""
echo " 💾 备份:"
echo " 手动: tar -czf hermes-backup-\$(date +%F).tar.gz ~/.hermes"
echo ""
echo " 📖 文档: https://hermes-agent.nousresearch.com"
echo "============================================================"
11. 与 OpenClaw 联合部署方案
据《OpenClaw + Hermes Agent: The Two-Agent System I Run Daily》(https://www.mejba.me/blog/openclaw-hermes-multi-agent-workflow),两者天然互补——OpenClaw 擅长规划和编排,Hermes 擅长执行和持续优化。
11.1 架构
plaintext
┌──────────────────────────────────────────────────────────────┐
│ OpenClaw + Hermes 联合架构 │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ OpenClaw │ │ Hermes Agent │ │
│ │ (规划/编排) │◄─────►│ (执行/学习) │ │
│ │ │ A2A │ │ │
│ │ ┌────────────┐ │ 协议 │ ┌────────────┐ │ │
│ │ │ Claude Opus│ │ │ │ DeepSeek V4│ │ │
│ │ │ 重推理模型 │ │ │ │ 轻执行模型 │ │ │
│ │ └────────────┘ │ │ └────────────┘ │ │
│ │ │ │ │ │
│ │ 不学新东西 │ │ 越用越聪明 │ │
│ │ 贵但稳 │ │ 便宜且进化 │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └──────────┬──────────────┘ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ 共享 Ollama │ │
│ │ (本地推理后端) │ │
│ │ port: 11434 │ │
│ └──────────────────────┘ │
│ │
│ 成本效果:总 AI 支出降低约 40%,吞吐量反而提升 │
└──────────────────────────────────────────────────────────────┘
11.2 同机 docker-compose.yml
yaml
# docker-compose.yml — OpenClaw + Hermes 联合部署
version: "3.8"
services:
# ── OpenClaw ────────────────────────────────────────────
openclaw:
image: anthropic/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ~/.openclaw:/home/user/.openclaw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
networks:
- agents-net
# ── Hermes Agent ────────────────────────────────────────
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: ["gateway", "run"]
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_UID=${HERMES_UID:-10000}
- HERMES_GID=${HERMES_GID:-10000}
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
depends_on:
redis:
condition: service_healthy
networks:
- agents-net
# ── Redis(Hermes 专用)────────────────────────────────
redis:
image: redis:7-alpine
container_name: hermes-redis
restart: unless-stopped
command: >
redis-server
--appendonly yes
--appendfsync everysec
--maxmemory 1gb
--maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- agents-net
# ── Ollama(共享推理后端)─────────────────────────────
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
deploy:
resources:
limits:
memory: 16G
cpus: "4.0"
networks:
- agents-net
volumes:
redis_data:
ollama_data:
networks:
agents-net:
driver: bridge
11.3 端口规划
表格
11.4 资源隔离
plaintext
┌──────────────────────────────────────────────────────────────┐
│ 8C16G 服务器资源分配 │
│ │
│ CPU: ████████░░ OpenClaw (4C) │
│ ██████░░░░ Hermes (3C) │
│ ██░░░░░░░░ Ollama/Redis (1C) │
│ │
│ 内存: ████████░░ OpenClaw (4GB) │
│ ██████░░░░ Hermes (4GB) │
│ ████░░░░░░ Ollama/Redis (4GB) │
│ ██░░░░░░░░ 系统 (2GB) │
│ │
│ 磁盘: ~/.openclaw ~500MB │
│ ~/.hermes ~2-5GB(持续增长) │
│ Ollama 模型 ~4-40GB/模型 │
└──────────────────────────────────────────────────────────────┘
11.5 A2A 协议互相发现
Hermes 和 OpenClaw 都支持 A2A(Agent-to-Agent)协议,可以通过 HTTP API 互相发现和协作:
yaml
# Hermes config.yaml — 添加 OpenClaw 为协作 Agent
# mcp:
# servers:
# - name: openclaw
# url: "http://openclaw:8080/v1/mcp"
# headers:
# Authorization: "Bearer ${OPENCLAW_API_KEY}"
11.6 互相健康监控
参考社区实践,让两个 Agent 互相监控对方的健康状态:
yaml
# hermes-tasks/openclaw-health-check.yml
name: openclaw_health_monitor
schedule: "*/30 * * * * *" # 每 30 秒
model: deepseek/deepseek-v4 # 便宜模型
task: |
Check if the OpenClaw process is running and responsive.
If unresponsive for 3+ consecutive checks:
1. Read /var/log/openclaw/latest.log
2. Identify the root cause
3. Apply fix from repair-patterns library
4. Restart openclaw service
5. Notify via Telegram: summary of failure + fix applied
retry_on_failure: true
max_retries: 3
12. 常见问题排查
12.1 Python 版本兼容
问题:python: command not found 或 Python 版本低于 3.11
bash
# 诊断
python3 --version
python3.11 --version
# 解决:用 uv 自动管理 Python 版本
uv venv venv --python 3.11 # uv 会自动下载 Python 3.11
# 或手动安装(Ubuntu)
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.11 python3.11-venv
12.2 PostgreSQL 连接失败
问题:connection refused 或 authentication failed
bash
# 诊断
pg_isready -h localhost -p 5432
psql -U hermes -d hermes -h localhost
# 常见原因 1:PostgreSQL 未启动
sudo systemctl start postgresql
sudo systemctl enable postgresql
# 常见原因 2:pg_hba.conf 不允许密码认证
sudo vim /etc/postgresql/16/main/pg_hba.conf
# 修改:local all all peer → local all all md5
sudo systemctl restart postgresql
# 常见原因 3:密码不对
sudo -u postgres psql -c "ALTER USER hermes WITH PASSWORD 'new-password';"
12.3 Skill 生成不触发
问题:Agent 工作了很多任务,但 Skills 目录是空的
bash
# 诊断 1:检查 Nudge 间隔配置
grep -A5 "skills:" ~/.hermes/config.yaml
# 诊断 2:检查是否手动禁用了
grep "HERMES_SKILL_NUDGE_DISABLE" ~/.hermes/.env
# 诊断 3:检查 Skill 目录权限
ls -la ~/.hermes/skills/
# 原因 1:任务太简单(工具调用 ≤ 5 次不触发)
# 解决:做更复杂的任务,或手动触发
hermes skills create "my-custom-skill"
# 原因 2:Nudge 间隔太大
# 解决:减小间隔
# skills:
# creation_nudge_interval: 5 # 从 10 减到 5
# 原因 3:session 内被关闭
# 解决:在聊天中执行 /skills nudge on
12.4 记忆丢失
问题:重启后 Agent 忘记了之前的内容
bash
# 诊断 1:检查记忆文件是否存在
ls -la ~/.hermes/memories/
cat ~/.hermes/memories/MEMORY.md
cat ~/.hermes/memories/USER.md
# 诊断 2:检查记忆是否被禁用
grep "memory_enabled" ~/.hermes/config.yaml
# 诊断 3:Docker 模式下检查卷挂载
docker inspect hermes | grep -A5 Mounts
# 常见原因 1:Docker 容器重建但未挂载数据卷
# 解决:确保 -v ~/.hermes:/opt/data
# 常见原因 2:Redis 未持久化
# 解决:
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG REWRITE
# 常见原因 3:会话级记忆未写回
# 解决:手动触发记忆保存
# 在对话中说 "请把刚才讨论的要点保存到记忆中"
12.5 Ollama 连接超时
问题:ollama connection refused 或 timeout
bash
# 诊断 1:Ollama 是否在运行
curl http://localhost:11434/api/tags
# 诊断 2:模型是否已下载
ollama list
# 诊断 3:Hermes 配置是否正确
grep -A3 "base_url" ~/.hermes/config.yaml
# 常见原因 1:Ollama 未启动
ollama serve # 或 sudo systemctl start ollama
# 常见原因 2:模型未下载
ollama pull qwen3:14b
# 常见原因 3:Docker 容器网络不通
# 解决:使用 host 网络或正确配置桥接
# docker run --network=host ...
# 或 config.yaml 中 base_url 改为 http://host.docker.internal:11434/v1
# 常见原因 4:超时设置太短
# 解决:增加超时
# providers:
# ollama-local:
# request_timeout_seconds: 300
# stale_timeout_seconds: 900
12.6 日志查看命令速查表
bash
# ── Hermes 内置日志 ─────────────────────────────────────
hermes logs # 所有日志
hermes logs gateway --since 10m # 网关最近 10 分钟
hermes logs errors --tail 100 # 最近 100 条错误
# ── Docker 模式 ─────────────────────────────────────────
docker compose logs hermes --tail 50 # 最近 50 行
docker compose logs hermes -f # 实时跟踪
docker compose logs hermes --since 1h # 最近 1 小时
docker compose logs hermes --grep error # 过滤错误
# ── Systemd 模式 ────────────────────────────────────────
journalctl -u hermes-agent -f # 实时跟踪
journalctl -u hermes-agent --since "10 minutes ago" # 最近 10 分钟
journalctl -u hermes-agent --since yesterday # 昨天以来
journalctl -u hermes-agent -p err # 只看错误
# ── 原始日志文件 ────────────────────────────────────────
tail -f ~/.hermes/logs/errors.log # 错误日志
tail -f ~/.hermes/logs/gateway.log # 网关日志
tail -f ~/.hermes/logs/agent.log # Agent 日志
# ── 健康检查 ────────────────────────────────────────────
curl http://localhost:8642/health # 基础检查
curl http://localhost:8642/health/detailed # 详细检查
# ── Redis 检查 ──────────────────────────────────────────
redis-cli ping # PONG = 正常
redis-cli info memory # 内存使用
redis-cli dbsize # Key 数量
# ── Docker 容器健康 ─────────────────────────────────────
docker compose ps # 所有容器状态
docker stats hermes # 实时资源占用
docker inspect hermes | jq '.[0].State' # 详细状态
12.7 环境诊断一键脚本
bash
#!/bin/bash
# hermes-diagnose.sh — 一键诊断 Hermes Agent 环境
echo "=== Hermes Agent 环境诊断 ==="
echo ""
echo "--- 1. 系统信息 ---"
uname -a
echo "内存: $(free -h | awk '/Mem/{print $2}')"
echo "磁盘: $(df -h ~ | awk 'NR==2{print $4}')"
echo ""
echo "--- 2. Python ---"
python3 --version 2>/dev/null || echo "Python3: 未安装"
python3.11 --version 2>/dev/null || echo "Python3.11: 未安装"
echo ""
echo "--- 3. uv ---"
uv --version 2>/dev/null || echo "uv: 未安装"
echo ""
echo "--- 4. Docker ---"
docker --version 2>/dev/null || echo "Docker: 未安装"
docker compose version 2>/dev/null || echo "Docker Compose: 未安装"
echo ""
echo "--- 5. Hermes 命令 ---"
which hermes 2>/dev/null || echo "hermes: 未找到"
hermes doctor 2>/dev/null || echo "hermes doctor: 执行失败"
echo ""
echo "--- 6. 配置文件 ---"
[[ -f ~/.hermes/.env ]] && echo ".env: 存在 (权限: $(stat -c %a ~/.hermes/.env 2>/dev/null || stat -f %Lp ~/.hermes/.env))" || echo ".env: 不存在"
[[ -f ~/.hermes/config.yaml ]] && echo "config.yaml: 存在" || echo "config.yaml: 不存在"
[[ -f ~/.hermes/memories/SOUL.md ]] && echo "SOUL.md: 存在" || echo "SOUL.md: 不存在"
echo ""
echo "--- 7. 记忆文件 ---"
ls -la ~/.hermes/memories/ 2>/dev/null || echo "memories 目录: 不存在"
echo ""
echo "--- 8. Skills ---"
ls ~/.hermes/skills/ 2>/dev/null | head -20 || echo "skills 目录: 不存在"
echo ""
echo "--- 9. 健康检查 ---"
curl -sf http://localhost:8642/health 2>/dev/null && echo "" || echo "Gateway: 未响应"
echo ""
echo "--- 10. Redis ---"
redis-cli ping 2>/dev/null || echo "Redis: 未运行或未安装"
echo ""
echo "=== 诊断完成 ==="
附录:快速参考
部署方式选择决策树
plaintext
你有 Docker 吗?
├── 是 → 想要隔离环境吗?
│ ├── 是 → 方案一:Docker 部署 ✅(推荐)
│ └── 否 → 方案二:pip/uv 部署
└── 否 → 你是什么系统?
├── macOS → 方案二:pip/uv 部署
├── Linux → 方案三:云服务器一键脚本
└── WSL2 → 先装 Docker,然后方案一
关键文件位置
表格
最小验收清单
上线前确认以下项目:
/health返回{"status":"ok"}/v1/models返回模型列表(需 API Server Key)最小 chat completions 请求成功
Gateway 日志无持续报错
Dashboard 可访问但不暴露公网
.env权限 600,不在 Git 仓库中API Server 前有 TLS 和访问控制
Docker 数据卷已持久化(非 tmpfs)
日志和健康检查已接入监控
自动备份脚本已配置并测试
下一篇预告:#62 将深入 Hermes Agent 的 Skill Hub 生态——如何从零构建和发布你自己的 Skill,以及 agentskills.io 的社区分发机制。
系列文章:
评论区